/// <summary>
        /// make sure the correct journal number is assigned and the batch.lastJournal is updated
        /// </summary>
        /// <param name="ANewRow"></param>
        public void NewRowManual(ref GLBatchTDSARecurringJournalRow ANewRow)
        {
            if ((ANewRow == null) || (FLedgerNumber == -1))
            {
                return;
            }

            ALedgerRow LedgerRow =
                ((ALedgerTable)TDataCache.TMFinance.GetCacheableFinanceTable(
                     TCacheableFinanceTablesEnum.LedgerDetails, FLedgerNumber))[0];

            ANewRow.LedgerNumber  = FBatchRow.LedgerNumber;
            ANewRow.BatchNumber   = FBatchRow.BatchNumber;
            ANewRow.JournalNumber = ++FBatchRow.LastJournal;

            // manually created journals are all GL
            ANewRow.SubSystemCode       = MFinanceConstants.SUB_SYSTEM_GL;
            ANewRow.TransactionTypeCode = MFinanceConstants.STANDARD_JOURNAL;

            ANewRow.TransactionCurrency    = LedgerRow.BaseCurrency;
            ANewRow.ExchangeRateToBase     = 1;
            ANewRow.DateEffective          = FBatchRow.DateEffective;
            ANewRow.JournalPeriod          = FBatchRow.BatchPeriod;
            ANewRow.JournalDebitTotalBase  = 0.0M;
            ANewRow.JournalCreditTotalBase = 0.0M;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Calculate the base amount for the transactions, and update the totals for the journals and the current batch
        /// </summary>
        /// <param name="AMainDS"></param>
        /// <param name="ACurrentBatchRow"></param>
        /// <param name="ACurrentJournalNumber"></param>
        /// <returns>false if no change to batch totals</returns>
        public static bool UpdateRecurringBatchTotals(ref GLBatchTDS AMainDS,
                                                      ref ARecurringBatchRow ACurrentBatchRow, Int32 ACurrentJournalNumber = 0)
        {
            #region Validate Arguments

            if (AMainDS == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString(
                                                                                         "Function:{0} - The Recurring GL Batch dataset is null!"),
                                                                                     Utilities.GetMethodName(true)));
            }
            else if (ACurrentBatchRow == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString(
                                                                                         "Function:{0} - The Recurring GL Batch data row is null!"),
                                                                                     Utilities.GetMethodName(true)));
            }

            #endregion Validate Arguments

            bool AmountsUpdated = false;

            decimal BatchDebitTotal  = 0.0m;
            decimal BatchCreditTotal = 0.0m;

            DataView JournalDV = new DataView(AMainDS.ARecurringJournal);

            JournalDV.RowFilter = String.Format("{0}={1}",
                                                ARecurringJournalTable.GetBatchNumberDBName(),
                                                ACurrentBatchRow.BatchNumber);

            foreach (DataRowView journalView in JournalDV)
            {
                GLBatchTDSARecurringJournalRow journalRow = (GLBatchTDSARecurringJournalRow)journalView.Row;

                if (((ACurrentJournalNumber > 0) && (ACurrentJournalNumber == journalRow.JournalNumber)) ||
                    (ACurrentJournalNumber == 0))
                {
                    if ((UpdateRecurringJournalTotals(ref AMainDS, ref journalRow)))
                    {
                        AmountsUpdated = true;
                    }
                }

                BatchDebitTotal  += journalRow.JournalDebitTotal;
                BatchCreditTotal += journalRow.JournalCreditTotal;
            }

            if ((ACurrentBatchRow.BatchDebitTotal != BatchDebitTotal) ||
                (ACurrentBatchRow.BatchCreditTotal != BatchCreditTotal))
            {
                ACurrentBatchRow.BatchDebitTotal  = BatchDebitTotal;
                ACurrentBatchRow.BatchCreditTotal = BatchCreditTotal;
                AmountsUpdated = true;
            }

            return(AmountsUpdated);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Update the specified Recurring Batch's LastJournal number. Assumes all necessary data is loaded for Batch
        /// </summary>
        /// <param name="AMainDS"></param>
        /// <param name="ACurrentBatchRow"></param>
        /// <param name="AIncludeJournals"></param>
        /// <returns>false if no change to batch totals</returns>
        public static bool UpdateRecurringBatchLastJournal(ref GLBatchTDS AMainDS,
                                                           ref ARecurringBatchRow ACurrentBatchRow, Boolean AIncludeJournals = false)
        {
            #region Validate Arguments

            if (AMainDS == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString("Function:{0} - The GL Batch dataset is null!"),
                                                                                     Utilities.GetMethodName(true)));
            }
            else if (ACurrentBatchRow == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString(
                                                                                         "Function:{0} - The Recurring GL Batch data row is null!"),
                                                                                     Utilities.GetMethodName(true)));
            }

            #endregion Validate Arguments

            bool RowUpdated = false;
            int  ActualLastJournalNumber = 0;

            DataView JournalDV = new DataView(AMainDS.ARecurringJournal);

            JournalDV.RowFilter = String.Format("{0}={1}",
                                                ARecurringJournalTable.GetBatchNumberDBName(),
                                                ACurrentBatchRow.BatchNumber);

            //Highest Journal number first
            JournalDV.Sort = String.Format("{0} DESC",
                                           ARecurringJournalTable.GetJournalNumberDBName());

            foreach (DataRowView journalView in JournalDV)
            {
                GLBatchTDSARecurringJournalRow journalRow = (GLBatchTDSARecurringJournalRow)journalView.Row;

                //Run once only
                if (ActualLastJournalNumber == 0)
                {
                    ActualLastJournalNumber = journalRow.JournalNumber;
                }

                if (AIncludeJournals && UpdateRecurringJournalLastTransaction(ref AMainDS, ref journalRow))
                {
                    RowUpdated = true;
                }
            }

            if (ACurrentBatchRow.LastJournal != ActualLastJournalNumber)
            {
                ACurrentBatchRow.BeginEdit();
                ACurrentBatchRow.LastJournal = ActualLastJournalNumber;
                ACurrentBatchRow.EndEdit();
                RowUpdated = true;
            }

            return(RowUpdated);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Update the specified recurring Journal's LastTransaction number. Assumes all necessary data is loaded for Journal
        /// </summary>
        /// <param name="AMainDS">ATransactions are filtered on current journal</param>
        /// <param name="ACurrentJournal"></param>
        /// <returns>false if no change to journal totals</returns>
        public static bool UpdateRecurringJournalLastTransaction(ref GLBatchTDS AMainDS,
                                                                 ref GLBatchTDSARecurringJournalRow ACurrentJournal)
        {
            #region Validate Arguments

            if (AMainDS == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString("Function:{0} - The GL Batch dataset is null!"),
                                                                                     Utilities.GetMethodName(true)));
            }
            else if (ACurrentJournal == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString(
                                                                                         "Function:{0} - The Recurring Journal row does not exist or is empty!"),
                                                                                     Utilities.GetMethodName(true)));
            }

            #endregion Validate Arguments

            bool RowUpdated = false;

            int ActualLastTransNumber = 0;

            DataView TransDV = new DataView(AMainDS.ARecurringTransaction);

            TransDV.RowFilter = String.Format("{0}={1} And {2}={3}",
                                              ARecurringTransactionTable.GetBatchNumberDBName(),
                                              ACurrentJournal.BatchNumber,
                                              ARecurringTransactionTable.GetJournalNumberDBName(),
                                              ACurrentJournal.JournalNumber);

            TransDV.Sort = String.Format("{0} DESC",
                                         ARecurringTransactionTable.GetTransactionNumberDBName());

            foreach (DataRowView drv in TransDV)
            {
                ARecurringTransactionRow transRow = (ARecurringTransactionRow)drv.Row;

                //Run once only
                ActualLastTransNumber = transRow.TransactionNumber;
                break;
            }

            if (ACurrentJournal.LastTransactionNumber != ActualLastTransNumber)
            {
                ACurrentJournal.BeginEdit();
                ACurrentJournal.LastTransactionNumber = ActualLastTransNumber;
                ACurrentJournal.EndEdit();
                RowUpdated = true;
            }

            return(RowUpdated);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Calculate the base amount for the transactions, and update the totals for the current journal
        /// NOTE this no longer calculates AmountInBaseCurrency
        /// ALSO - since the ExchangeRateToBase field is no longer used here, the code that asserts it to be valid is commented out.
        /// </summary>
        /// <param name="AMainDS">ATransactions are filtered on current journal</param>
        /// <param name="ACurrentJournal"></param>
        public static void UpdateTotalsOfRecurringJournal(ref GLBatchTDS AMainDS,
                                                          ref GLBatchTDSARecurringJournalRow ACurrentJournal)
        {
            if (ACurrentJournal == null)
            {
                return;
            }

            /* // Since I'm not using ExchangeRateToBase, I don't need to check that it's valid:
             *
             * if ((ACurrentJournal.ExchangeRateToBase == 0.0m)
             *  && (ACurrentJournal.TransactionTypeCode != CommonAccountingTransactionTypesEnum.REVAL.ToString()))
             * {
             *  throw new Exception(String.Format("Recurring Batch {0} Journal {1} has invalid exchange rate to base",
             *          ACurrentJournal.BatchNumber,
             *          ACurrentJournal.JournalNumber));
             * }
             */

            ACurrentJournal.JournalDebitTotal      = 0.0M;
            ACurrentJournal.JournalDebitTotalBase  = 0.0M;
            ACurrentJournal.JournalCreditTotal     = 0.0M;
            ACurrentJournal.JournalCreditTotalBase = 0.0M;

            DataView trnsDataView = new DataView(AMainDS.ARecurringTransaction);

            trnsDataView.RowFilter = String.Format("{0}={1} And {2}={3}",
                                                   ARecurringTransactionTable.GetBatchNumberDBName(),
                                                   ACurrentJournal.BatchNumber,
                                                   ARecurringTransactionTable.GetJournalNumberDBName(),
                                                   ACurrentJournal.JournalNumber);

            // transactions are filtered for this journal; add up the total amounts
            foreach (DataRowView v in trnsDataView)
            {
                ARecurringTransactionRow r = (ARecurringTransactionRow)v.Row;

                if (r.DebitCreditIndicator)
                {
                    ACurrentJournal.JournalDebitTotal     += r.TransactionAmount;
                    ACurrentJournal.JournalDebitTotalBase += r.AmountInBaseCurrency;
                }
                else
                {
                    ACurrentJournal.JournalCreditTotal     += r.TransactionAmount;
                    ACurrentJournal.JournalCreditTotalBase += r.AmountInBaseCurrency;
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Calculate the base amount for the transactions, and update the totals for the journals and the current batch
        /// </summary>
        /// <param name="AMainDS"></param>
        /// <param name="ACurrentBatch"></param>
        public static void UpdateTotalsOfRecurringBatch(ref GLBatchTDS AMainDS,
                                                        ARecurringBatchRow ACurrentBatch)
        {
            ACurrentBatch.BatchDebitTotal  = 0.0m;
            ACurrentBatch.BatchCreditTotal = 0.0m;

            DataView jnlDataView = new DataView(AMainDS.ARecurringJournal);

            jnlDataView.RowFilter = String.Format("{0}={1}",
                                                  ARecurringJournalTable.GetBatchNumberDBName(),
                                                  ACurrentBatch.BatchNumber);

            foreach (DataRowView journalView in jnlDataView)
            {
                GLBatchTDSARecurringJournalRow journalRow = (GLBatchTDSARecurringJournalRow)journalView.Row;

                UpdateTotalsOfRecurringJournal(ref AMainDS, ref journalRow);

                ACurrentBatch.BatchDebitTotal  += journalRow.JournalDebitTotal;
                ACurrentBatch.BatchCreditTotal += journalRow.JournalCreditTotal;
            }
        }
        /// <summary>
        /// Deletes the current row and optionally populates a completion message
        /// </summary>
        /// <param name="ARowToDelete">the currently selected row to delete</param>
        /// <param name="ACompletionMessage">if specified, is the deletion completion message</param>
        /// <returns>true if row deletion is successful</returns>
        private bool DeleteRowManual(GLBatchTDSARecurringJournalRow ARowToDelete, ref string ACompletionMessage)
        {
            //Assign default value(s)
            bool DeletionSuccessful = false;

            ACompletionMessage = string.Empty;

            if (ARowToDelete == null)
            {
                return(DeletionSuccessful);
            }

            //Delete current row
            ARowToDelete.RejectChanges();
            ShowDetails(ARowToDelete);

            //Take a backup of FMainDS
            GLBatchTDS BackupMainDS = null;
            //Pass a copy of FMainDS to the server-side delete method.
            GLBatchTDS TempDS = (GLBatchTDS)FMainDS.Copy();

            TempDS.Merge(FMainDS);

            int  CurrentBatchNumber = ARowToDelete.BatchNumber;
            bool CurrentBatchJournalTransactionsLoadedAndCurrent = false;

            FJournalNumberToDelete = ARowToDelete.JournalNumber;
            int TopMostJrnlNo = FBatchRow.LastJournal;

            TFrmRecurringGLBatch FMyForm = (TFrmRecurringGLBatch)this.ParentForm;

            try
            {
                this.Cursor = Cursors.WaitCursor;
                FMyForm.FCurrentGLBatchAction = TGLBatchEnums.GLBatchAction.DELETINGJOURNAL;

                //Backup the Dataset for reversion purposes
                BackupMainDS = (GLBatchTDS)FMainDS.GetChangesTyped(false);

                //Check if current batch transactions are loaded and being viewed in their tab
                CurrentBatchJournalTransactionsLoadedAndCurrent = (FMyForm.GetTransactionsControl().FBatchNumber == CurrentBatchNumber &&
                                                                   FMyForm.GetTransactionsControl().FJournalNumber == FJournalNumberToDelete);

                //Save and check for inactive values
                FPetraUtilsObject.SetChangedFlag();

                if (!FMyForm.SaveChangesManual(FMyForm.FCurrentGLBatchAction, false, !CurrentBatchJournalTransactionsLoadedAndCurrent))
                {
                    string msg = String.Format(Catalog.GetString("Recurring Journal {0} has not been deleted."),
                                               FJournalNumberToDelete);

                    MessageBox.Show(msg,
                                    Catalog.GetString("Recurring GL Batch Deletion"),
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);

                    return(false);
                }

                //Remove any changes to current batch that may cause validation issues
                PrepareJournalDataForDeleting(CurrentBatchNumber, FJournalNumberToDelete, true);

                if (CurrentBatchJournalTransactionsLoadedAndCurrent)
                {
                    //Clear any transactions currently being edited in the Transaction Tab
                    FMyForm.GetTransactionsControl().ClearCurrentSelection(CurrentBatchNumber, FJournalNumberToDelete);
                }

                //Load all journals for this batch
                TempDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadARecurringJournalAndRelatedTablesForBatch(FLedgerNumber, FBatchNumber));
                TempDS.AcceptChanges();

                //Clear the transactions and load newly saved dataset
                FMainDS.ARecurringTransAnalAttrib.Clear();
                FMainDS.ARecurringTransaction.Clear();
                FMainDS.ARecurringJournal.Clear();

                FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.ProcessRecurrJrnlTransAttribForDeletion(TempDS, FLedgerNumber, FBatchNumber,
                                                                                                        TopMostJrnlNo, FJournalNumberToDelete));

                FPreviouslySelectedDetailRow = null;
                FPetraUtilsObject.SetChangedFlag();

                ACompletionMessage = String.Format(Catalog.GetString("Recurring Journal no.: {0} deleted successfully."),
                                                   FJournalNumberToDelete);

                DeletionSuccessful = true;
            }
            catch (Exception ex)
            {
                //Normally set in PostDeleteManual
                FMyForm.FCurrentGLBatchAction = TGLBatchEnums.GLBatchAction.NONE;

                //Revert to previous state
                RevertDataSet(FMainDS, BackupMainDS);

                TLogging.LogException(ex, Utilities.GetMethodSignature());
                throw;
            }
            finally
            {
                SetJournalDefaultView();
                FFilterAndFindObject.ApplyFilter();
                this.Cursor = Cursors.Default;
            }

            return(DeletionSuccessful);
        }
        /// <summary>
        /// Deletes the current row and optionally populates a completion message
        /// </summary>
        /// <param name="ARowToDelete">the currently selected row to delete</param>
        /// <param name="ACompletionMessage">if specified, is the deletion completion message</param>
        /// <returns>true if row deletion is successful</returns>
        private bool DeleteRowManual(GLBatchTDSARecurringJournalRow ARowToDelete, ref string ACompletionMessage)
        {
            //Assign default value(s)
            bool DeletionSuccessful = false;

            ACompletionMessage = string.Empty;

            if (ARowToDelete == null)
            {
                return DeletionSuccessful;
            }

            bool RowToDeleteIsNew = (ARowToDelete.RowState == DataRowState.Added);

            if (!RowToDeleteIsNew)
            {
                //Reject any changes which may fail validation
                ARowToDelete.RejectChanges();
                ShowDetails(ARowToDelete);

                if (!((TFrmRecurringGLBatch) this.ParentForm).SaveChanges())
                {
                    MessageBox.Show(Catalog.GetString("Error in trying to save prior to deleting current recurring journal!"),
                        Catalog.GetString("Deletion Error"),
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);

                    return DeletionSuccessful;
                }
            }

            //Backup the Dataset for reversion purposes
            GLBatchTDS BackupMainDS = (GLBatchTDS)FMainDS.Copy();
            BackupMainDS.Merge(FMainDS);

            //Pass copy to delete method.
            GLBatchTDS TempDS = (GLBatchTDS)FMainDS.Copy();
            TempDS.Merge(FMainDS);

            FJournalNumberToDelete = ARowToDelete.JournalNumber;
            int TopMostJrnlNo = FBatchRow.LastJournal;

            try
            {
                this.Cursor = Cursors.WaitCursor;

                //clear any transactions currently being editied in the Transaction Tab
                ((TFrmRecurringGLBatch)ParentForm).GetTransactionsControl().ClearCurrentSelection();

                if (RowToDeleteIsNew)
                {
                    ProcessNewlyAddedJournalRowForDeletion(FJournalNumberToDelete);
                }
                else
                {
                    //Load all journals for this batch
                    TempDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadARecurringJournalAndContent(FLedgerNumber, FBatchNumber));
                    TempDS.AcceptChanges();

                    //Clear the transactions and load newly saved dataset
                    FMainDS.ARecurringTransAnalAttrib.Clear();
                    FMainDS.ARecurringTransaction.Clear();
                    FMainDS.ARecurringJournal.Clear();

                    FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.ProcessRecurrJrnlTransAttribForDeletion(TempDS, FLedgerNumber, FBatchNumber,
                            TopMostJrnlNo, FJournalNumberToDelete));
                }

                FPreviouslySelectedDetailRow = null;
                FPetraUtilsObject.SetChangedFlag();

                ACompletionMessage = String.Format(Catalog.GetString("Recurring Journal no.: {0} deleted successfully."),
                    FJournalNumberToDelete);

                DeletionSuccessful = true;
            }
            catch (Exception ex)
            {
                ACompletionMessage = ex.Message;
                MessageBox.Show(ex.Message,
                    "Deletion Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                //Revert to previous state
                FMainDS.Merge(BackupMainDS);
            }
            finally
            {
                SetJournalDefaultView();
                FFilterAndFindObject.ApplyFilter();
                this.Cursor = Cursors.Default;
            }

            return DeletionSuccessful;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Deletes the current row and optionally populates a completion message
        /// </summary>
        /// <param name="ARowToDelete">the currently selected row to delete</param>
        /// <param name="ACompletionMessage">if specified, is the deletion completion message</param>
        /// <returns>true if row deletion is successful</returns>
        private bool DeleteRowManual(GLBatchTDSARecurringJournalRow ARowToDelete, ref string ACompletionMessage)
        {
            //Assign default value(s)
            bool DeletionSuccessful = false;

            ACompletionMessage = string.Empty;

            if (ARowToDelete == null)
            {
                return(DeletionSuccessful);
            }

            bool RowToDeleteIsNew = (ARowToDelete.RowState == DataRowState.Added);

            if (!RowToDeleteIsNew)
            {
                //Reject any changes which may fail validation
                ARowToDelete.RejectChanges();
                ShowDetails(ARowToDelete);

                if (!((TFrmRecurringGLBatch)this.ParentForm).SaveChanges())
                {
                    MessageBox.Show(Catalog.GetString("Error in trying to save prior to deleting current recurring journal!"),
                                    Catalog.GetString("Deletion Error"),
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);

                    return(DeletionSuccessful);
                }
            }

            //Backup the Dataset for reversion purposes
            GLBatchTDS BackupMainDS = (GLBatchTDS)FMainDS.Copy();

            BackupMainDS.Merge(FMainDS);

            //Pass copy to delete method.
            GLBatchTDS TempDS = (GLBatchTDS)FMainDS.Copy();

            TempDS.Merge(FMainDS);

            FJournalNumberToDelete = ARowToDelete.JournalNumber;
            int TopMostJrnlNo = FBatchRow.LastJournal;

            try
            {
                this.Cursor = Cursors.WaitCursor;

                //clear any transactions currently being editied in the Transaction Tab
                ((TFrmRecurringGLBatch)ParentForm).GetTransactionsControl().ClearCurrentSelection();

                if (RowToDeleteIsNew)
                {
                    ProcessNewlyAddedJournalRowForDeletion(FJournalNumberToDelete);
                }
                else
                {
                    //Load all journals for this batch
                    TempDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadARecurringJournalAndContent(FLedgerNumber, FBatchNumber));
                    TempDS.AcceptChanges();

                    //Clear the transactions and load newly saved dataset
                    FMainDS.ARecurringTransAnalAttrib.Clear();
                    FMainDS.ARecurringTransaction.Clear();
                    FMainDS.ARecurringJournal.Clear();

                    FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.ProcessRecurrJrnlTransAttribForDeletion(TempDS, FLedgerNumber, FBatchNumber,
                                                                                                            TopMostJrnlNo, FJournalNumberToDelete));
                }

                FPreviouslySelectedDetailRow = null;
                FPetraUtilsObject.SetChangedFlag();

                ACompletionMessage = String.Format(Catalog.GetString("Recurring Journal no.: {0} deleted successfully."),
                                                   FJournalNumberToDelete);

                DeletionSuccessful = true;
            }
            catch (Exception ex)
            {
                ACompletionMessage = ex.Message;
                MessageBox.Show(ex.Message,
                                "Deletion Error",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);

                //Revert to previous state
                FMainDS.Merge(BackupMainDS);
            }
            finally
            {
                SetJournalDefaultView();
                FFilterAndFindObject.ApplyFilter();
                this.Cursor = Cursors.Default;
            }

            return(DeletionSuccessful);
        }
        private void ValidateDataDetailsManual(ARecurringTransactionRow ARow)
        {
            //Can be called from outside, so need to update fields
            FBatchRow = GetBatchRow();

            if (FBatchRow == null)
            {
                return;
            }

            FJournalRow = GetJournalRow();

            if (FJournalRow != null)
            {
                FJournalNumber = FJournalRow.JournalNumber;
            }

            if ((ARow == null) || (FBatchRow.BatchNumber != ARow.BatchNumber))
            {
                return;
            }

            TVerificationResultCollection VerificationResultCollection = FPetraUtilsObject.VerificationResultCollection;

            Control controlToPass = null;

            //Local validation
            if (((txtDebitAmount.NumberValueDecimal.Value == 0)
                 && (txtCreditAmount.NumberValueDecimal.Value == 0))
                || (txtDebitAmount.NumberValueDecimal.Value < 0))
            {
                controlToPass = txtDebitAmount;
            }
            else if (txtCreditAmount.NumberValueDecimal.Value < 0)
            {
                controlToPass = txtCreditAmount;
            }
            else if (TSystemDefaults.GetSystemDefault(SharedConstants.SYSDEFAULT_GLREFMANDATORY, "no") == "yes")
            {
                controlToPass = txtDetailReference;
            }
            else if ((VerificationResultCollection.Count == 1)
                     && (VerificationResultCollection[0].ResultCode == CommonErrorCodes.ERR_INVALIDNUMBER))
            {
                //The amount controls register as invalid even when value is correct. Need to reset
                //  Verifications accordingly.
                FPetraUtilsObject.VerificationResultCollection.Clear();
            }

            TSharedFinanceValidation_GL.ValidateRecurringGLDetailManual(this, FBatchRow, ARow, controlToPass, ref VerificationResultCollection,
                FValidationControlsDict);

            if ((FPreviouslySelectedDetailRow != null)
                && !FAnalysisAttributesLogic.AccountRecurringAnalysisAttributeCountIsCorrect(
                    FPreviouslySelectedDetailRow.TransactionNumber,
                    FPreviouslySelectedDetailRow.AccountCode,
                    FMainDS))
            {
                DataColumn ValidationColumn;
                TVerificationResult VerificationResult = null;
                object ValidationContext;

                ValidationColumn = ARow.Table.Columns[ARecurringTransactionTable.ColumnAccountCodeId];
                ValidationContext = "unused because of OverrideResultText";

                // This code is only running because of failure, so cause an error to occur.
                VerificationResult = TStringChecks.StringMustNotBeEmpty("",
                    ValidationContext.ToString(),
                    this, ValidationColumn, null);
                VerificationResult.OverrideResultText(String.Format(
                        "A value must be entered for 'Analysis Attributes' for Account Code {0} in Transaction {1}.",
                        ARow.AccountCode,
                        ARow.TransactionNumber));
                // Handle addition/removal to/from TVerificationResultCollection
                VerificationResultCollection.Auto_Add_Or_AddOrRemove(this, VerificationResult, ValidationColumn, true);
            }

            String ValueRequiredForType;

            if ((FPreviouslySelectedDetailRow != null)
                && !FAnalysisAttributesLogic.AccountRecurringAnalysisAttributesValuesExist(
                    FPreviouslySelectedDetailRow.TransactionNumber,
                    FPreviouslySelectedDetailRow.AccountCode,
                    FMainDS,
                    out ValueRequiredForType))
            {
                DataColumn ValidationColumn;
                TVerificationResult VerificationResult = null;
                object ValidationContext;

                ValidationColumn = ARow.Table.Columns[ARecurringTransactionTable.ColumnAccountCodeId];
                ValidationContext = String.Format("Analysis code {0} for Account Code {1} in Transaction {2}",
                    ValueRequiredForType,
                    ARow.AccountCode,
                    ARow.TransactionNumber);

                // This code is only running because of failure, so cause an error to occur.
                VerificationResult = TStringChecks.StringMustNotBeEmpty("",
                    ValidationContext.ToString(),
                    this, ValidationColumn, null);

                // Handle addition/removal to/from TVerificationResultCollection
                VerificationResultCollection.Auto_Add_Or_AddOrRemove(this, VerificationResult, ValidationColumn, true);
            }
        }
        /// <summary>
        /// load the transactions into the grid
        /// </summary>
        /// <param name="ALedgerNumber"></param>
        /// <param name="ABatchNumber"></param>
        /// <param name="AJournalNumber"></param>
        /// <param name="ACurrencyCode"></param>
        /// <param name="AFromBatchTab"></param>
        /// <returns>True if new GL transactions were loaded, false if transactions had been loaded already.</returns>
        public bool LoadTransactions(Int32 ALedgerNumber,
            Int32 ABatchNumber,
            Int32 AJournalNumber,
            string ACurrencyCode,
            bool AFromBatchTab = false)
        {
            TFrmStatusDialog dlgStatus = null;
            bool DifferentBatchSelected = false;

            FLoadCompleted = false;

            FBatchRow = GetBatchRow();
            FJournalRow = GetJournalRow();

            //FBatchNumber and FJournalNumber may have already been set outside
            //  so need to reset to previous value
            if (txtBatchNumber.Text.Length > 0)
            {
                FBatchNumber = Int32.Parse(txtBatchNumber.Text);
            }

            if (txtJournalNumber.Text.Length > 0)
            {
                FJournalNumber = Int32.Parse(txtJournalNumber.Text);
            }

            if (FLedgerNumber == -1)
            {
                InitialiseControls();
            }

            try
            {
                this.Cursor = Cursors.WaitCursor;

                //Check if the same batch is selected, so no need to apply filter
                if ((FLedgerNumber == ALedgerNumber)
                    && (FBatchNumber == ABatchNumber)
                    && (FJournalNumber == AJournalNumber)
                    && (FTransactionCurrency == ACurrencyCode)
                    && (FMainDS.ARecurringTransaction.DefaultView.Count > 0))
                {
                    //Same as previously selected

                    //Need to reconnect FPrev in some circumstances
                    if (FPreviouslySelectedDetailRow == null)
                    {
                        DataRowView rowView = (DataRowView)grdDetails.Rows.IndexToDataSourceRow(FPrevRowChangedRow);

                        if (rowView != null)
                        {
                            FPreviouslySelectedDetailRow = (GLBatchTDSARecurringTransactionRow)(rowView.Row);
                        }
                    }

                    if (GetSelectedRowIndex() > 0)
                    {
                        if (AFromBatchTab)
                        {
                            SelectRowInGrid(GetSelectedRowIndex());
                        }
                        else
                        {
                            GetDetailsFromControls(GetSelectedDetailRow());
                        }
                    }

                    FLoadCompleted = true;

                    return false;
                }

                // Different batch selected
                DifferentBatchSelected = true;
                bool requireControlSetup = (FLedgerNumber == -1) || (FTransactionCurrency != ACurrencyCode);

                //Handle dialog
                dlgStatus = new TFrmStatusDialog(FPetraUtilsObject.GetForm());

                if (FShowStatusDialogOnLoad)
                {
                    dlgStatus.Show();
                    FShowStatusDialogOnLoad = false;
                    dlgStatus.Heading = String.Format(Catalog.GetString("Recurring Batch {0}, Journal {1}"), ABatchNumber, AJournalNumber);
                    dlgStatus.CurrentStatus = Catalog.GetString("Loading transactions ...");
                }

                FLedgerNumber = ALedgerNumber;
                FBatchNumber = ABatchNumber;
                FJournalNumber = AJournalNumber;
                FTransactionNumber = -1;
                FTransactionCurrency = ACurrencyCode;

                FPreviouslySelectedDetailRow = null;
                grdDetails.SuspendLayout();
                //Empty grids before filling them
                grdDetails.DataSource = null;
                grdAnalAttributes.DataSource = null;

                // This sets the main part of the filter but excluding the additional items set by the user GUI
                // It gets the right sort order
                SetTransactionDefaultView();

                //Set the Analysis attributes filter as well
                FAnalysisAttributesLogic = new TAnalysisAttributes(FLedgerNumber, FBatchNumber, FJournalNumber);
                FAnalysisAttributesLogic.SetRecurringTransAnalAttributeDefaultView(FMainDS);
                FMainDS.ARecurringTransAnalAttrib.DefaultView.AllowNew = false;

                //Load from server if necessary
                if (FMainDS.ARecurringTransaction.DefaultView.Count == 0)
                {
                    dlgStatus.CurrentStatus = Catalog.GetString("Requesting transactions from server...");
                    FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadARecurringTransactionARecurringTransAnalAttrib(ALedgerNumber, ABatchNumber,
                            AJournalNumber));
                }
                else if (FMainDS.ARecurringTransAnalAttrib.DefaultView.Count == 0) // just in case transactions have been loaded in a separate process without analysis attributes
                {
                    dlgStatus.CurrentStatus = Catalog.GetString("Requesting analysis attributes from server...");
                    FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadARecurringTransAnalAttribForJournal(ALedgerNumber, ABatchNumber,
                            AJournalNumber));
                }

                // We need to call this because we have not called ShowData(), which would have set it.  This differs from the Gift screen.
                grdDetails.DataSource = new DevAge.ComponentModel.BoundDataView(FMainDS.ARecurringTransaction.DefaultView);

                // Now we set the full filter
                dlgStatus.CurrentStatus = Catalog.GetString("Selecting the records...");
                FFilterAndFindObject.ApplyFilter();

                dlgStatus.CurrentStatus = Catalog.GetString("Configuring analysis attributes ...");

                if (grdAnalAttributes.Columns.Count == 1)
                {
                    grdAnalAttributes.SpecialKeys = GridSpecialKeys.Default | GridSpecialKeys.Tab;

                    FcmbAnalAttribValues = new SourceGrid.Cells.Editors.ComboBox(typeof(string));
                    FcmbAnalAttribValues.EnableEdit = true;
                    FcmbAnalAttribValues.EditableMode = EditableMode.Focus;
                    grdAnalAttributes.AddTextColumn("Value",
                        FMainDS.ARecurringTransAnalAttrib.Columns[ARecurringTransAnalAttribTable.GetAnalysisAttributeValueDBName()], 100,
                        FcmbAnalAttribValues);
                    FcmbAnalAttribValues.Control.SelectedValueChanged += new EventHandler(this.AnalysisAttributeValueChanged);

                    grdAnalAttributes.Columns[0].Width = 99;
                }

                grdAnalAttributes.DataSource = new DevAge.ComponentModel.BoundDataView(FMainDS.ARecurringTransAnalAttrib.DefaultView);
                grdAnalAttributes.SetHeaderTooltip(0, Catalog.GetString("Type"));
                grdAnalAttributes.SetHeaderTooltip(1, Catalog.GetString("Value"));

                //Always show active and inactive values
                if (requireControlSetup)
                {
                    //Load all analysis attribute values
                    if (FCacheDS == null)
                    {
                        dlgStatus.CurrentStatus = Catalog.GetString("Loading analysis attributes ...");
                        FCacheDS = TRemote.MFinance.GL.WebConnectors.LoadAAnalysisAttributes(FLedgerNumber, FActiveOnly);
                    }

                    SetupExtraGridFunctionality();

                    dlgStatus.CurrentStatus = Catalog.GetString("Initialising accounts and cost centres ...");

                    // We suppress change detection because these are the correct values
                    // Then initialise our combo boxes for the correct account codes and cost centres
                    bool prevSuppressChangeDetection = FPetraUtilsObject.SuppressChangeDetection;
                    FPetraUtilsObject.SuppressChangeDetection = true;
                    TFinanceControls.InitialiseAccountList(ref cmbDetailAccountCode, FLedgerNumber,
                        true, false, FActiveOnly, false, ACurrencyCode, true);
                    TFinanceControls.InitialiseCostCentreList(ref cmbDetailCostCentreCode, FLedgerNumber, true, false, FActiveOnly, false);
                    FPetraUtilsObject.SuppressChangeDetection = prevSuppressChangeDetection;

                    cmbDetailAccountCode.AttachedLabel.Text = TFinanceControls.SELECT_VALID_ACCOUNT;
                    cmbDetailCostCentreCode.AttachedLabel.Text = TFinanceControls.SELECT_VALID_COST_CENTRE;
                }

                //Old data may not have correct LastTransactionNumber
                if (FJournalRow.LastTransactionNumber != FMainDS.ARecurringTransaction.DefaultView.Count)
                {
                    if (GLRoutines.UpdateRecurringJournalLastTransaction(ref FMainDS, ref FJournalRow))
                    {
                        FPetraUtilsObject.SetChangedFlag();
                    }
                }

                //Check for incorrect Exchange rate to base (mainly for existing Petra data)
                foreach (DataRowView drv in FMainDS.ARecurringTransaction.DefaultView)
                {
                    ARecurringTransactionRow rtr = (ARecurringTransactionRow)drv.Row;

                    if (rtr.ExchangeRateToBase == 0)
                    {
                        rtr.ExchangeRateToBase = 1;
                        FPetraUtilsObject.HasChanges = true;
                    }
                }

                UpdateTransactionTotals();
                grdDetails.ResumeLayout();
                FLoadCompleted = true;

                ShowData();
                SelectRowInGrid(1);
                ShowDetails(); //Needed because of how currency is handled
                UpdateChangeableStatus();

                UpdateRecordNumberDisplay();
                FFilterAndFindObject.SetRecordNumberDisplayProperties();

                //Check for missing analysis attributes and their values
                if (grdDetails.Rows.Count > 1)
                {
                    string updatedTransactions = string.Empty;

                    dlgStatus.CurrentStatus = Catalog.GetString("Checking analysis attributes ...");
                    FAnalysisAttributesLogic.ReconcileRecurringTransAnalysisAttributes(FMainDS, out updatedTransactions);

                    if (updatedTransactions.Length > 0)
                    {
                        //Remove trailing comma
                        updatedTransactions = updatedTransactions.Remove(updatedTransactions.Length - 2);
                        MessageBox.Show(String.Format(Catalog.GetString(
                                    "Analysis Attributes have been updated in transaction(s): {0}.{1}{1}Remember to check their values."),
                                updatedTransactions,
                                Environment.NewLine),
                            "Analysis Attributes",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);

                        FPetraUtilsObject.SetChangedFlag();
                    }
                }

                RefreshAnalysisAttributesGrid();
            }
            catch (Exception ex)
            {
                TLogging.Log(String.Format("Method:{0} - Unexpected error!{1}{1}{2}",
                        Utilities.GetMethodSignature(),
                        Environment.NewLine,
                        ex.Message));
                throw ex;
            }
            finally
            {
                if (dlgStatus != null)
                {
                    dlgStatus.Close();
                }

                this.Cursor = Cursors.Default;
            }

            return DifferentBatchSelected;
        }
        /// <summary>
        /// Undo all changes to the specified batch ready to cancel it.
        ///  This avoids unecessary validation errors when cancelling.
        /// </summary>
        /// <param name="ACurrentBatch"></param>
        /// <param name="AJournalToDelete"></param>
        /// <param name="ARedisplay"></param>
        public void PrepareJournalDataForDeleting(Int32 ACurrentBatch, Int32 AJournalToDelete, Boolean ARedisplay)
        {
            //This code will only be called when the Batch tab is active.

            DataView JournalDV   = new DataView(FMainDS.ARecurringJournal);
            DataView TransDV     = new DataView(FMainDS.ARecurringTransaction);
            DataView TransAnalDV = new DataView(FMainDS.ARecurringTransAnalAttrib);

            JournalDV.RowFilter = String.Format("{0}={1} And {2}={3}",
                                                ARecurringJournalTable.GetBatchNumberDBName(),
                                                ACurrentBatch,
                                                ARecurringJournalTable.GetJournalNumberDBName(),
                                                AJournalToDelete);

            TransDV.RowFilter = String.Format("{0}={1} And {2}={3}",
                                              ARecurringTransactionTable.GetBatchNumberDBName(),
                                              ACurrentBatch,
                                              ARecurringTransactionTable.GetJournalNumberDBName(),
                                              AJournalToDelete);

            TransAnalDV.RowFilter = String.Format("{0}={1} And {2}={3}",
                                                  ARecurringTransAnalAttribTable.GetBatchNumberDBName(),
                                                  ACurrentBatch,
                                                  ARecurringTransAnalAttribTable.GetJournalNumberDBName(),
                                                  AJournalToDelete);

            //Work from lowest level up
            if (TransAnalDV.Count > 0)
            {
                TransAnalDV.Sort = String.Format("{0}, {1}, {2}",
                                                 ARecurringTransAnalAttribTable.GetJournalNumberDBName(),
                                                 ARecurringTransAnalAttribTable.GetTransactionNumberDBName(),
                                                 ARecurringTransAnalAttribTable.GetAnalysisTypeCodeDBName());

                foreach (DataRowView drv in TransAnalDV)
                {
                    ARecurringTransAnalAttribRow transAnalRow = (ARecurringTransAnalAttribRow)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}",
                                             ARecurringTransactionTable.GetJournalNumberDBName(),
                                             ARecurringTransactionTable.GetTransactionNumberDBName());

                foreach (DataRowView drv in TransDV)
                {
                    ARecurringTransactionRow transRow = (ARecurringTransactionRow)drv.Row;

                    if (transRow.RowState == DataRowState.Added)
                    {
                        //Do nothing
                    }
                    else if (transRow.RowState != DataRowState.Unchanged)
                    {
                        transRow.RejectChanges();
                    }
                }
            }

            if (JournalDV.Count > 0)
            {
                GLBatchTDSARecurringJournalRow journalRow = (GLBatchTDSARecurringJournalRow)JournalDV[0].Row;

                //No need to check for Added state as new batches are always saved
                // on creation

                if (journalRow.RowState != DataRowState.Unchanged)
                {
                    journalRow.RejectChanges();
                }

                if (ARedisplay)
                {
                    ShowDetails(journalRow);
                }
            }

            if (TransDV.Count == 0)
            {
                //Load all related data for batch ready to delete/cancel
                FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadARecurringTransactionAndRelatedTablesForJournal(FLedgerNumber, ACurrentBatch,
                                                                                                                    AJournalToDelete));
            }
        }
        /// <summary>
        /// make sure the correct journal number is assigned and the batch.lastJournal is updated
        /// </summary>
        /// <param name="ANewRow"></param>
        public void NewRowManual(ref GLBatchTDSARecurringJournalRow ANewRow)
        {
            if ((ANewRow == null) || (FLedgerNumber == -1))
            {
                return;
            }

            ALedgerRow LedgerRow =
                ((ALedgerTable)TDataCache.TMFinance.GetCacheableFinanceTable(
                     TCacheableFinanceTablesEnum.LedgerDetails, FLedgerNumber))[0];

            ANewRow.LedgerNumber = FBatchRow.LedgerNumber;
            ANewRow.BatchNumber = FBatchRow.BatchNumber;
            ANewRow.JournalNumber = ++FBatchRow.LastJournal;

            // manually created journals are all GL
            ANewRow.SubSystemCode = MFinanceConstants.SUB_SYSTEM_GL;
            ANewRow.TransactionTypeCode = MFinanceConstants.STANDARD_JOURNAL;

            ANewRow.TransactionCurrency = FCurrencyCodeForJournals;
            ANewRow.ExchangeRateToBase = 1;
            ANewRow.DateEffective = FBatchRow.DateEffective;
            ANewRow.JournalPeriod = FBatchRow.BatchPeriod;
        }
        /// <summary>
        /// load the transactions into the grid
        /// </summary>
        /// <param name="ALedgerNumber"></param>
        /// <param name="ABatchNumber"></param>
        /// <param name="AJournalNumber"></param>
        /// <param name="ACurrencyCode"></param>
        /// <param name="AFromBatchTab"></param>
        /// <returns>True if new GL transactions were loaded, false if transactions had been loaded already.</returns>
        public bool LoadRecurringTransactions(Int32 ALedgerNumber,
            Int32 ABatchNumber,
            Int32 AJournalNumber,
            string ACurrencyCode,
            bool AFromBatchTab = false)
        {
            bool DifferentBatchSelected = false;
            bool HadChangesFromTheStart = FPetraUtilsObject.HasChanges;

            FLoadCompleted = false;
            FBatchRow = GetRecurringBatchRow();
            FJournalRow = GetRecurringJournalRow();

            if (FLedgerNumber == -1)
            {
                InitialiseControls();
            }

            //Check if the same batch is selected, so no need to apply filter
            if ((FLedgerNumber == ALedgerNumber) && (FBatchNumber == ABatchNumber) && (FJournalNumber == AJournalNumber)
                && (FTransactionCurrency == ACurrencyCode) && (FMainDS.ARecurringTransaction.DefaultView.Count > 0))
            {
                //Same as previously selected
                if (GetSelectedRowIndex() > 0)
                {
                    if (AFromBatchTab)
                    {
                        SelectRowInGrid(GetSelectedRowIndex());
                    }
                    else
                    {
                        GetDetailsFromControls(GetSelectedDetailRow());
                    }
                }

                FLoadCompleted = true;
            }
            else
            {
                // Different batch
                DifferentBatchSelected = true;
                bool requireControlSetup = (FLedgerNumber == -1) || (FTransactionCurrency != ACurrencyCode);

                FLedgerNumber = ALedgerNumber;
                FBatchNumber = ABatchNumber;
                FJournalNumber = AJournalNumber;
                FTransactionNumber = -1;
                FTransactionCurrency = ACurrencyCode;

                FPreviouslySelectedDetailRow = null;
                grdDetails.SuspendLayout();
                //Empty grids before filling them
                grdDetails.DataSource = null;
                grdAnalAttributes.DataSource = null;

                // This sets the main part of the filter but excluding the additional items set by the user GUI
                // It gets the right sort order
                SetTransactionDefaultView();

                //Load from server if necessary
                if (FMainDS.ARecurringTransaction.DefaultView.Count == 0)
                {
                    FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadARecurringTransactionARecurringTransAnalAttrib(ALedgerNumber, ABatchNumber,
                            AJournalNumber));
                }

                // We need to call this because we have not called ShowData(), which would have set it.  This differs from the Gift screen.
                grdDetails.DataSource = new DevAge.ComponentModel.BoundDataView(FMainDS.ARecurringTransaction.DefaultView);

                // Now we set the full filter
                FFilterAndFindObject.ApplyFilter();

                if (grdAnalAttributes.Columns.Count == 1)
                {
                    grdAnalAttributes.SpecialKeys = GridSpecialKeys.Default | GridSpecialKeys.Tab;

                    FcmbAnalAttribValues = new SourceGrid.Cells.Editors.ComboBox(typeof(string));
                    FcmbAnalAttribValues.EnableEdit = true;
                    FcmbAnalAttribValues.EditableMode = EditableMode.Focus;
                    grdAnalAttributes.AddTextColumn("Value",
                        FMainDS.ARecurringTransAnalAttrib.Columns[ARecurringTransAnalAttribTable.GetAnalysisAttributeValueDBName()], 100,
                        FcmbAnalAttribValues);
                    FcmbAnalAttribValues.Control.SelectedValueChanged += new EventHandler(this.AnalysisAttributeValueChanged);

                    grdAnalAttributes.Columns[0].Width = 99;
                }

                FAnalysisAttributesLogic = new TAnalysisAttributes(FLedgerNumber, FBatchNumber, FJournalNumber);

                FAnalysisAttributesLogic.SetRecurringTransAnalAttributeDefaultView(FMainDS);
                FMainDS.ARecurringTransAnalAttrib.DefaultView.AllowNew = false;
                grdAnalAttributes.DataSource = new DevAge.ComponentModel.BoundDataView(FMainDS.ARecurringTransAnalAttrib.DefaultView);
                grdAnalAttributes.SetHeaderTooltip(0, Catalog.GetString("Type"));
                grdAnalAttributes.SetHeaderTooltip(1, Catalog.GetString("Value"));

                //Always show active and inactive values
                if (requireControlSetup)
                {
                    //Load all analysis attribute values
                    if (FCacheDS == null)
                    {
                        FCacheDS = TRemote.MFinance.GL.WebConnectors.LoadAAnalysisAttributes(FLedgerNumber, FActiveOnly);
                    }

                    SetupExtraGridFunctionality();

                    TFinanceControls.InitialiseAccountList(ref cmbDetailAccountCode, FLedgerNumber,
                        true, false, FActiveOnly, false, ACurrencyCode, true);
                    TFinanceControls.InitialiseCostCentreList(ref cmbDetailCostCentreCode, FLedgerNumber, true, false, FActiveOnly, false);
                }

                // This modifies the content of the text boxes that display the totals.  This is not a user change.
                bool prev = FPetraUtilsObject.SuppressChangeDetection;
                FPetraUtilsObject.SuppressChangeDetection = true;
                UpdateTransactionTotals();
                FPetraUtilsObject.SuppressChangeDetection = prev;

                grdDetails.ResumeLayout();
                FLoadCompleted = true;
            }

            //Check for incorrect Exchange rate to base (mainly for existing Petra data)
            foreach (DataRowView drv in FMainDS.ARecurringTransaction.DefaultView)
            {
                ARecurringTransactionRow rtr = (ARecurringTransactionRow)drv.Row;

                if (rtr.ExchangeRateToBase == 0)
                {
                    rtr.ExchangeRateToBase = 1;
                    FPetraUtilsObject.HasChanges = true;
                }
            }

            if (FPetraUtilsObject.HasChanges && !HadChangesFromTheStart)
            {
                // This means we updated the transaction totals.  We will save them behind the scenes since there were no other changes when we started
                ((TFrmRecurringGLBatch)ParentForm).SaveChanges();
                FMainDS.ARecurringTransaction.AcceptChanges();
            }

            ShowData();
            SelectRowInGrid(1);
            ShowDetails(); //Needed because of how currency is handled

            UpdateChangeableStatus();
            UpdateRecordNumberDisplay();
            FFilterAndFindObject.SetRecordNumberDisplayProperties();

            return DifferentBatchSelected;
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Calculate the base amount for the transactions, and update the totals for the current journal
        /// NOTE this no longer calculates AmountInBaseCurrency
        /// ALSO - since the ExchangeRateToBase field is no longer used here, the code that asserts it to be valid is commented out.
        /// </summary>
        /// <param name="AMainDS">ATransactions are filtered on current journal</param>
        /// <param name="ACurrentJournal"></param>
        public static void UpdateTotalsOfRecurringJournal(ref GLBatchTDS AMainDS,
            ref GLBatchTDSARecurringJournalRow ACurrentJournal)
        {
            if (ACurrentJournal == null)
            {
                return;
            }

            /* // Since I'm not using ExchangeRateToBase, I don't need to check that it's valid:
             *
             * if ((ACurrentJournal.ExchangeRateToBase == 0.0m)
             *  && (ACurrentJournal.TransactionTypeCode != CommonAccountingTransactionTypesEnum.REVAL.ToString()))
             * {
             *  throw new Exception(String.Format("Recurring Batch {0} Journal {1} has invalid exchange rate to base",
             *          ACurrentJournal.BatchNumber,
             *          ACurrentJournal.JournalNumber));
             * }
             */

            ACurrentJournal.JournalDebitTotal = 0.0M;
            ACurrentJournal.JournalDebitTotalBase = 0.0M;
            ACurrentJournal.JournalCreditTotal = 0.0M;
            ACurrentJournal.JournalCreditTotalBase = 0.0M;

            DataView trnsDataView = new DataView(AMainDS.ARecurringTransaction);

            trnsDataView.RowFilter = String.Format("{0}={1} And {2}={3}",
                ARecurringTransactionTable.GetBatchNumberDBName(),
                ACurrentJournal.BatchNumber,
                ARecurringTransactionTable.GetJournalNumberDBName(),
                ACurrentJournal.JournalNumber);

            // transactions are filtered for this journal; add up the total amounts
            foreach (DataRowView v in trnsDataView)
            {
                ARecurringTransactionRow r = (ARecurringTransactionRow)v.Row;

                if (r.DebitCreditIndicator)
                {
                    ACurrentJournal.JournalDebitTotal += r.TransactionAmount;
                    ACurrentJournal.JournalDebitTotalBase += r.AmountInBaseCurrency;
                }
                else
                {
                    ACurrentJournal.JournalCreditTotal += r.TransactionAmount;
                    ACurrentJournal.JournalCreditTotalBase += r.AmountInBaseCurrency;
                }
            }
        }
Ejemplo n.º 16
0
        private static bool UpdateRecurringJournalTotals(ref GLBatchTDS AMainDS,
            ref GLBatchTDSARecurringJournalRow ACurrentJournal)
        {
            #region Validate Arguments

            if (AMainDS == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString("Function:{0} - The GL Batch dataset is null!"),
                        Utilities.GetMethodName(true)));
            }
            else if (ACurrentJournal == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString(
                            "Function:{0} - The Recurring Journal row does not exist or is empty!"),
                        Utilities.GetMethodName(true)));
            }

            #endregion Validate Arguments

            bool AmountsUpdated = false;

            decimal JournalDebitTotal = 0.0M;
            decimal JournalDebitTotalBase = 0.0M;
            decimal JournalCreditTotal = 0.0M;
            decimal JournalCreditTotalBase = 0.0M;

            if (ACurrentJournal.IsJournalDebitTotalBaseNull()) //DBNull.Value.Equals(ACurrentJournal[GLBatchTDSARecurringJournalTable.ColumnJournalDebitTotalBaseId])
            {
                ACurrentJournal.JournalDebitTotalBase = 0;
                AmountsUpdated = true;
            }

            if (ACurrentJournal.IsJournalCreditTotalBaseNull()) //DBNull.Value.Equals(ACurrentJournal[GLBatchTDSARecurringJournalTable.ColumnJournalCreditTotalBaseId])
            {
                ACurrentJournal.JournalCreditTotalBase = 0;
                AmountsUpdated = true;
            }

            DataView TransDV = new DataView(AMainDS.ARecurringTransaction);
            TransDV.RowFilter = String.Format("{0}={1} And {2}={3}",
                ARecurringTransactionTable.GetBatchNumberDBName(),
                ACurrentJournal.BatchNumber,
                ARecurringTransactionTable.GetJournalNumberDBName(),
                ACurrentJournal.JournalNumber);

            if ((TransDV.Count == 0) && (ACurrentJournal.LastTransactionNumber > 0))
            {
                //do not update totals as no transactions loaded as yet so no need to update journal total
                return AmountsUpdated;
            }

            // transactions are filtered for this journal; add up the total amounts
            foreach (DataRowView drv in TransDV)
            {
                ARecurringTransactionRow transRow = (ARecurringTransactionRow)drv.Row;

                if (transRow.DebitCreditIndicator)
                {
                    JournalDebitTotal += transRow.TransactionAmount;
                    JournalDebitTotalBase += transRow.AmountInBaseCurrency;
                }
                else
                {
                    JournalCreditTotal += transRow.TransactionAmount;
                    JournalCreditTotalBase += transRow.AmountInBaseCurrency;
                }
            }

            if ((ACurrentJournal.JournalDebitTotal != JournalDebitTotal)
                || (ACurrentJournal.JournalDebitTotalBase != JournalDebitTotalBase)
                || (ACurrentJournal.JournalCreditTotal != JournalCreditTotal)
                || (ACurrentJournal.JournalCreditTotalBase != JournalCreditTotalBase))
            {
                ACurrentJournal.JournalDebitTotal = JournalDebitTotal;
                ACurrentJournal.JournalDebitTotalBase = JournalDebitTotalBase;
                ACurrentJournal.JournalCreditTotal = JournalCreditTotal;
                ACurrentJournal.JournalCreditTotalBase = JournalCreditTotalBase;
                AmountsUpdated = true;
            }

            return AmountsUpdated;
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Update the specified recurring Journal's LastTransaction number. Assumes all necessary data is loaded for Journal
        /// </summary>
        /// <param name="AMainDS">ATransactions are filtered on current journal</param>
        /// <param name="ACurrentJournal"></param>
        /// <returns>false if no change to journal totals</returns>
        public static bool UpdateRecurringJournalLastTransaction(ref GLBatchTDS AMainDS,
            ref GLBatchTDSARecurringJournalRow ACurrentJournal)
        {
            #region Validate Arguments

            if (AMainDS == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString("Function:{0} - The GL Batch dataset is null!"),
                        Utilities.GetMethodName(true)));
            }
            else if (ACurrentJournal == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString(
                            "Function:{0} - The Recurring Journal row does not exist or is empty!"),
                        Utilities.GetMethodName(true)));
            }

            #endregion Validate Arguments

            bool RowUpdated = false;

            int ActualLastTransNumber = 0;

            DataView TransDV = new DataView(AMainDS.ARecurringTransaction);

            TransDV.RowFilter = String.Format("{0}={1} And {2}={3}",
                ARecurringTransactionTable.GetBatchNumberDBName(),
                ACurrentJournal.BatchNumber,
                ARecurringTransactionTable.GetJournalNumberDBName(),
                ACurrentJournal.JournalNumber);

            TransDV.Sort = String.Format("{0} DESC",
                ARecurringTransactionTable.GetTransactionNumberDBName());

            foreach (DataRowView drv in TransDV)
            {
                ARecurringTransactionRow transRow = (ARecurringTransactionRow)drv.Row;

                //Run once only
                ActualLastTransNumber = transRow.TransactionNumber;
                break;
            }

            if (ACurrentJournal.LastTransactionNumber != ActualLastTransNumber)
            {
                ACurrentJournal.LastTransactionNumber = ActualLastTransNumber;
                RowUpdated = true;
            }

            return RowUpdated;
        }
        private void RenumberJournals()
        {
            bool JournalsRenumbered = false;

            DataView JrnlView  = new DataView(FMainDS.ARecurringJournal);
            DataView TransView = new DataView(FMainDS.ARecurringTransaction);
            DataView AttrView  = new DataView(FMainDS.ARecurringTransAnalAttrib);

            //Reduce all trans and journal data by 1 in JournalNumber field
            //Reduce those with higher transaction number by one
            JrnlView.RowFilter = String.Format("{0}={1} AND {2}>{3}",
                                               ARecurringJournalTable.GetBatchNumberDBName(),
                                               FBatchNumber,
                                               ARecurringJournalTable.GetJournalNumberDBName(),
                                               FJournalNumberToDelete);

            JrnlView.Sort = String.Format("{0} ASC",
                                          ARecurringJournalTable.GetJournalNumberDBName());

            JournalsRenumbered = (JrnlView.Count > 0);

            // Delete the associated transaction analysis attributes
            //  if attributes do exist, and renumber those above
            foreach (DataRowView jV in JrnlView)
            {
                GLBatchTDSARecurringJournalRow jrnlRowCurrent = (GLBatchTDSARecurringJournalRow)jV.Row;

                int currentJnrlNumber = jrnlRowCurrent.JournalNumber;

                //Copy current row down to fill gap and then delete it
                GLBatchTDSARecurringJournalRow newJrnlRow = FMainDS.ARecurringJournal.NewRowTyped(true);

                newJrnlRow.ItemArray = jrnlRowCurrent.ItemArray;

                //reduce journal number by 1 in the new row
                newJrnlRow.JournalNumber--;

                FMainDS.ARecurringJournal.Rows.Add(newJrnlRow);

                //Process Transactions
                TransView.RowFilter = String.Format("{0}={1} AND {2}={3}",
                                                    ARecurringTransactionTable.GetBatchNumberDBName(),
                                                    FBatchNumber,
                                                    ARecurringTransactionTable.GetJournalNumberDBName(),
                                                    currentJnrlNumber);

                TransView.Sort = String.Format("{0} ASC, {1} ASC",
                                               ARecurringTransactionTable.GetJournalNumberDBName(),
                                               ARecurringTransactionTable.GetTransactionNumberDBName());

                //Iterate through higher number attributes and transaction numbers and reduce by one
                ARecurringTransactionRow transRowCurrent = null;

                foreach (DataRowView gv in TransView)
                {
                    transRowCurrent = (ARecurringTransactionRow)gv.Row;

                    GLBatchTDSARecurringTransactionRow newTransRow = FMainDS.ARecurringTransaction.NewRowTyped(true);

                    newTransRow.ItemArray = transRowCurrent.ItemArray;

                    //reduce journal number by 1 in the new row
                    newTransRow.JournalNumber--;

                    FMainDS.ARecurringTransaction.Rows.Add(newTransRow);

                    //Repeat process for attributes that belong to current transaction
                    AttrView.RowFilter = String.Format("{0}={1} And {2}={3} And {4}={5}",
                                                       ARecurringTransAnalAttribTable.GetBatchNumberDBName(),
                                                       FBatchNumber,
                                                       ARecurringTransAnalAttribTable.GetJournalNumberDBName(),
                                                       currentJnrlNumber,
                                                       ARecurringTransAnalAttribTable.GetTransactionNumberDBName(),
                                                       transRowCurrent.TransactionNumber);

                    AttrView.Sort = String.Format("{0} ASC, {1} ASC, {2} ASC",
                                                  ARecurringTransAnalAttribTable.GetJournalNumberDBName(),
                                                  ARecurringTransAnalAttribTable.GetTransactionNumberDBName(),
                                                  ARecurringTransAnalAttribTable.GetAnalysisTypeCodeDBName());

                    // Delete the associated transaction analysis attributes
                    //  if attributes do exist, and renumber those above
                    if (AttrView.Count > 0)
                    {
                        //Iterate through higher number attributes and transaction numbers and reduce by one
                        ARecurringTransAnalAttribRow attrRowCurrent = null;

                        foreach (DataRowView rV in AttrView)
                        {
                            attrRowCurrent = (ARecurringTransAnalAttribRow)rV.Row;

                            ARecurringTransAnalAttribRow newAttrRow = FMainDS.ARecurringTransAnalAttrib.NewRowTyped(true);

                            newAttrRow.ItemArray = attrRowCurrent.ItemArray;

                            //reduce journal number by 1
                            newAttrRow.JournalNumber--;

                            FMainDS.ARecurringTransAnalAttrib.Rows.Add(newAttrRow);

                            attrRowCurrent.Delete();
                        }
                    }

                    transRowCurrent.Delete();
                }

                jrnlRowCurrent.Delete();
            }

            if (JournalsRenumbered)
            {
                FPetraUtilsObject.SetChangedFlag();
            }

            //Need to refresh FPreviouslySelectedDetailRow else it points to a deleted row
            SelectRowInGrid(grdDetails.GetFirstHighlightedRowIndex());
        }
Ejemplo n.º 19
0
        private static bool UpdateRecurringJournalTotals(ref GLBatchTDS AMainDS,
                                                         ref GLBatchTDSARecurringJournalRow ACurrentJournal)
        {
            #region Validate Arguments

            if (AMainDS == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString("Function:{0} - The GL Batch dataset is null!"),
                                                                                     Utilities.GetMethodName(true)));
            }
            else if (ACurrentJournal == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString(
                                                                                         "Function:{0} - The Recurring Journal row does not exist or is empty!"),
                                                                                     Utilities.GetMethodName(true)));
            }

            #endregion Validate Arguments

            bool AmountsUpdated = false;

            decimal JournalDebitTotal      = 0.0M;
            decimal JournalDebitTotalBase  = 0.0M;
            decimal JournalCreditTotal     = 0.0M;
            decimal JournalCreditTotalBase = 0.0M;

            if (ACurrentJournal.IsJournalDebitTotalBaseNull()) //DBNull.Value.Equals(ACurrentJournal[GLBatchTDSARecurringJournalTable.ColumnJournalDebitTotalBaseId])
            {
                ACurrentJournal.JournalDebitTotalBase = 0;
                AmountsUpdated = true;
            }

            if (ACurrentJournal.IsJournalCreditTotalBaseNull()) //DBNull.Value.Equals(ACurrentJournal[GLBatchTDSARecurringJournalTable.ColumnJournalCreditTotalBaseId])
            {
                ACurrentJournal.JournalCreditTotalBase = 0;
                AmountsUpdated = true;
            }

            DataView TransDV = new DataView(AMainDS.ARecurringTransaction);
            TransDV.RowFilter = String.Format("{0}={1} And {2}={3}",
                                              ARecurringTransactionTable.GetBatchNumberDBName(),
                                              ACurrentJournal.BatchNumber,
                                              ARecurringTransactionTable.GetJournalNumberDBName(),
                                              ACurrentJournal.JournalNumber);

            if ((TransDV.Count == 0) && (ACurrentJournal.LastTransactionNumber > 0))
            {
                //do not update totals as no transactions loaded as yet so no need to update journal total
                return(AmountsUpdated);
            }

            // transactions are filtered for this journal; add up the total amounts
            foreach (DataRowView drv in TransDV)
            {
                ARecurringTransactionRow transRow = (ARecurringTransactionRow)drv.Row;

                if (transRow.DebitCreditIndicator)
                {
                    JournalDebitTotal     += transRow.TransactionAmount;
                    JournalDebitTotalBase += transRow.AmountInBaseCurrency;
                }
                else
                {
                    JournalCreditTotal     += transRow.TransactionAmount;
                    JournalCreditTotalBase += transRow.AmountInBaseCurrency;
                }
            }

            if ((ACurrentJournal.JournalDebitTotal != JournalDebitTotal) ||
                (ACurrentJournal.JournalDebitTotalBase != JournalDebitTotalBase) ||
                (ACurrentJournal.JournalCreditTotal != JournalCreditTotal) ||
                (ACurrentJournal.JournalCreditTotalBase != JournalCreditTotalBase))
            {
                ACurrentJournal.JournalDebitTotal      = JournalDebitTotal;
                ACurrentJournal.JournalDebitTotalBase  = JournalDebitTotalBase;
                ACurrentJournal.JournalCreditTotal     = JournalCreditTotal;
                ACurrentJournal.JournalCreditTotalBase = JournalCreditTotalBase;
                AmountsUpdated = true;
            }

            return(AmountsUpdated);
        }