private string EvaluateVerificationResults(TVerificationResult AExpectedResult, TVerificationResult ATestResult) { TVerificationResultCollection Tmp; if (!TVerificationHelper.AreVerificationResultsIdentical(ATestResult, AExpectedResult)) { Tmp = new TVerificationResultCollection(); if (AExpectedResult != null) { Tmp.Add(AExpectedResult); } if (ATestResult != null) { Tmp.Add(ATestResult); } return TVerificationHelper.FormatVerificationCollectionItems(Tmp); } else { return String.Empty; } }
/// <summary> /// Imports a string value from the specified text line using the specified delimiter /// </summary> /// <param name="AImportLine">The line containing the text to be imported. When the method returns the imported value /// will have been removed from the start ready for the next call to an Import method.</param> /// <param name="ADelimiter">The delimiter</param> /// <param name="AColumnTitle"></param> /// <param name="ADataColumn"></param> /// <param name="ARowNumber"></param> /// <param name="AMessages"></param> /// <param name="AValidationColumnsDict"></param> /// <param name="ATreatEmptyStringAsText">When true the return value will be the empty string. When false the return value will be null.</param> /// <returns>The string value. The AImportLine parameter will have been clipped.</returns> public static String ImportString(ref String AImportLine, String ADelimiter, String AColumnTitle, DataColumn ADataColumn, int ARowNumber, TVerificationResultCollection AMessages, TValidationControlsDict AValidationColumnsDict, bool ATreatEmptyStringAsText = true) { if ((ADataColumn != null) && (AValidationColumnsDict != null) && !AValidationColumnsDict.ContainsKey(ADataColumn)) { AValidationColumnsDict.Add(ADataColumn, new TValidationControlsData(null, AColumnTitle)); } String sReturn = StringHelper.GetNextCSV(ref AImportLine, ADelimiter); if ((sReturn == StringHelper.CSV_STRING_FORMAT_ERROR) && (AMessages != null)) { AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrParsingErrorInLineColumn, ARowNumber, AColumnTitle), Catalog.GetString("Could not parse the quoted string. Did you forget a quotation mark?"), TResultSeverity.Resv_Critical)); } if ((sReturn.Length == 0) && !ATreatEmptyStringAsText) { return null; } return sReturn; }
public static bool TPeriodYearEnd( int ALedgerNum, bool AIsInInfoMode, out TVerificationResultCollection AVerificationResult) { bool NewTransaction; DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.Serializable, out NewTransaction); try { TLedgerInfo LedgerInfo = new TLedgerInfo(ALedgerNum); bool res = new TYearEnd(LedgerInfo).RunYearEnd(AIsInInfoMode, out AVerificationResult); if (!res) { String SuccessMsg = AIsInInfoMode ? "YearEnd check: No problems found." : "Success."; AVerificationResult.Add(new TVerificationResult("Year End", SuccessMsg, "Success", TResultSeverity.Resv_Status)); } if (NewTransaction) { DBAccess.GDBAccessObj.CommitTransaction(); } return res; } catch (Exception e) { TLogging.Log("TPeriodIntervalConnector.TPeriodYearEnd() throws " + e.ToString()); AVerificationResult = new TVerificationResultCollection(); AVerificationResult.Add( new TVerificationResult( Catalog.GetString("Year End"), Catalog.GetString("Uncaught Exception: ") + e.Message, TResultSeverity.Resv_Critical)); DBAccess.GDBAccessObj.RollbackTransaction(); return false; } }
/// <summary> /// Downgrades all <see cref="TScreenVerificationResult" /> items in a <see cref="TVerificationResultCollection" /> /// to <see cref="TVerificationResult" /> items. /// </summary> /// <param name="AScreenVerificationResults">A <see cref="TVerificationResultCollection" /> holding <em>exclusively</em> /// <see cref="TScreenVerificationResult" /> items.</param> public static void DowngradeScreenVerificationResults(TVerificationResultCollection AScreenVerificationResults) { int NumberOfVerificationResults = AScreenVerificationResults.Count; int NumberOfDowngradedVerificationResults = 0; for (int Counter1 = 0; Counter1 < NumberOfVerificationResults; Counter1++) { if (AScreenVerificationResults[Counter1] is TScreenVerificationResult) { AScreenVerificationResults.Add(new TVerificationResult((TScreenVerificationResult)AScreenVerificationResults[Counter1])); NumberOfDowngradedVerificationResults++; } } for (int Counter2 = 0; Counter2 < NumberOfDowngradedVerificationResults; Counter2++) { AScreenVerificationResults.RemoveAt(0); } }
/// <summary> /// Reads from the table holding all the fees charged for this month and generates a GL batch from it. /// Relates to gl2150.p /// </summary> /// <param name="ALedgerNumber"></param> /// <param name="APeriodNumber"></param> /// <param name="APrintReport"></param> /// <param name="ADBTransaction"></param> /// <param name="AVerificationResult"></param> /// <returns></returns> private static bool GenerateAdminFeeBatch(int ALedgerNumber, int APeriodNumber, bool APrintReport, TDBTransaction ADBTransaction, ref TVerificationResultCollection AVerificationResult ) { bool IsSuccessful = false; bool CreatedSuccessfully = false; decimal TransactionAmount; string DrAccountCode; string DestCostCentreCode = string.Empty; string DestAccountCode = string.Empty; string FeeDescription = string.Empty; decimal DrFeeTotal = 0; bool DrCrIndicator = true; //Error handling string ErrorContext = String.Empty; string ErrorMessage = String.Empty; //Set default type as non-critical TResultSeverity ErrorType = TResultSeverity.Resv_Noncritical; /* Make a temporary table to hold totals for gifts going to * each account. */ GLStewardshipCalculationTDSCreditFeeTotalTable CreditFeeTotalDT = new GLStewardshipCalculationTDSCreditFeeTotalTable(); //int x = CreditFeeTotalDT.Count; /* Retrieve info on the ledger. */ ALedgerTable AvailableLedgers = ALedgerAccess.LoadByPrimaryKey(ALedgerNumber, ADBTransaction); ALedgerRow LedgerRow = (ALedgerRow)AvailableLedgers.Rows[0]; try { /* Check that we have not closed all periods for the year yet. * (Not at the provisional year end point) */ if (LedgerRow.ProvisionalYearEndFlag) { //Petra ErrorCode = GL0071 ErrorContext = Catalog.GetString("Generate Admin Fee Batch"); ErrorMessage = String.Format(Catalog.GetString( "Cannot progress as Ledger {0} is at the provisional year-end point"), ALedgerNumber); ErrorType = TResultSeverity.Resv_Critical; throw new System.InvalidOperationException(ErrorMessage); } /* 0003 Finds for ledger base currency format, for report currency format */ ACurrencyTable CurrencyInfo = ACurrencyAccess.LoadByPrimaryKey(LedgerRow.BaseCurrency, ADBTransaction); ACurrencyRow CurrencyRow = (ACurrencyRow)CurrencyInfo.Rows[0]; /* 0001 Extract number of decimal places */ string NumericFormat = CurrencyRow.DisplayFormat; int NumDecPlaces = THelperNumeric.CalcNumericFormatDecimalPlaces(NumericFormat); /* Create the journal to create the fee transactions in, if there are * fees to charge. * NOTE: if the date in the processed fee table is ? then that fee * hasn't been processed. */ AProcessedFeeTable ProcessedFeeDataTable = new AProcessedFeeTable(); string sqlStmt = String.Format("SELECT * FROM {0} WHERE {1} = ? AND {2} = ? AND {3} IS NULL AND {4} <> 0 ORDER BY {5}, {6}", AProcessedFeeTable.GetTableDBName(), AProcessedFeeTable.GetLedgerNumberDBName(), AProcessedFeeTable.GetPeriodNumberDBName(), AProcessedFeeTable.GetProcessedDateDBName(), AProcessedFeeTable.GetPeriodicAmountDBName(), AProcessedFeeTable.GetFeeCodeDBName(), AProcessedFeeTable.GetCostCentreCodeDBName() ); OdbcParameter[] parameters = new OdbcParameter[2]; parameters[0] = new OdbcParameter("LedgerNumber", OdbcType.Int); parameters[0].Value = ALedgerNumber; parameters[1] = new OdbcParameter("PeriodNumber", OdbcType.Int); parameters[1].Value = APeriodNumber; DBAccess.GDBAccessObj.SelectDT(ProcessedFeeDataTable, sqlStmt, ADBTransaction, parameters, -1, -1); if (ProcessedFeeDataTable.Count == 0) { if (TLogging.DebugLevel > 0) { TLogging.Log("No fees to charge were found"); AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Admin Fee Batch"), String.Format(Catalog.GetString("No admin fees charged in period {0}."), APeriodNumber), TResultSeverity.Resv_Status)); } IsSuccessful = true; } else { //Post to Ledger - Ln 132 //****************4GL Transaction Starts Here******************** AAccountingPeriodTable AccountingPeriodTable = AAccountingPeriodAccess.LoadByPrimaryKey(ALedgerNumber, APeriodNumber, ADBTransaction); AAccountingPeriodRow AccountingPeriodRow = (AAccountingPeriodRow)AccountingPeriodTable.Rows[0]; // Create a Batch. If no fees are to be charged, I'll delete this batch later. GLBatchTDS AdminFeeDS = TGLPosting.CreateABatch(ALedgerNumber, Catalog.GetString( "Admin Fees & Grants"), 0, AccountingPeriodRow.PeriodEndDate); ABatchRow BatchRow = AdminFeeDS.ABatch[0]; AJournalRow JournalRow = AdminFeeDS.AJournal.NewRowTyped(); JournalRow.LedgerNumber = ALedgerNumber; JournalRow.BatchNumber = BatchRow.BatchNumber; JournalRow.JournalNumber = ++BatchRow.LastJournal; JournalRow.JournalDescription = BatchRow.BatchDescription; JournalRow.SubSystemCode = MFinanceConstants.SUB_SYSTEM_GL; JournalRow.TransactionTypeCode = CommonAccountingTransactionTypesEnum.STD.ToString(); JournalRow.TransactionCurrency = LedgerRow.BaseCurrency; JournalRow.ExchangeRateToBase = 1; JournalRow.DateEffective = AccountingPeriodRow.PeriodEndDate; JournalRow.JournalPeriod = APeriodNumber; AdminFeeDS.AJournal.Rows.Add(JournalRow); // // Generate the transactions // /* M009 Changed the following loop for Petra 2.1 design changes. a_processed_fee * now has a record for each gift detail so it is necessary to sum up all the * totals for each fee code/cost centre so that only one transaction is posted * for each */ int GLJournalNumber = JournalRow.JournalNumber; int GLTransactionNumber = 0; string CurrentFeeCode = string.Empty; string CostCentreCode = string.Empty; string CostCentreCodeDBName = AProcessedFeeTable.GetCostCentreCodeDBName(); for (int i = 0; i < ProcessedFeeDataTable.Count; i++) { AProcessedFeeRow pFR = (AProcessedFeeRow)ProcessedFeeDataTable.Rows[i]; if (CurrentFeeCode != pFR.FeeCode) { CurrentFeeCode = pFR.FeeCode; // Find first AFeesPayableTable FeesPayableTable = AFeesPayableAccess.LoadByPrimaryKey(ALedgerNumber, CurrentFeeCode, ADBTransaction); if (FeesPayableTable.Count > 0) //if null try receivables instead { AFeesPayableRow FeesPayableRow = (AFeesPayableRow)FeesPayableTable.Rows[0]; DrAccountCode = FeesPayableRow.DrAccountCode; DestCostCentreCode = FeesPayableRow.CostCentreCode; DestAccountCode = FeesPayableRow.AccountCode; FeeDescription = FeesPayableRow.FeeDescription; } else { AFeesReceivableTable FeesReceivableTable = AFeesReceivableAccess.LoadByPrimaryKey(ALedgerNumber, CurrentFeeCode, ADBTransaction); if (FeesReceivableTable.Count > 0) { AFeesReceivableRow FeesReceivableRow = (AFeesReceivableRow)FeesReceivableTable.Rows[0]; DrAccountCode = FeesReceivableRow.DrAccountCode; DestCostCentreCode = FeesReceivableRow.CostCentreCode; DestAccountCode = FeesReceivableRow.AccountCode; FeeDescription = FeesReceivableRow.FeeDescription; } else { //Petra error: X_0007 ErrorContext = Catalog.GetString("Generate Transactions"); ErrorMessage = String.Format(Catalog.GetString( "Unable to access information for Fee Code '{1}' in either the Fees Payable & Receivable Tables for Ledger {0}"), ALedgerNumber, CurrentFeeCode); ErrorType = TResultSeverity.Resv_Critical; throw new System.InvalidOperationException(ErrorMessage); } } DrFeeTotal = 0; //Get all the distinct CostCentres DataView CostCentreView = ProcessedFeeDataTable.DefaultView; CostCentreView.Sort = CostCentreCodeDBName; CostCentreView.RowFilter = string.Format("{0} = '{1}'", AProcessedFeeTable.GetFeeCodeDBName(), CurrentFeeCode); DataTable ProcessedFeeCostCentresTable = CostCentreView.ToTable(true, CostCentreCodeDBName); foreach (DataRow r in ProcessedFeeCostCentresTable.Rows) { CostCentreCode = r[0].ToString(); DataView view = ProcessedFeeDataTable.DefaultView; view.Sort = CostCentreCodeDBName; view.RowFilter = string.Format("{0} = '{1}' AND {2} = '{3}'", AProcessedFeeTable.GetFeeCodeDBName(), CurrentFeeCode, CostCentreCodeDBName, CostCentreCode); //ProcessedFeeDataTable2 = ProcessedFeeDataTable2.Clone(); DataTable ProcessedFeeDataTable2 = view.ToTable(); Int32 FeeCodeRowCount = ProcessedFeeDataTable2.Rows.Count; for (int j = 0; j < FeeCodeRowCount; j++) { DataRow pFR2 = ProcessedFeeDataTable2.Rows[j]; DrFeeTotal = DrFeeTotal + Math.Round(Convert.ToDecimal( pFR2[AProcessedFeeTable.GetPeriodicAmountDBName()]), NumDecPlaces); //pFR2.PeriodicAmount; //ROUND(pFR2.PeriodicAmount, // lv_dp) if (j == (FeeCodeRowCount - 1)) //implies last of the CostCentre rows for this feecode { if (DrFeeTotal != 0) { if (DrFeeTotal < 0) { DrCrIndicator = false; //Credit DrFeeTotal = -DrFeeTotal; } else { DrCrIndicator = true; //Debit //lv_dr_fee_total remains unchanged } /* * Generate the transaction to deduct the fee amount from the source cost centre. (Expense leg) */ //RUN gl1130o.p -> gl1130.i //Create a transaction if (!TGLPosting.CreateATransaction(AdminFeeDS, ALedgerNumber, BatchRow.BatchNumber, GLJournalNumber, "Fee: " + FeeDescription + " (" + CurrentFeeCode + ")", DrAccountCode, CostCentreCode, DrFeeTotal, AccountingPeriodRow.PeriodEndDate, DrCrIndicator, "AG", true, DrFeeTotal, out GLTransactionNumber)) { ErrorContext = Catalog.GetString("Generating the Admin Fee batch"); ErrorMessage = String.Format(Catalog.GetString( "Unable to create a new transaction for Ledger {0}, Batch {1} and Journal {2}."), ALedgerNumber, BatchRow.BatchNumber, GLJournalNumber); ErrorType = TResultSeverity.Resv_Noncritical; throw new System.InvalidOperationException(ErrorMessage); } DrFeeTotal = 0; } } } } } /* Mark each fee entry as processed. */ pFR.ProcessedDate = DateTime.Today.Date; pFR.Timestamp = (DateTime.Today.TimeOfDay.Hours * 3600 + DateTime.Today.TimeOfDay.Minutes * 60 + DateTime.Today.TimeOfDay.Seconds); /* Add the charges on this account to the fee total, * creating an entry if necessary. (This is for the income total) */ GLStewardshipCalculationTDSCreditFeeTotalRow CreditFeeTotalRow = (GLStewardshipCalculationTDSCreditFeeTotalRow) CreditFeeTotalDT.Rows.Find(new object[] { DestCostCentreCode, DestAccountCode }); if (CreditFeeTotalRow != null) { CreditFeeTotalRow.TransactionAmount += Math.Round(pFR.PeriodicAmount, NumDecPlaces); } else { CreditFeeTotalRow = CreditFeeTotalDT.NewRowTyped(); CreditFeeTotalRow.CostCentreCode = DestCostCentreCode; CreditFeeTotalRow.AccountCode = DestAccountCode; CreditFeeTotalRow.TransactionAmount = Math.Round(pFR.PeriodicAmount, NumDecPlaces); CreditFeeTotalDT.Rows.Add(CreditFeeTotalRow); } } /* Generate the transaction to credit the fee amounts to * the destination accounts. (Income leg) */ for (int k = 0; k < CreditFeeTotalDT.Count; k++) { GLStewardshipCalculationTDSCreditFeeTotalRow cFT = (GLStewardshipCalculationTDSCreditFeeTotalRow) CreditFeeTotalDT.Rows[k]; if (cFT.TransactionAmount < 0) { /* The case of a negative gift total should be very rare. * It would only happen if, for instance, the was only * a reversal but no new gifts for a certain ledger. */ DrCrIndicator = true; //Debit TransactionAmount = -cFT.TransactionAmount; } else { DrCrIndicator = false; //Credit TransactionAmount = cFT.TransactionAmount; } /* 0002 - Ok for it to be 0 as just a correction */ if (cFT.TransactionAmount != 0) { GLTransactionNumber = 0; CreatedSuccessfully = TGLPosting.CreateATransaction(AdminFeeDS, ALedgerNumber, BatchRow.BatchNumber, JournalRow.JournalNumber, "Collected admin charges", cFT.AccountCode, cFT.CostCentreCode, TransactionAmount, AccountingPeriodRow.PeriodEndDate, DrCrIndicator, "AG", true, TransactionAmount, out GLTransactionNumber); } } TVerificationResultCollection Verification = null; /* check that something has been posted - we know this if the IsSuccessful flag is still false */ if (!CreatedSuccessfully) { IsSuccessful = true; AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Admin Fee Batch"), String.Format(Catalog.GetString("No admin fees charged in period ({0})."), APeriodNumber), TResultSeverity.Resv_Status)); // An empty GL Batch now exists, which I need to delete. // TVerificationResultCollection BatchCancelResult = new TVerificationResultCollection(); TGLPosting.DeleteGLBatch( ALedgerNumber, BatchRow.BatchNumber, out BatchCancelResult); AVerificationResult.AddCollection(BatchCancelResult); } else { //Post the batch just created GLBatchTDSAccess.SubmitChanges(AdminFeeDS); IsSuccessful = TGLPosting.PostGLBatch(ALedgerNumber, BatchRow.BatchNumber, out Verification); if (IsSuccessful) { AProcessedFeeAccess.SubmitChanges(ProcessedFeeDataTable, ADBTransaction); } } if (!TVerificationHelper.IsNullOrOnlyNonCritical(Verification)) { //Petra error: GL0067 ErrorContext = Catalog.GetString("Posting Admin Fee Batch"); ErrorMessage = String.Format(Catalog.GetString("The posting of the admin fee batch failed.")); ErrorType = TResultSeverity.Resv_Noncritical; throw new System.InvalidOperationException(ErrorMessage); } //End of Transaction block in 4GL /* Print the Admin Fee Calculations report, if requested */ if (APrintReport && IsSuccessful) { //TODO } } } catch (InvalidOperationException ex) { AVerificationResult.Add(new TVerificationResult(ErrorContext, ex.Message, ErrorType)); IsSuccessful = false; } catch (Exception ex) { ErrorContext = Catalog.GetString("Generate Admin Fee Batch"); ErrorMessage = String.Format(Catalog.GetString("Error while generating admin fee batch for Ledger {0}:" + Environment.NewLine + Environment.NewLine + ex.ToString()), ALedgerNumber ); ErrorType = TResultSeverity.Resv_Critical; AVerificationResult.Add(new TVerificationResult(ErrorContext, ErrorMessage, ErrorType)); IsSuccessful = false; } return IsSuccessful; }
public static bool GenerateICHStewardshipBatch(int ALedgerNumber, int APeriodNumber, ref TVerificationResultCollection AVerificationResult) { string StandardCostCentre = TLedgerInfo.GetStandardCostCentre(ALedgerNumber); bool IsSuccessful = false; bool DrCrIndicator = true; bool IncomeDrCrIndicator; bool ExpenseDrCrIndicator; bool AccountDrCrIndicator; string IncomeAccounts = string.Empty; string ExpenseAccounts = string.Empty; //Error handling string ErrorContext = String.Empty; string ErrorMessage = String.Empty; //Set default type as non-critical TResultSeverity ErrorType = TResultSeverity.Resv_Noncritical; bool NewTransaction = false; TDBTransaction DBTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.Serializable, out NewTransaction); //Generating the ICH batch... try { DateTime PeriodStartDate; DateTime PeriodEndDate; TFinancialYear.GetStartAndEndDateOfPeriod(ALedgerNumber, APeriodNumber, out PeriodStartDate, out PeriodEndDate, DBTransaction); String strPeriodStartDate = "#" + PeriodStartDate.ToString("yyyy-MM-dd") + "#"; String strPeriodEndDate = "#" + PeriodEndDate.ToString("yyyy-MM-dd") + "#"; AGiftBatchTable GiftBatchTable = new AGiftBatchTable(); String GiftQuery = "SELECT * FROM a_gift_batch WHERE " + AGiftBatchTable.GetLedgerNumberDBName() + " = " + ALedgerNumber + " AND " + AGiftBatchTable.GetBatchStatusDBName() + " = '" + MFinanceConstants.BATCH_POSTED + "'" + " AND " + AGiftBatchTable.GetGlEffectiveDateDBName() + " >= " + strPeriodStartDate + " AND " + AGiftBatchTable.GetGlEffectiveDateDBName() + " <= " + strPeriodEndDate + " ORDER BY " + AGiftBatchTable.GetBatchNumberDBName(); DBAccess.GDBAccessObj.SelectDT(GiftBatchTable, GiftQuery, DBTransaction); //Create a new batch. If it turns out I don't need one, I can delete it later. GLBatchTDS MainDS = TGLPosting.CreateABatch(ALedgerNumber, Catalog.GetString("ICH Stewardship"), 0, PeriodEndDate); ABatchRow NewBatchRow = MainDS.ABatch[0]; int GLBatchNumber = NewBatchRow.BatchNumber; //Load tables needed: AccountingPeriod, Ledger, Account, Cost Centre, Transaction, Gift Batch, ICHStewardship GLPostingTDS PostingDS = new GLPostingTDS(); ALedgerAccess.LoadByPrimaryKey(PostingDS, ALedgerNumber, DBTransaction); AAccountAccess.LoadViaALedger(PostingDS, ALedgerNumber, DBTransaction); AIchStewardshipAccess.LoadViaALedger(PostingDS, ALedgerNumber, DBTransaction); AAccountHierarchyAccess.LoadViaALedger(PostingDS, ALedgerNumber, DBTransaction); ABatchTable BatchTable = new ABatchTable(); ABatchRow BatchTemplateRow = (ABatchRow)BatchTable.NewRowTyped(false); BatchTemplateRow.LedgerNumber = ALedgerNumber; BatchTemplateRow.BatchPeriod = APeriodNumber; StringCollection Operators0 = StringHelper.InitStrArr(new string[] { "=", "=" }); StringCollection OrderList0 = new StringCollection(); OrderList0.Add("ORDER BY"); OrderList0.Add(ABatchTable.GetBatchNumberDBName() + " DESC"); ABatchTable BatchesInAPeriod = ABatchAccess.LoadUsingTemplate(BatchTemplateRow, Operators0, null, DBTransaction, OrderList0, 0, 0); if (BatchesInAPeriod != null) { int BatchNumber = 0; for (int i = 0; i < BatchesInAPeriod.Count; i++) { ABatchRow batchRow = (ABatchRow)BatchesInAPeriod.Rows[i]; BatchNumber = batchRow.BatchNumber; AJournalAccess.LoadViaABatch(MainDS, ALedgerNumber, BatchNumber, DBTransaction); ATransactionAccess.LoadViaABatch(MainDS, ALedgerNumber, BatchNumber, DBTransaction); } } else { ErrorContext = Catalog.GetString("Generating the ICH batch"); ErrorMessage = String.Format(Catalog.GetString("No Batches found to process in Ledger: {0}"), ALedgerNumber); ErrorType = TResultSeverity.Resv_Noncritical; throw new System.InvalidOperationException(ErrorMessage); } ALedgerRow LedgerRow = (ALedgerRow)PostingDS.ALedger.Rows[0]; //Create a new journal in the Batch //Run gl1120o.p AJournalRow NewJournalRow = MainDS.AJournal.NewRowTyped(); NewJournalRow.LedgerNumber = ALedgerNumber; NewJournalRow.BatchNumber = GLBatchNumber; NewJournalRow.JournalNumber = ++NewBatchRow.LastJournal; NewJournalRow.JournalDescription = NewBatchRow.BatchDescription; NewJournalRow.SubSystemCode = MFinanceConstants.SUB_SYSTEM_GL; NewJournalRow.TransactionTypeCode = CommonAccountingTransactionTypesEnum.STD.ToString(); NewJournalRow.TransactionCurrency = LedgerRow.BaseCurrency; NewJournalRow.ExchangeRateToBase = 1; NewJournalRow.DateEffective = PeriodEndDate; NewJournalRow.JournalPeriod = APeriodNumber; MainDS.AJournal.Rows.Add(NewJournalRow); int GLJournalNumber = NewJournalRow.JournalNumber; int GLTransactionNumber = NewJournalRow.LastTransactionNumber + 1; // *************************** // Generate the transactions // *************************** AAccountRow AccountRow = (AAccountRow)PostingDS.AAccount.Rows.Find(new object[] { ALedgerNumber, MFinanceConstants.INCOME_HEADING }); //Process income accounts if (AccountRow != null) { IncomeDrCrIndicator = AccountRow.DebitCreditIndicator; } else { ErrorContext = Catalog.GetString("Generating the ICH batch"); ErrorMessage = String.Format(Catalog.GetString("Income Account header: '{1}' not found in the accounts table for Ledger: {0}."), ALedgerNumber, MFinanceConstants.INCOME_HEADING); ErrorType = TResultSeverity.Resv_Noncritical; throw new System.InvalidOperationException(ErrorMessage); } BuildChildAccountList(ALedgerNumber, AccountRow, DBTransaction, ref IncomeAccounts, ref AVerificationResult); //Process expense accounts AccountRow = (AAccountRow)PostingDS.AAccount.Rows.Find(new object[] { ALedgerNumber, MFinanceConstants.EXPENSE_HEADING }); if (AccountRow != null) { ExpenseDrCrIndicator = AccountRow.DebitCreditIndicator; } else { ErrorContext = Catalog.GetString("Generating the ICH batch"); ErrorMessage = String.Format(Catalog.GetString("Expense Account header: '{1}' not found in the accounts table for Ledger: {0}."), ALedgerNumber, MFinanceConstants.EXPENSE_HEADING); ErrorType = TResultSeverity.Resv_Noncritical; throw new System.InvalidOperationException(ErrorMessage); } BuildChildAccountList(ALedgerNumber, AccountRow, DBTransaction, ref ExpenseAccounts, ref AVerificationResult); //Process P&L accounts AccountRow = (AAccountRow)PostingDS.AAccount.Rows.Find(new object[] { ALedgerNumber, MFinanceConstants.PROFIT_AND_LOSS_HEADING }); if (AccountRow != null) { AccountDrCrIndicator = AccountRow.DebitCreditIndicator; } else { ErrorContext = Catalog.GetString("Generating the ICH batch"); ErrorMessage = String.Format(Catalog.GetString("Profit & Loss Account header: '{1}' not found in the accounts table for Ledger: {0}."), ALedgerNumber, MFinanceConstants.PROFIT_AND_LOSS_HEADING); ErrorType = TResultSeverity.Resv_Noncritical; throw new System.InvalidOperationException(ErrorMessage); } // find out the stewardship number - Ln 275 // Increment the Last ICH No. int ICHProcessing = ++LedgerRow.LastIchNumber; decimal ICHTotal = 0; bool PostICHBatch = false; ACostCentreRow CCTemplateRow = PostingDS.ACostCentre.NewRowTyped(false); CCTemplateRow.LedgerNumber = ALedgerNumber; CCTemplateRow.PostingCostCentreFlag = true; CCTemplateRow.CostCentreType = MFinanceConstants.FOREIGN_CC_TYPE; ACostCentreAccess.LoadUsingTemplate(PostingDS, CCTemplateRow, DBTransaction); //Iterate through the cost centres // string OrderBy = ACostCentreTable.GetCostCentreCodeDBName(); StringDictionary DestinationAccount = GetDestinationAccountCodes(ALedgerNumber, PostingDS.ACostCentre, DBTransaction); AIchStewardshipTable ICHStewardshipTable = new AIchStewardshipTable(); Boolean NonIchTransactionsIncluded = false; String JournalRowOrder = "a_journal_number_i"; String TransRowOrder = "a_batch_number_i,a_journal_number_i,a_transaction_number_i"; foreach (ACostCentreRow CostCentreRow in PostingDS.ACostCentre.Rows) { string CostCentre = CostCentreRow.CostCentreCode; //Initialise values for each Cost Centre decimal SettlementAmount = 0; decimal IncomeAmount = 0; decimal ExpenseAmount = 0; decimal XferAmount = 0; decimal IncomeAmountIntl = 0; decimal ExpenseAmountIntl = 0; decimal XferAmountIntl = 0; Boolean TransferFound = false; /* 0008 Go through all of the transactions. Ln:301 */ String WhereClause = "a_cost_centre_code_c = '" + CostCentreRow.CostCentreCode + "' AND a_transaction_status_l=true AND a_ich_number_i = 0"; DataRow[] FoundTransRows = MainDS.ATransaction.Select(WhereClause, TransRowOrder); foreach (DataRow UntypedTransRow in FoundTransRows) { ATransactionRow TransRow = (ATransactionRow)UntypedTransRow; DataRow[] FoundJournalRows = MainDS.AJournal.Select( "a_batch_number_i = " + TransRow.BatchNumber + " AND a_journal_number_i = " + TransRow.JournalNumber, JournalRowOrder); if (FoundJournalRows != null) { TransferFound = true; PostICHBatch = true; TransRow.IchNumber = ICHProcessing; if (TransRow.DebitCreditIndicator == AccountDrCrIndicator) { SettlementAmount -= TransRow.AmountInBaseCurrency; } else { SettlementAmount += TransRow.AmountInBaseCurrency; } //Process Income (ln:333) if (IncomeAccounts.Contains(TransRow.AccountCode)) { if (TransRow.DebitCreditIndicator == IncomeDrCrIndicator) { IncomeAmount += TransRow.AmountInBaseCurrency; IncomeAmountIntl += TransRow.AmountInIntlCurrency; } else { IncomeAmount -= TransRow.AmountInBaseCurrency; IncomeAmountIntl -= TransRow.AmountInIntlCurrency; } } //process expenses if (ExpenseAccounts.Contains(TransRow.AccountCode) && (TransRow.AccountCode != MFinanceConstants.DIRECT_XFER_ACCT) && (TransRow.AccountCode != MFinanceConstants.ICH_ACCT_SETTLEMENT)) { if (TransRow.DebitCreditIndicator = ExpenseDrCrIndicator) { ExpenseAmount += TransRow.AmountInBaseCurrency; ExpenseAmountIntl += TransRow.AmountInIntlCurrency; } else { ExpenseAmount -= TransRow.AmountInBaseCurrency; ExpenseAmountIntl -= TransRow.AmountInIntlCurrency; } } //Process Direct Transfers if (TransRow.AccountCode == MFinanceConstants.DIRECT_XFER_ACCT) { if (TransRow.DebitCreditIndicator == ExpenseDrCrIndicator) { XferAmount += TransRow.AmountInBaseCurrency; XferAmountIntl += TransRow.AmountInIntlCurrency; } else { XferAmount -= TransRow.AmountInBaseCurrency; XferAmountIntl -= TransRow.AmountInIntlCurrency; } } } } //end of foreach transaction /* now mark all the gifts as processed */ if (TransferFound) { AGiftDetailTable GiftDetailTable = new AGiftDetailTable(); AGiftDetailRow GiftDetailTemplateRow = (AGiftDetailRow)GiftDetailTable.NewRowTyped(false); GiftDetailTemplateRow.LedgerNumber = ALedgerNumber; GiftDetailTemplateRow.IchNumber = 0; GiftDetailTemplateRow.CostCentreCode = CostCentreRow.CostCentreCode; foreach (AGiftBatchRow GiftBatchRow in GiftBatchTable.Rows) { GiftDetailTemplateRow.BatchNumber = GiftBatchRow.BatchNumber; GiftDetailTable = AGiftDetailAccess.LoadUsingTemplate(GiftDetailTemplateRow, DBTransaction); foreach (AGiftDetailRow GiftDetailRow in GiftDetailTable.Rows) { GiftDetailRow.IchNumber = ICHProcessing; } } } // if TransferFound if ((SettlementAmount == 0) // If there's no activity in this CC, && (IncomeAmount == 0) // bail to the next one. && (ExpenseAmount == 0) && (XferAmount == 0)) { continue; } /* Balance the cost centre by entering an opposite transaction * to ICH settlement. Use positive amounts only. */ /* Increment or decrement the ICH total to be transferred after this loop. * NOTE - if this is a "non-ICH fund", I need to balance it separately, and I'll do that right here. */ DrCrIndicator = AccountRow.DebitCreditIndicator; if (DestinationAccount[CostCentreRow.CostCentreCode] == MFinanceConstants.ICH_ACCT_ICH) { if (DrCrIndicator == MFinanceConstants.IS_DEBIT) { ICHTotal += SettlementAmount; } else { ICHTotal -= SettlementAmount; } } DrCrIndicator = AccountDrCrIndicator; if (SettlementAmount < 0) { DrCrIndicator = !AccountDrCrIndicator; SettlementAmount = 0 - SettlementAmount; } if ((DestinationAccount[CostCentreRow.CostCentreCode] != MFinanceConstants.ICH_ACCT_ICH) && (SettlementAmount != 0)) { // I'm creating a transaction right here for this "non-ICH" CostCentre. // This potentially means that there will be multiple transactions to the "non-ICH" account, // whereas the ICH account has only a single transaction, but that's not big deal: if (!TGLPosting.CreateATransaction(MainDS, ALedgerNumber, GLBatchNumber, GLJournalNumber, Catalog.GetString("Non-ICH foreign fund Clearing"), DestinationAccount[CostCentreRow.CostCentreCode], StandardCostCentre, SettlementAmount, PeriodEndDate, !DrCrIndicator, Catalog.GetString("Non-ICH"), true, SettlementAmount, out GLTransactionNumber)) { ErrorContext = Catalog.GetString("Generating the ICH batch"); ErrorMessage = String.Format(Catalog.GetString("Unable to create a new transaction for Ledger {0}, Batch {1} and Journal {2}."), ALedgerNumber, GLBatchNumber, GLJournalNumber); ErrorType = TResultSeverity.Resv_Noncritical; throw new System.InvalidOperationException(ErrorMessage); } NonIchTransactionsIncluded = true; } /* Generate the transaction to 'balance' the foreign fund - * in the ICH settlement account. */ //RUN gl1130o.p ("new":U, //Create a transaction if (SettlementAmount > 0) { if (!TGLPosting.CreateATransaction(MainDS, ALedgerNumber, GLBatchNumber, GLJournalNumber, Catalog.GetString("ICH Monthly Clearing"), MFinanceConstants.ICH_ACCT_SETTLEMENT, // DestinationAccount[CostCentreRow.CostCentreCode], CostCentreRow.CostCentreCode, SettlementAmount, PeriodEndDate, DrCrIndicator, Catalog.GetString("ICH Process"), true, SettlementAmount, out GLTransactionNumber)) { ErrorContext = Catalog.GetString("Generating the ICH batch"); ErrorMessage = String.Format(Catalog.GetString("Unable to create a new transaction for Ledger {0}, Batch {1} and Journal {2}."), ALedgerNumber, GLBatchNumber, GLJournalNumber); ErrorType = TResultSeverity.Resv_Noncritical; throw new System.InvalidOperationException(ErrorMessage); } //Mark as processed ATransactionRow TransRow = (ATransactionRow)MainDS.ATransaction.Rows.Find(new object[] { ALedgerNumber, GLBatchNumber, GLJournalNumber, GLTransactionNumber }); TransRow.IchNumber = ICHProcessing; } /* Now create corresponding report row on stewardship table, * Only for Cost Centres that cleared to ICH */ if ((DestinationAccount[CostCentreRow.CostCentreCode] == MFinanceConstants.ICH_ACCT_ICH) && ((IncomeAmount != 0) || (ExpenseAmount != 0) || (XferAmount != 0))) { AIchStewardshipRow ICHStewardshipRow = ICHStewardshipTable.NewRowTyped(true); //MainDS.Tables.Add(IchStewardshipTable); ICHStewardshipRow.LedgerNumber = ALedgerNumber; ICHStewardshipRow.PeriodNumber = APeriodNumber; ICHStewardshipRow.IchNumber = ICHProcessing; // ICHStewardshipRow.DateProcessed = DateTime.Today; // This would be strictly correct, but the Stewardship Reporting looks for ICHStewardshipRow.DateProcessed = PeriodEndDate; // rows using a date filter. ICHStewardshipRow.CostCentreCode = CostCentreRow.CostCentreCode; ICHStewardshipRow.IncomeAmount = IncomeAmount; ICHStewardshipRow.ExpenseAmount = ExpenseAmount; ICHStewardshipRow.DirectXferAmount = XferAmount; ICHStewardshipRow.IncomeAmountIntl = IncomeAmountIntl; ICHStewardshipRow.ExpenseAmountIntl = ExpenseAmountIntl; ICHStewardshipRow.DirectXferAmountIntl = XferAmountIntl; ICHStewardshipTable.Rows.Add(ICHStewardshipRow); } } // for each cost centre /* Update the balance of the ICH account (like a bank account). * If the total is negative, it means the ICH batch has a * credit total so far. Thus, we now balance it with the opposite * transaction. */ if (ICHTotal < 0) { DrCrIndicator = MFinanceConstants.IS_DEBIT; ICHTotal = -ICHTotal; } else if (ICHTotal > 0) { DrCrIndicator = MFinanceConstants.IS_CREDIT; } /* 0006 - If the balance is 0 then this is ok * (eg last minute change of a gift from one field to another) */ if ((ICHTotal == 0) && !NonIchTransactionsIncluded) { AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Generating the ICH batch"), Catalog.GetString("No ICH batch was required."), TResultSeverity.Resv_Status)); // An empty GL Batch now exists, which I need to delete. // TVerificationResultCollection BatchCancelResult = new TVerificationResultCollection(); TGLPosting.DeleteGLBatch( ALedgerNumber, GLBatchNumber, out BatchCancelResult); AVerificationResult.AddCollection(BatchCancelResult); IsSuccessful = true; } else { if (ICHTotal != 0) { //Create a transaction if (!TGLPosting.CreateATransaction(MainDS, ALedgerNumber, GLBatchNumber, GLJournalNumber, Catalog.GetString("ICH Monthly Clearing"), MFinanceConstants.ICH_ACCT_ICH, StandardCostCentre, ICHTotal, PeriodEndDate, DrCrIndicator, Catalog.GetString("ICH"), true, ICHTotal, out GLTransactionNumber)) { ErrorContext = Catalog.GetString("Generating the ICH batch"); ErrorMessage = String.Format(Catalog.GetString("Unable to create a new transaction for Ledger {0}, Batch {1} and Journal {2}."), ALedgerNumber, GLBatchNumber, GLJournalNumber); ErrorType = TResultSeverity.Resv_Noncritical; throw new System.InvalidOperationException(ErrorMessage); } } //Post the batch if (PostICHBatch) { AIchStewardshipAccess.SubmitChanges(ICHStewardshipTable, DBTransaction); MainDS.ThrowAwayAfterSubmitChanges = true; // SubmitChanges will not return to me any changes made in MainDS. GLBatchTDSAccess.SubmitChanges(MainDS); ALedgerAccess.SubmitChanges(PostingDS.ALedger, DBTransaction); // LastIchNumber has changed. IsSuccessful = TGLPosting.PostGLBatch(ALedgerNumber, GLBatchNumber, out AVerificationResult); } else { AVerificationResult.Add(new TVerificationResult(ErrorContext, Catalog.GetString("No Stewardship batch is required."), TResultSeverity.Resv_Status)); // An empty GL Batch now exists, which I need to delete. // TVerificationResultCollection BatchCancelResult = new TVerificationResultCollection(); TGLPosting.DeleteGLBatch( ALedgerNumber, GLBatchNumber, out BatchCancelResult); AVerificationResult.AddCollection(BatchCancelResult); } // else } // else } // try catch (ArgumentException Exc) { TLogging.Log("An ArgumentException occured during the generation of the Stewardship Batch:" + Environment.NewLine + Exc.ToString()); if (AVerificationResult == null) { AVerificationResult = new TVerificationResultCollection(); } AVerificationResult.Add(new TVerificationResult(ErrorContext, Exc.Message, ErrorType)); throw; } catch (InvalidOperationException Exc) { TLogging.Log( "An InvalidOperationException occured during the generation of the Stewardship Batch:" + Environment.NewLine + Exc.ToString()); if (AVerificationResult == null) { AVerificationResult = new TVerificationResultCollection(); } AVerificationResult.Add(new TVerificationResult(ErrorContext, Exc.Message, ErrorType)); throw; } catch (Exception Exc) { TLogging.Log("An Exception occured during the generation of the Stewardship Batch:" + Environment.NewLine + Exc.ToString()); ErrorContext = Catalog.GetString("Calculate Admin Fee"); ErrorMessage = String.Format(Catalog.GetString("Unknown error while generating the ICH batch for Ledger: {0} and Period: {1}" + Environment.NewLine + Environment.NewLine + Exc.ToString()), ALedgerNumber, APeriodNumber); ErrorType = TResultSeverity.Resv_Critical; if (AVerificationResult == null) { AVerificationResult = new TVerificationResultCollection(); } AVerificationResult.Add(new TVerificationResult(ErrorContext, ErrorMessage, ErrorType)); throw; } finally { if (IsSuccessful && NewTransaction) { DBAccess.GDBAccessObj.CommitTransaction(); } else if (!IsSuccessful && NewTransaction) { DBAccess.GDBAccessObj.RollbackTransaction(); } } return IsSuccessful; }
/// <summary> /// Updates the KeyCount on an Extract. /// </summary> /// <param name="AExtractId">ExtractId of the Extract that the KeyCount should /// get updated for.</param> /// <param name="ACount">New Key Count.</param> /// <param name="AVerificationResult">Contains errors or DB call exceptions, if there are any.</param> /// <returns>True if the updating was successful, otherwise false.</returns> public static bool UpdateExtractKeyCount(int AExtractId, int ACount, out TVerificationResultCollection AVerificationResult) { TDBTransaction Transaction = null; bool SubmissionOK = false; TVerificationResultCollection VerificationResult = new TVerificationResultCollection(); DBAccess.GDBAccessObj.GetNewOrExistingAutoTransaction(IsolationLevel.Serializable, ref Transaction, ref SubmissionOK, delegate { MExtractMasterTable ExtractMasterDT = MExtractMasterAccess.LoadByPrimaryKey(AExtractId, Transaction); if (ExtractMasterDT.Rows.Count == 1) { ExtractMasterDT[0].KeyCount = ACount; MExtractMasterAccess.SubmitChanges(ExtractMasterDT, Transaction); SubmissionOK = true; } else { VerificationResult.Add(new TVerificationResult( "TExtractsHandling.UpdateExtractCount", "Extract with Extract Id " + AExtractId.ToString() + " doesn't exist!", TResultSeverity.Resv_Critical)); } }); AVerificationResult = VerificationResult; return SubmissionOK; }
/// <summary> /// todoComment /// </summary> private static TSubmitChangesResult PerformSimilarLocationReUseChecks(ref PLocationRow ALocationRow, ref PartnerAddressAggregateTDS AResponseDS, TDBTransaction ASubmitChangesTransaction, Int64 APartnerKey, ref PartnerAddressAggregateTDSSimilarLocationParametersTable AExistingLocationParametersDT, ref PPartnerLocationTable APartnerLocationTable, ref TLocationPK[, ] ALocationReUseKeyMapping, out Boolean AReUseSimilarLocation, ref TVerificationResultCollection AVerificationResult) { TSubmitChangesResult ReturnValue; PPartnerLocationRow PartnerLocationCheckRow; DataView ExistingLocationParametersDV; PLocationRow ExistingLocationRow; Int64 CurrentSiteKey; Int64 ExistingSiteKey; Int32 CurrentLocationKey; Int32 ExistingLocationKey; PLocationTable SimilarLocationDT; // TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: AExistingLocationParametersDT.Rows.Count: " + // AExistingLocationParametersDT.Rows.Count.ToString()); AReUseSimilarLocation = false; if (CheckReUseExistingLocation(ALocationRow, APartnerKey, ref AExistingLocationParametersDT, ASubmitChangesTransaction, out ExistingSiteKey, out ExistingLocationKey)) { // Check if there is a Parameter Row for the LocationKey we are looking at ExistingLocationParametersDV = new DataView(AExistingLocationParametersDT, PartnerAddressAggregateTDSSimilarLocationParametersTable.GetSiteKeyDBName() + " = " + ALocationRow.SiteKey.ToString() + " AND " + PartnerAddressAggregateTDSSimilarLocationParametersTable.GetLocationKeyDBName() + " = " + ALocationRow.LocationKey.ToString() + " AND " + PartnerAddressAggregateTDSSimilarLocationParametersTable.GetAnswerProcessedClientSideDBName() + " = false", "", DataViewRowState.CurrentRows); if (ExistingLocationParametersDV.Count > 0) { // TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Location " + ALocationRow.LocationKey.ToString() + ": found similar Location, decision is needed."); /* * More information is needed (usually via user interaction) * -> stop processing here and return parameters * (usually used for UI interaction) */ if (AResponseDS == null) { // TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Creating AResponseDS."); AResponseDS = new PartnerAddressAggregateTDS(MPartnerConstants.PARTNERADDRESSAGGREGATERESPONSE_DATASET); } // TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: AExistingLocationParametersDT.Rows.Count: " + AExistingLocationParametersDT.Rows.Count.ToString()); AResponseDS.Merge(AExistingLocationParametersDT); // TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Merged ExistingLocationParametersDT into AResponseDS."); // TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: AResponseDS.Tables[" + MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME + // "].Rows.Count: " + AResponseDS.Tables[MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME].Rows.Count.ToString()); return TSubmitChangesResult.scrInfoNeeded; } else { // TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Location " + ALocationRow.LocationKey.ToString() + // ": found similar Location and this one (" + ExistingLocationKey.ToString() + ") should be used instead of creating a new one!"); /* * Location with the same data already exists and it should be * re-used instead of creating a new one! */ // Keep a mapping of the initially submitted LocationKey to the newly assigned one ALocationReUseKeyMapping = new TLocationPK[ALocationReUseKeyMapping.GetLength(0) + 1, 2]; ALocationReUseKeyMapping[(ALocationReUseKeyMapping.GetLength(0)) - 1, 0] = new TLocationPK(ALocationRow.SiteKey, (int)ALocationRow.LocationKey); ALocationReUseKeyMapping[(ALocationReUseKeyMapping.GetLength(0)) - 1, 1] = new TLocationPK(ExistingSiteKey, ExistingLocationKey); AReUseSimilarLocation = true; if (!AExistingLocationParametersDT[0].AnswerProcessedServerSide) { AExistingLocationParametersDT[0].AnswerProcessedServerSide = true; // Preserve Key of current Location CurrentSiteKey = ALocationRow.SiteKey; CurrentLocationKey = (int)ALocationRow.LocationKey; /* * Make sure that the Partner hasn't already got a PartnerLocation with * the same Key (neither in memory nor in the DB) */ // TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Finding PartnerLocation Row in APartnerLocationTable with LocationKey " + ALocationRow.LocationKey.ToString()); PartnerLocationCheckRow = (PPartnerLocationRow)APartnerLocationTable.Rows.Find(new object[] { APartnerKey, ALocationRow.SiteKey, ALocationRow.LocationKey }); if (PartnerLocationCheckRow != null) { /* * Checks in Memory: look for Current (ie. unchanged, new or edited) * rows first whether they are the Location that is about to being * reused. Secondly, check if there is a deleted Location with the same * LocationKey that is about to being reused; only if this is not the * case: * Check in the DB whether the Partner hasn't got the Location * with the same LocationKey that is about to being reuse. */ if ((APartnerLocationTable.Select(PPartnerLocationTable.GetPartnerKeyDBName() + " = " + APartnerKey.ToString() + " AND " + PPartnerLocationTable.GetSiteKeyDBName() + " = " + ExistingSiteKey.ToString() + " AND " + PPartnerLocationTable.GetLocationKeyDBName() + " = " + ExistingLocationKey.ToString(), "", DataViewRowState.CurrentRows).Length != 0) || ((APartnerLocationTable.Select(PPartnerLocationTable.GetPartnerKeyDBName() + " = " + APartnerKey.ToString() + " AND " + PPartnerLocationTable.GetSiteKeyDBName() + " = " + ExistingSiteKey.ToString() + " AND " + PPartnerLocationTable.GetLocationKeyDBName() + " = " + ExistingLocationKey.ToString(), "", DataViewRowState.Deleted).Length == 0) && (PPartnerLocationAccess.Exists(APartnerKey, ExistingSiteKey, ExistingLocationKey, ASubmitChangesTransaction)))) { AVerificationResult.Add(new TVerificationResult("[Partner Address Save]", "Partner " + APartnerKey.ToString() + " already has a " + "record linked with Location " + ExistingLocationKey.ToString() + Environment.NewLine + "Unable to save.", "Duplicate Address Entered", "", TResultSeverity.Resv_Critical)); ReturnValue = TSubmitChangesResult.scrError; return ReturnValue; } else { // TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: LocationKey: " + ExistingLocationKey.ToString() + " will later get assigned to PPartnerLocation."); } } else { throw new EOPAppException( "PerformSimilarLocationReUseChecks: PartnerLocationCheckRow with SiteKey " + ALocationRow.SiteKey.ToString() + " and LocationKey " + ALocationRow.LocationKey.ToString() + " not found!"); } /* * Copy all fields from the existing Location to the current Location */ SimilarLocationDT = PLocationAccess.LoadByPrimaryKey(ExistingSiteKey, ExistingLocationKey, null, ASubmitChangesTransaction); if (SimilarLocationDT.Rows.Count != 0) { ExistingLocationRow = (PLocationRow)SimilarLocationDT.Rows[0]; ALocationRow.ItemArray = ExistingLocationRow.ItemArray; /* * NOTE: The SiteKey and LocationKey are re-assigned to the ones of the * current Location. This is done to have the current SiteKey and * LocationKey preserved throughout the whole process of working with the * Locations. The SiteKey and LocationKey are exchanged with the ones of * the existing Location before the DataRow gets sent back to the Client! */ ALocationRow.SiteKey = CurrentSiteKey; ALocationRow.LocationKey = CurrentLocationKey; // TLogging.LogAtLevel(9, "CheckReUseExistingLocation: Location " + ALocationRow.LocationKey.ToString() + // ": data got replaced with data from the existing Location (" + ExistingLocationKey.ToString() + ")!"); } else { throw new EOPAppException( "Couldn''t find existing Similar Location with SiteKey " + ALocationRow.SiteKey.ToString() + " and LocationKey " + ALocationRow.LocationKey.ToString() + '!'); } } } } else { // TLogging.LogAtLevel(9, "CheckReUseExistingLocation: Location " + ALocationRow.LocationKey.ToString() + // ": Location does not exist yet (or an existing Location should not be re-used) -> will get saved later."); /* * No similar Location exists, or an existing similar Location should * not be re-used: Save this Location * -> will get saved later in call to SubmitChanges */ } return TSubmitChangesResult.scrOK; }
public static bool SetUserPassword(string AUsername, string APassword, string AOldPassword, bool APasswordNeedsChanged, out TVerificationResultCollection AVerification) { TDBTransaction Transaction; string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); TVerificationResult VerificationResult; AVerification = new TVerificationResultCollection(); if (!TSharedSysManValidation.CheckPasswordQuality(APassword, out VerificationResult)) { return false; } if (APasswordNeedsChanged && APassword == AOldPassword) { AVerification = new TVerificationResultCollection(); AVerification.Add(new TVerificationResult("\nPassword check.", Catalog.GetString( "Password not changed as the old password was reused. Please use a new password."), TResultSeverity.Resv_Critical)); return false; } if (UserAuthenticationMethod == "OpenPetraDBSUser") { TPetraPrincipal tempPrincipal; SUserRow UserDR = TUserManagerWebConnector.LoadUser(AUsername.ToUpper(), out tempPrincipal); if (TUserManagerWebConnector.CreateHashOfPassword(String.Concat(AOldPassword, UserDR.PasswordSalt)) != UserDR.PasswordHash) { AVerification = new TVerificationResultCollection(); AVerification.Add(new TVerificationResult("\nPassword quality check.", String.Format( Catalog.GetString( "Old password entered incorrectly. Password not changed.")), TResultSeverity.Resv_Critical)); return false; } SUserTable UserTable = (SUserTable)UserDR.Table; UserDR.PasswordHash = TUserManagerWebConnector.CreateHashOfPassword(String.Concat(APassword, UserDR.PasswordSalt)); UserDR.PasswordNeedsChange = false; Transaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.Serializable); try { SUserAccess.SubmitChanges(UserTable, Transaction); DBAccess.GDBAccessObj.CommitTransaction(); } catch (Exception Exc) { TLogging.Log("An Exception occured during the setting of the User Password:" + Environment.NewLine + Exc.ToString()); DBAccess.GDBAccessObj.RollbackTransaction(); throw; } return true; } else { IUserAuthentication auth = TUserManagerWebConnector.LoadAuthAssembly(UserAuthenticationMethod); return auth.SetPassword(AUsername, APassword, AOldPassword); } }
public static TSubmitChangesResult SaveCorporateExchangeSetupTDS(ref CorporateExchangeSetupTDS AInspectDS, out int ATransactionsChanged, out TVerificationResultCollection AVerificationResult) { AVerificationResult = new TVerificationResultCollection(); ATransactionsChanged = -1; int TransactionsChanged = -1; AInspectDS = AInspectDS.GetChangesTyped(true); if (AInspectDS == null) { AVerificationResult.Add(new TVerificationResult( Catalog.GetString("Save Corportate Exchange Rates"), Catalog.GetString("No changes - nothing to do"), TResultSeverity.Resv_Info)); return TSubmitChangesResult.scrNothingToBeSaved; } TDBTransaction Transaction = null; bool SubmissionOK = false; CorporateExchangeSetupTDS InspectDS = AInspectDS; DBAccess.GDBAccessObj.GetNewOrExistingAutoTransaction(IsolationLevel.Serializable, ref Transaction, ref SubmissionOK, delegate { foreach (ACorporateExchangeRateRow Row in InspectDS.ACorporateExchangeRate.Rows) { if ((Row.RowState == DataRowState.Modified) || (Row.RowState == DataRowState.Added)) { // should only be -1 if no exchange rates were modified or created if (TransactionsChanged == -1) { TransactionsChanged = 0; } // update international amounts for all gl transaction using modified or new exchange rate string Query = "UPDATE a_transaction SET a_amount_in_intl_currency_n = " + "(a_amount_in_base_currency_n / " + Row.RateOfExchange.ToString(CultureInfo.InvariantCulture) + ")" + " FROM a_ledger" + " WHERE EXTRACT(MONTH FROM a_transaction.a_transaction_date_d) = " + Row.DateEffectiveFrom.Month + " AND EXTRACT(YEAR FROM a_transaction.a_transaction_date_d) = " + Row.DateEffectiveFrom.Year + " AND a_ledger.a_ledger_number_i = a_transaction.a_ledger_number_i" + " AND a_ledger.a_base_currency_c = '" + Row.FromCurrencyCode + "'" + " AND a_ledger.a_intl_currency_c = '" + Row.ToCurrencyCode + "'"; TransactionsChanged += DBAccess.GDBAccessObj.ExecuteNonQuery(Query, Transaction); } } // save changes to exchange rates ACorporateExchangeRateAccess.SubmitChanges(InspectDS.ACorporateExchangeRate, Transaction); SubmissionOK = true; }); TSubmitChangesResult SubmissionResult; if (SubmissionOK) { SubmissionResult = TSubmitChangesResult.scrOK; } else { SubmissionResult = TSubmitChangesResult.scrError; } AInspectDS = InspectDS; ATransactionsChanged = TransactionsChanged; return SubmissionResult; }
private void PrepareBankingDetailsForSaving(ref PartnerEditTDS AInspectDS, ref TVerificationResultCollection AVerificationResult, TDBTransaction ATransaction) { if ((AInspectDS.PBankingDetails != null) && (AInspectDS.PBankingDetails.Rows.Count > 0)) { AInspectDS.Merge(new PBankingDetailsUsageTable()); AInspectDS.InitVars(); PBankingDetailsUsageAccess.LoadViaPPartner(AInspectDS, FPartnerKey, ATransaction); AInspectDS.PBankingDetailsUsage.AcceptChanges(); // make sure there is at least one main account, or no account at all // make sure there are no multiple main accounts PartnerEditTDS LocalDS = new PartnerEditTDS(); PBankingDetailsAccess.LoadViaPPartner(LocalDS, FPartnerKey, ATransaction); // there are problems with Mono on merging deleted rows into the LocalDS, they become modified rows // see https://tracker.openpetra.org/view.php?id=1871 LocalDS.Merge(AInspectDS.PBankingDetails); // workaround for bug 1871 List <Int32>DeletedBankingDetails = new List <Int32>(); if (AInspectDS.PPartnerBankingDetails != null) { foreach (DataRow bdrow in AInspectDS.PPartnerBankingDetails.Rows) { if (bdrow.RowState == DataRowState.Deleted) { DeletedBankingDetails.Add(Convert.ToInt32(bdrow[AInspectDS.PPartnerBankingDetails.ColumnBankingDetailsKey, DataRowVersion.Original])); } } } bool ThereIsAtLeastOneAccount = false; // get the main account Int32 MainAccountBankingDetails = Int32.MinValue; foreach (PartnerEditTDSPBankingDetailsRow detailRow in LocalDS.PBankingDetails.Rows) { if ((detailRow.RowState != DataRowState.Deleted) && !DeletedBankingDetails.Contains(detailRow.BankingDetailsKey)) { ThereIsAtLeastOneAccount = true; if (!detailRow.IsMainAccountNull() && detailRow.MainAccount) { if ((MainAccountBankingDetails != Int32.MinValue) && (detailRow.BankingDetailsKey != MainAccountBankingDetails)) { AVerificationResult.Add(new TVerificationResult( String.Format("Banking Details"), string.Format("there are multiple main accounts"), TResultSeverity.Resv_Critical)); return; } else { // if the main account has been changed MainAccountBankingDetails = detailRow.BankingDetailsKey; } } } } bool alreadyExists = false; foreach (PBankingDetailsUsageRow usageRow in AInspectDS.PBankingDetailsUsage.Rows) { if (usageRow.Type == MPartnerConstants.BANKINGUSAGETYPE_MAIN) { DataRow bdrow = LocalDS.PBankingDetails.Rows.Find(usageRow.BankingDetailsKey); if ((bdrow == null) || (bdrow.RowState == DataRowState.Deleted) || DeletedBankingDetails.Contains(usageRow.BankingDetailsKey)) { // deleting the account usageRow.Delete(); } else if (MainAccountBankingDetails == Int32.MinValue) { MainAccountBankingDetails = usageRow.BankingDetailsKey; alreadyExists = true; } else if ((MainAccountBankingDetails != Int32.MinValue) && (usageRow.BankingDetailsKey != MainAccountBankingDetails)) { usageRow.Delete(); } else { alreadyExists = true; } } } if (!alreadyExists && ThereIsAtLeastOneAccount) { if (MainAccountBankingDetails == Int32.MinValue) { AVerificationResult.Add(new TVerificationResult( "Banking Details", "One Bank Account of a Partner must be set as the 'Main Account'. Please select the record that should become the 'Main Account' and choose 'Set Main Account'.", TResultSeverity.Resv_Critical)); return; } else { PBankingDetailsUsageRow newUsageRow = AInspectDS.PBankingDetailsUsage.NewRowTyped(true); newUsageRow.PartnerKey = FPartnerKey; newUsageRow.BankingDetailsKey = MainAccountBankingDetails; newUsageRow.Type = MPartnerConstants.BANKINGUSAGETYPE_MAIN; AInspectDS.PBankingDetailsUsage.Rows.Add(newUsageRow); } } } }
public static bool PostGiftBatches(Int32 ALedgerNumber, List <Int32>ABatchNumbers, out TVerificationResultCollection AVerifications) { //Used in validation of arguments AVerifications = new TVerificationResultCollection(); #region Validate Arguments if (ALedgerNumber <= 0) { throw new EFinanceSystemInvalidLedgerNumberException(String.Format(Catalog.GetString( "Function:{0} - The Ledger number must be greater than 0!"), Utilities.GetMethodName(true)), ALedgerNumber); } else if (ABatchNumbers.Count == 0) { AVerifications.Add( new TVerificationResult( "Posting Gift Batch", "No Gift Batches to post", TResultSeverity.Resv_Noncritical)); return false; } foreach (Int32 batchNumber in ABatchNumbers) { if (batchNumber <= 0) { throw new EFinanceSystemInvalidBatchNumberException(String.Format(Catalog.GetString( "Function:{0} - The Batch number must be greater than 0!"), Utilities.GetMethodName(true)), ALedgerNumber, batchNumber); } } #endregion Validate Arguments List <Int32>GLBatchNumbers = new List <int>(); Dictionary <Int32, String>BatchCurrencyCode = new Dictionary <Int32, String>(); //For use in transaction delegate TVerificationResultCollection VerificationResult = AVerifications; TVerificationResultCollection SingleVerificationResultCollection; //Error handling string ErrorContext = "Posting a Gift Batch"; string ErrorMessage = String.Empty; TResultSeverity ErrorType = TResultSeverity.Resv_Noncritical; //TVerificationResultCollection VerificationResult = null; TDBTransaction Transaction = null; bool SubmissionOK = false; TProgressTracker.InitProgressTracker(DomainManager.GClientID.ToString(), Catalog.GetString("Posting gift batches"), ABatchNumbers.Count * 3 + 1); try { DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref Transaction, ref SubmissionOK, delegate { bool GLBatchIsRequired = false; // first prepare all the gift batches, mark them as posted, and create the GL batches foreach (Int32 BatchNumber in ABatchNumbers) { TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(), Catalog.GetString("Posting gift batches"), ABatchNumbers.IndexOf(BatchNumber) * 3); GiftBatchTDS MainDS = PrepareGiftBatchForPosting(ALedgerNumber, BatchNumber, ref Transaction, out SingleVerificationResultCollection); VerificationResult.AddCollection(SingleVerificationResultCollection); if (MainDS == null) { return; } BatchCurrencyCode[BatchNumber] = MainDS.AGiftBatch[0].CurrencyCode; TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(), Catalog.GetString("Posting gift batches"), ABatchNumbers.IndexOf(BatchNumber) * 3 + 1); // create GL batch GLBatchTDS GLDataset = CreateGLBatchAndTransactionsForPostingGifts(ALedgerNumber, ref MainDS); ABatchRow batch = GLDataset.ABatch[0]; // it is possible that gl transactions are not actually needed for a gift posting. // E.g. it is only a donor name adjustment -- there is no change in the general ledger account. bool GLBatchNotRequired = GLDataset.ATransaction.Count == 0; if (GLBatchNotRequired) { TGLPosting.DeleteGLBatch(ALedgerNumber, batch.BatchNumber, out SingleVerificationResultCollection); VerificationResult.AddCollection(SingleVerificationResultCollection); } else { GLBatchIsRequired = true; } // save the batch (or delete if it is not actually needed) if (GLBatchNotRequired || (TGLTransactionWebConnector.SaveGLBatchTDS(ref GLDataset, out SingleVerificationResultCollection) == TSubmitChangesResult.scrOK)) { if (!GLBatchNotRequired) // i.e. GL batch is required and saved OK { VerificationResult.AddCollection(SingleVerificationResultCollection); GLBatchNumbers.Add(batch.BatchNumber); } // // Assign ReceiptNumbers to Gifts // ALedgerAccess.LoadByPrimaryKey(MainDS, ALedgerNumber, Transaction); #region Validate Data if ((MainDS.ALedger == null) || (MainDS.ALedger.Count == 0)) { throw new EFinanceSystemDataTableReturnedNoDataException(String.Format(Catalog.GetString( "Function:{0} - Ledger data for Ledger number {1} does not exist or could not be accessed!"), Utilities.GetMethodName(true), ALedgerNumber)); } #endregion Validate Data Int32 LastReceiptNumber = MainDS.ALedger[0].LastHeaderRNumber; foreach (AGiftRow GiftRow in MainDS.AGift.Rows) { LastReceiptNumber++; GiftRow.ReceiptNumber = LastReceiptNumber; } MainDS.ALedger[0].LastHeaderRNumber = LastReceiptNumber; //Mark gift batch as posted MainDS.AGiftBatch[0].BatchStatus = MFinanceConstants.BATCH_POSTED; MainDS.ThrowAwayAfterSubmitChanges = true; GiftBatchTDSAccess.SubmitChanges(MainDS); } else { VerificationResult.AddCollection(SingleVerificationResultCollection); return; } } // foreach BatchNumber TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(), Catalog.GetString("Posting gift batches"), ABatchNumbers.Count * 3 - 1); // now post the GL batches if (!TGLPosting.PostGLBatches(ALedgerNumber, GLBatchNumbers, out SingleVerificationResultCollection) && GLBatchIsRequired) { VerificationResult.AddCollection(SingleVerificationResultCollection); // Transaction will be rolled back, no open GL batch flying around SubmissionOK = false; } else { VerificationResult.AddCollection(SingleVerificationResultCollection); SubmissionOK = true; string ledgerName = TLedgerInfo.GetLedgerName(ALedgerNumber); // // Print Gift Batch Detail report (on the client!) foreach (Int32 BatchNumber in ABatchNumbers) { String[] Params = { "param_ledger_number_i=" + ALedgerNumber, "param_batch_number_i=" + BatchNumber, "param_ledger_name=\"" + ledgerName + "\"", "param_currency_name=\"" + BatchCurrencyCode[BatchNumber] + "\"" }; String ParamStr = String.Join(",", Params); TGLPosting.PrintReportOnClientDelegate("Gift Batch Detail", ParamStr); } } }); // Begin AutoTransaction } catch (EVerificationResultsException ex) { ErrorMessage = String.Format(Catalog.GetString("Function:{0} - Unexpected error while posting Gift batch to Ledger {1}!{2}{2}{3}"), Utilities.GetMethodName(true), ALedgerNumber, Environment.NewLine, ex.Message); ErrorType = TResultSeverity.Resv_Critical; VerificationResult = new TVerificationResultCollection(); VerificationResult.Add(new TVerificationResult(ErrorContext, ErrorMessage, ErrorType)); throw new EVerificationResultsException(ErrorMessage, VerificationResult, ex.InnerException); } catch (Exception ex) { // show the full stacktrace of the caught exception TLogging.Log(ex.ToString()); TLogging.Log(String.Format("Method:{0} - Unexpected error!{1}{1}{2}", Utilities.GetMethodSignature(), Environment.NewLine, ex.Message)); throw ex; } TProgressTracker.FinishJob(DomainManager.GClientID.ToString()); AVerifications = VerificationResult; return SubmissionOK; }
public static GiftBatchTDS PrepareGiftBatchForPosting(Int32 ALedgerNumber, Int32 ABatchNumber, ref TDBTransaction ATransaction, out TVerificationResultCollection AVerifications) { #region Validate Arguments if (ALedgerNumber <= 0) { throw new EFinanceSystemInvalidLedgerNumberException(String.Format(Catalog.GetString( "Function:{0} - The Ledger number must be greater than 0!"), Utilities.GetMethodName(true)), ALedgerNumber); } else if (ABatchNumber <= 0) { throw new EFinanceSystemInvalidBatchNumberException(String.Format(Catalog.GetString( "Function:{0} - The Batch number must be greater than 0!"), Utilities.GetMethodName(true)), ALedgerNumber, ABatchNumber); } else if (ATransaction == null) { throw new EFinanceSystemDBTransactionNullException(String.Format(Catalog.GetString( "Function:{0} - Database Transaction must not be NULL!"), Utilities.GetMethodName(true))); } #endregion Validate Arguments bool ChangesToCommit = false; GiftBatchTDS MainDS = LoadAGiftBatchSingle(ALedgerNumber, ABatchNumber, ref ATransaction); string LedgerBaseCurrency = MainDS.ALedger[0].BaseCurrency; string LedgerIntlCurrency = MainDS.ALedger[0].IntlCurrency; AVerifications = new TVerificationResultCollection(); //Check Batch status if (MainDS.AGiftBatch[0].BatchStatus != MFinanceConstants.BATCH_UNPOSTED) { AVerifications.Add( new TVerificationResult( "Posting Gift Batch", String.Format("Cannot post batch ({0}, {1}) with status: {2}", ALedgerNumber, ABatchNumber, MainDS.AGiftBatch[0].BatchStatus), TResultSeverity.Resv_Critical)); return null; } //Load all other related data for the batch and commit any changes MainDS.Merge(LoadAGiftBatchAndRelatedData(ALedgerNumber, ABatchNumber, ATransaction, out ChangesToCommit, true)); if (ChangesToCommit) { GiftBatchTDSAccess.SubmitChanges(MainDS); } AGiftBatchRow GiftBatchRow = MainDS.AGiftBatch[0]; string BatchTransactionCurrency = GiftBatchRow.CurrencyCode; // check that the Gift Batch BatchPeriod matches the date effective DateTime GLEffectiveDate = GiftBatchRow.GlEffectiveDate; DateTime StartOfMonth = new DateTime(GLEffectiveDate.Year, GLEffectiveDate.Month, 1); int DateEffectivePeriod, DateEffectiveYear; TFinancialYear.IsValidPostingPeriod(GiftBatchRow.LedgerNumber, GiftBatchRow.GlEffectiveDate, out DateEffectivePeriod, out DateEffectiveYear, ATransaction); decimal IntlToBaseExchRate = TExchangeRateTools.GetCorporateExchangeRate(LedgerBaseCurrency, LedgerIntlCurrency, StartOfMonth, GLEffectiveDate); //Check Batch period if (GiftBatchRow.BatchPeriod != DateEffectivePeriod) { AVerifications.Add( new TVerificationResult( "Posting Gift Batch", String.Format("Invalid gift batch period {0} for date {1}", GiftBatchRow.BatchPeriod, GLEffectiveDate), TResultSeverity.Resv_Critical)); return null; } //Check international exchange rate else if (IntlToBaseExchRate == 0) { AVerifications.Add( new TVerificationResult( "Posting Gift Batch", String.Format(Catalog.GetString("No Corporate Exchange rate exists for the month: {0:MMMM yyyy}!"), GLEffectiveDate), TResultSeverity.Resv_Critical)); return null; } //Check Hash total else if ((GiftBatchRow.HashTotal != 0) && (GiftBatchRow.BatchTotal != GiftBatchRow.HashTotal)) { AVerifications.Add( new TVerificationResult( "Posting Gift Batch", String.Format("The gift batch total ({0}) does not equal the hash total ({1}).", StringHelper.FormatUsingCurrencyCode(GiftBatchRow.BatchTotal, GiftBatchRow.CurrencyCode), StringHelper.FormatUsingCurrencyCode(GiftBatchRow.HashTotal, GiftBatchRow.CurrencyCode)), TResultSeverity.Resv_Critical)); return null; } //Check validity at the gift detail level foreach (GiftBatchTDSAGiftDetailRow giftDetail in MainDS.AGiftDetail.Rows) { // find motivation detail row AMotivationDetailRow motivationRow = (AMotivationDetailRow)MainDS.AMotivationDetail.Rows.Find(new object[] { ALedgerNumber, giftDetail.MotivationGroupCode, giftDetail.MotivationDetailCode }); //do not allow posting gifts with no donor if (giftDetail.DonorKey == 0) { AVerifications.Add( new TVerificationResult( "Posting Gift Batch", String.Format(Catalog.GetString("Donor Key needed in gift {0}"), giftDetail.GiftTransactionNumber), TResultSeverity.Resv_Critical)); return null; } //check for valid motivation detail code else if (motivationRow == null) { AVerifications.Add( new TVerificationResult( "Posting Gift Batch", String.Format("Invalid motivation detail {0}/{1} in gift {2}", giftDetail.MotivationGroupCode, giftDetail.MotivationDetailCode, giftDetail.GiftTransactionNumber), TResultSeverity.Resv_Critical)); return null; } // data is only updated if the gift amount is positive if (giftDetail.GiftTransactionAmount >= 0) { // The recipient ledger number must not be 0 if the motivation group is 'GIFT' if ((giftDetail.IsRecipientLedgerNumberNull() || (giftDetail.RecipientLedgerNumber == 0)) && (giftDetail.MotivationGroupCode == MFinanceConstants.MOTIVATION_GROUP_GIFT)) { AVerifications.Add( new TVerificationResult( "Posting Gift Batch", String.Format(Catalog.GetString("No valid Gift Destination exists for the recipient {0} ({1}) of gift {2}."), giftDetail.RecipientDescription, giftDetail.RecipientKey.ToString("0000000000"), giftDetail.GiftTransactionNumber) + "\n\n" + Catalog.GetString( "A Gift Destination will need to be assigned to this Partner before this gift can be posted with the Motivation Group 'GIFT'."), TResultSeverity.Resv_Critical)); return null; } //Check for missing cost centre code else if (giftDetail.IsCostCentreCodeNull() || (giftDetail.CostCentreCode == string.Empty)) { AVerifications.Add( new TVerificationResult( "Posting Gift Batch", String.Format(Catalog.GetString("No valid Cost Centre Code exists for the recipient {0} ({1}) of gift {2}."), giftDetail.RecipientDescription, giftDetail.RecipientKey.ToString("0000000000"), giftDetail.GiftTransactionNumber) + "\n\n" + Catalog.GetString( "A Gift Destination will need to be assigned to this Partner."), TResultSeverity.Resv_Critical)); return null; } } // set column giftdetail.AccountCode motivation giftDetail.AccountCode = motivationRow.AccountCode; // validate exchange rate to base if (GiftBatchRow.ExchangeRateToBase == 0) { AVerifications.Add( new TVerificationResult( "Posting Gift Batch", String.Format(Catalog.GetString("Exchange rate to base currency is 0 in Batch {0}!"), ABatchNumber), TResultSeverity.Resv_Critical)); return null; } else if ((GiftBatchRow.CurrencyCode != LedgerBaseCurrency) && !IsDailyExchangeRateIsStillValid(GiftBatchRow.CurrencyCode, LedgerBaseCurrency, GiftBatchRow.GlEffectiveDate, GiftBatchRow.ExchangeRateToBase, ATransaction)) { AVerifications.Add( new TVerificationResult( "Posting Gift Batch", String.Format(Catalog.GetString("Exchange rate to base currency is invalid in Batch {0}!"), ABatchNumber), TResultSeverity.Resv_Critical)); return null; } //Calculate GiftAmount giftDetail.GiftAmount = giftDetail.GiftTransactionAmount / GiftBatchRow.ExchangeRateToBase; if (BatchTransactionCurrency != LedgerIntlCurrency) { giftDetail.GiftAmountIntl = giftDetail.GiftAmount / IntlToBaseExchRate; } else { giftDetail.GiftAmountIntl = giftDetail.GiftTransactionAmount; } // for calculation of admin fees LoadAdminFeeTablesForGiftDetail(MainDS, giftDetail, ATransaction); // get all motivation detail fees for this gift foreach (AMotivationDetailFeeRow motivationFeeRow in MainDS.AMotivationDetailFee.Rows) { // If the charge flag is not set, still process fees for GIF and ICT but do not process other fees. if (giftDetail.ChargeFlag || (motivationFeeRow.FeeCode == MFinanceConstants.ADMIN_FEE_GIF) || (motivationFeeRow.FeeCode == MFinanceConstants.ADMIN_FEE_ICT)) { TVerificationResultCollection Verifications2; decimal FeeAmount = CalculateAdminFee(MainDS, ALedgerNumber, motivationFeeRow.FeeCode, giftDetail.GiftAmount, out Verifications2); if (!TVerificationHelper.IsNullOrOnlyNonCritical(Verifications2)) { AVerifications.AddCollection(Verifications2); return null; } if (FeeAmount != 0) { AddToFeeTotals(MainDS, giftDetail, motivationFeeRow.FeeCode, FeeAmount, GiftBatchRow.BatchPeriod); } } } } return MainDS; }
public static TSubmitChangesResult SaveGiftBatchTDS(ref GiftBatchTDS AInspectDS, out TVerificationResultCollection AVerificationResult) { AVerificationResult = new TVerificationResultCollection(); TSubmitChangesResult SubmissionResult = TSubmitChangesResult.scrError; // make sure that empty tables are removed !! This can return NULL! AInspectDS = AInspectDS.GetChangesTyped(true); if (AInspectDS == null) { AVerificationResult.Add(new TVerificationResult( Catalog.GetString("Save Gift Batch"), Catalog.GetString("No changes - nothing to do"), TResultSeverity.Resv_Info)); return TSubmitChangesResult.scrNothingToBeSaved; } bool AllValidationsOK = true; bool GiftBatchTableInDataSet = (AInspectDS.AGiftBatch != null && AInspectDS.AGiftBatch.Count > 0); bool GiftTableInDataSet = (AInspectDS.AGift != null && AInspectDS.AGift.Count > 0); bool GiftDetailTableInDataSet = (AInspectDS.AGiftDetail != null && AInspectDS.AGiftDetail.Count > 0); //Not needed at present //int GiftBatchCount = GiftBatchTableInDataSet ? AInspectDS.AGiftBatch.Count : 0; int GiftCount = GiftTableInDataSet ? AInspectDS.AGift.Count : 0; int GiftDetailCount = GiftDetailTableInDataSet ? AInspectDS.AGiftDetail.Count : 0; bool RecurrGiftBatchTableInDataSet = (AInspectDS.ARecurringGiftBatch != null && AInspectDS.ARecurringGiftBatch.Count > 0); bool RecurrGiftTableInDataSet = (AInspectDS.ARecurringGift != null && AInspectDS.ARecurringGift.Count > 0); bool RecurrGiftDetailTableInDataSet = (AInspectDS.ARecurringGiftDetail != null && AInspectDS.ARecurringGiftDetail.Count > 0); if (RecurrGiftBatchTableInDataSet || RecurrGiftTableInDataSet || RecurrGiftDetailTableInDataSet) { if (GiftBatchTableInDataSet || GiftTableInDataSet || GiftDetailTableInDataSet) { throw new Exception(String.Format("Function:{0} - Recurring and normal gift data found in same changes batch!", Utilities.GetMethodName(true))); } return SaveRecurringGiftBatchTDS(ref AInspectDS, ref AVerificationResult, RecurrGiftBatchTableInDataSet, RecurrGiftTableInDataSet, RecurrGiftDetailTableInDataSet); } else { if (!(GiftBatchTableInDataSet || GiftTableInDataSet || GiftDetailTableInDataSet)) { throw new Exception(String.Format("Function:{0} - No gift data changes to save!", Utilities.GetMethodName(true))); } } //Get a list of all batches involved List <Int32>ListAllGiftBatchesToProcess = new List <int>(); //Get batch numbers involved if (GiftDetailTableInDataSet) { DataView AllBatchesToProcess = new DataView(AInspectDS.AGiftDetail); AllBatchesToProcess.RowStateFilter = DataViewRowState.OriginalRows | DataViewRowState.Added; foreach (DataRowView drv in AllBatchesToProcess) { AGiftDetailRow gdr = (AGiftDetailRow)drv.Row; int batchNumber; if (gdr.RowState != DataRowState.Deleted) { batchNumber = gdr.BatchNumber; } else { batchNumber = (Int32)gdr[AGiftDetailTable.ColumnBatchNumberId, DataRowVersion.Original]; } if (!ListAllGiftBatchesToProcess.Contains(batchNumber)) { ListAllGiftBatchesToProcess.Add(batchNumber); } } ValidateGiftDetail(ref AVerificationResult, AInspectDS.AGiftDetail); ValidateGiftDetailManual(ref AVerificationResult, AInspectDS.AGiftDetail); if (!TVerificationHelper.IsNullOrOnlyNonCritical(AVerificationResult)) { AllValidationsOK = false; } } //Get batch numbers involved if (GiftTableInDataSet) { DataView AllBatchesToProcess = new DataView(AInspectDS.AGift); AllBatchesToProcess.RowStateFilter = DataViewRowState.OriginalRows | DataViewRowState.Added; foreach (DataRowView drv in AllBatchesToProcess) { AGiftRow gdr = (AGiftRow)drv.Row; int batchNumber; if (gdr.RowState != DataRowState.Deleted) { batchNumber = gdr.BatchNumber; } else { // for deleted batches batchNumber = (Int32)gdr[AGiftTable.ColumnBatchNumberId, DataRowVersion.Original]; } if (!ListAllGiftBatchesToProcess.Contains(batchNumber)) { ListAllGiftBatchesToProcess.Add(batchNumber); } } } //Get batch numbers involved if (GiftBatchTableInDataSet) { DataView AllBatchesToProcess = new DataView(AInspectDS.AGiftBatch); AllBatchesToProcess.RowStateFilter = DataViewRowState.OriginalRows | DataViewRowState.Added; foreach (DataRowView drv in AllBatchesToProcess) { AGiftBatchRow gdr = (AGiftBatchRow)drv.Row; int batchNumber; if (gdr.RowState != DataRowState.Deleted) { batchNumber = gdr.BatchNumber; } else { // for deleted batches batchNumber = (Int32)gdr[AGiftBatchTable.ColumnBatchNumberId, DataRowVersion.Original]; } if (!ListAllGiftBatchesToProcess.Contains(batchNumber)) { ListAllGiftBatchesToProcess.Add(batchNumber); } } ValidateGiftBatch(ref AVerificationResult, AInspectDS.AGiftBatch); ValidateGiftBatchManual(ref AVerificationResult, AInspectDS.AGiftBatch); if (!TVerificationHelper.IsNullOrOnlyNonCritical(AVerificationResult)) { AllValidationsOK = false; } } if (AVerificationResult.Count > 0) { // Downgrade TScreenVerificationResults to TVerificationResults in order to allow // Serialisation (needed for .NET Remoting). TVerificationResultCollection.DowngradeScreenVerificationResults(AVerificationResult); } if (AllValidationsOK) { if ((GiftCount > 0) && (GiftDetailCount > 1)) { //The Gift Detail table must be in ascending order AGiftDetailTable cloneDetail = (AGiftDetailTable)AInspectDS.AGiftDetail.Clone(); foreach (int batchNumber in ListAllGiftBatchesToProcess) { //Copy across any rows marked as deleted first. DataView giftDetails1 = new DataView(AInspectDS.AGiftDetail); giftDetails1.RowFilter = string.Format("{0}={1}", AGiftDetailTable.GetBatchNumberDBName(), batchNumber); giftDetails1.RowStateFilter = DataViewRowState.Deleted; foreach (DataRowView drv in giftDetails1) { AGiftDetailRow gDetailRow = (AGiftDetailRow)drv.Row; cloneDetail.ImportRow(gDetailRow); } //Import the other rows in ascending order DataView giftDetails2 = new DataView(AInspectDS.AGiftDetail); giftDetails2.RowFilter = string.Format("{0}={1}", AGiftDetailTable.GetBatchNumberDBName(), batchNumber); giftDetails2.Sort = String.Format("{0} ASC, {1} ASC, {2} ASC", AGiftDetailTable.GetBatchNumberDBName(), AGiftDetailTable.GetGiftTransactionNumberDBName(), AGiftDetailTable.GetDetailNumberDBName()); foreach (DataRowView giftDetailRows in giftDetails2) { AGiftDetailRow gDR = (AGiftDetailRow)giftDetailRows.Row; cloneDetail.ImportRow(gDR); } } //Clear the table and import the rows from the clone AInspectDS.AGiftDetail.Clear(); for (int i = 0; i < GiftDetailCount; i++) { AGiftDetailRow gDR2 = (AGiftDetailRow)cloneDetail[i]; AInspectDS.AGiftDetail.ImportRow(gDR2); } } GiftBatchTDSAccess.SubmitChanges(AInspectDS); SubmissionResult = TSubmitChangesResult.scrOK; if (GiftTableInDataSet) { if (GiftDetailTableInDataSet) { AInspectDS.AGiftDetail.AcceptChanges(); } AInspectDS.AGift.AcceptChanges(); if (AInspectDS.AGift.Count > 0) { AGiftRow tranR = (AGiftRow)AInspectDS.AGift.Rows[0]; Int32 currentLedger = tranR.LedgerNumber; Int32 currentBatch = tranR.BatchNumber; Int32 giftToDelete = 0; try { DataRow[] foundGiftsForDeletion = AInspectDS.AGift.Select(String.Format("{0} = '{1}'", AGiftTable.GetGiftStatusDBName(), MFinanceConstants.MARKED_FOR_DELETION)); if (foundGiftsForDeletion.Length > 0) { AGiftRow giftRowClient = null; for (int i = 0; i < foundGiftsForDeletion.Length; i++) { //A gift has been deleted giftRowClient = (AGiftRow)foundGiftsForDeletion[i]; giftToDelete = giftRowClient.GiftTransactionNumber; TLogging.Log(String.Format("Gift to Delete: {0} from Batch: {1}", giftToDelete, currentBatch)); giftRowClient.Delete(); } } GiftBatchTDSAccess.SubmitChanges(AInspectDS); SubmissionResult = TSubmitChangesResult.scrOK; } catch (Exception ex) { TLogging.Log(String.Format("Method:{0} - Unexpected error trying to save gift batch!{1}{1}{2}", Utilities.GetMethodSignature(), Environment.NewLine, ex.Message)); throw ex; } } } } return SubmissionResult; }
public static bool IsRecipientLedgerNumberSetupForILT(Int32 ALedgerNumber, Int64 ARecipientPartnerKey, Int64 ARecipientLedgerNumber, out TVerificationResultCollection AVerificationResults) { #region Validate Arguments if (ALedgerNumber <= 0) { throw new EFinanceSystemInvalidLedgerNumberException(String.Format(Catalog.GetString( "Function:{0} - The Ledger number must be greater than 0!"), Utilities.GetMethodName(true)), ALedgerNumber); } else if (ARecipientPartnerKey < 0) { throw new ArgumentException(String.Format(Catalog.GetString("Function:{0} - The Recipient Partner Key is less than 0!"), Utilities.GetMethodName(true))); } else if (ARecipientLedgerNumber < 0) { throw new ArgumentException(String.Format(Catalog.GetString("Function:{0} - The Recipient Ledger Number is less than 0!"), Utilities.GetMethodName(true))); } #endregion Validate Arguments AVerificationResults = new TVerificationResultCollection(); Int32 RecipientLedger = (int)ARecipientLedgerNumber / 1000000; try { if ((RecipientLedger != ALedgerNumber) && (ARecipientPartnerKey > 0)) { string CostCentreCode = string.Empty; //Valid ledger number table if (!CheckCostCentreDestinationForRecipient(ALedgerNumber, ARecipientLedgerNumber, out CostCentreCode) && !CheckCostCentreDestinationForRecipient(ALedgerNumber, ARecipientPartnerKey, out CostCentreCode)) { TPartnerClass Class; string ARecipientLedgerNumberName = string.Empty; TPartnerServerLookups.GetPartnerShortName(ARecipientLedgerNumber, out ARecipientLedgerNumberName, out Class); AVerificationResults.Add( new TVerificationResult( null, string.Format(ErrorCodes.GetErrorInfo(PetraErrorCodes.ERR_RECIPIENTFIELD_NOT_ILT).ErrorMessageText, ARecipientLedgerNumberName, ARecipientLedgerNumber.ToString("0000000000")), PetraErrorCodes.ERR_RECIPIENTFIELD_NOT_ILT, TResultSeverity.Resv_Critical)); return false; } } } catch (Exception ex) { TLogging.Log(String.Format("Method:{0} - Unexpected error!{1}{1}{2}", Utilities.GetMethodSignature(), Environment.NewLine, ex.Message)); throw ex; } return true; }
/// <summary> /// Load the AP documents and see if they are ready to be posted /// </summary> /// <param name="ALedgerNumber"></param> /// <param name="AAPDocumentIds"></param> /// <param name="APostingDate"></param> /// <param name="Reversal"></param> /// <param name="MustBeApproved"></param> /// <param name="AVerifications"></param> /// <returns> The TDS for posting</returns> private static AccountsPayableTDS LoadDocumentsAndCheck(Int32 ALedgerNumber, List <Int32>AAPDocumentIds, DateTime APostingDate, Boolean Reversal, out Boolean MustBeApproved, out TVerificationResultCollection AVerifications) { AccountsPayableTDS MainDS = new AccountsPayableTDS(); AVerifications = new TVerificationResultCollection(); bool IsMyOwnTransaction; // If I create a transaction here, then I need to rollback when I'm done. TDBTransaction Transaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction (IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out IsMyOwnTransaction); // collect the AP documents from the database foreach (Int32 APDocumentId in AAPDocumentIds) { AApDocumentAccess.LoadByPrimaryKey(MainDS, APDocumentId, Transaction); AApDocumentDetailAccess.LoadViaAApDocument(MainDS, APDocumentId, Transaction); } MustBeApproved = LedgerRquiresDocumentApproval(ALedgerNumber, Transaction); // do some checks on state of AP documents foreach (AApDocumentRow document in MainDS.AApDocument.Rows) { if (Reversal) { if (document.DocumentStatus != MFinanceConstants.AP_DOCUMENT_POSTED) { AVerifications.Add(new TVerificationResult( Catalog.GetString("Error during reversal of posted AP document"), String.Format(Catalog.GetString("Document Number {0} cannot be reversed since the status is {1}."), document.ApNumber, document.DocumentStatus), TResultSeverity.Resv_Critical)); } } else { if ( (MustBeApproved && (document.DocumentStatus != MFinanceConstants.AP_DOCUMENT_APPROVED)) || (!MustBeApproved && ((document.DocumentStatus != MFinanceConstants.AP_DOCUMENT_OPEN) && (document.DocumentStatus != MFinanceConstants.AP_DOCUMENT_APPROVED))) ) { AVerifications.Add(new TVerificationResult( Catalog.GetString("Error during posting of AP document"), String.Format(Catalog.GetString("Document Number {0} cannot be posted since the status is {1}."), document.ApNumber, document.DocumentStatus), TResultSeverity.Resv_Critical)); } } // TODO: also check if details are filled, and they each have a costcentre and account? // TODO: check for document.apaccount, if not set, get the default apaccount from the supplier, and save the ap document // Check that the amount of the document equals the totals of details if (!DocumentBalanceOK(MainDS, document.ApDocumentId, Transaction)) { AVerifications.Add(new TVerificationResult( String.Format(Catalog.GetString("Cannot post the AP document {0} in Ledger {1}"), document.ApNumber, ALedgerNumber), String.Format(Catalog.GetString("The value does not match the sum of the details.")), TResultSeverity.Resv_Critical)); } // Load Analysis Attributes and check they're all present. if (!AttributesAllOK(MainDS, ALedgerNumber, document.ApDocumentId, Transaction)) { AVerifications.Add(new TVerificationResult( String.Format(Catalog.GetString("Cannot post the AP document {0} in Ledger {1}"), document.ApNumber, ALedgerNumber), String.Format(Catalog.GetString("Analysis Attributes are required.")), TResultSeverity.Resv_Critical)); } } //foreach // is APostingDate inside the valid posting periods? Int32 DateEffectivePeriodNumber, DateEffectiveYearNumber; if (!TFinancialYear.IsValidPostingPeriod(ALedgerNumber, APostingDate, out DateEffectivePeriodNumber, out DateEffectiveYearNumber, Transaction)) { AVerifications.Add(new TVerificationResult( String.Format(Catalog.GetString("Cannot post the AP documents in Ledger {0}"), ALedgerNumber), String.Format(Catalog.GetString("The Date Effective {0:d-MMM-yyyy} does not fit any open accounting period."), APostingDate), TResultSeverity.Resv_Critical)); } if (IsMyOwnTransaction) { DBAccess.GDBAccessObj.RollbackTransaction(); } return MainDS; }
public static bool ApproveAPDocuments(Int32 ALedgerNumber, List <Int32>AApproveTheseDocs, out TVerificationResultCollection AVerificationResult) { AVerificationResult = new TVerificationResultCollection(); bool ResultValue = false; AccountsPayableTDS TempDS = new AccountsPayableTDS(); if (AApproveTheseDocs.Count == 0) { AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Approve AP Documents"), Catalog.GetString("Nothing to do - the document list is empty"), TResultSeverity.Resv_Noncritical)); return false; } foreach (Int32 ApDocumentId in AApproveTheseDocs) { TempDS.Merge(LoadAApDocument(ALedgerNumber, ApDocumentId)); // This gives me documents, details, and potentially ap_anal_attrib records. } foreach (AApDocumentRow ApDocumentRow in TempDS.AApDocument.Rows) { if (ApDocumentRow.DocumentStatus == MFinanceConstants.AP_DOCUMENT_OPEN) { ApDocumentRow.DocumentStatus = MFinanceConstants.AP_DOCUMENT_APPROVED; } else { AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Approve AP Documents"), Catalog.GetString("Only OPEN documents can be approved"), TResultSeverity.Resv_Noncritical)); return false; } } TDBTransaction SubmitChangesTransaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.Serializable); try { AApDocumentAccess.SubmitChanges(TempDS.AApDocument, SubmitChangesTransaction); DBAccess.GDBAccessObj.CommitTransaction(); ResultValue = true; } catch (Exception Exc) { TLogging.Log("An Exception occured during the approval of AP Documents:" + Environment.NewLine + Exc.ToString()); DBAccess.GDBAccessObj.RollbackTransaction(); AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Approve AP Documents"), Exc.Message, TResultSeverity.Resv_Critical)); throw; } return ResultValue; }
private static void AddVerificationResult(ref TVerificationResultCollection ReferenceResults, String AResultText, TResultSeverity Severity) { if (Severity != TResultSeverity.Resv_Status) { TLogging.Log(AResultText); } ReferenceResults.Add(new TVerificationResult(FImportContext, AResultText, Severity)); }
/// <summary> /// check the location change; validate and take other required action /// eg. change the location of family members, promote address changes /// </summary> /// <param name="ALocationRow"></param> /// <param name="APartnerKey"></param> /// <param name="AResponseDS"></param> /// <param name="ASubmitChangesTransaction"></param> /// <param name="AAddressAddedPromotionDT"></param> /// <param name="AChangeLocationParametersDT"></param> /// <param name="APartnerLocationTable"></param> /// <param name="AVerificationResult"></param> /// <param name="ACreateLocation"></param> /// <param name="AOriginalLocationKey"></param> /// <returns></returns> private static TSubmitChangesResult PerformLocationChangeChecks(PLocationRow ALocationRow, Int64 APartnerKey, ref PartnerAddressAggregateTDS AResponseDS, TDBTransaction ASubmitChangesTransaction, ref PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable AAddressAddedPromotionDT, ref PartnerAddressAggregateTDSChangePromotionParametersTable AChangeLocationParametersDT, ref PPartnerLocationTable APartnerLocationTable, ref TVerificationResultCollection AVerificationResult, out Boolean ACreateLocation, out TLocationPK AOriginalLocationKey) { TSubmitChangesResult ReturnValue; DataView PropagateLocationParametersDV; DataView PropagateLocationParametersDV2; Boolean UpdateLocation; Int64[] CreateLocationOtherPartnerKeys; PartnerAddressAggregateTDSChangePromotionParametersTable ChangePromotionParametersDT; PLocationTable NewLocationTable; PLocationRow NewLocationRowSaved; Int32 NewLocationLocationKey; PPartnerLocationRow PartnerLocationRowForChangedLocation; DataSet PartnerLocationModifyDS; int Counter; Int64 OldLocationKey; OdbcParameter[] ParametersArray; String OtherPartnerKeys = ""; AOriginalLocationKey = null; // TLogging.LogAtLevel(9, "PerformLocationChangeChecks: AAddressAddedPromotionDT.Rows.Count: " + AAddressAddedPromotionDT.Rows.Count.ToString()); if (CheckLocationChange(ALocationRow, APartnerKey, ref AAddressAddedPromotionDT, ASubmitChangesTransaction, out UpdateLocation, out ACreateLocation, out CreateLocationOtherPartnerKeys, out ChangePromotionParametersDT)) { // Check if there is a Parameter Row for the LocationKey we are looking at PropagateLocationParametersDV = new DataView(AAddressAddedPromotionDT, PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetSiteKeyDBName() + " = " + ALocationRow.SiteKey.ToString() + " AND " + PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationKeyDBName() + " = " + ALocationRow.LocationKey.ToString() + " AND " + PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationChangeDBName() + " = true AND " + PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetAnswerProcessedClientSideDBName() + " = false", "", DataViewRowState.CurrentRows); if (PropagateLocationParametersDV.Count > 0) { // TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Location " + ALocationRow.LocationKey.ToString() + // ": Location has been changed, decision on propagation is needed."); /* * More information is needed (usually via user interaction) * -> stop processing here and return parameters * (usually used for UI interaction) */ if (AResponseDS == null) { // TLogging.LogAtLevel(9, TLogging.Log("PerformLocationChangeChecks: Creating AResponseDS."); AResponseDS = new PartnerAddressAggregateTDS(MPartnerConstants.PARTNERADDRESSAGGREGATERESPONSE_DATASET); } // TLogging.LogAtLevel(9, "PerformLocationChangeChecks: AAddressAddedPromotionDT.Rows.Count: " + AAddressAddedPromotionDT.Rows.Count.ToString()); AResponseDS.Merge(AAddressAddedPromotionDT); // TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Merged AAddressAddedPromotionDT into AResponseDS."); AResponseDS.Merge(ChangePromotionParametersDT); // TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Merged ChangePromotionParametersDT into AResponseDS."); // TLogging.LogAtLevel(9, "PerformLocationChangeChecks: AResponseDS.Tables[" + MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME + // "].Rows.Count: " + AResponseDS.Tables[MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME].Rows.Count.ToString()); return TSubmitChangesResult.scrInfoNeeded; } else { // TLogging.LogAtLevel(9, "PerformLocationChangeChecks: User made his/her choice regarding Location Change promotion; now processing..."); /* * User made his/her choice regarding Location Change promotion; now process it */ if (ACreateLocation) { OldLocationKey = ALocationRow.LocationKey; AOriginalLocationKey = new TLocationPK( Convert.ToInt64(ALocationRow[PLocationTable.GetSiteKeyDBName(), DataRowVersion.Original]), Convert.ToInt32(ALocationRow[PLocationTable.GetLocationKeyDBName(), DataRowVersion.Original])); // ALocationRow.LocationKey; // TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Location " + AOriginalLocationKey.LocationKey.ToString() + ": should be created."); /* * Create and save NEW Location that holds the same data than the changed * Location. */ NewLocationTable = new PLocationTable(); NewLocationRowSaved = NewLocationTable.NewRowTyped(false); NewLocationRowSaved.ItemArray = DataUtilities.DestinationSaveItemArray(NewLocationRowSaved, ALocationRow); NewLocationRowSaved.LocationKey = -1; NewLocationTable.Rows.Add(NewLocationRowSaved); // Submit the NEW Location to the DB PLocationAccess.SubmitChanges(NewLocationTable, ASubmitChangesTransaction); // The DB gives us a LocationKey from a Sequence. Remember this one. NewLocationLocationKey = (Int32)NewLocationRowSaved.LocationKey; // TLogging.LogAtLevel(9, "PerformLocationChangeChecks: New Location created! Its Location Key is: " + NewLocationLocationKey.ToString()); // Add the new row to the LocationTable that is beeing processed as well // NewLocationCurrentTableRow := (ALocationRow.Table as PLocationTable).NewRowTyped(false); // NewLocationCurrentTableRow.ItemArray := NewLocationRowSaved.ItemArray; // ALocationRow.Table.Rows.Add(NewLocationCurrentTableRow); // Make the row unchanged so that it isn't picked up as a 'new Address' // and that it doesn't get saved later. Will be sent back to the Partner // Edit screen lateron. // NewLocationCurrentTableRow.AcceptChanges; /* * Update the reference from the changed Location to the new Location in * the Partner's PartnerLocation DataTable. This will be saved later in * the call to SubmitChanges in the main loop of the SubmitData function. */ PartnerLocationRowForChangedLocation = (PPartnerLocationRow)APartnerLocationTable.Rows.Find(new object[] { APartnerKey, ALocationRow.SiteKey, ALocationRow.LocationKey }); PartnerLocationRowForChangedLocation.LocationKey = NewLocationLocationKey; // Now delete the changed Location so that it doesn't get saved! // ALocationRow.Delete; // ALocationRow.AcceptChanges; // Overwrite the Location that should be replaced with the data of the new Location ALocationRow.ItemArray = NewLocationRowSaved.ItemArray; PropagateLocationParametersDV2 = new DataView(AAddressAddedPromotionDT, PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetSiteKeyDBName() + " = " + NewLocationRowSaved.SiteKey.ToString() + " AND " + PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationKeyDBName() + " = " + OldLocationKey.ToString() + " AND " + PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationChangeDBName() + " = true AND " + PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetAnswerProcessedClientSideDBName() + " = true", "", DataViewRowState.CurrentRows); ((PartnerAddressAggregateTDSAddressAddedOrChangedPromotionRow)(PropagateLocationParametersDV2[0].Row)).LocationKey = ALocationRow.LocationKey; if (CreateLocationOtherPartnerKeys.Length > 0) { // TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Created Location " + NewLocationLocationKey.ToString() + // ": should be assigned to " + Convert.ToInt32(CreateLocationOtherPartnerKeys.Length).ToString() + " Partners..."); // Build list of PartnerKeys for IN (x,y) clause in the SQL statement for (Counter = 0; Counter <= CreateLocationOtherPartnerKeys.Length - 1; Counter += 1) { OtherPartnerKeys = OtherPartnerKeys + CreateLocationOtherPartnerKeys[Counter].ToString() + ','; } // remove last ',' OtherPartnerKeys = OtherPartnerKeys.Substring(0, OtherPartnerKeys.Length - 1); // Load data for all the other selected Partners that reference // the PartnerLocation PartnerLocationModifyDS = new DataSet(); PartnerLocationModifyDS.Tables.Add(new PPartnerLocationTable()); ParametersArray = new OdbcParameter[2]; ParametersArray[0] = new OdbcParameter("", OdbcType.Decimal, 10); ParametersArray[0].Value = (System.Object)(NewLocationRowSaved.SiteKey); ParametersArray[1] = new OdbcParameter("", OdbcType.Int); ParametersArray[1].Value = (System.Object)(AOriginalLocationKey.LocationKey); PartnerLocationModifyDS = DBAccess.GDBAccessObj.Select(PartnerLocationModifyDS, "SELECT * " + "FROM PUB_" + PPartnerLocationTable.GetTableDBName() + ' ' + "WHERE " + PPartnerLocationTable.GetPartnerKeyDBName() + " IN (" + OtherPartnerKeys + ") " + "AND " + PPartnerLocationTable.GetSiteKeyDBName() + " = ? " + "AND " + PPartnerLocationTable.GetLocationKeyDBName() + " = ?", PPartnerLocationTable.GetTableName(), ASubmitChangesTransaction, ParametersArray); // Change the LocationKey for every one of those PartnerLocation // DataRows to point to the NEW Location for (Counter = 0; Counter <= CreateLocationOtherPartnerKeys.Length - 1; Counter += 1) { ((PPartnerLocationTable)PartnerLocationModifyDS.Tables[0])[Counter].LocationKey = NewLocationLocationKey; } // Submit the changes to those PartnerLocations to the DB PPartnerLocationAccess.SubmitChanges((PPartnerLocationTable)PartnerLocationModifyDS.Tables[0], ASubmitChangesTransaction); } else { // TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Created Location " + NewLocationLocationKey.ToString() + ": should not be assigned to any other Partners..."); /* * Don't need to do anything here - the just created Location got already * assigned to the Partner we are currently working with. */ } } else if (UpdateLocation) { // TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Location " + ALocationRow.LocationKey.ToString() + // ": should simply get updated; therefore the Locations of ALL Partners will be changed..."); /* * Don't need to do anything here - the changed Location will be saved * in the call to SubmitChanges in the main loop of the SubmitData function. */ } } ReturnValue = TSubmitChangesResult.scrOK; } else { TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Location " + ALocationRow.LocationKey.ToString() + ": User cancelled the selection - stopping the whole saving process!"); /* * User cancelled the selection - stop the whole saving process! */ AVerificationResult.Add(new TVerificationResult("Location Change Promotion: Information", "No changes were saved because the Location Change Promotion dialog was cancelled by the user.", "Saving cancelled by user", "", TResultSeverity.Resv_Noncritical)); ReturnValue = TSubmitChangesResult.scrError; } return ReturnValue; }
public static bool CancelExpiredSubscriptions() { TDBTransaction Transaction = null; bool SubmissionOK = false; //Error handling string ErrorContext = "Create a Batch"; string ErrorMessage = String.Empty; //Set default type as non-critical TResultSeverity ErrorType = TResultSeverity.Resv_Noncritical; TVerificationResultCollection VerificationResult = null; DBAccess.GDBAccessObj.GetNewOrExistingAutoTransaction(IsolationLevel.Serializable, TEnforceIsolationLevel.eilMinimum, ref Transaction, ref SubmissionOK, delegate { try { DBAccess.GDBAccessObj.ExecuteNonQuery("UPDATE " + PSubscriptionTable.GetTableDBName() + " SET " + PSubscriptionTable.GetDateCancelledDBName() + " = DATE(NOW()), " + PSubscriptionTable.GetSubscriptionStatusDBName() + " = 'EXPIRED', " + PSubscriptionTable.GetReasonSubsCancelledCodeDBName() + " = 'COMPLETE' " + "WHERE " + PSubscriptionTable.GetExpiryDateDBName() + " < DATE(NOW()) " + "AND " + PSubscriptionTable.GetDateCancelledDBName() + " IS NULL", Transaction); SubmissionOK = true; } catch (Exception ex) { ErrorMessage = Catalog.GetString("Unknown error while cancelling expired subscriptions:" + Environment.NewLine + Environment.NewLine + ex.ToString()); ErrorType = TResultSeverity.Resv_Critical; VerificationResult = new TVerificationResultCollection(); VerificationResult.Add(new TVerificationResult(ErrorContext, ErrorMessage, ErrorType)); throw new EVerificationResultsException(ErrorMessage, VerificationResult, ex.InnerException); } }); return SubmissionOK; }
public static bool DeleteConference(Int64 AConferenceKey, out TVerificationResultCollection AVerificationResult) { TVerificationResultCollection VerificationResult = null; TProgressTracker.InitProgressTracker(DomainManager.GClientID.ToString(), Catalog.GetString("Deleting conference"), 100); TDBTransaction Transaction = null; bool SubmissionOK = false; DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref Transaction, ref SubmissionOK, delegate { try { string[] TableNames = new string[] { PcAttendeeTable.GetTableDBName(), PcConferenceCostTable.GetTableDBName(), PcConferenceOptionTable.GetTableDBName(), PcConferenceVenueTable.GetTableDBName(), PcDiscountTable.GetTableDBName(), PcEarlyLateTable.GetTableDBName(), PcExtraCostTable.GetTableDBName(), PcGroupTable.GetTableDBName(), PcSupplementTable.GetTableDBName() }; OdbcParameter[] ConferenceParameter = new OdbcParameter[] { new OdbcParameter("conferencekey", OdbcType.BigInt) }; ConferenceParameter[0].Value = AConferenceKey; int Progress = 0; foreach (string Table in TableNames) { TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(), Catalog.GetString("Deleting: ") + Table, 10 * Progress); DBAccess.GDBAccessObj.ExecuteNonQuery( String.Format("DELETE FROM PUB_{0} WHERE pc_conference_key_n = ?", Table), Transaction, ConferenceParameter); Progress++; } TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(), Catalog.GetString("Deleting: Conference"), 90); PcConferenceAccess.DeleteByPrimaryKey(AConferenceKey, Transaction); if (TProgressTracker.GetCurrentState(DomainManager.GClientID.ToString()).CancelJob == false) { SubmissionOK = true; } TProgressTracker.FinishJob(DomainManager.GClientID.ToString()); } catch (Exception e) { TLogging.Log(e.ToString()); VerificationResult = new TVerificationResultCollection(); VerificationResult.Add(new TVerificationResult( "Problems deleting conference " + AConferenceKey.ToString("0000000000"), e.Message, "Cannot delete conference", string.Empty, TResultSeverity.Resv_Critical, Guid.Empty)); TProgressTracker.CancelJob(DomainManager.GClientID.ToString()); } }); AVerificationResult = VerificationResult; return SubmissionOK; }
public static TSubmitChangesResult SaveData(string ATablename, ref TTypedDataTable ASubmitTable, out TVerificationResultCollection AVerificationResult) { TDBTransaction SubmitChangesTransaction = null; bool SubmissionOK = false; TTypedDataTable SubmitTable = ASubmitTable; TVerificationResultCollection VerificationResult = null; // TODO: check write permissions if (ASubmitTable != null) { VerificationResult = new TVerificationResultCollection(); DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref SubmitChangesTransaction, ref SubmissionOK, delegate { try { if (ATablename == AAccountingPeriodTable.GetTableDBName()) { AAccountingPeriodAccess.SubmitChanges((AAccountingPeriodTable)SubmitTable, SubmitChangesTransaction); TCacheableTablesManager.GCacheableTablesManager.MarkCachedTableNeedsRefreshing( TCacheableFinanceTablesEnum.AccountingPeriodList.ToString()); } else if (ATablename == ACurrencyTable.GetTableDBName()) { ACurrencyAccess.SubmitChanges((ACurrencyTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == ADailyExchangeRateTable.GetTableDBName()) { ADailyExchangeRateAccess.SubmitChanges((ADailyExchangeRateTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == ACorporateExchangeRateTable.GetTableDBName()) { ACorporateExchangeRateAccess.SubmitChanges((ACorporateExchangeRateTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == ACurrencyLanguageTable.GetTableDBName()) { ACurrencyLanguageAccess.SubmitChanges((ACurrencyLanguageTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == AFeesPayableTable.GetTableDBName()) { AFeesPayableAccess.SubmitChanges((AFeesPayableTable)SubmitTable, SubmitChangesTransaction); TCacheableTablesManager.GCacheableTablesManager.MarkCachedTableNeedsRefreshing( TCacheableFinanceTablesEnum.FeesPayableList.ToString()); } else if (ATablename == AFeesReceivableTable.GetTableDBName()) { AFeesReceivableAccess.SubmitChanges((AFeesReceivableTable)SubmitTable, SubmitChangesTransaction); TCacheableTablesManager.GCacheableTablesManager.MarkCachedTableNeedsRefreshing( TCacheableFinanceTablesEnum.FeesReceivableList.ToString()); } else if (ATablename == AGiftBatchTable.GetTableDBName()) { // This method is called from ADailyExchangeRate Setup - please do not remove // The method is not required for changes made to the gift batch screens, which use a TDS AGiftBatchAccess.SubmitChanges((AGiftBatchTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == AJournalTable.GetTableDBName()) { // This method is called from ADailyExchangeRate Setup - please do not remove // The method is not required for changes made to the journal screens, which use a TDS AJournalAccess.SubmitChanges((AJournalTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == ARecurringJournalTable.GetTableDBName()) { // This method is called from Submit Recurring GL Batch form - please do not remove // The method is not required for changes made to the journal screens, which use a TDS ARecurringJournalAccess.SubmitChanges((ARecurringJournalTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == ALedgerTable.GetTableDBName()) { // This method is called from ADailyExchangeRate Testing - please do not remove ALedgerAccess.SubmitChanges((ALedgerTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == AAnalysisTypeTable.GetTableDBName()) { AAnalysisTypeAccess.SubmitChanges((AAnalysisTypeTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == ASuspenseAccountTable.GetTableDBName()) { ASuspenseAccountAccess.SubmitChanges((ASuspenseAccountTable)SubmitTable, SubmitChangesTransaction); TCacheableTablesManager.GCacheableTablesManager.MarkCachedTableNeedsRefreshing( TCacheableFinanceTablesEnum.SuspenseAccountList.ToString()); } else if (ATablename == PcAttendeeTable.GetTableDBName()) { PcAttendeeAccess.SubmitChanges((PcAttendeeTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == PcConferenceTable.GetTableDBName()) { PcConferenceAccess.SubmitChanges((PcConferenceTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == PcConferenceCostTable.GetTableDBName()) { PcConferenceCostAccess.SubmitChanges((PcConferenceCostTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == PcEarlyLateTable.GetTableDBName()) { PcEarlyLateAccess.SubmitChanges((PcEarlyLateTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == PcSupplementTable.GetTableDBName()) { PcSupplementAccess.SubmitChanges((PcSupplementTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == PcDiscountTable.GetTableDBName()) { PcDiscountAccess.SubmitChanges((PcDiscountTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == PInternationalPostalTypeTable.GetTableDBName()) { ValidateInternationalPostalType(ref VerificationResult, SubmitTable); ValidateInternationalPostalTypeManual(ref VerificationResult, SubmitTable); if (TVerificationHelper.IsNullOrOnlyNonCritical(VerificationResult)) { PInternationalPostalTypeAccess.SubmitChanges((PInternationalPostalTypeTable)SubmitTable, SubmitChangesTransaction); } } else if (ATablename == PtApplicationTypeTable.GetTableDBName()) { PtApplicationTypeAccess.SubmitChanges((PtApplicationTypeTable)SubmitTable, SubmitChangesTransaction); // mark dependent lists for needing to be refreshed since there was a change in base list TCacheableTablesManager.GCacheableTablesManager.MarkCachedTableNeedsRefreshing( TCacheablePersonTablesEnum.EventApplicationTypeList.ToString()); TCacheableTablesManager.GCacheableTablesManager.MarkCachedTableNeedsRefreshing( TCacheablePersonTablesEnum.FieldApplicationTypeList.ToString()); } else if (ATablename == PFormTable.GetTableDBName()) { PFormAccess.SubmitChanges((PFormTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == PFormalityTable.GetTableDBName()) { PFormalityAccess.SubmitChanges((PFormalityTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == PMailingTable.GetTableDBName()) { PMailingAccess.SubmitChanges((PMailingTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == PPartnerGiftDestinationTable.GetTableDBName()) { PPartnerGiftDestinationAccess.SubmitChanges((PPartnerGiftDestinationTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == PmDocumentTypeTable.GetTableDBName()) { PmDocumentTypeAccess.SubmitChanges((PmDocumentTypeTable)SubmitTable, SubmitChangesTransaction); } else if (ATablename == SGroupTable.GetTableDBName()) { SGroupAccess.SubmitChanges((SGroupTable)SubmitTable, SubmitChangesTransaction); } else { throw new EOPAppException("TCommonDataReader.SaveData: unknown table '" + ATablename + "'"); } SubmissionOK = true; } catch (Exception Exc) { VerificationResult.Add( new TVerificationResult(null, "Cannot SubmitChanges:" + Environment.NewLine + Exc.Message, "UNDEFINED", TResultSeverity.Resv_Critical)); } }); } ASubmitTable = SubmitTable; AVerificationResult = VerificationResult; if ((AVerificationResult != null) && (AVerificationResult.Count > 0)) { // Downgrade TScreenVerificationResults to TVerificationResults in order to allow // Serialisation (needed for .NET Remoting). TVerificationResultCollection.DowngradeScreenVerificationResults(AVerificationResult); return AVerificationResult.HasCriticalErrors ? TSubmitChangesResult.scrError : TSubmitChangesResult.scrOK; } return TSubmitChangesResult.scrOK; }
/// <summary> /// send report as email /// </summary> public Boolean SendEmail(string AEmailAddresses, bool AAttachExcelFile, bool AAttachCSVFile, bool AAttachPDF, bool AWrapColumn, out TVerificationResultCollection AVerification) { TSmtpSender EmailSender = new TSmtpSender(); AVerification = new TVerificationResultCollection(); if (!EmailSender.ValidateEmailConfiguration()) { AVerification.Add(new TVerificationResult( Catalog.GetString("Sending Email"), Catalog.GetString("Missing configuration for sending emails. Please edit your server configuration file"), CommonErrorCodes.ERR_MISSINGEMAILCONFIGURATION, TResultSeverity.Resv_Critical, new System.Guid())); return false; } List <string>FilesToAttach = new List <string>(); if (AAttachExcelFile) { string ExcelFile = TFileHelper.GetTempFileName( FParameterList.Get("currentReport").ToString(), ".xlsx"); if (ExportToExcelFile(ExcelFile)) { FilesToAttach.Add(ExcelFile); } } if (AAttachCSVFile) { string CSVFile = TFileHelper.GetTempFileName( FParameterList.Get("currentReport").ToString(), ".csv"); if (ExportToCSVFile(CSVFile)) { FilesToAttach.Add(CSVFile); } } if (AAttachPDF) { string PDFFile = TFileHelper.GetTempFileName( FParameterList.Get("currentReport").ToString(), ".pdf"); if (PrintToPDF(PDFFile, AWrapColumn)) { FilesToAttach.Add(PDFFile); } } if (FilesToAttach.Count == 0) { AVerification.Add(new TVerificationResult( Catalog.GetString("Sending Email"), Catalog.GetString("Missing any attachments, not sending the email"), "Missing Attachments", TResultSeverity.Resv_Critical, new System.Guid())); return false; } // TODO use the email address of the user, from s_user if (EmailSender.SendEmail("<" + TAppSettingsManager.GetValue("Reports.Email.Sender") + ">", "OpenPetra Reports", AEmailAddresses, FParameterList.Get("currentReport").ToString(), Catalog.GetString("Please see attachment!"), FilesToAttach.ToArray())) { foreach (string file in FilesToAttach) { File.Delete(file); } return true; } AVerification.Add(new TVerificationResult( Catalog.GetString("Sending Email"), Catalog.GetString("Problem sending email"), "server problems", TResultSeverity.Resv_Critical, new System.Guid())); return false; }
public static bool PostAPDocuments(Int32 ALedgerNumber, List <Int32>AAPDocumentIds, DateTime APostingDate, Boolean Reversal, out TVerificationResultCollection AVerificationResult) { bool PostingWorkedOk = true; ABatchRow batch; TVerificationResultCollection ResultsCollection = new TVerificationResultCollection(); TDBTransaction HighLevelTransaction = null; Boolean WillCommit = true; Boolean MustBeApproved; DBAccess.GDBAccessObj.GetNewOrExistingAutoTransaction(IsolationLevel.Serializable, ref HighLevelTransaction, ref WillCommit, delegate { AccountsPayableTDS MainDS = LoadDocumentsAndCheck(ALedgerNumber, AAPDocumentIds, APostingDate, Reversal, out MustBeApproved, out ResultsCollection); if (!TVerificationHelper.IsNullOrOnlyNonCritical(ResultsCollection)) { PostingWorkedOk = false; return; // This is returning from the AutoTransaction, not from the whole method. } GLBatchTDS GLDataset = CreateGLBatchAndTransactionsForPosting(ALedgerNumber, APostingDate, Reversal, ref MainDS); batch = GLDataset.ABatch[0]; // save the batch if (TGLTransactionWebConnector.SaveGLBatchTDS(ref GLDataset, out ResultsCollection) != TSubmitChangesResult.scrOK) { PostingWorkedOk = false; } // post the batch if (PostingWorkedOk) { PostingWorkedOk = TGLPosting.PostGLBatch(ALedgerNumber, batch.BatchNumber, out ResultsCollection); } if (!PostingWorkedOk) { TVerificationResultCollection MoreResults; TGLPosting.DeleteGLBatch( ALedgerNumber, GLDataset.ABatch[0].BatchNumber, out MoreResults); ResultsCollection.AddCollection(MoreResults); return; } // GL posting is OK - change status of AP documents and save to database foreach (AApDocumentRow row in MainDS.AApDocument.Rows) { if (Reversal) { row.DocumentStatus = MustBeApproved ? MFinanceConstants.AP_DOCUMENT_APPROVED : MFinanceConstants.AP_DOCUMENT_OPEN; } else { row.DocumentStatus = MFinanceConstants.AP_DOCUMENT_POSTED; } } try { AApDocumentAccess.SubmitChanges(MainDS.AApDocument, HighLevelTransaction); } catch (Exception Exc) { // Now I've got GL entries, but "unposted" AP documents! TLogging.Log("An Exception occured during the Posting of an AP Document:" + Environment.NewLine + Exc.ToString()); ResultsCollection.Add(new TVerificationResult(Catalog.GetString("Post AP Document"), Catalog.GetString("NOTE THAT A GL ENTRY MAY HAVE BEEN CREATED.") + Environment.NewLine + Exc.Message, TResultSeverity.Resv_Critical)); PostingWorkedOk = false; return; } }); AVerificationResult = ResultsCollection; // The System.Action defined in the delegate below cannot directly access // "out" parameters, so this intermediate variable was used. return PostingWorkedOk; }
/// <summary> /// To build a CSV list of accounts /// </summary> /// <param name="ALedgerNumber"></param> /// <param name="AAccountRowFirst"></param> /// <param name="DBTransaction"></param> /// <param name="AChildAccounts"></param> /// <param name="AVerificationResult"></param> private static void BuildChildAccountList(int ALedgerNumber, AAccountRow AAccountRowFirst, TDBTransaction DBTransaction, ref string AChildAccounts, ref TVerificationResultCollection AVerificationResult) { //Return value string AccountCode = AAccountRowFirst.AccountCode; //Error handling string ErrorContext = Catalog.GetString("List Child Accounts"); string ErrorMessage = String.Empty; //Set default type as non-critical TResultSeverity ErrorType = TResultSeverity.Resv_Noncritical; try { if (AAccountRowFirst.PostingStatus) { AChildAccounts += AccountCode + ","; } else { AAccountHierarchyDetailTable AccountHierarchyDetailTable1 = new AAccountHierarchyDetailTable(); AAccountHierarchyDetailRow TemplateRow = (AAccountHierarchyDetailRow)AccountHierarchyDetailTable1.NewRowTyped(false); TemplateRow.LedgerNumber = ALedgerNumber; TemplateRow.AccountHierarchyCode = MFinanceConstants.ACCOUNT_HIERARCHY_CODE; TemplateRow.AccountCodeToReportTo = AAccountRowFirst.AccountCode; StringCollection operators = StringHelper.InitStrArr(new string[] { "=", "=", "=" }); AAccountHierarchyDetailTable AccountHierarchyDetailTable2 = AAccountHierarchyDetailAccess.LoadUsingTemplate(TemplateRow, operators, null, DBTransaction); if (AccountHierarchyDetailTable2 != null) { for (int m = 0; m < AccountHierarchyDetailTable2.Count; m++) { AAccountHierarchyDetailRow AccountHierarchyDetailRow = (AAccountHierarchyDetailRow)AccountHierarchyDetailTable2.Rows[m]; AAccountTable AccountTable = AAccountAccess.LoadByPrimaryKey(ALedgerNumber, AccountHierarchyDetailRow.ReportingAccountCode, DBTransaction); if (AccountTable != null) { AAccountRow AccountRow = (AAccountRow)AccountTable.Rows[0]; BuildChildAccountList(ALedgerNumber, AccountRow, DBTransaction, ref AChildAccounts, ref AVerificationResult); } else { break; } } } } } catch (ArgumentException ex) { AVerificationResult.Add(new TVerificationResult(ErrorContext, ex.Message, ErrorType)); } catch (InvalidOperationException ex) { AVerificationResult.Add(new TVerificationResult(ErrorContext, ex.Message, ErrorType)); } catch (Exception ex) { ErrorMessage = String.Format(Catalog.GetString("Unknown error while building list of Child Accounts for Ledger: {0} and Account code: {1}" + Environment.NewLine + Environment.NewLine + ex.ToString()), ALedgerNumber, AAccountRowFirst.AccountCode ); ErrorType = TResultSeverity.Resv_Critical; AVerificationResult.Add(new TVerificationResult(ErrorContext, ErrorMessage, ErrorType)); } }
public static bool PostAPPayments( ref AccountsPayableTDS MainDS, DateTime APostingDate, out TVerificationResultCollection AVerificationResult) { bool NewTransaction; TDBTransaction ReadTransaction; AVerificationResult = new TVerificationResultCollection(); bool ResultValue = false; if ((MainDS.AApPayment.Rows.Count < 1) || (MainDS.AApDocumentPayment.Rows.Count < 1)) { AVerificationResult = new TVerificationResultCollection(); AVerificationResult.Add(new TVerificationResult("Post Payment", String.Format("Nothing to do - Payments has {0} rows, Documents has {1} rows.", MainDS.AApPayment.Rows.Count, MainDS.AApDocumentPayment.Rows.Count), TResultSeverity.Resv_Noncritical)); return false; } ReadTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out NewTransaction); foreach (AccountsPayableTDSAApDocumentPaymentRow row in MainDS.AApDocumentPayment.Rows) { AccountsPayableTDSAApDocumentRow documentRow = (AccountsPayableTDSAApDocumentRow)MainDS.AApDocument.Rows.Find(row.ApDocumentId); if (documentRow != null) { MainDS.AApDocument.Rows.Remove(documentRow); } documentRow = (AccountsPayableTDSAApDocumentRow) AApDocumentAccess.LoadByPrimaryKey(MainDS, row.ApDocumentId, ReadTransaction); SetOutstandingAmount(documentRow, documentRow.LedgerNumber, MainDS.AApDocumentPayment); // // If the amount paid is negative, this is a refund.. if (row.Amount < 0) { if (row.Amount <= documentRow.OutstandingAmount) { documentRow.DocumentStatus = MFinanceConstants.AP_DOCUMENT_PAID; } else { documentRow.DocumentStatus = MFinanceConstants.AP_DOCUMENT_PARTIALLY_PAID; } } else { if ((row.Amount >= documentRow.OutstandingAmount) || (documentRow.OutstandingAmount == 0.0m)) { documentRow.DocumentStatus = MFinanceConstants.AP_DOCUMENT_PAID; } else { documentRow.DocumentStatus = MFinanceConstants.AP_DOCUMENT_PARTIALLY_PAID; } } } // Get max payment number for this ledger // PROBLEM: what if two payments are happening at the same time? do we need locking? // see also http://sourceforge.net/apps/mantisbt/openpetraorg/view.php?id=50 object maxPaymentCanBeNull = DBAccess.GDBAccessObj.ExecuteScalar( "SELECT MAX(PUB_a_ap_payment.a_payment_number_i) FROM PUB_a_ap_payment WHERE PUB_a_ap_payment.a_ledger_number_i = " + MainDS.AApPayment[0].LedgerNumber.ToString(), ReadTransaction); Int32 maxPaymentNumberInLedger = (maxPaymentCanBeNull == System.DBNull.Value ? 0 : Convert.ToInt32(maxPaymentCanBeNull)); if (NewTransaction) { DBAccess.GDBAccessObj.RollbackTransaction(); } foreach (AccountsPayableTDSAApPaymentRow paymentRow in MainDS.AApPayment.Rows) { paymentRow.PaymentDate = APostingDate; paymentRow.Amount = 0.0M; Int32 NewPaymentNumber = maxPaymentNumberInLedger + (-1 * paymentRow.PaymentNumber); foreach (AccountsPayableTDSAApDocumentPaymentRow docPaymentRow in MainDS.AApDocumentPayment.Rows) { if (docPaymentRow.PaymentNumber == paymentRow.PaymentNumber) { paymentRow.Amount += docPaymentRow.Amount; docPaymentRow.PaymentNumber = NewPaymentNumber; } } paymentRow.PaymentNumber = NewPaymentNumber; } TDBTransaction SubmitChangesTransaction = null; try { // create GL batch GLBatchTDS GLDataset = CreateGLBatchAndTransactionsForPaying(MainDS.AApPayment[0].LedgerNumber, APostingDate, ref MainDS); ABatchRow batch = GLDataset.ABatch[0]; // save the batch Boolean PostingWorkedOk = (TGLTransactionWebConnector.SaveGLBatchTDS(ref GLDataset, out AVerificationResult) == TSubmitChangesResult.scrOK); if (PostingWorkedOk) { // post the batch PostingWorkedOk = TGLPosting.PostGLBatch(MainDS.AApPayment[0].LedgerNumber, batch.BatchNumber, out AVerificationResult); } if (!PostingWorkedOk) { TVerificationResultCollection MoreResults; TGLPosting.DeleteGLBatch( MainDS.AApPayment[0].LedgerNumber, batch.BatchNumber, out MoreResults); AVerificationResult.AddCollection(MoreResults); return false; } SubmitChangesTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction (IsolationLevel.Serializable, TEnforceIsolationLevel.eilMinimum, out NewTransaction); // store ApPayment and ApDocumentPayment to database AApPaymentAccess.SubmitChanges(MainDS.AApPayment, SubmitChangesTransaction); AApDocumentPaymentAccess.SubmitChanges(MainDS.AApDocumentPayment, SubmitChangesTransaction); // save changed status of AP documents to database AApDocumentAccess.SubmitChanges(MainDS.AApDocument, SubmitChangesTransaction); ResultValue = true; } catch (Exception e) { // Now I've got payment entries in the GL, and "unposted" payment records. TLogging.Log("Posting AP payments: exception " + e.Message); if ((SubmitChangesTransaction != null) && NewTransaction) { DBAccess.GDBAccessObj.RollbackTransaction(); } AVerificationResult.Add(new TVerificationResult("Post AP Payment", e.Message, TResultSeverity.Resv_Critical)); throw; } if ((SubmitChangesTransaction != null) && NewTransaction) { if (ResultValue) { DBAccess.GDBAccessObj.CommitTransaction(); } else { DBAccess.GDBAccessObj.RollbackTransaction(); } } return ResultValue; }
public static bool CheckPartnersCanBeMerged(long AFromPartnerKey, long AToPartnerKey, TPartnerClass AFromPartnerClass, TPartnerClass AToPartnerClass, string AReasonForMerging, out TVerificationResultCollection AVerificationResult) { AVerificationResult = new TVerificationResultCollection(); if (AFromPartnerClass != AToPartnerClass) { // confirm that user wants to merge partners from different partner classes AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Merge Partners"), String.Format(Catalog.GetString("Do you really want to merge a Partner of class {0} into a Partner of class {1}?"), AFromPartnerClass, AToPartnerClass), TResultSeverity.Resv_Noncritical)); // Family Partner cannot be merged into a different partner class if family members, donations or bank accounts exist for that partner if (AFromPartnerClass == TPartnerClass.FAMILY) { int FamilyMergeResult = CanFamilyMergeIntoDifferentClass(AFromPartnerKey); if (FamilyMergeResult != 0) { string ErrorMessage = ""; if (FamilyMergeResult == 1) { ErrorMessage = Catalog.GetString( "This Family record cannot be merged into a Partner with different class as Family members exist!"); } else if (FamilyMergeResult == 2) { ErrorMessage = Catalog.GetString( "This Family record cannot be merged into a Partner with different class as donations were received for it!"); } else if (FamilyMergeResult == 3) { ErrorMessage = Catalog.GetString( "This record cannot be merged into a Partner with different class as bank accounts exist for it!"); } // critical error - only need to return this VerificationResult AVerificationResult.Clear(); AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Merge Partners"), ErrorMessage, TResultSeverity.Resv_Critical)); return false; } } } else // partner classes are the same { string FromPartnerSupplierCurrency; string ToPartnerSupplierCurrency; // if two partners are suppliers they must have the same currency if ((GetSupplierCurrency(AFromPartnerKey, out FromPartnerSupplierCurrency) == true) && (GetSupplierCurrency(AToPartnerKey, out ToPartnerSupplierCurrency) == true)) { if (FromPartnerSupplierCurrency != ToPartnerSupplierCurrency) { // critical error - only need to return this VerificationResult AVerificationResult.Clear(); AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Merge Partners"), Catalog.GetString( "These Partners cannot be merged. Partners that are suppliers must have the same currency in order to merge."), TResultSeverity.Resv_Critical)); return false; } } if (AFromPartnerClass == TPartnerClass.VENUE) { AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Merge Partners"), Catalog.GetString("You are about to merge VENUEs. This will imply merging of buildings, rooms and room " + "allocations defined for these Venues in the Conference Module!") + "\n\n" + Catalog.GetString("Continue?"), TResultSeverity.Resv_Noncritical)); } if (AFromPartnerClass == TPartnerClass.BANK) { AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Merge Partners"), Catalog.GetString("You are about to merge BANKSs. This will imply that all bank accounts that were with the " + "From-Bank Partner will become bank accounts of the To-Bank Partner. For this reason you should merge Banks only when " + "both Bank Partners actually represented the same Bank, or if two different Banks have merged their operations!") + "\n\n" + Catalog.GetString("Continue?"), Catalog.GetString("Merge Partners"), TResultSeverity.Resv_Noncritical)); } } if (AReasonForMerging == "Duplicate Record Exists") { if (AFromPartnerClass == TPartnerClass.FAMILY) { // AFromPartnerClass and AToPartnerClass are the same int CheckCommitmentsResult = CheckPartnerCommitments(AFromPartnerKey, AToPartnerKey, AFromPartnerClass); // if the from family Partner contains a person with an ongoing commitment if (CheckCommitmentsResult != 0) { string FromPartnerShortName; string ToPartnerShortName; TPartnerClass PartnerClass; TPartnerServerLookups.GetPartnerShortName(AFromPartnerKey, out FromPartnerShortName, out PartnerClass); TPartnerServerLookups.GetPartnerShortName(AFromPartnerKey, out ToPartnerShortName, out PartnerClass); string ErrorMessage = string.Format(Catalog.GetString("WARNING: You are about to change the family of {0} ({1}).") + "\n\n" + Catalog.GetString( "Changing a person's family can affect the person's ability to see their support information in" + " the Intranet including any support that they may receive from other Fields."), FromPartnerShortName, AFromPartnerKey); if (CheckCommitmentsResult == 1) { ErrorMessage += "\n\n" + string.Format(Catalog.GetString("It is STRONGLY recommended that you do not continue and " + "consider merging family {0} ({1}) into family {2} ({3})."), ToPartnerShortName, AToPartnerKey, FromPartnerShortName, AFromPartnerKey); } ErrorMessage += "\n\n" + Catalog.GetString("Do you want to continue?"); AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Merge Partners"), ErrorMessage, Catalog.GetString("Merge Partners"), TResultSeverity.Resv_Noncritical)); } } else if (AFromPartnerClass == TPartnerClass.PERSON) { // AFromPartnerClass and AToPartnerClass are the same int CheckCommitmentsResult = CheckPartnerCommitments(AFromPartnerKey, AToPartnerKey, AFromPartnerClass); // if the from Partner has an ongoing commitment if (CheckCommitmentsResult != 0) { string ErrorMessage = ""; string FromPartnerShortName; TPartnerClass PartnerClass; TPartnerServerLookups.GetPartnerShortName(AFromPartnerKey, out FromPartnerShortName, out PartnerClass); if (CheckCommitmentsResult == 3) { ErrorMessage = string.Format(Catalog.GetString("WARNING: You are about to change the family of {0} ({1}).") + "\n\n" + Catalog.GetString( "Changing a person's family can affect the person's ability to see their support information in" + " the Intranet including any support that they may receive from other Fields."), FromPartnerShortName, AFromPartnerKey); } else if (CheckCommitmentsResult == 2) { ErrorMessage = Catalog.GetString("WARNING: Both Persons have a current commitment. " + "Be aware that merging these Persons may affect their usage of the Intranet.") + "\n\n" + Catalog.GetString("Do you want to continue?"); } else if (CheckCommitmentsResult == 1) { ErrorMessage = string.Format(Catalog.GetString("WARNING: Person {0} ({1}) has a current commitment. " + "We strongly recommend merging the other way around."), FromPartnerShortName, AFromPartnerKey) + "\n\n" + Catalog.GetString("Do you want to continue?"); } AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Merge Partners"), ErrorMessage, Catalog.GetString("Merge Partners"), TResultSeverity.Resv_Noncritical)); } } } // checks if one of the partners is a Foundation organisation. if ((AFromPartnerClass == TPartnerClass.ORGANISATION) || (AToPartnerClass == TPartnerClass.ORGANISATION)) { PFoundationTable FromFoundationTable = null; PFoundationTable ToFoundationTable = null; string ErrorMessage = ""; if (AFromPartnerClass == TPartnerClass.ORGANISATION) { FromFoundationTable = GetOrganisationFoundation(AFromPartnerKey); } if (AToPartnerClass == TPartnerClass.ORGANISATION) { ToFoundationTable = GetOrganisationFoundation(AToPartnerKey); } // if both partners are Foundation organisations check permissions if ((FromFoundationTable != null) && (ToFoundationTable != null)) { if (!TSecurity.CheckFoundationSecurity((PFoundationRow)FromFoundationTable.Rows[0])) { ErrorMessage = Catalog.GetString("The Partner that you are merging from is a Foundation, but you do not " + "have access rights to view its data. Therefore you are not allowed to merge these Foundations!") + "\n\n" + Catalog.GetString("Access Denied"); } else if (!TSecurity.CheckFoundationSecurity((PFoundationRow)ToFoundationTable.Rows[0])) { ErrorMessage = Catalog.GetString("The Partner that you are merging into is a Foundation, but you do not " + "have access rights to view its data. Therefore you are not allowed to merge these Foundations!") + "\n\n" + Catalog.GetString("Access Denied"); } } // none or both partners must be Foundation organisations else if (FromFoundationTable != null) { ErrorMessage = Catalog.GetString("The Partner that you are merging from is a Foundation, but the Partner that you " + "are merging into is not a Foundation. This is not allowed!") + "\n\n" + Catalog.GetString("Both Merge Partners Need to be Foundations!"); } else if (ToFoundationTable != null) { ErrorMessage = Catalog.GetString("The Partner that you are merging from isn't a Foundation, but the Partner that you " + "are merging into is a Foundation. This is not allowed!") + "\n\n" + Catalog.GetString("Both Merge Partners Need to be Foundations!"); } if (ErrorMessage != "") { // critical error - only need to return this VerificationResult AVerificationResult.Clear(); AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Merge Partners"), ErrorMessage, TResultSeverity.Resv_Critical)); return false; } } return true; }
public static bool ReversePayment(Int32 ALedgerNumber, Int32 APaymentNumber, DateTime APostingDate, out TVerificationResultCollection AVerifications) { // // I need to create new documents and post them. // First, a squeaky clean TDS, and also one with the existing payment: AccountsPayableTDS ReverseDS = new AccountsPayableTDS(); AccountsPayableTDS TempDS = LoadAPPayment(ALedgerNumber, APaymentNumber); Int32 NewApNum = -1; AVerifications = new TVerificationResultCollection(); // This transaction encloses the entire operation. // I can call lower-level functions, so long as they use // GetNewOrExistingTransaction. TDBTransaction ReversalTransaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.Serializable); Boolean MustBeApproved = LedgerRquiresDocumentApproval(ALedgerNumber, ReversalTransaction); List <Int32>PostTheseDocs = new List <Int32>(); try { // // Now produce a reversed copy of each referenced document // TempDS.AApDocument.DefaultView.Sort = AApDocumentTable.GetApDocumentIdDBName(); TempDS.AApPayment.DefaultView.Sort = AApPaymentTable.GetPaymentNumberDBName(); foreach (AApDocumentPaymentRow DocPaymentRow in TempDS.AApDocumentPayment.Rows) { Int32 DocIdx = TempDS.AApDocument.DefaultView.Find(DocPaymentRow.ApDocumentId); AApDocumentRow OldDocumentRow = TempDS.AApDocument[DocIdx]; AccountsPayableTDSAApDocumentRow NewDocumentRow = ReverseDS.AApDocument.NewRowTyped(); DocIdx = TempDS.AApPayment.DefaultView.Find(DocPaymentRow.PaymentNumber); AApPaymentRow OldPaymentRow = TempDS.AApPayment[DocIdx]; DataUtilities.CopyAllColumnValues(OldDocumentRow, NewDocumentRow); NewDocumentRow.ApDocumentId = (Int32)TSequenceWebConnector.GetNextSequence(TSequenceNames.seq_ap_document); PostTheseDocs.Add(NewDocumentRow.ApDocumentId); NewDocumentRow.CreditNoteFlag = !OldDocumentRow.CreditNoteFlag; // Here's the actual reversal! NewDocumentRow.DocumentCode = "Reversal " + OldDocumentRow.DocumentCode; NewDocumentRow.Reference = "Reversal " + OldDocumentRow.Reference; NewDocumentRow.DocumentStatus = MustBeApproved ? MFinanceConstants.AP_DOCUMENT_APPROVED : MFinanceConstants.AP_DOCUMENT_OPEN; NewDocumentRow.DateCreated = DateTime.Now; NewDocumentRow.DateEntered = DateTime.Now; NewDocumentRow.ApNumber = NextApDocumentNumber(ALedgerNumber, ReversalTransaction); NewDocumentRow.ExchangeRateToBase = OldDocumentRow.ExchangeRateToBase; NewDocumentRow.SavedExchangeRate = OldPaymentRow.ExchangeRateToBase; ReverseDS.AApDocument.Rows.Add(NewDocumentRow); TempDS.AApDocumentDetail.DefaultView.RowFilter = String.Format("{0}={1}", AApDocumentDetailTable.GetApDocumentIdDBName(), OldDocumentRow.ApDocumentId); foreach (DataRowView rv in TempDS.AApDocumentDetail.DefaultView) { AApDocumentDetailRow OldDetailRow = (AApDocumentDetailRow)rv.Row; AApDocumentDetailRow NewDetailRow = ReverseDS.AApDocumentDetail.NewRowTyped(); DataUtilities.CopyAllColumnValues(OldDetailRow, NewDetailRow); NewDetailRow.ApDocumentId = NewDocumentRow.ApDocumentId; ReverseDS.AApDocumentDetail.Rows.Add(NewDetailRow); } // // if the original invoice has AnalAttrib records attached, I need to copy those over.. TempDS.AApAnalAttrib.DefaultView.RowFilter = String.Format("{0}={1}", AApAnalAttribTable.GetApDocumentIdDBName(), OldDocumentRow.ApDocumentId); foreach (DataRowView rv in TempDS.AApAnalAttrib.DefaultView) { AApAnalAttribRow OldAttribRow = (AApAnalAttribRow)rv.Row; AApAnalAttribRow NewAttribRow = ReverseDS.AApAnalAttrib.NewRowTyped(); DataUtilities.CopyAllColumnValues(OldAttribRow, NewAttribRow); NewAttribRow.ApDocumentId = NewDocumentRow.ApDocumentId; ReverseDS.AApAnalAttrib.Rows.Add(NewAttribRow); } } // // Save these new documents, with their details and analAttribs. if (SaveAApDocument(ref ReverseDS, out AVerifications) != TSubmitChangesResult.scrOK) { DBAccess.GDBAccessObj.RollbackTransaction(); return false; } // // Now I can post these new documents, and pay them: // foreach (AccountsPayableTDSAApDocumentRow DocumentRow in ReverseDS.AApDocument.Rows) { // // For foreign invoices, // I need to ensure that the reverse payment uses the exchange rate that was used // when the original document was paid. // Decimal PaymentExchangeRate = DocumentRow.SavedExchangeRate; DocumentRow.SavedExchangeRate = DocumentRow.ExchangeRateToBase; DocumentRow.ExchangeRateToBase = PaymentExchangeRate; } if (!PostAPDocuments( ALedgerNumber, PostTheseDocs, APostingDate, false, out AVerifications)) { DBAccess.GDBAccessObj.RollbackTransaction(); return false; } CreatePaymentTableEntries(ref ReverseDS, ALedgerNumber, PostTheseDocs); // AccountsPayableTDSAApPaymentTable AApPayment = ReverseDS.AApPayment; // AccountsPayableTDSAApDocumentPaymentTable AApDocumentPayment = ReverseDS.AApDocumentPayment; // // For foreign invoices, // I need to ensure that the invoice shows the exchange rate that was used // when the original document was posted. // foreach (AccountsPayableTDSAApDocumentRow DocumentRow in ReverseDS.AApDocument.Rows) { // // I'll restore the exchange rates I save above... DocumentRow.ExchangeRateToBase = DocumentRow.SavedExchangeRate; // If this exchange rate is different to the one // used in the payment, a "Forex Reval" transaction will be // created to balance the books. } if (!PostAPPayments( ref ReverseDS, APostingDate, out AVerifications)) { DBAccess.GDBAccessObj.RollbackTransaction(); return false; } // // Now I need to re-create and Post new documents that match the previous ones that were reversed! // AccountsPayableTDS CreateDs = new AccountsPayableTDS(); NewApNum = -1; foreach (AApDocumentPaymentRow PaymentRow in TempDS.AApDocumentPayment.Rows) { Int32 DocIdx = TempDS.AApDocument.DefaultView.Find(PaymentRow.ApDocumentId); AApDocumentRow OldDocumentRow = TempDS.AApDocument[DocIdx]; AApDocumentRow NewDocumentRow = CreateDs.AApDocument.NewRowTyped(); DataUtilities.CopyAllColumnValues(OldDocumentRow, NewDocumentRow); NewDocumentRow.ApDocumentId = (Int32)TSequenceWebConnector.GetNextSequence(TSequenceNames.seq_ap_document); NewDocumentRow.DocumentCode = "Duplicate " + OldDocumentRow.DocumentCode; NewDocumentRow.Reference = "Duplicate " + OldDocumentRow.Reference; NewDocumentRow.DateEntered = APostingDate; NewDocumentRow.ApNumber = NewApNum; NewDocumentRow.DocumentStatus = MustBeApproved ? MFinanceConstants.AP_DOCUMENT_APPROVED : MFinanceConstants.AP_DOCUMENT_OPEN; CreateDs.AApDocument.Rows.Add(NewDocumentRow); TempDS.AApDocumentDetail.DefaultView.RowFilter = String.Format("{0}={1}", AApDocumentDetailTable.GetApDocumentIdDBName(), OldDocumentRow.ApDocumentId); foreach (DataRowView rv in TempDS.AApDocumentDetail.DefaultView) { AApDocumentDetailRow OldDetailRow = (AApDocumentDetailRow)rv.Row; AApDocumentDetailRow NewDetailRow = CreateDs.AApDocumentDetail.NewRowTyped(); DataUtilities.CopyAllColumnValues(OldDetailRow, NewDetailRow); NewDetailRow.ApDocumentId = NewDocumentRow.ApDocumentId; CreateDs.AApDocumentDetail.Rows.Add(NewDetailRow); } // // if the invoice had AnalAttrib records attached, I need to copy those over.. TempDS.AApAnalAttrib.DefaultView.RowFilter = String.Format("{0}={1}", AApAnalAttribTable.GetApDocumentIdDBName(), OldDocumentRow.ApDocumentId); foreach (DataRowView rv in TempDS.AApAnalAttrib.DefaultView) { AApAnalAttribRow OldAttribRow = (AApAnalAttribRow)rv.Row; AApAnalAttribRow NewAttribRow = CreateDs.AApAnalAttrib.NewRowTyped(); DataUtilities.CopyAllColumnValues(OldAttribRow, NewAttribRow); NewAttribRow.ApDocumentId = NewDocumentRow.ApDocumentId; CreateDs.AApAnalAttrib.Rows.Add(NewAttribRow); } NewApNum--; // These negative record numbers should be replaced on posting. } if (SaveAApDocument(ref CreateDs, out AVerifications) != TSubmitChangesResult.scrOK) { DBAccess.GDBAccessObj.RollbackTransaction(); return false; } // // The process of saving those new documents should have given them all shiny new ApNumbers, // So finally I need to make a list of those Document numbers, and post them. PostTheseDocs.Clear(); foreach (AApDocumentRow DocumentRow in CreateDs.AApDocument.Rows) { PostTheseDocs.Add(DocumentRow.ApDocumentId); } if (!PostAPDocuments(ALedgerNumber, PostTheseDocs, APostingDate, false, out AVerifications)) { DBAccess.GDBAccessObj.RollbackTransaction(); return false; } DBAccess.GDBAccessObj.CommitTransaction(); return true; } catch (Exception e) { DBAccess.GDBAccessObj.RollbackTransaction(); // throw away all that... AVerifications = new TVerificationResultCollection(); TLogging.Log("In ReversePayment: exception " + e.Message); TLogging.Log(e.StackTrace); TVerificationResult Res = new TVerificationResult("Exception", e.Message + "\r\n" + e.StackTrace, TResultSeverity.Resv_Critical); AVerifications.Add(Res); return false; } }
/// <summary> /// A Method to transform the exception message(s) into a /// TVerificationResultCollection /// </summary> /// <returns></returns> public TVerificationResultCollection ResultCollection() { TVerificationResultCollection collection = new TVerificationResultCollection(); TVerificationResult avrEntry; avrEntry = new TVerificationResult(this.Context, this.Message, "", this.ErrorCode, TResultSeverity.Resv_Critical); collection.Add(avrEntry); avrEntry = new TVerificationResult(Catalog.GetString("Exception has been thrown"), this.ToString(), "", this.ErrorCode, TResultSeverity.Resv_Critical); collection.Add(avrEntry); if (this.InnerException != null) { avrEntry = new TVerificationResult(Catalog.GetString("Inner Exception"), this.InnerException.ToString(), TResultSeverity.Resv_Critical); collection.Add(avrEntry); } return collection; }
public static TSubmitChangesResult SaveAApDocument(ref AccountsPayableTDS AInspectDS, out TVerificationResultCollection AVerificationResult) { bool IsMyOwnTransaction = false; // If I create a transaction here, then I need to commit it when I'm done. AVerificationResult = new TVerificationResultCollection(); TVerificationResultCollection LocalVerificationResults = new TVerificationResultCollection(); TSubmitChangesResult SubmitChangesResult = TSubmitChangesResult.scrError; if (AInspectDS == null) { return TSubmitChangesResult.scrNothingToBeSaved; } TDBTransaction SubmitChangesTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction (IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out IsMyOwnTransaction); if ((AInspectDS.AApDocument != null) && (AInspectDS.AApDocument.Rows.Count > 0)) { // I want to check that the Invoice numbers are not blank, // and that none of the documents already exist in the database. foreach (AApDocumentRow NewDocRow in AInspectDS.AApDocument.Rows) { if (NewDocRow.DocumentCode.Length == 0) { LocalVerificationResults.Add(new TVerificationResult(Catalog.GetString("Save Document"), Catalog.GetString("The Document has no Document number."), TResultSeverity.Resv_Noncritical)); return TSubmitChangesResult.scrInfoNeeded; } AApDocumentRow DocTemplateRow = AInspectDS.AApDocument.NewRowTyped(false); DocTemplateRow.LedgerNumber = NewDocRow.LedgerNumber; DocTemplateRow.PartnerKey = NewDocRow.PartnerKey; DocTemplateRow.DocumentCode = NewDocRow.DocumentCode; AApDocumentTable MatchingRecords = AApDocumentAccess.LoadUsingTemplate(DocTemplateRow, SubmitChangesTransaction); foreach (AApDocumentRow MatchingRow in MatchingRecords.Rows) // Generally I expect this table is empty.. { if (MatchingRow.ApDocumentId != NewDocRow.ApDocumentId) // This Document Code is in use, and not by me! { LocalVerificationResults.Add(new TVerificationResult(Catalog.GetString("Save Document"), String.Format(Catalog.GetString("Document Code {0} already exists."), NewDocRow.DocumentCode), TResultSeverity.Resv_Noncritical)); return TSubmitChangesResult.scrInfoNeeded; } } } // foreach (document) } // if {there's actually a document} try { if (AInspectDS.AApDocument != null) { foreach (AccountsPayableTDSAApDocumentRow NewDocRow in AInspectDS.AApDocument.Rows) { // Set AP Number if it has not been set yet. if (NewDocRow.ApNumber < 0) { NewDocRow.ApNumber = NextApDocumentNumber(NewDocRow.LedgerNumber, SubmitChangesTransaction); } SetOutstandingAmount(NewDocRow, NewDocRow.LedgerNumber, AInspectDS.AApDocumentPayment); } AApDocumentAccess.SubmitChanges(AInspectDS.AApDocument, SubmitChangesTransaction); } if (AInspectDS.AApDocumentDetail != null) // Document detail lines { ValidateApDocumentDetail(ref LocalVerificationResults, AInspectDS.AApDocumentDetail); ValidateApDocumentDetailManual(ref LocalVerificationResults, AInspectDS.AApDocumentDetail); if (TVerificationHelper.IsNullOrOnlyNonCritical(LocalVerificationResults)) { AApDocumentDetailAccess.SubmitChanges(AInspectDS.AApDocumentDetail, SubmitChangesTransaction); } } if (AInspectDS.AApAnalAttrib != null) // Analysis attributes { AApAnalAttribAccess.SubmitChanges(AInspectDS.AApAnalAttrib, SubmitChangesTransaction); } SubmitChangesResult = TSubmitChangesResult.scrOK; } catch (Exception Exc) { TLogging.Log("An Exception occured while saving an AP Document:" + Environment.NewLine + Exc.ToString()); if (LocalVerificationResults == null) // This shouldn't be possible? { LocalVerificationResults = new TVerificationResultCollection(); } LocalVerificationResults.Add(new TVerificationResult("Save AP Document", Exc.Message, TResultSeverity.Resv_Critical)); throw; } finally { if (IsMyOwnTransaction) { if (SubmitChangesResult == TSubmitChangesResult.scrOK) { DBAccess.GDBAccessObj.CommitTransaction(); } else { DBAccess.GDBAccessObj.RollbackTransaction(); } } } if ((LocalVerificationResults != null) && (LocalVerificationResults.Count > 0)) { // Downgrade TScreenVerificationResults to TVerificationResults in order to allow // Serialisation (needed for .NET Remoting). AVerificationResult = LocalVerificationResults; TVerificationResultCollection.DowngradeScreenVerificationResults(AVerificationResult); } return SubmitChangesResult; }