/// <summary> /// Exports the contributions. /// </summary> /// <param name="modifiedSince">The modified since.</param> public override void ExportContributions(DateTime modifiedSince, bool exportContribImages) { try { using (var dtHoh = GetTableData(SQL_HEAD_OF_HOUSEHOLD)) using (var dtPeople = GetTableData(SQL_PEOPLE)) using (var dtContributions = GetTableData(SQL_CONTRIBUTIONS)) { var headOfHouseholdMap = GetHeadOfHouseholdMap(dtHoh); var dtCompanies = GetTableData(SQL_COMPANIES); var companyIds = new HashSet <int>(dtCompanies.AsEnumerable().Select(s => s.Field <int>("HOUSEHOLD_ID"))); foreach (DataRow row in dtContributions.Rows) { var importTransaction = F1FinancialTransaction.Translate(row, headOfHouseholdMap, companyIds); if (importTransaction != null) { ImportPackage.WriteToPackage(importTransaction); } } } } catch (Exception ex) { ErrorMessage = ex.Message; } }
/// <summary> /// Internal method for ExportContributions(). /// </summary> /// <param name="modifiedSince">The modified since.</param> /// <param name="exportContribImages">Indicates whether images should be exported. (WARNING: Not implemented.)</param> private void ExportContributions_Internal(DateTime modifiedSince, bool exportContribImages) { using (var dtHoh = GetTableData(SqlQueries.HEAD_OF_HOUSEHOLD, true)) using (var dtPeople = GetTableData(SqlQueries.PEOPLE, true)) using (var dtContributions = GetTableData(SqlQueries.CONTRIBUTIONS)) { var headOfHouseholdMap = GetHeadOfHouseholdMap(dtHoh); var dtCompanies = GetTableData(SqlQueries.COMPANY, true); var companyIds = new HashSet <int>(dtCompanies.AsEnumerable().Select(s => s.Field <int>("HOUSEHOLD_ID"))); foreach (DataRow row in dtContributions.Rows) { var importTransaction = F1FinancialTransaction.Translate(row, headOfHouseholdMap, companyIds); if (importTransaction != null) { ImportPackage.WriteToPackage(importTransaction); } } // Cleanup - Remember not to Clear() any cached tables. dtContributions.Clear(); GC.Collect(); } }
/// <summary> /// Exports the contributions. /// </summary> /// <param name="modifiedSince">The modified since.</param> public override void ExportContributions(DateTime modifiedSince, bool exportContribImages) { try { using (var dtContributions = GetTableData(SQL_CONTRIBUTIONS)) { //Get head of house holds because in F1 pledges can be tied to indiviuals or households var headOfHouseHolds = GetTableData(SQL_PEOPLE).Select("household_position = 'Head' "); foreach (DataRow row in dtContributions.Rows) { var importTransaction = F1FinancialTransaction.Translate(row, headOfHouseHolds); if (importTransaction != null) { ImportPackage.WriteToPackage(importTransaction); } } } } catch (Exception ex) { ErrorMessage = ex.Message; } }
/// <summary> /// Internal method for ExportContributions(). /// </summary> /// <param name="modifiedSince">The modified since.</param> /// <param name="exportContribImages">Indicates whether images should be exported. (WARNING: Not implemented.)</param> private void ExportContributions_Internal(DateTime modifiedSince, bool exportContribImages) { var dtContributions = _db.Table("Contribution").Data; var headOfHouseholdMap = GetHeadOfHouseholdMap(_db.Table("Company").Data); var dtCompany = _db.Table("Company").Data; var companyIds = new HashSet <int>(dtCompany.AsEnumerable().Select(s => s.Field <int>("Household_ID"))); foreach (DataRow row in dtContributions.Rows) { var importTransaction = F1FinancialTransaction.Translate(row, headOfHouseholdMap, companyIds); if (importTransaction != null) { ImportPackage.WriteToPackage(importTransaction); } } }
/// <summary> /// Exports the contributions. /// </summary> /// <param name="modifiedSince">The modified since.</param> public override void ExportContributions(DateTime modifiedSince, bool exportContribImages) { HashSet <int> transactionIds = new HashSet <int>(); List <Task> tasks = new List <Task>(); // if empty, build head of household lookups if (!familyMembers.Any()) { familyMembers = GetFamilyMembers(); } // we'll make an api call for each month until the modifiedSince date var today = DateTime.Now; var numberOfMonths = (((today.Year - modifiedSince.Year) * 12) + today.Month - modifiedSince.Month) + 1; try { for (int i = 0; i < numberOfMonths; i++) { DateTime referenceDate = today.AddMonths(((numberOfMonths - i) - 1) * -1); DateTime startDate = new DateTime(referenceDate.Year, referenceDate.Month, 1); DateTime endDate = new DateTime(referenceDate.Year, referenceDate.Month, DateTime.DaysInMonth(referenceDate.Year, referenceDate.Month)); endDate = endDate.AddDays(1); // if it's the first instance set start date to the modifiedSince date if (i == 0) { startDate = modifiedSince; } // if it's the last time through set the end dat to today's date if (i == numberOfMonths - 1) { endDate = today.AddDays(1); } int transactionCurrentPage = 1; int transactionLoopCounter = 0; bool moreTransactionsExist = true; while (moreTransactionsExist) { _request = new RestRequest(API_CONTRIBUTION_RECEIPTS, Method.GET); _request.AddQueryParameter("startReceivedDate", startDate.ToString("yyyy-MM-dd")); _request.AddQueryParameter("endReceivedDate", endDate.ToString("yyyy-MM-dd")); _request.AddQueryParameter("recordsPerPage", "1000"); _request.AddQueryParameter("page", transactionCurrentPage.ToString()); _request.AddHeader("content-type", "application/xml"); var response = _client.Execute(_request); ApiCounter++; XDocument xTransactionsDoc = XDocument.Parse(response.Content); if (F1Api.DumpResponseToXmlFile) { xTransactionsDoc.Save(Path.Combine(ImportPackage.PackageDirectory, $"API_FINANCIAL_TRANSACTIONS_ResponseLog_{transactionLoopCounter++}.xml")); } var sourceTransactions = xTransactionsDoc.Element("results"); if (sourceTransactions != null) { var transactionReturnCount = sourceTransactions.Attribute("count")?.Value.AsIntegerOrNull(); var transactionAdditionalPages = sourceTransactions.Attribute("additionalPages").Value.AsInteger(); if (transactionReturnCount.HasValue) { foreach (var sourceTransaction in sourceTransactions.Elements()) { // If a transaction is updated during an export, the transaction could be returned // twice by the API. Also, since there is a slight overlap in dates, this ensures // that a transaction only gets imported once. if (!transactionIds.Contains(sourceTransaction.Attribute("id").Value.AsInteger())) { var importTransaction = F1FinancialTransaction.Translate(sourceTransaction, familyMembers); var importTransactionDetail = F1FinancialTransactionDetail.Translate(sourceTransaction); if (importTransaction != null) { ImportPackage.WriteToPackage(importTransaction); } if (importTransactionDetail != null) { ImportPackage.WriteToPackage(importTransactionDetail); } // save check image if (exportContribImages) { var checkImageId = sourceTransaction.Element("referenceImage").Attribute("id")?.Value; if (checkImageId.IsNotNullOrWhitespace()) { var task = Task.Run(() => { var client = new RestClient(ApiUrl); client.Authenticator = OAuth1Authenticator.ForProtectedResource(ApiConsumerKey, ApiConsumerSecret, OAuthToken, OAuthSecret); var imageRequest = new RestRequest(API_CONTRIBUTION_RECEIPT_IMAGE + checkImageId, Method.GET); var image = client.DownloadData(imageRequest); ApiCounter++; if (image != null) { var transactionId = sourceTransaction.Attribute("id").Value; var path = Path.Combine(ImportPackage.ImageDirectory, "FinancialTransaction_" + transactionId + "_0.jpg"); File.WriteAllBytes(path, image); } }); tasks.Add(task); } } transactionIds.Add(sourceTransaction.Attribute("id").Value.AsInteger()); } } if (transactionAdditionalPages <= 0) { moreTransactionsExist = false; } else { transactionCurrentPage++; } } } else { moreTransactionsExist = false; } // developer safety blanket (prevents eating all the api calls for the day) if (transactionLoopCounter > loopThreshold) { break; } transactionLoopCounter++; } } // wait till all images are downloaded Task.WaitAll(tasks.ToArray()); } catch (Exception ex) { ErrorMessage = ex.Message; } }