/// <summary> /// update the journal header fields from a batch /// </summary> /// <param name="ABatch"></param> public void UpdateHeaderTotals(ABatchRow ABatch) { decimal SumDebits = 0.0M; decimal SumCredits = 0.0M; DataView JournalDV = new DataView(FMainDS.AJournal); JournalDV.RowFilter = String.Format("{0}={1}", AJournalTable.GetBatchNumberDBName(), ABatch.BatchNumber); foreach (DataRowView v in JournalDV) { AJournalRow r = (AJournalRow)v.Row; SumCredits += r.JournalCreditTotal; SumDebits += r.JournalDebitTotal; } FPetraUtilsObject.DisableDataChangedEvent(); txtDebit.NumberValueDecimal = SumDebits; txtCredit.NumberValueDecimal = SumCredits; txtControl.NumberValueDecimal = ABatch.BatchControlTotal; txtCurrentPeriod.Text = ABatch.BatchPeriod.ToString(); FPetraUtilsObject.EnableDataChangedEvent(); }
private void InitBatchAndJournal() { F_GLDataset = TGLPosting.CreateABatch(F_LedgerNum); F_batch = F_GLDataset.ABatch[0]; F_batch.BatchDescription = Catalog.GetString("Period end revaluations"); TAccountPeriodInfo accountingPeriodInfo = new TAccountPeriodInfo(F_LedgerNum); accountingPeriodInfo.AccountingPeriodNumber = F_batch.BatchPeriod; F_batch.DateEffective = accountingPeriodInfo.PeriodEndDate; F_batch.BatchStatus = MFinanceConstants.BATCH_UNPOSTED; F_journal = F_GLDataset.AJournal.NewRowTyped(); F_journal.LedgerNumber = F_batch.LedgerNumber; F_journal.BatchNumber = F_batch.BatchNumber; F_journal.JournalNumber = 1; F_journal.DateEffective = F_batch.DateEffective; F_journal.JournalPeriod = F_batch.BatchPeriod; F_journal.TransactionCurrency = F_BaseCurrency; F_journal.JournalDescription = F_batch.BatchDescription; F_journal.TransactionTypeCode = CommonAccountingTransactionTypesEnum.REVAL.ToString(); F_journal.SubSystemCode = CommonAccountingSubSystemsEnum.GL.ToString(); F_journal.LastTransactionNumber = 0; F_journal.DateOfEntry = DateTime.Now; F_journal.ExchangeRateToBase = 1.0M; F_GLDataset.AJournal.Rows.Add(F_journal); }
private void ValidateDataDetailsManual(AJournalRow ARow) { TVerificationResultCollection VerificationResultCollection = FPetraUtilsObject.VerificationResultCollection; TSharedFinanceValidation_GL.ValidateGLJournalManual(this, ARow, ref VerificationResultCollection, FValidationControlsDict, null, null, null, FLedgerBaseCurrency); //TODO: remove this once database definition is set for Batch Description to be NOT NULL // Description is mandatory then make sure it is set if (txtDetailJournalDescription.Text.Length == 0) { DataColumn ValidationColumn; TVerificationResult VerificationResult = null; object ValidationContext; ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnJournalDescriptionId]; ValidationContext = String.Format("Batch no.: {0}, Journal no.: {1}", ARow.BatchNumber, ARow.JournalNumber); VerificationResult = TStringChecks.StringMustNotBeEmpty(ARow.JournalDescription, "Description of " + ValidationContext, this, ValidationColumn, null); // Handle addition/removal to/from TVerificationResultCollection VerificationResultCollection.Auto_Add_Or_AddOrRemove(this, VerificationResult, ValidationColumn, true); } }
/// Initialise some comboboxes private void BeforeShowDetailsManual(AJournalRow ARow) { // SubSystemCode: the user can only select GL, but the system can generate eg. AP journals or GR journals this.cmbDetailSubSystemCode.Items.Clear(); this.cmbDetailSubSystemCode.Items.AddRange(new object[] { ARow.SubSystemCode }); TFinanceControls.InitialiseTransactionTypeList(ref cmbDetailTransactionTypeCode, FLedgerNumber, ARow.SubSystemCode); }
/// <summary> /// Cancel any changes made to this form /// </summary> public void CancelChangesToFixedBatches() { if ((GetBatchRow() != null) && (GetBatchRow().BatchStatus != MFinanceConstants.BATCH_UNPOSTED)) { DataView journalDV = new DataView(FMainDS.AJournal); journalDV.RowFilter = string.Format("{0}={1}", AJournalTable.GetBatchNumberDBName(), GetBatchRow().BatchNumber); foreach (DataRowView drv in journalDV) { AJournalRow jr = (AJournalRow)drv.Row; jr.RejectChanges(); } } }
private Boolean CloseSaveAndPost_(TVerificationResultCollection AVerifications) { if (FJournalCount != 0) { // The checksum of the "last journal" is used to update the checksum of the batch. FBatchRow.BatchControlTotal += FJournalRow.JournalDebitTotal - FJournalRow.JournalCreditTotal; } FBatchTDS.ThrowAwayAfterSubmitChanges = true; GLBatchTDSAccess.SubmitChanges(FBatchTDS); Boolean PostedOk = TGLPosting.PostGLBatch( FLedgerInfo.LedgerNumber, FBatchNumber, out AVerifications); // Make sure that this object cannot be used for another posting ... FBatchTDS = null; FBatchRow = null; FJournalRow = null; return(PostedOk); }
void WriteJournalLine(AJournalRow journal) { WriteStringQuoted("J"); WriteStringQuoted(journal.JournalDescription); WriteStringQuoted(journal.SubSystemCode); WriteStringQuoted(journal.TransactionTypeCode); if (FUseBaseCurrency) { WriteStringQuoted(FBaseCurrency); WriteGeneralNumber(1); } else { WriteStringQuoted(journal.TransactionCurrency); WriteGeneralNumber(journal.ExchangeRateToBase); } WriteDate(journal.DateEffective, true); }
private void ShowDetailsManual(AJournalRow ARow) { bool JournalRowIsNull = (ARow == null); grdDetails.TabStop = (!JournalRowIsNull); //Enable the transactions tab accordingly ((TFrmGLBatch)ParentForm).EnableTransactions(!JournalRowIsNull && (ARow.JournalStatus != MFinanceConstants.BATCH_CANCELLED)); UpdateChangeableStatus(); if (JournalRowIsNull) { btnAdd.Focus(); } else { RefreshCurrencyAndExchangeRate(); } }
private void AddAJournal(decimal AExchangeRateToBase) { if (blnInitBatchDate) { TAccountPeriodInfo getAccountingPeriodInfo = new TAccountPeriodInfo(FLedgerInfo.LedgerNumber, FLedgerInfo.CurrentPeriod); FBatchRow.DateEffective = getAccountingPeriodInfo.PeriodEndDate; blnInitBatchDate = false; } if (FJournalCount != 0) { // The checksum of the "last journal" is used to update the checksum of the batch. FBatchRow.BatchControlTotal += FJournalRow.JournalDebitTotal - FJournalRow.JournalCreditTotal; } ++FJournalCount; FJournalRow = FBatchTDS.AJournal.NewRowTyped(); FJournalRow.LedgerNumber = FBatchRow.LedgerNumber; FJournalRow.BatchNumber = FBatchRow.BatchNumber; FJournalRow.JournalNumber = FJournalCount; FJournalRow.DateEffective = FBatchRow.DateEffective; FJournalRow.JournalPeriod = FLedgerInfo.CurrentPeriod; FJournalRow.TransactionCurrency = (FForeignJournal) ? FForeignCurrencyInfo.CurrencyCode : FBaseCurrencyInfo.CurrencyCode; FJournalRow.JournalDescription = FBatchRow.BatchDescription; FJournalRow.TransactionTypeCode = CommonAccountingTransactionTypesEnum.STD.ToString(); FJournalRow.SubSystemCode = CommonAccountingSubSystemsEnum.GL.ToString(); FJournalRow.LastTransactionNumber = 0; FJournalRow.DateOfEntry = DateTime.Now; FJournalRow.ExchangeRateToBase = AExchangeRateToBase; FJournalRow.JournalCreditTotal = 0; FJournalRow.JournalDebitTotal = 0; FBatchTDS.AJournal.Rows.Add(FJournalRow); blnReadyForTransaction = true; }
/// <summary> /// Validates the GL Journal data. /// </summary> /// <param name="AContext">Context that describes where the data validation failed.</param> /// <param name="ARow">The <see cref="DataRow" /> which holds the the data against which the validation is run.</param> /// <param name="AVerificationResultCollection">Will be filled with any <see cref="TVerificationResult" /> items if /// data validation errors occur.</param> /// <param name="AValidationControlsDict">A <see cref="TValidationControlsDict" /> containing the Controls that /// display data that is about to be validated.</param> /// <param name="ACorporateExchangeTableRef">Corporate exchange rate table. A reference to this table is REQUIRED when importing - optional otherwise</param> /// <param name="ABaseCurrency">Ledger base currency. Required when importing</param> /// <returns>True if the validation found no data validation errors, otherwise false.</returns> public static bool ValidateGLJournalManual(object AContext, AJournalRow ARow, ref TVerificationResultCollection AVerificationResultCollection, TValidationControlsDict AValidationControlsDict, ACorporateExchangeRateTable ACorporateExchangeTableRef = null, string ABaseCurrency = null) { DataColumn ValidationColumn; TValidationControlsData ValidationControlsData; TScreenVerificationResult VerificationResult; string ValidationContext; int VerifResultCollAddedCount = 0; // Don't validate deleted or posted DataRows if ((ARow.RowState == DataRowState.Deleted) || (ARow.JournalStatus == MFinanceConstants.BATCH_POSTED)) { return true; } bool isImporting = AContext.ToString().Contains("Importing"); // 'Exchange Rate' must be greater than 0 ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnExchangeRateToBaseId]; ValidationContext = ARow.JournalNumber.ToString() + " of Batch Number: " + ARow.BatchNumber.ToString(); if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { VerificationResult = (TScreenVerificationResult)TNumericalChecks.IsPositiveDecimal(ARow.ExchangeRateToBase, ValidationControlsData.ValidationControlLabel + (isImporting ? String.Empty : " of Journal Number: " + ValidationContext.ToString()), AContext, ValidationColumn, ValidationControlsData.ValidationControl); // Handle addition/removal to/from TVerificationResultCollection if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn, true)) { VerifResultCollAddedCount++; } } if ((ACorporateExchangeTableRef != null) && (ABaseCurrency != null) && (ARow.TransactionCurrency != ABaseCurrency)) { // For gifts in non-base currency there must be a corporate exchange rate ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnTransactionCurrencyId]; ValidationContext = ARow.JournalNumber.ToString() + " of Batch Number: " + ARow.BatchNumber.ToString(); if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { DateTime firstOfMonth = new DateTime(ARow.DateEffective.Year, ARow.DateEffective.Month, 1); ACorporateExchangeRateRow foundRow = (ACorporateExchangeRateRow)ACorporateExchangeTableRef.Rows.Find( new object[] { ARow.TransactionCurrency, ABaseCurrency, firstOfMonth }); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString("There is no Corporate Exchange Rate defined for the month starting on '{0}'."), StringHelper.DateToLocalizedString(firstOfMonth)), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } } } return VerifResultCollAddedCount == 0; }
/// <summary> /// Validates the GL Journal data. /// </summary> /// <param name="AContext">Context that describes where the data validation failed.</param> /// <param name="ARow">The <see cref="DataRow" /> which holds the the data against which the validation is run.</param> /// <param name="AVerificationResultCollection">Will be filled with any <see cref="TVerificationResult" /> items if /// data validation errors occur.</param> /// <param name="AValidationControlsDict">A <see cref="TValidationControlsDict" /> containing the Controls that /// display data that is about to be validated.</param> /// <param name="AGLSetupDSRef">A GLSetupTDS reference with a populated ATransactionTypeTable. A reference to this DataSet is REQUIRED when importing - optional otherwise</param> /// <param name="ACurrencyTableRef">A reference to the Currency table. A reference to this table is REQUIRED when importing - optional otherwise</param> /// <param name="ACorporateExchangeTableRef">Corporate exchange rate table. A reference to this table is REQUIRED when importing - optional otherwise</param> /// <param name="ABaseCurrency">Ledger base currency. Required when importing</param> /// <param name="AIntlCurrency">Ledger international currency. Required when importing</param> /// <returns>True if the validation found no data validation errors, otherwise false.</returns> public static bool ValidateGLJournalManual(object AContext, AJournalRow ARow, ref TVerificationResultCollection AVerificationResultCollection, TValidationControlsDict AValidationControlsDict, GLSetupTDS AGLSetupDSRef = null, ACurrencyTable ACurrencyTableRef = null, ACorporateExchangeRateTable ACorporateExchangeTableRef = null, String ABaseCurrency = null, String AIntlCurrency = null) { DataColumn ValidationColumn; TValidationControlsData ValidationControlsData; TScreenVerificationResult VerificationResult; string ValidationContext; int VerifResultCollAddedCount = 0; // Don't validate deleted or posted DataRows if ((ARow.RowState == DataRowState.Deleted) || (ARow.JournalStatus == MFinanceConstants.BATCH_POSTED)) { return true; } bool isImporting = AContext.ToString().Contains("Importing"); // 'Exchange Rate' must be greater than 0 ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnExchangeRateToBaseId]; ValidationContext = ARow.JournalNumber.ToString() + " of Batch Number: " + ARow.BatchNumber.ToString(); if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { VerificationResult = (TScreenVerificationResult)TNumericalChecks.IsPositiveDecimal(ARow.ExchangeRateToBase, ValidationControlsData.ValidationControlLabel + (isImporting ? String.Empty : " of Journal Number: " + ValidationContext.ToString()), AContext, ValidationColumn, ValidationControlsData.ValidationControl); // Handle addition/removal to/from TVerificationResultCollection if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn, true)) { VerifResultCollAddedCount++; } // Exchange rate must be 1.00 if the currency is the base ledger currency if ((ABaseCurrency != null) && (!ARow.IsExchangeRateToBaseNull()) && (ARow.TransactionCurrency == ABaseCurrency) && (ARow.ExchangeRateToBase != 1.00m)) { if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, new TVerificationResult(ValidationContext, Catalog.GetString("A journal in the ledger base currency must have exchange rate of 1.00."), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } } } // Transaction currency must be valid bool isValidTransactionCurrency = true; if (isImporting && (ACurrencyTableRef != null)) { ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnTransactionCurrencyId]; if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { ACurrencyRow foundRow = (ACurrencyRow)ACurrencyTableRef.Rows.Find(ARow.TransactionCurrency); isValidTransactionCurrency = (foundRow != null); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString("'{0}' is not a valid currency."), ARow.TransactionCurrency), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } } } if ((ACorporateExchangeTableRef != null) && isValidTransactionCurrency && (ABaseCurrency != null) && (AIntlCurrency != null) && !ARow.IsDateEffectiveNull() && (ABaseCurrency != AIntlCurrency)) { // For ledgers where the base currency and intl currency differ there must be a corporate exchange rate to the international currency ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnTransactionCurrencyId]; ValidationContext = ARow.JournalNumber.ToString() + " of Batch Number: " + ARow.BatchNumber.ToString(); if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { DateTime firstOfMonth; if (TSharedFinanceValidationHelper.GetFirstDayOfAccountingPeriod(ARow.LedgerNumber, ARow.DateEffective, out firstOfMonth)) { ACorporateExchangeRateRow foundRow = (ACorporateExchangeRateRow)ACorporateExchangeTableRef.Rows.Find( new object[] { ABaseCurrency, AIntlCurrency, firstOfMonth }); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString( "There is no Corporate Exchange Rate defined for '{0}' to '{1}' for the month starting on '{2}'."), ABaseCurrency, AIntlCurrency, StringHelper.DateToLocalizedString(firstOfMonth)), TResultSeverity.Resv_Noncritical), ValidationColumn)) { VerifResultCollAddedCount++; } } } } // Sub-system code must exist in the transaction type table if (isImporting && (AGLSetupDSRef.ATransactionType != null)) { ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnSubSystemCodeId]; if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { ATransactionTypeRow foundRow = (ATransactionTypeRow)AGLSetupDSRef.ATransactionType.Rows.Find( new object[] { ARow.LedgerNumber, ARow.SubSystemCode, ARow.TransactionTypeCode }); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString( "The combination of Transaction Type of '{0}' and Sub-system Code of '{1}' is not valid for journals in Ledger {2}."), ARow.TransactionTypeCode, ARow.SubSystemCode, ARow.LedgerNumber), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } } } // Journal description must not be null if (isImporting) { ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnJournalDescriptionId]; if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { if ((ARow.JournalDescription == null) || (ARow.JournalDescription.Length == 0)) { if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, Catalog.GetString("The journal description must not be empty."), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } } } } return VerifResultCollAddedCount == 0; }
/// <summary> /// load the journals into the grid /// </summary> /// <param name="ACurrentBatchRow"></param> public void LoadJournals(ABatchRow ACurrentBatchRow) { FJournalsLoaded = false; FBatchRow = ACurrentBatchRow; if (FBatchRow == null) { return; } Int32 CurrentLedgerNumber = FBatchRow.LedgerNumber; Int32 CurrentBatchNumber = FBatchRow.BatchNumber; string CurrentBatchStatus = FBatchRow.BatchStatus; bool BatchIsUnposted = (FBatchRow.BatchStatus == MFinanceConstants.BATCH_UNPOSTED); bool FirstRun = (FLedgerNumber != CurrentLedgerNumber); bool BatchChanged = (FBatchNumber != CurrentBatchNumber); bool BatchStatusChanged = (!BatchChanged && (FBatchStatus != CurrentBatchStatus)); if (FirstRun) { FLedgerNumber = CurrentLedgerNumber; } if (BatchChanged) { FBatchNumber = CurrentBatchNumber; } if (BatchStatusChanged) { FBatchStatus = CurrentBatchStatus; } //Create object to control deletion FCancelLogicObject = new TUC_GLJournals_Cancel(FPetraUtilsObject, FLedgerNumber, FMainDS); //Make sure the current effective date for the Batch is correct DateTime BatchDateEffective = FBatchRow.DateEffective; //Check if need to load Journals if (!(FirstRun || BatchChanged || BatchStatusChanged)) { //Need to reconnect FPrev in some circumstances if (FPreviouslySelectedDetailRow == null) { DataRowView rowView = (DataRowView)grdDetails.Rows.IndexToDataSourceRow(FPrevRowChangedRow); if (rowView != null) { FPreviouslySelectedDetailRow = (GLBatchTDSAJournalRow)(rowView.Row); } } // The journals are the same and we have loaded them already if (BatchIsUnposted) { if (GetSelectedRowIndex() > 0) { GetDetailsFromControls(GetSelectedDetailRow()); } } } else { // a different journal SetJournalDefaultView(); FPreviouslySelectedDetailRow = null; //Load Journals if (FMainDS.AJournal.DefaultView.Count == 0) { FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadAJournal(FLedgerNumber, FBatchNumber)); } if (BatchIsUnposted) { if (!dtpDetailDateEffective.Date.HasValue || (dtpDetailDateEffective.Date.Value != BatchDateEffective)) { dtpDetailDateEffective.Date = BatchDateEffective; } } //Check if DateEffective has changed and then update all foreach (DataRowView drv in FMainDS.AJournal.DefaultView) { AJournalRow jr = (AJournalRow)drv.Row; if (jr.DateEffective != BatchDateEffective) { ((TFrmGLBatch)ParentForm).GetTransactionsControl().UpdateTransactionTotals(TGLBatchEnums.eGLLevel.Batch, true); break; } } ShowData(); // Now set up the complete current filter FFilterAndFindObject.FilterPanelControls.SetBaseFilter(FMainDS.AJournal.DefaultView.RowFilter, true); FFilterAndFindObject.ApplyFilter(); } int nRowToSelect = 1; TFrmGLBatch myParentForm = (TFrmGLBatch)ParentForm; if (myParentForm.InitialBatchFound) { DataView myView = (grdDetails.DataSource as DevAge.ComponentModel.BoundDataView).DataView; for (int counter = 0; (counter < myView.Count); counter++) { int myViewJournalNumber = (int)myView[counter][AJournalTable.GetJournalNumberDBName()]; if (myViewJournalNumber == myParentForm.InitialJournalNumber) { nRowToSelect = counter + 1; break; } } } else { nRowToSelect = (BatchChanged || FirstRun) ? 1 : FPrevRowChangedRow; } //This will also call UpdateChangeableStatus SelectRowInGrid(nRowToSelect); UpdateRecordNumberDisplay(); FFilterAndFindObject.SetRecordNumberDisplayProperties(); txtControl.CurrencyCode = TTxtCurrencyTextBox.CURRENCY_STANDARD_2_DP; txtCredit.CurrencyCode = FLedgerBaseCurrency; txtDebit.CurrencyCode = FLedgerBaseCurrency; FJournalsLoaded = true; }
/// <summary> /// Undo all changes to the specified batch ready to cancel it. /// This avoids unecessary validation errors when cancelling. /// </summary> /// <param name="ABatchToCancel"></param> /// <param name="ARedisplay"></param> public void PrepareBatchDataForCancelling(Int32 ABatchToCancel, Boolean ARedisplay) { //This code will only be called when the Batch tab is active. DataView GLBatchDV = new DataView(FMainDS.ABatch); DataView JournalDV = new DataView(FMainDS.AJournal); DataView TransDV = new DataView(FMainDS.ATransaction); DataView TransAnalDV = new DataView(FMainDS.ATransAnalAttrib); GLBatchDV.RowFilter = String.Format("{0}={1}", ABatchTable.GetBatchNumberDBName(), ABatchToCancel); JournalDV.RowFilter = String.Format("{0}={1}", AJournalTable.GetBatchNumberDBName(), ABatchToCancel); TransDV.RowFilter = String.Format("{0}={1}", ATransactionTable.GetBatchNumberDBName(), ABatchToCancel); TransAnalDV.RowFilter = String.Format("{0}={1}", ATransAnalAttribTable.GetBatchNumberDBName(), ABatchToCancel); //Work from lowest level up if (TransAnalDV.Count > 0) { TransAnalDV.Sort = String.Format("{0}, {1}, {2}", ATransAnalAttribTable.GetJournalNumberDBName(), ATransAnalAttribTable.GetTransactionNumberDBName(), ATransAnalAttribTable.GetAnalysisTypeCodeDBName()); foreach (DataRowView drv in TransAnalDV) { ATransAnalAttribRow transAnalRow = (ATransAnalAttribRow)drv.Row; if (transAnalRow.RowState == DataRowState.Added) { //Do nothing } else if (transAnalRow.RowState != DataRowState.Unchanged) { transAnalRow.RejectChanges(); } } } if (TransDV.Count > 0) { TransDV.Sort = String.Format("{0}, {1}", ATransactionTable.GetJournalNumberDBName(), ATransactionTable.GetTransactionNumberDBName()); foreach (DataRowView drv in TransDV) { ATransactionRow transRow = (ATransactionRow)drv.Row; if (transRow.RowState == DataRowState.Added) { //Do nothing } else if (transRow.RowState != DataRowState.Unchanged) { transRow.RejectChanges(); } } } if (JournalDV.Count > 0) { JournalDV.Sort = String.Format("{0}", AJournalTable.GetJournalNumberDBName()); foreach (DataRowView drv in JournalDV) { AJournalRow journalRow = (AJournalRow)drv.Row; if (journalRow.RowState == DataRowState.Added) { //Do nothing } else if (journalRow.RowState != DataRowState.Unchanged) { journalRow.RejectChanges(); } } } if (GLBatchDV.Count > 0) { ABatchRow batchRow = (ABatchRow)GLBatchDV[0].Row; //No need to check for Added state as new batches are always saved // on creation if (batchRow.RowState != DataRowState.Unchanged) { batchRow.RejectChanges(); } if (ARedisplay) { ShowDetails(batchRow); } } if (TransDV.Count == 0) { //Load all related data for batch ready to delete/cancel FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadAJournalAndRelatedTablesForBatch(FLedgerNumber, ABatchToCancel)); } }
/// <summary> /// make sure the correct transaction number is assigned and the journal.lastTransactionNumber is updated /// </summary> /// <param name="ANewRow">returns the modified new transaction row</param> /// <param name="ARefJournalRow">this can be null; otherwise this is the journal that the transaction should belong to</param> public void NewRowManual(ref GLBatchTDSATransactionRow ANewRow, AJournalRow ARefJournalRow) { if (ARefJournalRow == null) { ARefJournalRow = FJournalRow; } ANewRow.LedgerNumber = ARefJournalRow.LedgerNumber; ANewRow.BatchNumber = ARefJournalRow.BatchNumber; ANewRow.JournalNumber = ARefJournalRow.JournalNumber; ANewRow.TransactionNumber = ++ARefJournalRow.LastTransactionNumber; ANewRow.TransactionDate = GetBatchRow().DateEffective; if (FPreviouslySelectedDetailRow != null) { ANewRow.CostCentreCode = FPreviouslySelectedDetailRow.CostCentreCode; ANewRow.Narrative = FPreviouslySelectedDetailRow.Narrative; ANewRow.Reference = FPreviouslySelectedDetailRow.Reference; } }
/// load transactions from a CSV file into the currently selected batch private void CreateBatchFromCSVFile(string ADataFilename, XmlNode ARootNode, AJournalRow ARefJournalRow, Int32 AFirstTransactionRow, string ADefaultCostCentre, out DateTime ALatestTransactionDate) { StreamReader dataFile = new StreamReader(ADataFilename, System.Text.Encoding.Default); XmlNode ColumnsNode = TXMLParser.GetChild(ARootNode, "Columns"); string Separator = TXMLParser.GetAttribute(ARootNode, "Separator"); string DateFormat = TXMLParser.GetAttribute(ARootNode, "DateFormat"); string ThousandsSeparator = TXMLParser.GetAttribute(ARootNode, "ThousandsSeparator"); string DecimalSeparator = TXMLParser.GetAttribute(ARootNode, "DecimalSeparator"); Int32 lineCounter; // read headers for (lineCounter = 0; lineCounter < AFirstTransactionRow - 1; lineCounter++) { dataFile.ReadLine(); } decimal sumDebits = 0.0M; decimal sumCredits = 0.0M; ALatestTransactionDate = DateTime.MinValue; do { string line = dataFile.ReadLine(); lineCounter++; GLBatchTDSATransactionRow NewTransaction = FMainDS.ATransaction.NewRowTyped(true); FMyForm.GetTransactionsControl().NewRowManual(ref NewTransaction, ARefJournalRow); FMainDS.ATransaction.Rows.Add(NewTransaction); foreach (XmlNode ColumnNode in ColumnsNode.ChildNodes) { string Value = StringHelper.GetNextCSV(ref line, Separator); string UseAs = TXMLParser.GetAttribute(ColumnNode, "UseAs"); if (UseAs.ToLower() == "reference") { NewTransaction.Reference = Value; } else if (UseAs.ToLower() == "narrative") { NewTransaction.Narrative = Value; } else if (UseAs.ToLower() == "dateeffective") { NewTransaction.SetTransactionDateNull(); if (Value.Trim().ToString().Length > 0) { try { NewTransaction.TransactionDate = XmlConvert.ToDateTime(Value, DateFormat); if (NewTransaction.TransactionDate > ALatestTransactionDate) { ALatestTransactionDate = NewTransaction.TransactionDate; } } catch (Exception exp) { MessageBox.Show(Catalog.GetString("Problem with date in row " + lineCounter.ToString() + " Error: " + exp.Message)); } } } else if (UseAs.ToLower() == "account") { if (Value.Length > 0) { if (Value.Contains(" ")) { // cut off currency code; should have been defined in the data description file, for the whole batch Value = Value.Substring(0, Value.IndexOf(" ") - 1); } Value = Value.Replace(ThousandsSeparator, ""); Value = Value.Replace(DecimalSeparator, "."); NewTransaction.TransactionAmount = Convert.ToDecimal(Value, System.Globalization.CultureInfo.InvariantCulture); NewTransaction.CostCentreCode = ADefaultCostCentre; NewTransaction.AccountCode = ColumnNode.Name; NewTransaction.DebitCreditIndicator = true; if (TXMLParser.HasAttribute(ColumnNode, "CreditDebit") && (TXMLParser.GetAttribute(ColumnNode, "CreditDebit").ToLower() == "credit")) { NewTransaction.DebitCreditIndicator = false; } if (NewTransaction.TransactionAmount < 0) { NewTransaction.TransactionAmount *= -1.0M; NewTransaction.DebitCreditIndicator = !NewTransaction.DebitCreditIndicator; } if (TXMLParser.HasAttribute(ColumnNode, "AccountCode")) { NewTransaction.AccountCode = TXMLParser.GetAttribute(ColumnNode, "AccountCode"); } if (NewTransaction.DebitCreditIndicator) { sumDebits += NewTransaction.TransactionAmount; } else if (!NewTransaction.DebitCreditIndicator) { sumCredits += NewTransaction.TransactionAmount; } } } } if (!NewTransaction.IsTransactionDateNull()) { NewTransaction.AmountInBaseCurrency = GLRoutines.Multiply(NewTransaction.TransactionAmount, TExchangeRateCache.GetDailyExchangeRate( ARefJournalRow.TransactionCurrency, FMainDS.ALedger[0].BaseCurrency, NewTransaction.TransactionDate, false)); // // The International currency calculation is changed to "Base -> International", because it's likely // we won't have a "Transaction -> International" conversion rate defined. // NewTransaction.AmountInIntlCurrency = GLRoutines.Multiply(NewTransaction.AmountInBaseCurrency, TExchangeRateCache.GetDailyExchangeRate( FMainDS.ALedger[0].BaseCurrency, FMainDS.ALedger[0].IntlCurrency, NewTransaction.TransactionDate, false)); } } while (!dataFile.EndOfStream); // create a balancing transaction; not sure if this is needed at all??? if (Convert.ToDecimal(sumCredits - sumDebits) != 0) { GLBatchTDSATransactionRow BalancingTransaction = FMainDS.ATransaction.NewRowTyped(true); FMyForm.GetTransactionsControl().NewRowManual(ref BalancingTransaction, ARefJournalRow); FMainDS.ATransaction.Rows.Add(BalancingTransaction); BalancingTransaction.TransactionDate = ALatestTransactionDate; BalancingTransaction.DebitCreditIndicator = true; BalancingTransaction.TransactionAmount = sumCredits - sumDebits; if (BalancingTransaction.TransactionAmount < 0) { BalancingTransaction.TransactionAmount *= -1; BalancingTransaction.DebitCreditIndicator = !BalancingTransaction.DebitCreditIndicator; } if (BalancingTransaction.DebitCreditIndicator) { sumDebits += BalancingTransaction.TransactionAmount; } else { sumCredits += BalancingTransaction.TransactionAmount; } BalancingTransaction.AmountInIntlCurrency = GLRoutines.Multiply(BalancingTransaction.TransactionAmount, TExchangeRateCache.GetDailyExchangeRate( ARefJournalRow.TransactionCurrency, FMainDS.ALedger[0].IntlCurrency, BalancingTransaction.TransactionDate, false)); BalancingTransaction.AmountInBaseCurrency = GLRoutines.Multiply(BalancingTransaction.TransactionAmount, TExchangeRateCache.GetDailyExchangeRate( ARefJournalRow.TransactionCurrency, FMainDS.ALedger[0].BaseCurrency, BalancingTransaction.TransactionDate, false)); BalancingTransaction.Narrative = Catalog.GetString("Automatically generated balancing transaction"); BalancingTransaction.CostCentreCode = TXMLParser.GetAttribute(ARootNode, "CashCostCentre"); BalancingTransaction.AccountCode = TXMLParser.GetAttribute(ARootNode, "CashAccount"); } ARefJournalRow.JournalCreditTotal = sumCredits; ARefJournalRow.JournalDebitTotal = sumDebits; ARefJournalRow.JournalDescription = Path.GetFileNameWithoutExtension(ADataFilename); ABatchRow RefBatch = (ABatchRow)FMainDS.ABatch.Rows[FMainDS.ABatch.Rows.Count - 1]; RefBatch.BatchCreditTotal = sumCredits; RefBatch.BatchDebitTotal = sumDebits; // todo RefBatch.BatchControlTotal = sumCredits - sumDebits; // csv ! }
/// <summary> /// make sure the correct transaction number is assigned and the journal.lastTransactionNumber is updated /// </summary> /// <param name="ANewRow">returns the modified new transaction row</param> /// <param name="ARefJournalRow">this can be null; otherwise this is the journal that the transaction should belong to</param> public void NewRowManual(ref GLBatchTDSATransactionRow ANewRow, AJournalRow ARefJournalRow) { if (ARefJournalRow == null) { ARefJournalRow = FJournalRow; } ANewRow.LedgerNumber = ARefJournalRow.LedgerNumber; ANewRow.BatchNumber = ARefJournalRow.BatchNumber; ANewRow.JournalNumber = ARefJournalRow.JournalNumber; ANewRow.TransactionNumber = ++ARefJournalRow.LastTransactionNumber; ANewRow.TransactionDate = GetBatchRow().DateEffective; if (FPreviouslySelectedDetailRow != null) { ANewRow.CostCentreCode = FPreviouslySelectedDetailRow.CostCentreCode; // don't want these copied over if previous transaction was a reversal if (!FPreviouslySelectedDetailRow.SystemGenerated) { ANewRow.Narrative = FPreviouslySelectedDetailRow.Narrative; ANewRow.Reference = FPreviouslySelectedDetailRow.Reference; } } }
private static void AddGiftDetailToGLBatch(ref GLBatchTDS AGLDataset, string ACostCentre, string AAccountCode, decimal ATransactionAmount, decimal AAmountInBaseCurrency, decimal AAmountInIntlCurrency, AJournalRow AJournal, AGiftBatchRow AGiftBatch) { ATransactionRow transaction = null; // do we have already a transaction for this costcentre&account? AGLDataset.ATransaction.DefaultView.RowFilter = String.Format("{0}='{1}' and {2}='{3}'", ATransactionTable.GetAccountCodeDBName(), AAccountCode, ATransactionTable.GetCostCentreCodeDBName(), ACostCentre); if (AGLDataset.ATransaction.DefaultView.Count == 0) { transaction = AGLDataset.ATransaction.NewRowTyped(); transaction.LedgerNumber = AJournal.LedgerNumber; transaction.BatchNumber = AJournal.BatchNumber; transaction.JournalNumber = AJournal.JournalNumber; transaction.TransactionNumber = ++AJournal.LastTransactionNumber; transaction.AccountCode = AAccountCode; transaction.CostCentreCode = ACostCentre; transaction.Narrative = "GB - Gift Batch " + AGiftBatch.BatchNumber.ToString(); transaction.Reference = "GB" + AGiftBatch.BatchNumber.ToString(); transaction.DebitCreditIndicator = ATransactionAmount < 0; transaction.TransactionAmount = 0; transaction.AmountInBaseCurrency = 0; transaction.AmountInIntlCurrency = 0; transaction.SystemGenerated = true; transaction.TransactionDate = AGiftBatch.GlEffectiveDate; AGLDataset.ATransaction.Rows.Add(transaction); } else { transaction = (ATransactionRow)AGLDataset.ATransaction.DefaultView[0].Row; } // if gift has same debit/credit indicator as transaction if (transaction.DebitCreditIndicator == ATransactionAmount < 0) { transaction.TransactionAmount += Math.Abs(ATransactionAmount); transaction.AmountInBaseCurrency += Math.Abs(AAmountInBaseCurrency); transaction.AmountInIntlCurrency += Math.Abs(AAmountInIntlCurrency); } // if gift has a different debit/credit indicator as transaction else { transaction.TransactionAmount -= Math.Abs(ATransactionAmount); transaction.AmountInBaseCurrency -= Math.Abs(AAmountInBaseCurrency); transaction.AmountInIntlCurrency -= Math.Abs(AAmountInIntlCurrency); // if transaction amount has went negative then the debit/credit indicator must change if (transaction.TransactionAmount < 0) { transaction.TransactionAmount = Math.Abs(transaction.TransactionAmount); transaction.AmountInBaseCurrency = Math.Abs(transaction.AmountInBaseCurrency); transaction.AmountInIntlCurrency = Math.Abs(transaction.AmountInIntlCurrency); transaction.DebitCreditIndicator = !transaction.DebitCreditIndicator; } } if (transaction.TransactionAmount == 0) { transaction.Delete(); } }
/// <summary> /// load the journals into the grid /// </summary> /// <param name="ALedgerNumber"></param> /// <param name="ABatchNumber"></param> /// <param name="ABatchStatus"></param> public void LoadJournals(Int32 ALedgerNumber, Int32 ABatchNumber, string ABatchStatus = MFinanceConstants.BATCH_UNPOSTED) { FJournalsLoaded = false; FBatchRow = GetBatchRow(); if (FBatchRow == null) { return; } FCancelLogicObject = new TUC_GLJournals_Cancel(FPetraUtilsObject, FLedgerNumber, FMainDS); //Make sure the current effective date for the Batch is correct DateTime BatchDateEffective = FBatchRow.DateEffective; bool FirstRun = (FLedgerNumber != ALedgerNumber); bool BatchChanged = (FBatchNumber != ABatchNumber); bool BatchStatusChanged = (!BatchChanged && FBatchStatus != ABatchStatus); //Check if need to load Journals if (FirstRun || BatchChanged || BatchStatusChanged) { FLedgerNumber = ALedgerNumber; FBatchNumber = ABatchNumber; FBatchStatus = ABatchStatus; SetJournalDefaultView(); FPreviouslySelectedDetailRow = null; //Load Journals if (FMainDS.AJournal.DefaultView.Count == 0) { FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadAJournalAndContent(FLedgerNumber, FBatchNumber)); } if (FBatchStatus == MFinanceConstants.BATCH_UNPOSTED) { if (!dtpDetailDateEffective.Date.HasValue || (dtpDetailDateEffective.Date.Value != BatchDateEffective)) { dtpDetailDateEffective.Date = BatchDateEffective; } } foreach (DataRowView drv in FMainDS.AJournal.DefaultView) { AJournalRow jr = (AJournalRow)drv.Row; if (jr.DateEffective != BatchDateEffective) { ((TFrmGLBatch)ParentForm).GetTransactionsControl().UpdateTransactionTotals("BATCH", true); break; } } ShowData(); // Now set up the complete current filter FFilterAndFindObject.FilterPanelControls.SetBaseFilter(FMainDS.AJournal.DefaultView.RowFilter, true); FFilterAndFindObject.ApplyFilter(); } else { // The journals are the same and we have loaded them already if (FBatchRow.BatchStatus == MFinanceConstants.BATCH_UNPOSTED) { if (GetSelectedRowIndex() > 0) { GetDetailsFromControls(GetSelectedDetailRow()); } } } //This will also call UpdateChangeableStatus SelectRowInGrid((BatchChanged || FirstRun) ? 1 : FPrevRowChangedRow); UpdateRecordNumberDisplay(); FFilterAndFindObject.SetRecordNumberDisplayProperties(); FJournalsLoaded = true; }
/// <summary> /// Validates the GL Journal data. /// </summary> /// <param name="AContext">Context that describes where the data validation failed.</param> /// <param name="ARow">The <see cref="DataRow" /> which holds the the data against which the validation is run.</param> /// <param name="AVerificationResultCollection">Will be filled with any <see cref="TVerificationResult" /> items if /// data validation errors occur.</param> /// <param name="AGLSetupDSRef">A GLSetupTDS reference with a populated ATransactionTypeTable. A reference to this DataSet is REQUIRED when importing - optional otherwise</param> /// <param name="ACurrencyTableRef">A reference to the Currency table. A reference to this table is REQUIRED when importing - optional otherwise</param> /// <param name="ACorporateExchangeTableRef">Corporate exchange rate table. A reference to this table is REQUIRED when importing - optional otherwise</param> /// <param name="ABaseCurrency">Ledger base currency. Required when importing</param> /// <param name="AIntlCurrency">Ledger international currency. Required when importing</param> /// <returns>True if the validation found no data validation errors, otherwise false.</returns> public static bool ValidateGLJournalManual(object AContext, AJournalRow ARow, ref TVerificationResultCollection AVerificationResultCollection, GLSetupTDS AGLSetupDSRef = null, ACurrencyTable ACurrencyTableRef = null, ACorporateExchangeRateTable ACorporateExchangeTableRef = null, String ABaseCurrency = null, String AIntlCurrency = null) { DataColumn ValidationColumn; TScreenVerificationResult VerificationResult; string ValidationContext; int VerifResultCollAddedCount = 0; // Don't validate deleted or posted DataRows if ((ARow.RowState == DataRowState.Deleted) || (ARow.JournalStatus == MFinanceConstants.BATCH_POSTED)) { return(true); } bool isImporting = AContext.ToString().Contains("Importing"); // 'Exchange Rate' must be greater than 0 ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnExchangeRateToBaseId]; ValidationContext = ARow.JournalNumber.ToString() + " of Batch Number: " + ARow.BatchNumber.ToString(); if (true) { VerificationResult = (TScreenVerificationResult)TNumericalChecks.IsPositiveDecimal(ARow.ExchangeRateToBase, String.Empty + (isImporting ? String.Empty : " of Journal Number: " + ValidationContext.ToString()), AContext, ValidationColumn); // Handle addition/removal to/from TVerificationResultCollection if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult)) { VerifResultCollAddedCount++; } // Exchange rate must be 1.00 if the currency is the base ledger currency if ((ABaseCurrency != null) && (!ARow.IsExchangeRateToBaseNull()) && (ARow.TransactionCurrency == ABaseCurrency) && (ARow.ExchangeRateToBase != 1.00m)) { if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, new TVerificationResult(ValidationContext, Catalog.GetString("A journal in the ledger base currency must have exchange rate of 1.00."), TResultSeverity.Resv_Critical))) { VerifResultCollAddedCount++; } } } // Transaction currency must be valid bool isValidTransactionCurrency = true; if (isImporting && (ACurrencyTableRef != null)) { ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnTransactionCurrencyId]; if (true) { ACurrencyRow foundRow = (ACurrencyRow)ACurrencyTableRef.Rows.Find(ARow.TransactionCurrency); isValidTransactionCurrency = (foundRow != null); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString("'{0}' is not a valid currency."), ARow.TransactionCurrency), TResultSeverity.Resv_Critical))) { VerifResultCollAddedCount++; } } } if ((ACorporateExchangeTableRef != null) && isValidTransactionCurrency && (ABaseCurrency != null) && (AIntlCurrency != null) && !ARow.IsDateEffectiveNull() && (ABaseCurrency != AIntlCurrency)) { // For ledgers where the base currency and intl currency differ there must be a corporate exchange rate to the international currency ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnTransactionCurrencyId]; ValidationContext = ARow.JournalNumber.ToString() + " of Batch Number: " + ARow.BatchNumber.ToString(); if (true) { DateTime firstOfMonth; if (TSharedFinanceValidationHelper.GetFirstDayOfAccountingPeriod(ARow.LedgerNumber, ARow.DateEffective, out firstOfMonth)) { ACorporateExchangeRateRow foundRow = (ACorporateExchangeRateRow)ACorporateExchangeTableRef.Rows.Find( new object[] { ABaseCurrency, AIntlCurrency, firstOfMonth }); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString( "There is no Corporate Exchange Rate defined for '{0}' to '{1}' for the month starting on '{2}'."), ABaseCurrency, AIntlCurrency, StringHelper.DateToLocalizedString(firstOfMonth)), TResultSeverity.Resv_Noncritical))) { VerifResultCollAddedCount++; } } } } // Sub-system code must exist in the transaction type table if (isImporting && (AGLSetupDSRef.ATransactionType != null)) { ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnSubSystemCodeId]; if (true) { ATransactionTypeRow foundRow = (ATransactionTypeRow)AGLSetupDSRef.ATransactionType.Rows.Find( new object[] { ARow.LedgerNumber, ARow.SubSystemCode, ARow.TransactionTypeCode }); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString( "The combination of Transaction Type of '{0}' and Sub-system Code of '{1}' is not valid for journals in Ledger {2}."), ARow.TransactionTypeCode, ARow.SubSystemCode, ARow.LedgerNumber), TResultSeverity.Resv_Critical))) { VerifResultCollAddedCount++; } } } // Journal description must not be null if (isImporting) { ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnJournalDescriptionId]; if (true) { if ((ARow.JournalDescription == null) || (ARow.JournalDescription.Length == 0)) { if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, Catalog.GetString("The journal description must not be empty."), TResultSeverity.Resv_Critical))) { VerifResultCollAddedCount++; } } } } return(VerifResultCollAddedCount == 0); }
} // Import GL Transactions private void ImportGLTransactionsInner(Int32 ALedgerNumber, Int32 ARowNumber, ref GLBatchTDS AMainDS, ref GLSetupTDS ASetupDS, ref ABatchRow ANewBatchRow, ref AJournalRow ANewJournalRow, decimal AIntlRateFromBase, ref TDBTransaction ATransaction, ref string AImportMessage, ref TVerificationResultCollection AMessages, ref TValidationControlsDict AValidationControlsDictTransaction) { AImportMessage = Catalog.GetString("Parsing a transaction line."); string strIgnoreAnalysisTypeAndValue = Catalog.GetString(" The analysis type/value pair will be ignored."); GLBatchTDSATransactionRow NewTransaction = AMainDS.ATransaction.NewRowTyped(true); NewTransaction.LedgerNumber = ANewJournalRow.LedgerNumber; NewTransaction.BatchNumber = ANewJournalRow.BatchNumber; NewTransaction.JournalNumber = ANewJournalRow.JournalNumber; NewTransaction.TransactionNumber = ++ANewJournalRow.LastTransactionNumber; AMainDS.ATransaction.Rows.Add(NewTransaction); int preParseMessageCount = AMessages.Count; int nonCriticalErrorCount = 0; string costCentreCode = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Cost centre"), AMainDS.ATransaction.ColumnCostCentreCode, ARowNumber, AMessages, AValidationControlsDictTransaction).ToUpper(); string accountCode = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Account code"), AMainDS.ATransaction.ColumnAccountCode, ARowNumber, AMessages, AValidationControlsDictTransaction).ToUpper(); // This might add a non-critical error int msgCount = AMessages.Count; TCommonImport.FixAccountCodes(ALedgerNumber, ARowNumber, ref accountCode, ASetupDS.AAccount, ref costCentreCode, ASetupDS.ACostCentre, AMessages); nonCriticalErrorCount = AMessages.Count - msgCount; NewTransaction.CostCentreCode = costCentreCode; NewTransaction.AccountCode = accountCode; NewTransaction.Narrative = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Narrative"), AMainDS.ATransaction.ColumnNarrative, ARowNumber, AMessages, AValidationControlsDictTransaction); NewTransaction.Reference = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Reference"), AMainDS.ATransaction.ColumnReference, ARowNumber, AMessages, AValidationControlsDictTransaction); DateTime TransactionDate = TCommonImport.ImportDate(ref FImportLine, FDelimiter, FCultureInfoDate, Catalog.GetString("Transaction date"), AMainDS.ATransaction.ColumnTransactionDate, ARowNumber, AMessages, AValidationControlsDictTransaction); decimal DebitAmount = TCommonImport.ImportDecimal(ref FImportLine, FDelimiter, FCultureInfoNumberFormat, Catalog.GetString("Debit amount"), AMainDS.ATransaction.ColumnTransactionAmount, ARowNumber, AMessages, AValidationControlsDictTransaction, "0"); decimal CreditAmount = TCommonImport.ImportDecimal(ref FImportLine, FDelimiter, FCultureInfoNumberFormat, Catalog.GetString("Credit amount"), AMainDS.ATransaction.ColumnTransactionAmount, ARowNumber, AMessages, AValidationControlsDictTransaction, "0"); // The critical parsing is complete now bool hasParsingErrors = (AMessages.Count != (preParseMessageCount + nonCriticalErrorCount)); for (int i = 0; i < 10; i++) { String analysisType = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Analysis Type") + "#" + i, AMainDS.ATransAnalAttrib.ColumnAnalysisTypeCode, ARowNumber, AMessages, AValidationControlsDictTransaction).ToUpper(); String analysisValue = TCommonImport.ImportString(ref FImportLine, FDelimiter, Catalog.GetString("Analysis Value") + "#" + i, AMainDS.ATransAnalAttrib.ColumnAnalysisAttributeValue, ARowNumber, AMessages, AValidationControlsDictTransaction); bool gotType = (analysisType != null) && (analysisType.Length > 0); bool gotValue = (analysisValue != null) && (analysisValue.Length > 0); if (gotType && !gotValue) { // All analysis analysisType errors are non-critical AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportValidationWarningInLine, ARowNumber), Catalog.GetString("Transaction analysis attributes must have an attribute value.") + strIgnoreAnalysisTypeAndValue, TResultSeverity.Resv_Noncritical)); } if (!hasParsingErrors) { // The analysis data is only imported if all corresponding values are there: // Errors are recorded on-the-fly but are marked as non-critical if (gotType && gotValue) { DataRow atrow = ASetupDS.AAnalysisType.Rows.Find(new Object[] { NewTransaction.LedgerNumber, analysisType }); DataRow afrow = ASetupDS.AFreeformAnalysis.Rows.Find(new Object[] { NewTransaction.LedgerNumber, analysisType, analysisValue }); AAnalysisAttributeRow anrow = (AAnalysisAttributeRow)ASetupDS.AAnalysisAttribute.Rows.Find( new Object[] { NewTransaction.LedgerNumber, analysisType, NewTransaction.AccountCode }); bool isActive = (anrow != null) && anrow.Active; if ((atrow != null) && (afrow != null) && isActive) { ATransAnalAttribRow NewTransAnalAttrib = AMainDS.ATransAnalAttrib.NewRowTyped(true); NewTransAnalAttrib.LedgerNumber = NewTransaction.LedgerNumber; NewTransAnalAttrib.BatchNumber = NewTransaction.BatchNumber; NewTransAnalAttrib.JournalNumber = NewTransaction.JournalNumber; NewTransAnalAttrib.TransactionNumber = NewTransaction.TransactionNumber; NewTransAnalAttrib.AnalysisTypeCode = analysisType; NewTransAnalAttrib.AnalysisAttributeValue = analysisValue; NewTransAnalAttrib.AccountCode = NewTransaction.AccountCode; AMainDS.ATransAnalAttrib.Rows.Add(NewTransAnalAttrib); } else { // All analysis analysisType errors are non-critical if (atrow == null) { AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportValidationWarningInLine, ARowNumber), String.Format(Catalog.GetString("Unknown transaction analysis attribute '{0}'."), analysisType) + strIgnoreAnalysisTypeAndValue, TResultSeverity.Resv_Noncritical)); } else if (afrow == null) { AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportValidationWarningInLine, ARowNumber), String.Format(Catalog.GetString("Unknown transaction analysis value '{0}' for type '{1}'."), analysisValue, analysisType) + strIgnoreAnalysisTypeAndValue, TResultSeverity.Resv_Noncritical)); } else if (!isActive) { if (anrow == null) { AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportValidationWarningInLine, ARowNumber), String.Format(Catalog.GetString( "Transaction analysis type/value '{0}'/'{1}' is not associated with account '{2}'."), analysisType, analysisValue, NewTransaction.AccountCode) + strIgnoreAnalysisTypeAndValue, TResultSeverity.Resv_Noncritical)); } else { AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportValidationWarningInLine, ARowNumber), String.Format(Catalog.GetString("Transaction analysis type/value '{0}'/'{1}' is no longer active."), analysisType, analysisValue) + strIgnoreAnalysisTypeAndValue, TResultSeverity.Resv_Noncritical)); } } } } } } if (!hasParsingErrors) { NewTransaction.TransactionDate = TransactionDate; if ((DebitAmount == 0) && (CreditAmount == 0)) { AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportValidationErrorInLine, ARowNumber), Catalog.GetString("Either the debit amount or the credit amount must be greater than 0."), TResultSeverity.Resv_Critical)); } if ((DebitAmount < 0) || (CreditAmount < 0)) { AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportValidationErrorInLine, ARowNumber), Catalog.GetString("Negative amount specified - debits and credits must be positive."), TResultSeverity.Resv_Critical)); } if ((DebitAmount != 0) && (CreditAmount != 0)) { AMessages.Add(new TVerificationResult(String.Format(MCommonConstants.StrImportValidationErrorInLine, ARowNumber), Catalog.GetString("Transactions cannot have values for both debit and credit amounts."), TResultSeverity.Resv_Critical)); } if (DebitAmount != 0) { NewTransaction.DebitCreditIndicator = true; NewTransaction.TransactionAmount = DebitAmount; } else { NewTransaction.DebitCreditIndicator = false; NewTransaction.TransactionAmount = CreditAmount; } NewTransaction.AmountInBaseCurrency = GLRoutines.Divide(NewTransaction.TransactionAmount, ANewJournalRow.ExchangeRateToBase); // If we know the international currency exchange rate we can set the value for the transaction amount if (AIntlRateFromBase > 0.0m) { NewTransaction.AmountInIntlCurrency = GLRoutines.Divide(NewTransaction.AmountInBaseCurrency, AIntlRateFromBase, 2); } // Now we can start validation int messageCountBeforeValidate = AMessages.Count; // Do our standard gift batch validation checks on this row AImportMessage = Catalog.GetString("Validating the transaction data"); ATransactionValidation.Validate(this, NewTransaction, ref AMessages, AValidationControlsDictTransaction); // And do the additional manual ones AImportMessage = Catalog.GetString("Additional validation of the transaction data"); TSharedFinanceValidation_GL.ValidateGLDetailManual(this, ANewBatchRow, NewTransaction, null, ref AMessages, AValidationControlsDictTransaction, ASetupDS.ACostCentre, ASetupDS.AAccount); for (int i = messageCountBeforeValidate; i < AMessages.Count; i++) { ((TVerificationResult)AMessages[i]).OverrideResultContext(String.Format(MCommonConstants.StrValidationErrorInLine, ARowNumber)); if (AMessages[i] is TScreenVerificationResult) { TVerificationResult downgrade = new TVerificationResult((TScreenVerificationResult)AMessages[i]); AMessages.RemoveAt(i); AMessages.Insert(i, downgrade); } } if (NewTransaction.TransactionAmount <= 0.0m) { // We will have a validation message that will duplicate one we already have and may not really make sense in the context // of separate credit and debit amounts for (int i = messageCountBeforeValidate; i < AMessages.Count; i++) { TVerificationResult msg = (TVerificationResult)AMessages[i]; if (msg.ResultText.Contains(Catalog.GetString("Debit amount")) || msg.ResultText.Contains(Catalog.GetString("Credit amount"))) { AMessages.RemoveAt(i); break; } } } } }
/// <summary> /// Validates the GL Journal data. /// </summary> /// <param name="AContext">Context that describes where the data validation failed.</param> /// <param name="ARow">The <see cref="DataRow" /> which holds the the data against which the validation is run.</param> /// <param name="AVerificationResultCollection">Will be filled with any <see cref="TVerificationResult" /> items if /// data validation errors occur.</param> /// <param name="AValidationControlsDict">A <see cref="TValidationControlsDict" /> containing the Controls that /// display data that is about to be validated.</param> /// <param name="ACorporateExchangeTableRef">Corporate exchange rate table. A reference to this table is REQUIRED when importing - optional otherwise</param> /// <param name="ABaseCurrency">Ledger base currency. Required when importing</param> /// <returns>True if the validation found no data validation errors, otherwise false.</returns> public static bool ValidateGLJournalManual(object AContext, AJournalRow ARow, ref TVerificationResultCollection AVerificationResultCollection, TValidationControlsDict AValidationControlsDict, ACorporateExchangeRateTable ACorporateExchangeTableRef = null, string ABaseCurrency = null) { DataColumn ValidationColumn; TValidationControlsData ValidationControlsData; TScreenVerificationResult VerificationResult; string ValidationContext; int VerifResultCollAddedCount = 0; // Don't validate deleted or posted DataRows if ((ARow.RowState == DataRowState.Deleted) || (ARow.JournalStatus == MFinanceConstants.BATCH_POSTED)) { return(true); } bool isImporting = AContext.ToString().Contains("Importing"); // 'Exchange Rate' must be greater than 0 ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnExchangeRateToBaseId]; ValidationContext = ARow.JournalNumber.ToString() + " of Batch Number: " + ARow.BatchNumber.ToString(); if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { VerificationResult = (TScreenVerificationResult)TNumericalChecks.IsPositiveDecimal(ARow.ExchangeRateToBase, ValidationControlsData.ValidationControlLabel + (isImporting ? String.Empty : " of Journal Number: " + ValidationContext.ToString()), AContext, ValidationColumn, ValidationControlsData.ValidationControl); // Handle addition/removal to/from TVerificationResultCollection if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn, true)) { VerifResultCollAddedCount++; } } if ((ACorporateExchangeTableRef != null) && (ABaseCurrency != null) && (ARow.TransactionCurrency != ABaseCurrency)) { // For gifts in non-base currency there must be a corporate exchange rate ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnTransactionCurrencyId]; ValidationContext = ARow.JournalNumber.ToString() + " of Batch Number: " + ARow.BatchNumber.ToString(); if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData)) { DateTime firstOfMonth = new DateTime(ARow.DateEffective.Year, ARow.DateEffective.Month, 1); ACorporateExchangeRateRow foundRow = (ACorporateExchangeRateRow)ACorporateExchangeTableRef.Rows.Find( new object[] { ARow.TransactionCurrency, ABaseCurrency, firstOfMonth }); if ((foundRow == null) && AVerificationResultCollection.Auto_Add_Or_AddOrRemove( AContext, new TVerificationResult(ValidationContext, String.Format(Catalog.GetString("There is no Corporate Exchange Rate defined for the month starting on '{0}'."), StringHelper.DateToLocalizedString(firstOfMonth)), TResultSeverity.Resv_Critical), ValidationColumn)) { VerifResultCollAddedCount++; } } } return(VerifResultCollAddedCount == 0); }
/// load transactions from a CSV file into the currently selected batch private void CreateBatchFromCSVFile(string ADataFilename, XmlNode ARootNode, AJournalRow ARefJournalRow, Int32 AFirstTransactionRow, string ADefaultCostCentre, out DateTime ALatestTransactionDate) { StreamReader dataFile = new StreamReader(ADataFilename, System.Text.Encoding.Default); XmlNode ColumnsNode = TXMLParser.GetChild(ARootNode, "Columns"); string Separator = TXMLParser.GetAttribute(ARootNode, "Separator"); string DateFormat = TXMLParser.GetAttribute(ARootNode, "DateFormat"); string ThousandsSeparator = TXMLParser.GetAttribute(ARootNode, "ThousandsSeparator"); string DecimalSeparator = TXMLParser.GetAttribute(ARootNode, "DecimalSeparator"); Int32 lineCounter; // read headers for (lineCounter = 0; lineCounter < AFirstTransactionRow - 1; lineCounter++) { dataFile.ReadLine(); } decimal sumDebits = 0.0M; decimal sumCredits = 0.0M; ALatestTransactionDate = DateTime.MinValue; do { string line = dataFile.ReadLine(); lineCounter++; GLBatchTDSATransactionRow NewTransaction = FMainDS.ATransaction.NewRowTyped(true); FMyForm.GetTransactionsControl().NewRowManual(ref NewTransaction, ARefJournalRow); FMainDS.ATransaction.Rows.Add(NewTransaction); foreach (XmlNode ColumnNode in ColumnsNode.ChildNodes) { string Value = StringHelper.GetNextCSV(ref line, Separator); string UseAs = TXMLParser.GetAttribute(ColumnNode, "UseAs"); if (UseAs.ToLower() == "reference") { NewTransaction.Reference = Value; } else if (UseAs.ToLower() == "narrative") { NewTransaction.Narrative = Value; } else if (UseAs.ToLower() == "dateeffective") { NewTransaction.SetTransactionDateNull(); if (Value.Trim().ToString().Length > 0) { try { NewTransaction.TransactionDate = XmlConvert.ToDateTime(Value, DateFormat); if (NewTransaction.TransactionDate > ALatestTransactionDate) { ALatestTransactionDate = NewTransaction.TransactionDate; } } catch (Exception exp) { MessageBox.Show(Catalog.GetString("Problem with date in row " + lineCounter.ToString() + " Error: " + exp.Message)); } } } else if (UseAs.ToLower() == "account") { if (Value.Length > 0) { if (Value.Contains(" ")) { // cut off currency code; should have been defined in the data description file, for the whole batch Value = Value.Substring(0, Value.IndexOf(" ") - 1); } Value = Value.Replace(ThousandsSeparator, ""); Value = Value.Replace(DecimalSeparator, "."); NewTransaction.TransactionAmount = Convert.ToDecimal(Value, System.Globalization.CultureInfo.InvariantCulture); NewTransaction.CostCentreCode = ADefaultCostCentre; NewTransaction.AccountCode = ColumnNode.Name; NewTransaction.DebitCreditIndicator = true; if (TXMLParser.HasAttribute(ColumnNode, "CreditDebit") && (TXMLParser.GetAttribute(ColumnNode, "CreditDebit").ToLower() == "credit")) { NewTransaction.DebitCreditIndicator = false; } if (NewTransaction.TransactionAmount < 0) { NewTransaction.TransactionAmount *= -1.0M; NewTransaction.DebitCreditIndicator = !NewTransaction.DebitCreditIndicator; } if (TXMLParser.HasAttribute(ColumnNode, "AccountCode")) { NewTransaction.AccountCode = TXMLParser.GetAttribute(ColumnNode, "AccountCode"); } if (NewTransaction.DebitCreditIndicator) { sumDebits += NewTransaction.TransactionAmount; } else if (!NewTransaction.DebitCreditIndicator) { sumCredits += NewTransaction.TransactionAmount; } } } } if (!NewTransaction.IsTransactionDateNull()) { NewTransaction.AmountInBaseCurrency = GLRoutines.CurrencyMultiply(NewTransaction.TransactionAmount, TExchangeRateCache.GetDailyExchangeRate( ARefJournalRow.TransactionCurrency, FMainDS.ALedger[0].BaseCurrency, NewTransaction.TransactionDate, false)); // // The International currency calculation is changed to "Base -> International", because it's likely // we won't have a "Transaction -> International" conversion rate defined. // NewTransaction.AmountInIntlCurrency = GLRoutines.CurrencyMultiply(NewTransaction.AmountInBaseCurrency, TExchangeRateCache.GetDailyExchangeRate( FMainDS.ALedger[0].BaseCurrency, FMainDS.ALedger[0].IntlCurrency, NewTransaction.TransactionDate, false)); } } while (!dataFile.EndOfStream); // create a balancing transaction; not sure if this is needed at all??? if (Convert.ToDecimal(sumCredits - sumDebits) != 0) { GLBatchTDSATransactionRow BalancingTransaction = FMainDS.ATransaction.NewRowTyped(true); FMyForm.GetTransactionsControl().NewRowManual(ref BalancingTransaction, ARefJournalRow); FMainDS.ATransaction.Rows.Add(BalancingTransaction); BalancingTransaction.TransactionDate = ALatestTransactionDate; BalancingTransaction.DebitCreditIndicator = true; BalancingTransaction.TransactionAmount = sumCredits - sumDebits; if (BalancingTransaction.TransactionAmount < 0) { BalancingTransaction.TransactionAmount *= -1; BalancingTransaction.DebitCreditIndicator = !BalancingTransaction.DebitCreditIndicator; } if (BalancingTransaction.DebitCreditIndicator) { sumDebits += BalancingTransaction.TransactionAmount; } else { sumCredits += BalancingTransaction.TransactionAmount; } BalancingTransaction.AmountInIntlCurrency = GLRoutines.CurrencyMultiply(BalancingTransaction.TransactionAmount, TExchangeRateCache.GetDailyExchangeRate( ARefJournalRow.TransactionCurrency, FMainDS.ALedger[0].IntlCurrency, BalancingTransaction.TransactionDate, false)); BalancingTransaction.AmountInBaseCurrency = GLRoutines.CurrencyMultiply(BalancingTransaction.TransactionAmount, TExchangeRateCache.GetDailyExchangeRate( ARefJournalRow.TransactionCurrency, FMainDS.ALedger[0].BaseCurrency, BalancingTransaction.TransactionDate, false)); BalancingTransaction.Narrative = Catalog.GetString("Automatically generated balancing transaction"); BalancingTransaction.CostCentreCode = TXMLParser.GetAttribute(ARootNode, "CashCostCentre"); BalancingTransaction.AccountCode = TXMLParser.GetAttribute(ARootNode, "CashAccount"); } ARefJournalRow.JournalCreditTotal = sumCredits; ARefJournalRow.JournalDebitTotal = sumDebits; ARefJournalRow.JournalDescription = Path.GetFileNameWithoutExtension(ADataFilename); ABatchRow RefBatch = (ABatchRow)FMainDS.ABatch.Rows[FMainDS.ABatch.Rows.Count - 1]; RefBatch.BatchCreditTotal = sumCredits; RefBatch.BatchDebitTotal = sumDebits; // todo RefBatch.BatchControlTotal = sumCredits - sumDebits; // csv ! }
/// <summary> /// this supports the transaction export files from Petra 2.x. /// Lines do NOT start with T for transaction /// </summary> public void ImportTransactions(ABatchRow ACurrentBatchRow, AJournalRow ACurrentJournalRow, TImportDataSourceEnum AImportDataSource) { bool ok = false; String importString; String impOptions; OpenFileDialog dialog = null; if (FPetraUtilsObject.HasChanges && !FMyForm.SaveChanges()) { // saving failed, therefore do not try to import MessageBox.Show(Catalog.GetString("Please save your changes before Importing new transactions"), Catalog.GetString( "Import GL Transactions"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if ((ACurrentBatchRow == null) || (ACurrentJournalRow == null) || (ACurrentJournalRow.JournalStatus != MFinanceConstants.BATCH_UNPOSTED)) { MessageBox.Show(Catalog.GetString("Please select an unposted journal to import transactions."), Catalog.GetString("Import GL Transactions")); return; } if (ACurrentJournalRow.LastTransactionNumber > 0) { if (MessageBox.Show(Catalog.GetString( "The current journal already contains some transactions. Do you really want to add more transactions to this journal?"), Catalog.GetString("Import GL Transactions"), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No) { return; } } FdlgSeparator = new TDlgSelectCSVSeparator(false); if (AImportDataSource == TImportDataSourceEnum.FromClipboard) { importString = Clipboard.GetText(TextDataFormat.UnicodeText); if ((importString == null) || (importString.Length == 0)) { MessageBox.Show(Catalog.GetString("Please first copy data from your spreadsheet application!"), Catalog.GetString("Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } impOptions = TUserDefaults.GetStringDefault("Imp Options", ";American"); String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY"); FdlgSeparator = new TDlgSelectCSVSeparator(false); FdlgSeparator.SelectedSeparator = "\t"; FdlgSeparator.CSVData = importString; FdlgSeparator.DateFormat = dateFormatString; if (impOptions.Length > 1) { FdlgSeparator.NumberFormat = impOptions.Substring(1); } } else if (AImportDataSource == TImportDataSourceEnum.FromFile) { dialog = new OpenFileDialog(); string exportPath = TClientSettings.GetExportPath(); string fullPath = TUserDefaults.GetStringDefault("Imp Filename", exportPath + Path.DirectorySeparatorChar + "import.csv"); TImportExportDialogs.SetOpenFileDialogFilePathAndName(dialog, fullPath, exportPath); dialog.Title = Catalog.GetString("Import Transactions from CSV File"); dialog.Filter = Catalog.GetString("GL Transactions files (*.csv)|*.csv"); impOptions = TUserDefaults.GetStringDefault("Imp Options", ";" + TDlgSelectCSVSeparator.NUMBERFORMAT_AMERICAN); // This call fixes Windows7 Open File Dialogs. It must be the line before ShowDialog() TWin7FileOpenSaveDialog.PrepareDialog(Path.GetFileName(fullPath)); if (dialog.ShowDialog() == DialogResult.OK) { Boolean fileCanOpen = FdlgSeparator.OpenCsvFile(dialog.FileName); if (!fileCanOpen) { MessageBox.Show(Catalog.GetString("Unable to open file."), Catalog.GetString("Transaction Import"), MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } importString = File.ReadAllText(dialog.FileName, Encoding.Default); String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY"); FdlgSeparator.DateFormat = dateFormatString; if (impOptions.Length > 1) { FdlgSeparator.NumberFormat = impOptions.Substring(1); } FdlgSeparator.SelectedSeparator = impOptions.Substring(0, 1); } else { return; } } else { // unknown source!! The following need a value... impOptions = String.Empty; importString = String.Empty; } if (FdlgSeparator.ShowDialog() == DialogResult.OK) { Hashtable requestParams = new Hashtable(); requestParams.Add("ALedgerNumber", FLedgerNumber); requestParams.Add("Delimiter", FdlgSeparator.SelectedSeparator); requestParams.Add("DateFormatString", FdlgSeparator.DateFormat); requestParams.Add("NumberFormat", FdlgSeparator.NumberFormat); requestParams.Add("NewLine", Environment.NewLine); TVerificationResultCollection AMessages = new TVerificationResultCollection(); Thread ImportThread = new Thread(() => ImportGLTransactions(requestParams, importString, ACurrentBatchRow.BatchNumber, ACurrentJournalRow.JournalNumber, out AMessages, out ok)); using (TProgressDialog ImportDialog = new TProgressDialog(ImportThread)) { ImportDialog.ShowDialog(); } // It is important to save user defaults here, even if there were errors // because in that case the user will want to import the same file again after fixing it. SaveUserDefaults(dialog, impOptions); ShowMessages(AMessages); } if (ok) { MessageBox.Show(Catalog.GetString("Your data was imported successfully!"), Catalog.GetString("Transactions Import"), MessageBoxButtons.OK, MessageBoxIcon.Information); // Update the client side with new information from the server FMyForm.Cursor = Cursors.WaitCursor; FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadABatchAJournal(FLedgerNumber, ACurrentBatchRow.BatchNumber)); FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadATransactionATransAnalAttrib(FLedgerNumber, ACurrentBatchRow.BatchNumber, ACurrentJournalRow.JournalNumber)); FMainDS.AcceptChanges(); FMyForm.Cursor = Cursors.Default; FMyForm.GetTransactionsControl().SelectRow(1); } }
private void InitBatchAndJournal(decimal AExchangeRate, string ACurrencyCode) { F_GLDataset = TGLPosting.CreateABatch(F_LedgerNum); F_batch = F_GLDataset.ABatch[0]; F_batch.BatchDescription = Catalog.GetString("Period end revaluations"); TAccountPeriodInfo accountingPeriodInfo = new TAccountPeriodInfo(F_LedgerNum); accountingPeriodInfo.AccountingPeriodNumber = F_batch.BatchPeriod; F_batch.DateEffective = accountingPeriodInfo.PeriodEndDate; F_batch.BatchStatus = MFinanceConstants.BATCH_UNPOSTED; F_journal = F_GLDataset.AJournal.NewRowTyped(); F_journal.LedgerNumber = F_batch.LedgerNumber; F_journal.BatchNumber = F_batch.BatchNumber; F_journal.JournalNumber = 1; F_journal.DateEffective = F_batch.DateEffective; F_journal.ExchangeRateTime = 14400; // revaluations are typically later than 'new rates' F_journal.JournalPeriod = F_batch.BatchPeriod; F_journal.TransactionCurrency = F_BaseCurrency; F_journal.JournalDescription = F_batch.BatchDescription; F_journal.TransactionTypeCode = CommonAccountingTransactionTypesEnum.REVAL.ToString(); F_journal.SubSystemCode = CommonAccountingSubSystemsEnum.GL.ToString(); F_journal.LastTransactionNumber = 0; F_journal.DateOfEntry = DateTime.Now; F_journal.ExchangeRateToBase = 1.0M; F_GLDataset.AJournal.Rows.Add(F_journal); ARevaluationRow revalRow = F_GLDataset.ARevaluation.NewRowTyped(); revalRow.LedgerNumber = F_journal.LedgerNumber; revalRow.BatchNumber = F_journal.BatchNumber; revalRow.JournalNumber = F_journal.JournalNumber; revalRow.ExchangeRateToBase = AExchangeRate; revalRow.RevaluationCurrency = ACurrencyCode; F_GLDataset.ARevaluation.Rows.Add(revalRow); }
private Boolean CloseSaveAndPost_(TVerificationResultCollection AVerifications) { if (FJournalCount != 0) { // The checksum of the "last journal" is used to update the checksum of the batch. FBatchRow.BatchControlTotal += FJournalRow.JournalDebitTotal - FJournalRow.JournalCreditTotal; } FBatchTDS.ThrowAwayAfterSubmitChanges = true; GLBatchTDSAccess.SubmitChanges(FBatchTDS); Boolean PostedOk = TGLPosting.PostGLBatch( FLedgerInfo.LedgerNumber, FBatchNumber, out AVerifications); // Make sure that this object cannot be used for another posting ... FBatchTDS = null; FBatchRow = null; FJournalRow = null; return PostedOk; }
private void ShowDetailsManual(AJournalRow ARow) { bool JournalRowIsNull = (ARow == null); grdDetails.TabStop = (!JournalRowIsNull); if (JournalRowIsNull) { FTransactionCurrency = string.Empty; btnAdd.Focus(); } else { FTransactionCurrency = ARow.TransactionCurrency; } //Enable the transactions tab accordingly ((TFrmGLBatch)ParentForm).EnableTransactions(!JournalRowIsNull && (ARow.JournalStatus != MFinanceConstants.BATCH_CANCELLED)); UpdateChangeableStatus(); }
/// <summary> /// this supports the transaction export files from Petra 2.x. /// Lines do NOT start with T for transaction /// </summary> public void ImportTransactions(ABatchRow ACurrentBatchRow, AJournalRow ACurrentJournalRow, TImportDataSourceEnum AImportDataSource) { bool ok = false; bool RefreshGUIAfterImport = false; OpenFileDialog dialog = null; if (FPetraUtilsObject.HasChanges && !FMyForm.SaveChanges()) { // saving failed, therefore do not try to import MessageBox.Show(Catalog.GetString("Please save your changes before Importing new transactions"), Catalog.GetString( "Import GL Transactions"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if ((ACurrentBatchRow == null) || (ACurrentJournalRow == null) || (ACurrentJournalRow.JournalStatus != MFinanceConstants.BATCH_UNPOSTED)) { MessageBox.Show(Catalog.GetString("Please select an unposted journal to import transactions."), Catalog.GetString("Import GL Transactions")); return; } if (ACurrentJournalRow.LastTransactionNumber > 0) { if (MessageBox.Show(Catalog.GetString( "The current journal already contains some transactions. Do you really want to add more transactions to this journal?"), Catalog.GetString("Import GL Transactions"), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No) { return; } } bool datesMayBeIntegers = TUserDefaults.GetBooleanDefault(MCommonConstants.USERDEFAULT_IMPORTEDDATESMAYBEINTEGERS, false); FdlgSeparator = new TDlgSelectCSVSeparator(false); FdlgSeparator.DateMayBeInteger = datesMayBeIntegers; if (AImportDataSource == TImportDataSourceEnum.FromClipboard) { string importString = Clipboard.GetText(TextDataFormat.UnicodeText); if ((importString == null) || (importString.Length == 0)) { MessageBox.Show(Catalog.GetString("Please first copy data from your spreadsheet application!"), Catalog.GetString("Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } FdlgSeparator.CSVData = importString; } else if (AImportDataSource == TImportDataSourceEnum.FromFile) { dialog = new OpenFileDialog(); string exportPath = TClientSettings.GetExportPath(); string fullPath = TUserDefaults.GetStringDefault("Imp Filename", exportPath + Path.DirectorySeparatorChar + "import.csv"); TImportExportDialogs.SetOpenFileDialogFilePathAndName(dialog, fullPath, exportPath); dialog.Title = Catalog.GetString("Import Transactions from CSV File"); dialog.Filter = Catalog.GetString("GL Transactions files (*.csv)|*.csv|Text Files (*.txt)|*.txt"); // This call fixes Windows7 Open File Dialogs. It must be the line before ShowDialog() TWin7FileOpenSaveDialog.PrepareDialog(Path.GetFileName(fullPath)); if (dialog.ShowDialog() == DialogResult.OK) { Boolean fileCanOpen = FdlgSeparator.OpenCsvFile(dialog.FileName); if (!fileCanOpen) { MessageBox.Show(Catalog.GetString("Unable to open file."), Catalog.GetString("Transaction Import"), MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } } else { return; } } else { // unknown source!! return; } String impOptions = TUserDefaults.GetStringDefault("Imp Options", ";" + TDlgSelectCSVSeparator.NUMBERFORMAT_AMERICAN); String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY"); FdlgSeparator.DateFormat = dateFormatString; FdlgSeparator.NumberFormat = (impOptions.Length > 1) ? impOptions.Substring(1) : TDlgSelectCSVSeparator.NUMBERFORMAT_AMERICAN; FdlgSeparator.SelectedSeparator = StringHelper.GetCSVSeparator(FdlgSeparator.FileContent) ?? ((impOptions.Length > 0) ? impOptions.Substring(0, 1) : ";"); if (FdlgSeparator.ShowDialog() == DialogResult.OK) { Hashtable requestParams = new Hashtable(); requestParams.Add("ALedgerNumber", FLedgerNumber); requestParams.Add("Delimiter", FdlgSeparator.SelectedSeparator); requestParams.Add("DateFormatString", FdlgSeparator.DateFormat); requestParams.Add("DatesMayBeIntegers", datesMayBeIntegers); requestParams.Add("NumberFormat", FdlgSeparator.NumberFormat); requestParams.Add("NewLine", Environment.NewLine); requestParams.Add("LastTransactionNumber", ACurrentJournalRow.LastTransactionNumber); TVerificationResultCollection AMessages = new TVerificationResultCollection(); Thread ImportThread = new Thread(() => ImportGLTransactions(requestParams, FdlgSeparator.FileContent, ACurrentBatchRow.BatchNumber, ACurrentJournalRow.JournalNumber, out AMessages, out ok, out RefreshGUIAfterImport)); using (TProgressDialog ImportDialog = new TProgressDialog(ImportThread)) { ImportDialog.ShowDialog(); } ShowMessages(AMessages); } // It is important to save user defaults here, even if there were errors // because in that case the user will want to import the same file again after fixing it. SaveUserDefaults(dialog); if (ok || RefreshGUIAfterImport) { if (ok) { MessageBox.Show(Catalog.GetString("Your data was imported successfully!"), Catalog.GetString("Transactions Import"), MessageBoxButtons.OK, MessageBoxIcon.Information); } // Update the client side with new information from the server FMyForm.Cursor = Cursors.WaitCursor; FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadABatchAJournal(FLedgerNumber, ACurrentBatchRow.BatchNumber)); FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadATransactionAndRelatedTablesForJournal(FLedgerNumber, ACurrentBatchRow.BatchNumber, ACurrentJournalRow.JournalNumber)); FMainDS.AcceptChanges(); FMyForm.Cursor = Cursors.Default; FMyForm.GetTransactionsControl().SelectRow(1); } }
private void ValidateDataDetailsManual(AJournalRow ARow) { TVerificationResultCollection VerificationResultCollection = FPetraUtilsObject.VerificationResultCollection; TSharedFinanceValidation_GL.ValidateGLJournalManual(this, ARow, ref VerificationResultCollection, FValidationControlsDict); //TODO: remove this once database definition is set for Batch Description to be NOT NULL // Description is mandatory then make sure it is set if (txtDetailJournalDescription.Text.Length == 0) { DataColumn ValidationColumn; TVerificationResult VerificationResult = null; object ValidationContext; ValidationColumn = ARow.Table.Columns[AJournalTable.ColumnJournalDescriptionId]; ValidationContext = String.Format("Batch no.: {0}, Journal no.: {1}", ARow.BatchNumber, ARow.JournalNumber); VerificationResult = TStringChecks.StringMustNotBeEmpty(ARow.JournalDescription, "Description of " + ValidationContext, this, ValidationColumn, null); // Handle addition/removal to/from TVerificationResultCollection VerificationResultCollection.Auto_Add_Or_AddOrRemove(this, VerificationResult, ValidationColumn, true); } }
/// <summary> /// this supports the transaction export files from Petra 2.x. /// Lines do NOT start with T for transaction /// </summary> public void ImportTransactions(ABatchRow ACurrentBatchRow, AJournalRow ACurrentJournalRow, TImportDataSourceEnum AImportDataSource) { bool ok = false; String importString; String impOptions; OpenFileDialog dialog = null; if (FPetraUtilsObject.HasChanges && !FMyForm.SaveChanges()) { // saving failed, therefore do not try to import MessageBox.Show(Catalog.GetString("Please save your changes before Importing new transactions"), Catalog.GetString( "Import GL Transactions"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if ((ACurrentBatchRow == null) || (ACurrentJournalRow == null) || (ACurrentJournalRow.JournalStatus != MFinanceConstants.BATCH_UNPOSTED)) { MessageBox.Show(Catalog.GetString("Please select an unposted journal to import transactions."), Catalog.GetString("Import GL Transactions")); return; } if (ACurrentJournalRow.LastTransactionNumber > 0) { if (MessageBox.Show(Catalog.GetString( "The current journal already contains some transactions. Do you really want to add more transactions to this journal?"), Catalog.GetString("Import GL Transactions"), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No) { return; } } FdlgSeparator = new TDlgSelectCSVSeparator(false); if (AImportDataSource == TImportDataSourceEnum.FromClipboard) { importString = Clipboard.GetText(TextDataFormat.UnicodeText); if ((importString == null) || (importString.Length == 0)) { MessageBox.Show(Catalog.GetString("Please first copy data from your spreadsheet application!"), Catalog.GetString("Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } impOptions = TUserDefaults.GetStringDefault("Imp Options", ";American"); String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY"); FdlgSeparator = new TDlgSelectCSVSeparator(false); FdlgSeparator.SelectedSeparator = "\t"; FdlgSeparator.CSVData = importString; FdlgSeparator.DateFormat = dateFormatString; if (impOptions.Length > 1) { FdlgSeparator.NumberFormat = impOptions.Substring(1); } } else if (AImportDataSource == TImportDataSourceEnum.FromFile) { dialog = new OpenFileDialog(); dialog.FileName = TUserDefaults.GetStringDefault("Imp Filename", TClientSettings.GetExportPath() + Path.DirectorySeparatorChar + "import.csv"); dialog.Title = Catalog.GetString("Import Transactions from CSV File"); dialog.Filter = Catalog.GetString("GL Transactions files (*.csv)|*.csv"); impOptions = TUserDefaults.GetStringDefault("Imp Options", ";American"); if (dialog.ShowDialog() == DialogResult.OK) { Boolean fileCanOpen = FdlgSeparator.OpenCsvFile(dialog.FileName); if (!fileCanOpen) { MessageBox.Show(Catalog.GetString("Unable to open file."), Catalog.GetString("Transaction Import"), MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } importString = File.ReadAllText(dialog.FileName); String dateFormatString = TUserDefaults.GetStringDefault("Imp Date", "MDY"); FdlgSeparator.DateFormat = dateFormatString; if (impOptions.Length > 1) { FdlgSeparator.NumberFormat = impOptions.Substring(1); } FdlgSeparator.SelectedSeparator = impOptions.Substring(0, 1); } else { return; } } else { // unknown source!! The following need a value... impOptions = String.Empty; importString = String.Empty; } if (FdlgSeparator.ShowDialog() == DialogResult.OK) { Hashtable requestParams = new Hashtable(); requestParams.Add("ALedgerNumber", FLedgerNumber); requestParams.Add("Delimiter", FdlgSeparator.SelectedSeparator); requestParams.Add("DateFormatString", FdlgSeparator.DateFormat); requestParams.Add("NumberFormat", FdlgSeparator.NumberFormat); requestParams.Add("NewLine", Environment.NewLine); TVerificationResultCollection AMessages = new TVerificationResultCollection(); Thread ImportThread = new Thread(() => ImportGLTransactions(requestParams, importString, ACurrentBatchRow.BatchNumber, ACurrentJournalRow.JournalNumber, out AMessages, out ok)); using (TProgressDialog ImportDialog = new TProgressDialog(ImportThread)) { ImportDialog.ShowDialog(); } ShowMessages(AMessages); } if (ok) { MessageBox.Show(Catalog.GetString("Your data was imported successfully!"), Catalog.GetString("Transactions Import"), MessageBoxButtons.OK, MessageBoxIcon.Information); SaveUserDefaults(dialog, impOptions); // Update the client side with new information from the server FMyForm.Cursor = Cursors.WaitCursor; FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadABatchAJournal(FLedgerNumber, ACurrentBatchRow.BatchNumber)); FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadATransactionATransAnalAttrib(FLedgerNumber, ACurrentBatchRow.BatchNumber, ACurrentJournalRow.JournalNumber)); FMainDS.AcceptChanges(); FMyForm.Cursor = Cursors.Default; FMyForm.GetTransactionsControl().SelectRow(1); } }