Пример #1
0
 void WriteBatchLine(ABatchRow batch)
 {
     WriteStringQuoted("B");
     WriteStringQuoted(batch.BatchDescription);
     WriteCurrency(batch.BatchControlTotal);
     WriteDate(batch.DateEffective, true);
 }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ACurrentBatchRow"></param>
        /// <returns></returns>
        public Boolean BatchIsAutoGenerated(ABatchRow ACurrentBatchRow)
        {
            Boolean  containsSystemGenerated = false;
            DataView transactionView         = new DataView(FMainDS.ATransaction);

            transactionView.RowFilter = "a_batch_number_i=" + ACurrentBatchRow.BatchNumber;

            if (transactionView.Count == 0)
            {
                LoadJournals(ACurrentBatchRow);
            }

            foreach (DataRowView rv in transactionView)
            {
                if (((ATransactionRow)rv.Row).SystemGenerated)
                {
                    containsSystemGenerated = true;
                }

                break; // In practice, Batches are always EITHER SystemGenerated, or not.
                       // I only need to look at the first transaction in the batch, to see if it's SystemGenerated.
            }

            return(containsSystemGenerated);
        }
Пример #3
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 UpdateTotalsOfBatch(ref GLBatchTDS AMainDS,
                                               ABatchRow ACurrentBatch)
        {
            decimal BatchDebitTotal  = 0.0m;
            decimal BatchCreditTotal = 0.0m;

            DataView jnlDataView = new DataView(AMainDS.AJournal);

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

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

                UpdateTotalsOfJournal(ref AMainDS, ref journalRow);

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

            if ((ACurrentBatch.BatchDebitTotal != BatchDebitTotal) ||
                (ACurrentBatch.BatchCreditTotal != BatchCreditTotal))
            {
                ACurrentBatch.BatchDebitTotal  = BatchDebitTotal;
                ACurrentBatch.BatchCreditTotal = BatchCreditTotal;
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        private void ValidateDataDetailsManual(ABatchRow ARow)
        {
            if ((ARow == null) || (ARow.BatchStatus != MFinanceConstants.BATCH_UNPOSTED))
            {
                return;
            }

            TVerificationResultCollection VerificationResultCollection = FPetraUtilsObject.VerificationResultCollection;

            ParseHashTotal(ARow);

            TSharedFinanceValidation_GL.ValidateGLBatchManual(this, ARow, ref VerificationResultCollection,
                                                              FValidationControlsDict, FStartDateCurrentPeriod, FEndDateLastForwardingPeriod);

            //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 (txtDetailBatchDescription.Text.Length == 0)
            {
                DataColumn          ValidationColumn;
                TVerificationResult VerificationResult = null;
                object ValidationContext;

                ValidationColumn  = ARow.Table.Columns[ABatchTable.ColumnBatchDescriptionId];
                ValidationContext = String.Format("Batch number {0}",
                                                  ARow.BatchNumber);

                VerificationResult = TStringChecks.StringMustNotBeEmpty(ARow.BatchDescription,
                                                                        "Description of " + ValidationContext,
                                                                        this, ValidationColumn, null);

                // Handle addition/removal to/from TVerificationResultCollection
                VerificationResultCollection.Auto_Add_Or_AddOrRemove(this, VerificationResult, ValidationColumn, true);
            }
        }
Пример #6
0
        private void ShowDetailsManual(ABatchRow ARow)
        {
            AutoEnableTransTabForBatch();
            grdDetails.TabStop = (ARow != null);

            if (ARow == null)
            {
                pnlDetails.Enabled = false;
                ((TFrmGLBatch)this.ParentForm).DisableJournals();
                ((TFrmGLBatch)this.ParentForm).DisableTransactions();
                EnableButtonControl(false);
                ClearDetailControls();
                return;
            }

            FPetraUtilsObject.DetailProtectedMode =
                (ARow.BatchStatus.Equals(MFinanceConstants.BATCH_POSTED) ||
                 ARow.BatchStatus.Equals(MFinanceConstants.BATCH_CANCELLED));

            FCurrentEffectiveDate = ARow.DateEffective;

            UpdateBatchPeriod(null, null);

            UpdateChangeableStatus();
            ((TFrmGLBatch)this.ParentForm).EnableJournals();
        }
Пример #7
0
        private int GetDataTableRowIndexByPrimaryKeys(int ALedgerNumber, int ABatchNumber)
        {
            int  rowPos     = 0;
            bool batchFound = false;

            foreach (DataRowView rowView in FMainDS.ABatch.DefaultView)
            {
                ABatchRow row = (ABatchRow)rowView.Row;

                if ((row.LedgerNumber == ALedgerNumber) && (row.BatchNumber == ABatchNumber))
                {
                    batchFound = true;
                    break;
                }

                rowPos++;
            }

            if (!batchFound)
            {
                rowPos = 0;
            }

            //remember grid is out of sync with DataView by 1 because of grid header rows
            return(rowPos + 1);
        }
Пример #8
0
        /// <summary>
        /// Update the dictionary that stores all unposted batches
        ///  and whether or not they have been warned about inactive
        ///   fields
        /// </summary>
        /// <param name="ABatchNumberToExclude"></param>
        public void UpdateUnpostedBatchDictionary(int ABatchNumberToExclude = 0)
        {
            if (ABatchNumberToExclude > 0)
            {
                FUnpostedBatchesVerifiedOnSavingDict.Remove(ABatchNumberToExclude);
            }

            DataView BatchDV = new DataView(FMainDS.ABatch);

            //Just want unposted batches
            BatchDV.RowFilter = string.Format("{0}='{1}'",
                                              ABatchTable.GetBatchStatusDBName(),
                                              MFinanceConstants.BATCH_UNPOSTED);

            foreach (DataRowView bRV in BatchDV)
            {
                ABatchRow br = (ABatchRow)bRV.Row;

                int currentBatch = br.BatchNumber;

                if ((currentBatch != ABatchNumberToExclude) && !FUnpostedBatchesVerifiedOnSavingDict.ContainsKey(currentBatch))
                {
                    FUnpostedBatchesVerifiedOnSavingDict.Add(br.BatchNumber, false);
                }
            }
        }
Пример #9
0
        /// <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();
        }
Пример #10
0
        /// <summary>
        /// Validates the GL Batch 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="AStartDateCurrentPeriod">If the caller knows this value it can be supplied. Otherwise the server will supply the value for the ledger.</param>
        /// <param name="AEndDateLastForwardingPeriod">If the caller knows this value it can be supplied. Otherwise the server will supply the value for the ledger.</param>
        /// <returns>True if the validation found no data validation errors, otherwise false.</returns>
        public static bool ValidateGLBatchManual(object AContext, ABatchRow ARow,
            ref TVerificationResultCollection AVerificationResultCollection, TValidationControlsDict AValidationControlsDict,
            DateTime? AStartDateCurrentPeriod = null, DateTime? AEndDateLastForwardingPeriod = null)
        {
            DataColumn ValidationColumn;
            TValidationControlsData ValidationControlsData;
            TScreenVerificationResult VerificationResult;
            object ValidationContext;
            int VerifResultCollAddedCount = 0;

            // Don't validate deleted or posted DataRows
            if ((ARow.RowState == DataRowState.Deleted) || (ARow.BatchStatus == MFinanceConstants.BATCH_POSTED)
                || (ARow.BatchStatus == MFinanceConstants.BATCH_CANCELLED))
            {
                return true;
            }

            bool isImporting = AContext.ToString().Contains("Importing");

            // 'Effective From Date' must be valid
            ValidationColumn = ARow.Table.Columns[ABatchTable.ColumnDateEffectiveId];
            ValidationContext = ARow.BatchNumber;

            DateTime StartDateCurrentPeriod;
            DateTime EndDateLastForwardingPeriod;

            if ((AStartDateCurrentPeriod == null) || (AEndDateLastForwardingPeriod == null))
            {
                TSharedFinanceValidationHelper.GetValidPostingDateRange(ARow.LedgerNumber,
                    out StartDateCurrentPeriod,
                    out EndDateLastForwardingPeriod);
            }
            else
            {
                StartDateCurrentPeriod = AStartDateCurrentPeriod.Value;
                EndDateLastForwardingPeriod = AEndDateLastForwardingPeriod.Value;
            }

            if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData))
            {
                VerificationResult = (TScreenVerificationResult)TDateChecks.IsDateBetweenDates(ARow.DateEffective,
                    StartDateCurrentPeriod,
                    EndDateLastForwardingPeriod,
                    ValidationControlsData.ValidationControlLabel + (isImporting ? String.Empty : " of Batch Number " + ValidationContext.ToString()),
                    TDateBetweenDatesCheckType.dbdctUnspecific,
                    TDateBetweenDatesCheckType.dbdctUnspecific,
                    AContext,
                    ValidationColumn,
                    ValidationControlsData.ValidationControl);

                // Handle addition/removal to/from TVerificationResultCollection
                if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn, true))
                {
                    VerifResultCollAddedCount++;
                }
            }

            return VerifResultCollAddedCount == 0;
        }
Пример #11
0
        /// <summary>
        /// Validates the GL Batch 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="AStartDateCurrentPeriod">If the caller knows this value it can be supplied. Otherwise the server will supply the value for the ledger.</param>
        /// <param name="AEndDateLastForwardingPeriod">If the caller knows this value it can be supplied. Otherwise the server will supply the value for the ledger.</param>
        /// <returns>True if the validation found no data validation errors, otherwise false.</returns>
        public static bool ValidateGLBatchManual(object AContext, ABatchRow ARow,
                                                 ref TVerificationResultCollection AVerificationResultCollection, TValidationControlsDict AValidationControlsDict,
                                                 DateTime?AStartDateCurrentPeriod = null, DateTime?AEndDateLastForwardingPeriod = null)
        {
            DataColumn ValidationColumn;
            TValidationControlsData   ValidationControlsData;
            TScreenVerificationResult VerificationResult;
            object ValidationContext;
            int    VerifResultCollAddedCount = 0;

            // Don't validate deleted or posted DataRows
            if ((ARow.RowState == DataRowState.Deleted) || (ARow.BatchStatus == MFinanceConstants.BATCH_POSTED))
            {
                return(true);
            }

            bool isImporting = AContext.ToString().Contains("Importing");

            // 'Effective From Date' must be valid
            ValidationColumn  = ARow.Table.Columns[ABatchTable.ColumnDateEffectiveId];
            ValidationContext = ARow.BatchNumber;

            DateTime StartDateCurrentPeriod;
            DateTime EndDateLastForwardingPeriod;

            if ((AStartDateCurrentPeriod == null) || (AEndDateLastForwardingPeriod == null))
            {
                TSharedFinanceValidationHelper.GetValidPostingDateRange(ARow.LedgerNumber,
                                                                        out StartDateCurrentPeriod,
                                                                        out EndDateLastForwardingPeriod);
            }
            else
            {
                StartDateCurrentPeriod      = AStartDateCurrentPeriod.Value;
                EndDateLastForwardingPeriod = AEndDateLastForwardingPeriod.Value;
            }

            if (AValidationControlsDict.TryGetValue(ValidationColumn, out ValidationControlsData))
            {
                VerificationResult = (TScreenVerificationResult)TDateChecks.IsDateBetweenDates(ARow.DateEffective,
                                                                                               StartDateCurrentPeriod,
                                                                                               EndDateLastForwardingPeriod,
                                                                                               ValidationControlsData.ValidationControlLabel + (isImporting ? String.Empty : " of Batch Number " + ValidationContext.ToString()),
                                                                                               TDateBetweenDatesCheckType.dbdctUnspecific,
                                                                                               TDateBetweenDatesCheckType.dbdctUnspecific,
                                                                                               AContext,
                                                                                               ValidationColumn,
                                                                                               ValidationControlsData.ValidationControl);

                // Handle addition/removal to/from TVerificationResultCollection
                if (AVerificationResultCollection.Auto_Add_Or_AddOrRemove(AContext, VerificationResult, ValidationColumn, true))
                {
                    VerifResultCollAddedCount++;
                }
            }

            return(VerifResultCollAddedCount == 0);
        }
Пример #12
0
        /// <summary>
        /// Reload batches after an import
        /// </summary>
        public void ReloadBatches(bool AIsFromMessage = false)
        {
            try
            {
                FPetraUtilsObject.GetForm().Cursor = Cursors.WaitCursor;

                if (!AIsFromMessage)
                {
                    // Before we re-load make a note of the 'last' batch number so we can work out which batches have been imported.
                    DataView dv = new DataView(FMainDS.ABatch, String.Empty, String.Format("{0} DESC",
                                                                                           ABatchTable.GetBatchNumberDBName()), DataViewRowState.CurrentRows);
                    int lastBatchNumber = (dv.Count == 0) ? 0 : ((ABatchRow)dv[0].Row).BatchNumber;

                    // Merge the new batches into our data set
                    FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadABatch(FLedgerNumber, FCurrentLedgerYear, 0));

                    // Go round each imported batch loading its journals
                    // Start with the highest batch number and continue until we reach the 'old' last batch
                    for (int i = 0; i < dv.Count; i++)
                    {
                        ABatchRow batchRow    = (ABatchRow)dv[i].Row;
                        int       batchNumber = batchRow.BatchNumber;

                        if (batchNumber <= lastBatchNumber)
                        {
                            break;
                        }

                        batchRow.SetModified();

                        FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadAJournalAndRelatedTablesForBatch(FLedgerNumber, batchNumber));
                    }

                    EnsureNewBatchIsVisible();
                }
                else
                {
                    if (FPetraUtilsObject.HasChanges && !((TFrmGLBatch)ParentForm).SaveChanges())
                    {
                        string msg = String.Format(Catalog.GetString("A validation error has occured on the GL Batches" +
                                                                     " form while trying to refresh.{0}{0}" +
                                                                     "You will need to close and reopen the GL Batches form to see the new batch" +
                                                                     " after you have fixed the validation error."),
                                                   Environment.NewLine);

                        MessageBox.Show(msg, "Refresh GL Batches");
                        return;
                    }

                    FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadABatch(FLedgerNumber, FCurrentLedgerYear, 0));
                    grdDetails.SelectRowInGrid(1);
                }
            }
            finally
            {
                FPetraUtilsObject.GetForm().Cursor = Cursors.Default;
            }
        }
Пример #13
0
 private void TCommonAccountingTool_(string ABatchDescription)
 {
     FBatchTDS                  = TGLPosting.CreateABatch(FLedgerInfo.LedgerNumber);
     FBaseCurrencyInfo          = new TCurrencyInfo(FLedgerInfo.BaseCurrency);
     FBatchRow                  = FBatchTDS.ABatch[0];
     FBatchRow.BatchDescription = ABatchDescription;
     FBatchRow.BatchStatus      = MFinanceConstants.BATCH_UNPOSTED;
     FBatchNumber               = FBatchRow.BatchNumber;
     FJournalCount              = 0;
     blnReadyForTransaction     = false;
     blnInitBatchDate           = true;
 }
Пример #14
0
        /// <summary>
        /// Print out the selected batch using FastReports template.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FilePrint(object sender, EventArgs e)
        {
            if (!this.tpgJournals.Enabled)
            {
                MessageBox.Show(Catalog.GetString("No Batch is selected"), Catalog.GetString("Batch Posting Register"),
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            ABatchRow BatchRow = ucoBatches.GetSelectedDetailRow();

            PrintPostingRegister(FLedgerNumber, BatchRow.BatchNumber, ModifierKeys.HasFlag(Keys.Control));
        }
Пример #15
0
        /// <summary>
        /// Uses the current Batch effective date to return the
        ///   corporate exchange rate value
        /// </summary>
        /// <returns></returns>
        public decimal GetInternationalCurrencyExchangeRate()
        {
            string NotUsed = string.Empty;

            ABatchRow BatchRow = ucoBatches.GetSelectedDetailRow();

            if (BatchRow == null)
            {
                return(0);
            }

            return(GetInternationalCurrencyExchangeRate(BatchRow.DateEffective, out NotUsed));
        }
Пример #16
0
        /// <summary>
        /// Uses the current Batch effective date to return the
        ///   corporate exchange rate value
        /// </summary>
        /// <returns></returns>
        public decimal GetInternationalCurrencyExchangeRate()
        {
            decimal IntlToBaseCurrencyExchRate = 0;

            ABatchRow BatchRow = ucoBatches.GetSelectedDetailRow();

            if (BatchRow == null)
            {
                return(IntlToBaseCurrencyExchRate);
            }

            return(GetInternationalCurrencyExchangeRate(BatchRow.DateEffective));
        }
Пример #17
0
        /// <summary>
        /// Re-show the specified row
        /// </summary>
        /// <param name="AModifiedBatchRow"></param>
        /// <param name="ARedisplay"></param>
        public void UndoModifiedBatchRow(ABatchRow AModifiedBatchRow, bool ARedisplay)
        {
            //Check if new row or not
            if (AModifiedBatchRow.RowState == DataRowState.Added)
            {
                return;
            }

            AModifiedBatchRow.RejectChanges();

            if (ARedisplay)
            {
                ShowDetails(AModifiedBatchRow);
            }
        }
Пример #18
0
        /// <summary>
        /// Print out the selected batch using FastReports template.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FilePrint(object sender, EventArgs e)
        {
            if (!this.tpgJournals.Enabled)
            {
                MessageBox.Show(Catalog.GetString("No Batch is selected"), Catalog.GetString("Batch Posting Register"),
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            ABatchRow BatchRow = ucoBatches.GetSelectedDetailRow();

            TFrmBatchPostingRegister ReportGui = new TFrmBatchPostingRegister(this);

//          ReportGui.PrintReportNoUi(FLedgerNumber, BatchRow.BatchNumber); // This alternative doesn't show the UI

            ReportGui.LedgerNumber = FLedgerNumber;
            ReportGui.BatchNumber  = BatchRow.BatchNumber;
            ReportGui.Show();
        }
Пример #19
0
        private void ParseHashTotal(ABatchRow ARow)
        {
            if (ARow.BatchStatus != MFinanceConstants.BATCH_UNPOSTED)
            {
                return;
            }

            if ((txtDetailBatchControlTotal.NumberValueDecimal == null) || !txtDetailBatchControlTotal.NumberValueDecimal.HasValue)
            {
                bool prev = FPetraUtilsObject.SuppressChangeDetection;
                FPetraUtilsObject.SuppressChangeDetection     = true;
                txtDetailBatchControlTotal.NumberValueDecimal = 0m;
                FPetraUtilsObject.SuppressChangeDetection     = prev;
            }

            if (ARow.BatchControlTotal != txtDetailBatchControlTotal.NumberValueDecimal.Value)
            {
                ARow.BatchControlTotal = txtDetailBatchControlTotal.NumberValueDecimal.Value;
            }
        }
Пример #20
0
        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);
        }
Пример #21
0
        /// <summary>
        /// Calculate the base amount for the transactions, and update the totals for the journals and the current batch
        ///   Assumes that all transactions for the journal are already loaded.
        /// </summary>
        /// <param name="AMainDS"></param>
        /// <param name="ACurrentBatch"></param>
        /// <param name="ACurrentJournal"></param>
        public static void UpdateTotalsOfBatchForJournal(ref GLBatchTDS AMainDS,
                                                         ABatchRow ACurrentBatch, GLBatchTDSAJournalRow ACurrentJournal)
        {
            //Save current values
            decimal JournalDebitTotal  = ACurrentJournal.JournalDebitTotal;
            decimal JournalCreditTotal = ACurrentJournal.JournalCreditTotal;

            bool JournalUpdated;

            UpdateTotalsOfJournal(ref AMainDS, ref ACurrentJournal, out JournalUpdated);

            if (JournalUpdated)
            {
                //Subtract old amounts
                ACurrentBatch.BatchDebitTotal  -= JournalDebitTotal;
                ACurrentBatch.BatchCreditTotal -= JournalCreditTotal;
                //Add updated Journals amounts
                ACurrentBatch.BatchDebitTotal  += ACurrentJournal.JournalDebitTotal;
                ACurrentBatch.BatchCreditTotal += ACurrentJournal.JournalCreditTotal;
            }
        }
Пример #22
0
        private void ParseHashTotal(ABatchRow ARow)
        {
            decimal CorrectHashValue = 0m;

            if (ARow.BatchStatus != MFinanceConstants.BATCH_UNPOSTED)
            {
                return;
            }

            if ((txtDetailBatchControlTotal.NumberValueDecimal == null) || !txtDetailBatchControlTotal.NumberValueDecimal.HasValue)
            {
                CorrectHashValue = 0m;
            }
            else
            {
                CorrectHashValue = txtDetailBatchControlTotal.NumberValueDecimal.Value;
            }

            // AlanP: is this another case of needing to check for a real change??
            txtDetailBatchControlTotal.NumberValueDecimal = CorrectHashValue;
            ARow.BatchControlTotal = CorrectHashValue;
        }
Пример #23
0
        private void InitBatchAndJournal(decimal AExchangeRate, string ACurrencyCode)
        {
            F_GLDataset = TGLPosting.CreateABatch(F_LedgerNum, false, true);
            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);
        }
Пример #24
0
 private void TCommonAccountingTool_(string ABatchDescription)
 {
     FBatchTDS = TGLPosting.CreateABatch(FLedgerInfo.LedgerNumber);
     FBaseCurrencyInfo = new TCurrencyInfo(FLedgerInfo.BaseCurrency);
     FBatchRow = FBatchTDS.ABatch[0];
     FBatchRow.BatchDescription = ABatchDescription;
     FBatchRow.BatchStatus = MFinanceConstants.BATCH_UNPOSTED;
     FBatchNumber = FBatchRow.BatchNumber;
     FJournalCount = 0;
     blnReadyForTransaction = false;
     blnInitBatchDate = true;
 }
Пример #25
0
        /// <summary>
        /// mark each journal, each transaction as being posted;
        /// add sums for costcentre/account combinations
        /// </summary>
        /// <param name="MainDS">can contain several batches and journals and transactions</param>
        /// <param name="APostingDS"></param>
        /// <param name="APostingLevel">the balance changes at the posting level</param>
        /// <param name="ABatchToPost">the batch to post</param>
        /// <returns>a list with the sums for each costcentre/account combination</returns>
        private static SortedList <string, TAmount>MarkAsPostedAndCollectData(GLBatchTDS MainDS,
            GLPostingTDS APostingDS,
            SortedList <string, TAmount>APostingLevel, ABatchRow ABatchToPost)
        {
            DataView myView = new DataView(MainDS.ATransaction);

            myView.Sort = ATransactionTable.GetJournalNumberDBName();

            foreach (AJournalRow journal in MainDS.AJournal.Rows)
            {
                if (journal.BatchNumber != ABatchToPost.BatchNumber)
                {
                    continue;
                }

                foreach (DataRowView transactionview in myView.FindRows(journal.JournalNumber))
                {
                    ATransactionRow transaction = (ATransactionRow)transactionview.Row;

                    if (transaction.BatchNumber != ABatchToPost.BatchNumber)
                    {
                        continue;
                    }

                    transaction.TransactionStatus = true;

                    // get the account that this transaction is writing to
                    AAccountRow Account = (AAccountRow)APostingDS.AAccount.Rows.Find(new object[] { transaction.LedgerNumber, transaction.AccountCode });

                    // Set the sign of the amounts according to the debit/credit indicator
                    decimal SignBaseAmount = transaction.AmountInBaseCurrency;
                    decimal SignTransAmount = transaction.TransactionAmount;

                    if (Account.DebitCreditIndicator != transaction.DebitCreditIndicator)
                    {
                        SignBaseAmount *= -1.0M;
                        SignTransAmount *= -1.0M;
                    }

                    // TODO: do we need to check for base currency corrections?
                    // or do we get rid of these problems by not having international currency?

                    string key = TAmount.MakeKey(transaction.AccountCode, transaction.CostCentreCode);

                    if (!APostingLevel.ContainsKey(key))
                    {
                        APostingLevel.Add(key, new TAmount());
                    }

                    APostingLevel[key].baseAmount += SignBaseAmount;

                    // Only foreign currency accounts store a value in the transaction currency,
                    // if the transaction was actually in the foreign currency.

                    if (Account.ForeignCurrencyFlag && (journal.TransactionCurrency == Account.ForeignCurrencyCode))
                    {
                        APostingLevel[key].transAmount += SignTransAmount;
                    }
                }

                journal.JournalStatus = MFinanceConstants.BATCH_POSTED;
            }

            ABatchToPost.BatchStatus = MFinanceConstants.BATCH_POSTED;

            return APostingLevel;
        }
Пример #26
0
 /// <summary>
 /// Load Journals for current Batch
 /// </summary>
 /// <param name="ACurrentBatchRow"></param>
 public void LoadJournals(ABatchRow ACurrentBatchRow)
 {
     this.ucoJournals.LoadJournals(ACurrentBatchRow);
 }
        /// 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>
        /// Method to cancel a specified journal
        /// </summary>
        /// <param name="AJournalRowToCancel">The row to cancel</param>
        /// <returns>True if the journal is cancelled.</returns>
        public bool CancelRow(GLBatchTDSAJournalRow AJournalRowToCancel)
        {
            bool CancellationSuccessful = false;

            if ((AJournalRowToCancel == null) || (AJournalRowToCancel.JournalStatus != MFinanceConstants.BATCH_UNPOSTED))
            {
                return(false);
            }

            int  CurrentBatchNo   = AJournalRowToCancel.BatchNumber;
            int  CurrentJournalNo = AJournalRowToCancel.JournalNumber;
            bool CurrentJournalTransactionsLoadedAndCurrent = false;

            string CancelMessage     = string.Empty;
            string CompletionMessage = string.Empty;

            CancelMessage = String.Format(Catalog.GetString("Are you sure you want to cancel GL Journal {0} in Batch {1}?"),
                                          CurrentJournalNo,
                                          CurrentBatchNo);

            if ((MessageBox.Show(CancelMessage,
                                 Catalog.GetString("Confirm Cancel"),
                                 MessageBoxButtons.YesNo,
                                 MessageBoxIcon.Question,
                                 MessageBoxDefaultButton.Button2) != System.Windows.Forms.DialogResult.Yes))
            {
                return(false);
            }

            //Backup the Dataset for reversion purposes
            GLBatchTDS BackupMainDS = null;

            try
            {
                FMyForm.Cursor = Cursors.WaitCursor;

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

                //Don't run an inactive fields check on this batch
                FMyForm.GetBatchControl().UpdateUnpostedBatchDictionary(CurrentBatchNo);

                //Check if current batch details are currently loaded
                CurrentJournalTransactionsLoadedAndCurrent = (FMyForm.GetTransactionsControl().FBatchNumber == CurrentBatchNo);

                //Save and check for inactive values in other unsaved Batches
                FPetraUtilsObject.SetChangedFlag();

                if (!FMyForm.SaveChangesManual(FMyForm.FCurrentGLBatchAction, false, !CurrentJournalTransactionsLoadedAndCurrent))
                {
                    FMyForm.GetBatchControl().UpdateUnpostedBatchDictionary();

                    CompletionMessage = String.Format(Catalog.GetString("Journal {0} in GL Batch {1} has not been cancelled."),
                                                      CurrentJournalNo,
                                                      CurrentBatchNo);

                    MessageBox.Show(CompletionMessage,
                                    Catalog.GetString("GL Journal Cancellation"),
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);

                    return(false);
                }

                //Remove any changes, which may cause validation issues, before cancelling
                FMyForm.GetJournalsControl().PrepareJournalDataForCancelling(CurrentBatchNo, CurrentJournalNo, true);

                if (CurrentJournalTransactionsLoadedAndCurrent)
                {
                    //Clear any transactions currently being edited in the Transaction Tab
                    FMyForm.GetTransactionsControl().ClearCurrentSelection(CurrentBatchNo);
                }

                //Delete transactions and attributes for current jouernal only
                FMyForm.GetTransactionsControl().DeleteTransactionData(CurrentBatchNo, CurrentJournalNo);

                //Edit current Journal
                decimal journalCreditTotal = AJournalRowToCancel.JournalCreditTotal;
                decimal journalDebitTotal  = AJournalRowToCancel.JournalDebitTotal;
                AJournalRowToCancel.BeginEdit();
                AJournalRowToCancel.JournalStatus         = MFinanceConstants.BATCH_CANCELLED;
                AJournalRowToCancel.LastTransactionNumber = 0;
                AJournalRowToCancel.JournalCreditTotal    = 0;
                AJournalRowToCancel.JournalDebitTotal     = 0;
                AJournalRowToCancel.EndEdit();

                //Edit current Batch
                ABatchRow CurrentBatchRow   = FMyForm.GetBatchControl().GetSelectedDetailRow();
                decimal   batchControlTotal = CurrentBatchRow.BatchControlTotal;
                CurrentBatchRow.BeginEdit();
                CurrentBatchRow.BatchCreditTotal  -= journalCreditTotal;
                CurrentBatchRow.BatchDebitTotal   -= journalDebitTotal;
                CurrentBatchRow.BatchControlTotal -= (batchControlTotal != 0 ? journalCreditTotal : 0);
                CurrentBatchRow.EndEdit();

                FPetraUtilsObject.SetChangedFlag();
                FMyForm.SaveChangesManual();

                CompletionMessage = String.Format(Catalog.GetString("Journal no.: {0} cancelled successfully."),
                                                  CurrentJournalNo);

                MessageBox.Show(CompletionMessage,
                                Catalog.GetString("Journal Cancelled"),
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);

                FMyForm.DisableTransactions();

                CancellationSuccessful = true;
            }
            catch (Exception ex)
            {
                //Revert to previous state
                if (BackupMainDS != null)
                {
                    FMainDS.RejectChanges();
                    FMainDS.Merge(BackupMainDS);

                    FMyForm.GetJournalsControl().ShowDetailsRefresh();
                }

                TLogging.LogException(ex, Utilities.GetMethodSignature());
                throw;
            }
            finally
            {
                FMyForm.Cursor = Cursors.Default;
            }

            return(CancellationSuccessful);
        }
        /// <summary>
        /// Method to cancel a specified batch
        /// </summary>
        /// <param name="ACurrentBatchRow">The row to cancel</param>
        /// <param name="ABatchDescriptionTextBox">Pass a reference to a TextBox that is used to display the batch description text.  This is required
        /// to ensure that validation passes when the cancelled batch is saved.</param>
        /// <returns></returns>
        public bool CancelBatch(ABatchRow ACurrentBatchRow, TextBox ABatchDescriptionTextBox)
        {
            if ((ACurrentBatchRow == null) || !FMyForm.SaveChanges())
            {
                return false;
            }

            int CurrentBatchNumber = ACurrentBatchRow.BatchNumber;

            if ((MessageBox.Show(String.Format(Catalog.GetString("You have chosen to cancel this batch ({0}).\n\nDo you really want to cancel it?"),
                         CurrentBatchNumber),
                     Catalog.GetString("Confirm Cancel"),
                     MessageBoxButtons.YesNo,
                     MessageBoxIcon.Question,
                     MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes))
            {
                try
                {
                    //clear any transactions currently being editied in the Transaction Tab
                    FMyForm.GetTransactionsControl().ClearCurrentSelection();
                    //clear any journals currently being editied in the Journals Tab
                    FMyForm.GetJournalsControl().ClearCurrentSelection();

                    //Clear Journals etc for current Batch
                    FMainDS.ATransAnalAttrib.Clear();
                    FMainDS.ATransaction.Clear();
                    FMainDS.AJournal.Clear();

                    //Load tables afresh
                    FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadAJournal(FLedgerNumber, CurrentBatchNumber));
                    FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadATransactionForBatch(FLedgerNumber, CurrentBatchNumber));
                    FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadATransAnalAttribForBatch(FLedgerNumber, CurrentBatchNumber));

                    //Delete transactions
                    for (int i = FMainDS.ATransAnalAttrib.Count - 1; i >= 0; i--)
                    {
                        FMainDS.ATransAnalAttrib[i].Delete();
                    }

                    for (int i = FMainDS.ATransaction.Count - 1; i >= 0; i--)
                    {
                        FMainDS.ATransaction[i].Delete();
                    }

                    //Update Journal totals and status
                    foreach (AJournalRow journal in FMainDS.AJournal.Rows)
                    {
                        if (journal.BatchNumber == CurrentBatchNumber)
                        {
                            journal.BeginEdit();
                            journal.JournalStatus = MFinanceConstants.BATCH_CANCELLED;
                            journal.JournalCreditTotal = 0;
                            journal.JournalDebitTotal = 0;
                            journal.EndEdit();
                        }
                    }

                    // Edit the batch row
                    ACurrentBatchRow.BeginEdit();

                    //Ensure validation passes
                    if (ACurrentBatchRow.BatchDescription.Length == 0)
                    {
                        ABatchDescriptionTextBox.Text = " ";
                    }

                    ACurrentBatchRow.BatchCreditTotal = 0;
                    ACurrentBatchRow.BatchDebitTotal = 0;
                    ACurrentBatchRow.BatchControlTotal = 0;
                    ACurrentBatchRow.BatchStatus = MFinanceConstants.BATCH_CANCELLED;

                    ACurrentBatchRow.EndEdit();

                    FPetraUtilsObject.SetChangedFlag();

                    //Need to call save
                    if (FMyForm.SaveChanges())
                    {
                        MessageBox.Show(Catalog.GetString("The batch has been cancelled successfully!"),
                            Catalog.GetString("Success"),
                            MessageBoxButtons.OK, MessageBoxIcon.Information);

                        return true;
                    }
                    else
                    {
                        // saving failed, therefore do not try to post
                        MessageBox.Show(Catalog.GetString(
                                "The batch has been cancelled but there were problems during saving; ") + Environment.NewLine +
                            Catalog.GetString("Please try and save the cancellation immediately."),
                            Catalog.GetString("Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

            return false;
        }
        /// <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>
        /// <param name="ABatchStatus"></param>
        /// <param name="AJournalStatus"></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,
            string ABatchStatus = MFinanceConstants.BATCH_UNPOSTED,
            string AJournalStatus = MFinanceConstants.BATCH_UNPOSTED)
        {
            TFrmStatusDialog dlgStatus = null;
            bool DifferentBatchSelected = false;

            FLoadCompleted = false;

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

            if ((FBatchRow == null) || (FJournalRow == null))
            {
                return false;
            }

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

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

            bool FirstRun = (FLedgerNumber != ALedgerNumber);
            bool BatchChanged = (FBatchNumber != ABatchNumber);
            bool BatchStatusChanged = (!BatchChanged && (FBatchStatus != ABatchStatus));
            bool JournalChanged = (BatchChanged || (FJournalNumber != AJournalNumber));
            bool JournalStatusChanged = (!JournalChanged && (FJournalStatus != AJournalStatus));
            bool CurrencyChanged = (FTransactionCurrency != ACurrencyCode);

            if (FirstRun)
            {
                FLedgerNumber = ALedgerNumber;
            }

            if (BatchChanged)
            {
                FBatchNumber = ABatchNumber;
            }

            if (BatchStatusChanged)
            {
                FBatchStatus = ABatchStatus;
            }

            if (JournalChanged)
            {
                FJournalNumber = AJournalNumber;
            }

            if (JournalStatusChanged)
            {
                FJournalStatus = AJournalStatus;
            }

            if (CurrencyChanged)
            {
                FTransactionCurrency = ACurrencyCode;
            }

            FIsUnposted = (FBatchRow.BatchStatus == MFinanceConstants.BATCH_UNPOSTED);

            if (FirstRun)
            {
                InitialiseControls();
            }

            try
            {
                this.Cursor = Cursors.WaitCursor;

                //Check if the same batch and journal is selected, so no need to apply filter
                if (!FirstRun
                    && !BatchChanged
                    && !JournalChanged
                    && !BatchStatusChanged
                    && !JournalStatusChanged
                    && !CurrencyChanged
                    && (FMainDS.ATransaction.DefaultView.Count > 0))
                {
                    //Same as previously selected batch and journal

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

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

                    if (FIsUnposted && (GetSelectedRowIndex() > 0))
                    {
                        if (AFromBatchTab)
                        {
                            SelectRowInGrid(GetSelectedRowIndex());
                        }
                        else
                        {
                            GetDetailsFromControls(FPreviouslySelectedDetailRow);
                        }
                    }

                    FLoadCompleted = true;

                    return false;
                }

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

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

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

                FLedgerNumber = ALedgerNumber;
                FBatchNumber = ABatchNumber;
                FJournalNumber = AJournalNumber;
                FTransactionNumber = -1;
                FTransactionCurrency = ACurrencyCode;
                FBatchStatus = ABatchStatus;
                FJournalStatus = AJournalStatus;

                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.SetTransAnalAttributeDefaultView(FMainDS);
                FMainDS.ATransAnalAttrib.DefaultView.AllowNew = false;

                //Load from server if necessary
                if (FMainDS.ATransaction.DefaultView.Count == 0)
                {
                    dlgStatus.CurrentStatus = Catalog.GetString("Requesting transactions from server...");
                    FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadATransactionATransAnalAttrib(ALedgerNumber, ABatchNumber, AJournalNumber));
                }
                else if (FMainDS.ATransAnalAttrib.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.LoadATransAnalAttribForJournal(ALedgerNumber, ABatchNumber, AJournalNumber));
                }

                FContainsSystemGenerated = false;

                // check if any of the rows are system generated (i.e. reversals)
                foreach (DataRowView rv in FMainDS.ATransaction.DefaultView)
                {
                    if (((ATransactionRow)rv.Row).SystemGenerated)
                    {
                        FContainsSystemGenerated = true;
                        break;
                    }
                }

                // 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.ATransaction.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(Catalog.GetString("Value"),
                        FMainDS.ATransAnalAttrib.Columns[ATransAnalAttribTable.GetAnalysisAttributeValueDBName()], 150,
                        FcmbAnalAttribValues);
                    FcmbAnalAttribValues.Control.SelectedValueChanged += new EventHandler(this.AnalysisAttributeValueChanged);

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

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

                // if this form is readonly or batch is posted, then we need all account and cost centre codes, because old codes might have been used
                bool ActiveOnly = false; //(this.Enabled && FIsUnposted && !FContainsSystemGenerated);

                if (requireControlSetup || (FActiveOnly != ActiveOnly))
                {
                    FActiveOnly = ActiveOnly;

                    //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, ActiveOnly, false, ACurrencyCode, true);
                    TFinanceControls.InitialiseCostCentreList(ref cmbDetailCostCentreCode, FLedgerNumber, true, false, ActiveOnly, false);
                    FPetraUtilsObject.SuppressChangeDetection = prevSuppressChangeDetection;

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

                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 (FIsUnposted && (grdDetails.Rows.Count > 1))
                {
                    string updatedTransactions = string.Empty;

                    dlgStatus.CurrentStatus = Catalog.GetString("Checking analysis attributes ...");
                    FAnalysisAttributesLogic.ReconcileTransAnalysisAttributes(FMainDS, FCacheDS, 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}Remeber to set their values before posting!"),
                                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;
        }
Пример #31
0
        /// <summary>
        /// Calculate the base amount for the transactions, and update the totals for the journals and the current batch
        ///   Assumes that all transactions for the journal are already loaded.
        /// </summary>
        /// <param name="AMainDS"></param>
        /// <param name="ACurrentBatch"></param>
        /// <param name="ACurrentJournal"></param>
        public static void UpdateTotalsOfBatchForJournal(ref GLBatchTDS AMainDS,
            ABatchRow ACurrentBatch, GLBatchTDSAJournalRow ACurrentJournal)
        {
            //Save current values
            decimal JournalDebitTotal = ACurrentJournal.JournalDebitTotal;
            decimal JournalCreditTotal = ACurrentJournal.JournalCreditTotal;

            bool JournalUpdated;

            UpdateTotalsOfJournal(ref AMainDS, ref ACurrentJournal, out JournalUpdated);

            if (JournalUpdated)
            {
                //Subtract old amounts
                ACurrentBatch.BatchDebitTotal -= JournalDebitTotal;
                ACurrentBatch.BatchCreditTotal -= JournalCreditTotal;
                //Add updated Journals amounts
                ACurrentBatch.BatchDebitTotal += ACurrentJournal.JournalDebitTotal;
                ACurrentBatch.BatchCreditTotal += ACurrentJournal.JournalCreditTotal;
            }
        }
Пример #32
0
        private static bool ValidateGLBatchJournalNumbering(ref GLBatchTDS AGLBatch,
            ref ABatchRow ABatchToPost,
            ref TVerificationResultCollection AVerifications)
        {
            #region Validate Arguments

            if ((AGLBatch.ABatch == null) || (AGLBatch.ABatch.Count == 0) || (ABatchToPost == null))
            {
                throw new EFinanceSystemDataTableReturnedNoDataException(String.Format(Catalog.GetString(
                            "Function:{0} - No GL Batch data is present!"),
                        Utilities.GetMethodName(true)));
            }

            #endregion Validate Arguments

            //Default to most likely outcome
            bool NumberingIsValid = true;

            string SQLStatement = string.Empty;
            string TempTableName = "TempCheckForConsecutiveJournals";

            //Parameters for SQL as strings
            string prmLedgerNumber = ABatchToPost.LedgerNumber.ToString();
            string prmBatchNumber = ABatchToPost.BatchNumber.ToString();

            //Tables with alias
            string BatchTableAlias = "b";
            string bBatchTable = ABatchTable.GetTableDBName() + " " + BatchTableAlias;
            string JournalTableAlias = "j";
            string jJournalTable = AJournalTable.GetTableDBName() + " " + JournalTableAlias;

            //Table: ABudgetTable and fields
            string bLedgerNumber = BatchTableAlias + "." + ABatchTable.GetLedgerNumberDBName();
            string bBatchNumber = BatchTableAlias + "." + ABatchTable.GetBatchNumberDBName();
            string bBatchNumberAlias = "BatchNumber";
            string bBatchLastJournal = BatchTableAlias + "." + ABatchTable.GetLastJournalDBName();
            string bBatchLastJournalAlias = "BatchLastJournal";
            string jLedgerNumber = JournalTableAlias + "." + AJournalTable.GetLedgerNumberDBName();
            string jBatchNumber = JournalTableAlias + "." + AJournalTable.GetBatchNumberDBName();
            string jJournalNumber = JournalTableAlias + "." + AJournalTable.GetJournalNumberDBName();
            string jFirstJournalAlias = "FirstJournal";
            string jLastJournalAlias = "LastJournal";
            string jCountJournalAlias = "CountJournal";

            try
            {
                DataTable tempTable = AGLBatch.Tables.Add(TempTableName);
                tempTable.Columns.Add(bBatchNumberAlias, typeof(Int32));
                tempTable.Columns.Add(bBatchLastJournalAlias, typeof(Int32));
                tempTable.Columns.Add(jFirstJournalAlias, typeof(Int32));
                tempTable.Columns.Add(jLastJournalAlias, typeof(Int32));
                tempTable.Columns.Add(jCountJournalAlias, typeof(Int32));

                SQLStatement = "SELECT " + bBatchNumber + " " + bBatchNumberAlias + "," +
                               "      MIN(" + bBatchLastJournal + ") " + bBatchLastJournalAlias + "," +
                               "      COALESCE(MIN(" + jJournalNumber + "), 0) " + jFirstJournalAlias + "," +
                               "      COALESCE(MAX(" + jJournalNumber + "), 0) " + jLastJournalAlias + "," +
                               "      Count(" + jJournalNumber + ") " + jCountJournalAlias +
                               " FROM " + bBatchTable + " LEFT OUTER JOIN " + jJournalTable +
                               "        ON " + bLedgerNumber + " = " + jLedgerNumber +
                               "         AND " + bBatchNumber + " = " + jBatchNumber +
                               " WHERE " + bLedgerNumber + " = " + prmLedgerNumber +
                               "   AND " + bBatchNumber + " = " + prmBatchNumber +
                               " GROUP BY " + bBatchNumber + ";";

                //Create temp table to check veracity of Journal numbering
                GLBatchTDS gLBatch = AGLBatch;
                TDBTransaction transaction = null;

                DBAccess.GDBAccessObj.GetNewOrExistingAutoReadTransaction(IsolationLevel.ReadCommitted,
                    TEnforceIsolationLevel.eilMinimum,
                    ref transaction,
                    delegate
                    {
                        DBAccess.GDBAccessObj.Select(gLBatch, SQLStatement, TempTableName, transaction);
                    });

                //As long as Batches exist, rows will be returned
                int numTempRows = AGLBatch.Tables[TempTableName].Rows.Count;

                DataView tempDV = new DataView(AGLBatch.Tables[TempTableName]);

                //Confirm are all equal and correct - the most common
                tempDV.RowFilter = string.Format("{0}={1} And {1}={2} And {0}={2} And (({2}>0 And {3}=1) Or ({2}=0 And {3}=0))",
                    bBatchLastJournalAlias,
                    jLastJournalAlias,
                    jCountJournalAlias,
                    jFirstJournalAlias);

                //If all records are correct, nothing to do
                if (tempDV.Count == numTempRows)
                {
                    return NumberingIsValid;
                }

                //!!Reaching this point means there are issues that need addressing.

                //Confirm that no negative numbers exist
                tempDV.RowFilter = string.Format("{0} < 0 Or {1} < 0",
                    bBatchLastJournalAlias,
                    jFirstJournalAlias);

                if (tempDV.Count > 0)
                {
                    string errMessage =
                        "The following Batches have a negative LastJournalNumber or have Journals with a negative JournalNumber!";

                    foreach (DataRowView drv in tempDV)
                    {
                        errMessage += string.Format("{0}Batch:{1}",
                            Environment.NewLine,
                            drv[bBatchNumberAlias]);
                    }

                    AVerifications.Add(new TVerificationResult(
                            String.Format(Catalog.GetString("Cannot post Batch {0} in Ledger {1}"), ABatchToPost.BatchNumber,
                                ABatchToPost.LedgerNumber),
                            errMessage,
                            TResultSeverity.Resv_Critical));

                    return false;
                }

                //Display non-sequential journals
                tempDV.RowFilter = string.Format("{2}>0 And ({3}<>1 Or {1}<>{2})",
                    bBatchLastJournalAlias,
                    jLastJournalAlias,
                    jCountJournalAlias,
                    jFirstJournalAlias);

                if (tempDV.Count > 0)
                {
                    string errMessage =
                        "The following Batches have gaps in their Journal numbering! You will need to cancel the Batch(es) and recreate:";

                    foreach (DataRowView drv in tempDV)
                    {
                        errMessage += string.Format("{0}Batch:{1}",
                            Environment.NewLine,
                            drv[bBatchNumberAlias]);
                    }

                    AVerifications.Add(new TVerificationResult(
                            String.Format(Catalog.GetString("Cannot post Batch {0} in Ledger {1}"), ABatchToPost.BatchNumber,
                                ABatchToPost.LedgerNumber),
                            errMessage,
                            TResultSeverity.Resv_Critical));

                    return false;
                }

                //The next most likely, is where the BatchLastJournal needs updating
                //Display mismatched journal last number
                tempDV.RowFilter = string.Format("{0}<>{1} And {1}={2} And (({2}>0 And {3}=1) Or ({2}=0 And {3}=0))",
                    bBatchLastJournalAlias,
                    jLastJournalAlias,
                    jCountJournalAlias,
                    jFirstJournalAlias);

                if (tempDV.Count > 0)
                {
                    ABatchToPost.LastJournal = Convert.ToInt32(tempDV[0][jLastJournalAlias]);
                }
            }
            catch (Exception ex)
            {
                TLogging.Log(String.Format("Method:{0} - Unexpected error!{1}{1}{2}",
                        Utilities.GetMethodSignature(),
                        Environment.NewLine,
                        ex.Message));
                throw ex;
            }
            finally
            {
                if (AGLBatch.Tables.Contains(TempTableName))
                {
                    AGLBatch.Tables.Remove(TempTableName);
                }
            }

            return NumberingIsValid;
        }
Пример #33
0
        private void ValidateDataDetailsManual(ABatchRow ARow)
        {
            if ((ARow == null) || (ARow.BatchStatus != MFinanceConstants.BATCH_UNPOSTED))
            {
                return;
            }

            TVerificationResultCollection VerificationResultCollection = FPetraUtilsObject.VerificationResultCollection;

            ParseHashTotal(ARow);

            TSharedFinanceValidation_GL.ValidateGLBatchManual(this,
                ARow,
                ref VerificationResultCollection,
                FValidationControlsDict,
                FStartDateCurrentPeriod,
                FEndDateLastForwardingPeriod);

            //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 (txtDetailBatchDescription.Text.Length == 0)
            {
                DataColumn ValidationColumn;
                TVerificationResult VerificationResult = null;
                object ValidationContext;

                ValidationColumn = ARow.Table.Columns[ABatchTable.ColumnBatchDescriptionId];
                ValidationContext = String.Format("Batch number {0}",
                    ARow.BatchNumber);

                VerificationResult = TStringChecks.StringMustNotBeEmpty(ARow.BatchDescription,
                    "Description of " + ValidationContext,
                    this, ValidationColumn, null);

                // Handle addition/removal to/from TVerificationResultCollection
                VerificationResultCollection.Auto_Add_Or_AddOrRemove(this, VerificationResult, ValidationColumn, true);
            }
        }
        /// <summary>
        /// Posts a batch
        /// </summary>
        /// <param name="ACurrentBatchRow">The data row corresponding to the batch to post</param>
        /// <param name="AEffectiveDate">The effective date for the batch</param>
        /// <param name="AStartDateCurrentPeriod">The earliest postable date</param>
        /// <param name="AEndDateLastForwardingPeriod">The latest postable date</param>
        /// <returns>
        /// True if the batch was successfully posted
        /// </returns>
        public bool PostBatch(ABatchRow ACurrentBatchRow,
            DateTime AEffectiveDate,
            DateTime AStartDateCurrentPeriod,
            DateTime AEndDateLastForwardingPeriod)
        {
            bool RetVal = false;

            if (!SaveBatchForPosting())
            {
                return RetVal;
            }

            // TODO: display progress of posting
            TVerificationResultCollection Verifications;

            int CurrentBatchNumber = ACurrentBatchRow.BatchNumber;

            if ((AEffectiveDate.Date < AStartDateCurrentPeriod) || (AEffectiveDate.Date > AEndDateLastForwardingPeriod))
            {
                MessageBox.Show(String.Format(Catalog.GetString(
                            "The Date Effective is outside the periods available for posting. Enter a date between {0:d} and {1:d}."),
                        AStartDateCurrentPeriod,
                        AEndDateLastForwardingPeriod));

                return RetVal;
            }

            // check that a corportate exchange rate exists
            FMyForm.WarnAboutMissingIntlExchangeRate = true;

            if (FMyForm.GetInternationalCurrencyExchangeRate() == 0)
            {
                return false;
            }

            if (MessageBox.Show(String.Format(Catalog.GetString("Are you sure you want to post batch {0}?"),
                        CurrentBatchNumber),
                    Catalog.GetString("Question"),
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == System.Windows.Forms.DialogResult.Yes)
            {
                try
                {
                    Cursor.Current = Cursors.WaitCursor;

                    if (!TRemote.MFinance.GL.WebConnectors.PostGLBatch(FLedgerNumber, CurrentBatchNumber, out Verifications))
                    {
                        string ErrorMessages = String.Empty;

                        foreach (TVerificationResult verif in Verifications)
                        {
                            ErrorMessages += "[" + verif.ResultContext + "] " +
                                             verif.ResultTextCaption + ": " +
                                             verif.ResultText + Environment.NewLine;
                        }

                        System.Windows.Forms.MessageBox.Show(ErrorMessages, Catalog.GetString("Posting failed"),
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Error);
                    }
                    else
                    {
                        //I don't need to call this directly, because the server calls it:
                        //TFrmGLBatch.PrintPostingRegister(FLedgerNumber, CurrentBatchNumber);

                        // TODO: print reports on successfully posted batch
                        MessageBox.Show(Catalog.GetString("The batch has been posted successfully!"),
                            Catalog.GetString("Success"),
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);

                        // refresh the grid, to reflect that the batch has been posted
                        FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadABatchAndContent(FLedgerNumber, CurrentBatchNumber));

                        // make sure that the current dataset is clean,
                        // otherwise the next save would try to modify the posted batch, even though no values have been changed
                        FMainDS.AcceptChanges();

                        // Ensure these tabs will ask the server for updates
                        FMyForm.GetJournalsControl().ClearCurrentSelection();
                        FMyForm.GetTransactionsControl().ClearCurrentSelection();

                        FMyUserControl.UpdateDisplay();

                        RetVal = true;
                    }
                }
                catch (Exception ex)
                {
                    string msg = (String.Format(Catalog.GetString("Unexpected error occurred during the posting of a GL Batch!{0}{1}{2}{1}    {3}"),
                                      Utilities.GetMethodSignature(),
                                      Environment.NewLine,
                                      ex.Message,
                                      ex.InnerException.Message));

                    TLogging.Log(msg);
                    MessageBox.Show(msg, "Post GL Batch Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    Cursor.Current = Cursors.Default;
                }
            }

            return RetVal;
        }
        /// <summary>
        /// Runs a test on posting a batch
        /// </summary>
        /// <param name="ACurrentBatchRow">The data row corresponding to the batch to post</param>
        public void TestPostBatch(ABatchRow ACurrentBatchRow)
        {
            if (!SaveBatchForPosting())
            {
                return;
            }

            TVerificationResultCollection Verifications;

            FMyForm.Cursor = Cursors.WaitCursor;

            List <TVariant>Result = TRemote.MFinance.GL.WebConnectors.TestPostGLBatch(FLedgerNumber, ACurrentBatchRow.BatchNumber, out Verifications);

            try
            {
                if ((Verifications != null) && (Verifications.Count > 0))
                {
                    string ErrorMessages = string.Empty;

                    foreach (TVerificationResult verif in Verifications)
                    {
                        ErrorMessages += "[" + verif.ResultContext + "] " +
                                         verif.ResultTextCaption + ": " +
                                         verif.ResultText + Environment.NewLine;
                    }

                    System.Windows.Forms.MessageBox.Show(ErrorMessages, Catalog.GetString("Posting failed"),
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                }
                else if (Result.Count < 25)
                {
                    string message = string.Empty;

                    foreach (TVariant value in Result)
                    {
                        ArrayList compValues = value.ToComposite();

                        message +=
                            string.Format(
                                Catalog.GetString("{1}/{0} ({3}/{2}) is: {4} and would be: {5}"),
                                ((TVariant)compValues[0]).ToString(),
                                ((TVariant)compValues[2]).ToString(),
                                ((TVariant)compValues[1]).ToString(),
                                ((TVariant)compValues[3]).ToString(),
                                StringHelper.FormatCurrency((TVariant)compValues[4], "currency"),
                                StringHelper.FormatCurrency((TVariant)compValues[5], "currency")) +
                            Environment.NewLine;
                    }

                    MessageBox.Show(message, Catalog.GetString("Result of Test Posting"));
                }
                else
                {
                    // store to CSV file
                    string message = string.Empty;

                    foreach (TVariant value in Result)
                    {
                        ArrayList compValues = value.ToComposite();

                        string[] columns = new string[] {
                            ((TVariant)compValues[0]).ToString(),
                            ((TVariant)compValues[1]).ToString(),
                            ((TVariant)compValues[2]).ToString(),
                            ((TVariant)compValues[3]).ToString(),
                            StringHelper.FormatCurrency((TVariant)compValues[4], "CurrencyCSV"),
                            StringHelper.FormatCurrency((TVariant)compValues[5], "CurrencyCSV")
                        };

                        message += StringHelper.StrMerge(columns,
                            Thread.CurrentThread.CurrentCulture.TextInfo.ListSeparator[0]) +
                                   Environment.NewLine;
                    }

                    string CSVFilePath = TClientSettings.PathLog + Path.DirectorySeparatorChar + "Batch" + ACurrentBatchRow.BatchNumber.ToString() +
                                         "_TestPosting.csv";
                    StreamWriter sw = new StreamWriter(CSVFilePath, false, System.Text.Encoding.UTF8);
                    sw.Write(message);
                    sw.Close();

                    MessageBox.Show(
                        String.Format(Catalog.GetString("Please see file {0} for the result of the test posting"), CSVFilePath),
                        Catalog.GetString("Result of Test Posting"));
                }
            }
            finally
            {
                FMyForm.Cursor = Cursors.Default;
            }
        }
        /// <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();
            txtCurrentPeriod.Text = ABatch.BatchPeriod.ToString();
            txtDebit.NumberValueDecimal = SumDebits;
            txtCredit.NumberValueDecimal = SumCredits;
            txtControl.NumberValueDecimal = ABatch.BatchControlTotal;
            FPetraUtilsObject.EnableDataChangedEvent();
        }
        /// <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());
                    }
                }
            }

            int nRowToSelect = 1;

            TFrmGLBatch myParentForm = (TFrmGLBatch)ParentForm;

            if (myParentForm.InitialBatchFound)
            {
                string filter = String.Format("{0}={1}", AJournalTable.GetJournalNumberDBName(), myParentForm.InitialJournalNumber);
                DataView dv = new DataView(FMainDS.AJournal, filter, "", DataViewRowState.CurrentRows);

                if (dv.Count > 0)
                {
                    nRowToSelect = grdDetails.DataSourceRowToIndex2(dv[0].Row) + 1;
                }
            }
            else
            {
                nRowToSelect = (BatchChanged || FirstRun) ? 1 : FPrevRowChangedRow;
            }

            //This will also call UpdateChangeableStatus
            SelectRowInGrid(nRowToSelect);

            UpdateRecordNumberDisplay();
            FFilterAndFindObject.SetRecordNumberDisplayProperties();

            FJournalsLoaded = 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();

                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);
            }
        }
Пример #39
0
        /// <summary>
        /// Load all GLM and GLMPeriod records for the batch period and the following periods, since that will avoid loading them one by one during submitchanges.
        /// this is called after ValidateBatchAndTransactions, because the BatchYear and BatchPeriod are validated and recalculated there
        /// </summary>
        private static void LoadGLMData(ref GLPostingTDS AGLPostingDS, Int32 ALedgerNumber, ABatchRow ABatchToPost)
        {
            TDBTransaction Transaction = null;
            GLPostingTDS GLPostingDS = AGLPostingDS;

            DBAccess.GDBAccessObj.GetNewOrExistingAutoReadTransaction(IsolationLevel.ReadCommitted,
                TEnforceIsolationLevel.eilMinimum,
                ref Transaction,
                delegate
                {
                    AGeneralLedgerMasterRow GLMTemplateRow = GLPostingDS.AGeneralLedgerMaster.NewRowTyped(false);

                    GLMTemplateRow.LedgerNumber = ALedgerNumber;
                    GLMTemplateRow.Year = ABatchToPost.BatchYear;
                    AGeneralLedgerMasterAccess.LoadUsingTemplate(GLPostingDS, GLMTemplateRow, Transaction);

                    string query = "SELECT PUB_a_general_ledger_master_period.* " +
                                   "FROM PUB_a_general_ledger_master, PUB_a_general_ledger_master_period " +
                                   "WHERE PUB_a_general_ledger_master.a_ledger_number_i = ? " +
                                   "AND PUB_a_general_ledger_master.a_year_i = ? " +
                                   "AND PUB_a_general_ledger_master_period.a_glm_sequence_i = PUB_a_general_ledger_master.a_glm_sequence_i " +
                                   "AND PUB_a_general_ledger_master_period.a_period_number_i >= ?";

                    List <OdbcParameter>parameters = new List <OdbcParameter>();

                    OdbcParameter parameter = new OdbcParameter("ledgernumber", OdbcType.Int);
                    parameter.Value = ALedgerNumber;
                    parameters.Add(parameter);
                    parameter = new OdbcParameter("year", OdbcType.Int);
                    parameter.Value = ABatchToPost.BatchYear;
                    parameters.Add(parameter);
                    parameter = new OdbcParameter("period", OdbcType.Int);
                    parameter.Value = ABatchToPost.BatchPeriod;
                    parameters.Add(parameter);
                    DBAccess.GDBAccessObj.Select(GLPostingDS,
                        query,
                        GLPostingDS.AGeneralLedgerMasterPeriod.TableName, Transaction, parameters.ToArray());
                });
        }
Пример #40
0
        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 void ValidateDataDetailsManual(ATransactionRow 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;
                FJournalStatus = FJournalRow.JournalStatus;
            }

            FIsUnposted = (FBatchRow.BatchStatus == MFinanceConstants.BATCH_UNPOSTED);

            if ((ARow == null) || (FBatchRow.BatchNumber != ARow.BatchNumber) || !FIsUnposted)
            {
                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.ValidateGLDetailManual(this, FBatchRow, ARow, controlToPass, ref VerificationResultCollection,
                FValidationControlsDict);

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

                ValidationColumn = ARow.Table.Columns[ATransactionTable.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.AccountAnalysisAttributesValuesExist(
                    FPreviouslySelectedDetailRow.TransactionNumber,
                    FPreviouslySelectedDetailRow.AccountCode,
                    FMainDS,
                    out ValueRequiredForType,
                    FIsUnposted))
            {
                DataColumn ValidationColumn;
                TVerificationResult VerificationResult = null;
                object ValidationContext;

                ValidationColumn = ARow.Table.Columns[ATransactionTable.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);
            }
        }
Пример #42
0
        /// <summary>
        /// Load all GLM and GLMPeriod records for the batch period and the following periods, since that will avoid loading them one by one during submitchanges.
        /// this is called after ValidateBatchAndTransactions, because the BatchYear and BatchPeriod are validated and recalculated there
        ///
        /// This should probably be changed, in the new, skinny summarization, only a few rows need to be accessed.
        /// </summary>
        private static void LoadGLMData(ref GLPostingTDS AGLPostingDS, Int32 ALedgerNumber, ABatchRow ABatchToPost)
        {
            #region Validate Arguments

            if (AGLPostingDS == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString(
                            "Function:{0} - The GL Posting dataset is null!"),
                        Utilities.GetMethodName(true)));
            }
            else if (ALedgerNumber <= 0)
            {
                throw new EFinanceSystemInvalidLedgerNumberException(String.Format(Catalog.GetString(
                            "Function:{0} - The Ledger number must be greater than 0!"),
                        Utilities.GetMethodName(true)), ALedgerNumber);
            }
            else if (ABatchToPost == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString(
                            "Function:{0} - The GL Batch to post data row is null!"),
                        Utilities.GetMethodName(true)));
            }

            #endregion Validate Arguments

            GLPostingTDS GLPostingDS = AGLPostingDS;

            TDBTransaction Transaction = null;

            try
            {
                DBAccess.GDBAccessObj.GetNewOrExistingAutoReadTransaction(IsolationLevel.ReadCommitted,
                    TEnforceIsolationLevel.eilMinimum,
                    ref Transaction,
                    delegate
                    {
                        AGeneralLedgerMasterRow GLMTemplateRow = GLPostingDS.AGeneralLedgerMaster.NewRowTyped(false);

                        GLMTemplateRow.LedgerNumber = ALedgerNumber;
                        GLMTemplateRow.Year = ABatchToPost.BatchYear;
                        AGeneralLedgerMasterAccess.LoadUsingTemplate(GLPostingDS, GLMTemplateRow, Transaction);

                        string query = "SELECT PUB_a_general_ledger_master_period.* " +
                                       "FROM PUB_a_general_ledger_master, PUB_a_general_ledger_master_period " +
                                       "WHERE PUB_a_general_ledger_master.a_ledger_number_i = ? " +
                                       "AND PUB_a_general_ledger_master.a_year_i = ? " +
                                       "AND PUB_a_general_ledger_master_period.a_glm_sequence_i = PUB_a_general_ledger_master.a_glm_sequence_i " +
                                       "AND PUB_a_general_ledger_master_period.a_period_number_i >= ?";

                        List <OdbcParameter>parameters = new List <OdbcParameter>();

                        OdbcParameter parameter = new OdbcParameter("ledgernumber", OdbcType.Int);
                        parameter.Value = ALedgerNumber;
                        parameters.Add(parameter);
                        parameter = new OdbcParameter("year", OdbcType.Int);
                        parameter.Value = ABatchToPost.BatchYear;
                        parameters.Add(parameter);
                        parameter = new OdbcParameter("period", OdbcType.Int);
                        parameter.Value = ABatchToPost.BatchPeriod;
                        parameters.Add(parameter);
                        DBAccess.GDBAccessObj.Select(GLPostingDS,
                            query,
                            GLPostingDS.AGeneralLedgerMasterPeriod.TableName, Transaction, parameters.ToArray());
                    });
            }
            catch (Exception ex)
            {
                TLogging.Log(String.Format("Method:{0} - Unexpected error!{1}{1}{2}",
                        Utilities.GetMethodSignature(),
                        Environment.NewLine,
                        ex.Message));
                throw ex;
            }
        }
Пример #43
0
        /// <summary>
        /// Re-show the specified row
        /// </summary>
        /// <param name="AModifiedBatchRow"></param>
        /// <param name="ARedisplay"></param>
        public void UndoModifiedBatchRow(ABatchRow AModifiedBatchRow, bool ARedisplay)
        {
            //Check if new row or not
            if (AModifiedBatchRow.RowState == DataRowState.Added)
            {
                return;
            }

            AModifiedBatchRow.RejectChanges();

            if (ARedisplay)
            {
                ShowDetails(AModifiedBatchRow);
            }
        }
        /// <summary>
        /// Posts a batch
        /// </summary>
        /// <param name="ACurrentBatchRow">The data row corresponding to the batch to post</param>
        /// <param name="AEffectiveDate">The effective date for the batch</param>
        /// <param name="AStartDateCurrentPeriod">The earliest postable date</param>
        /// <param name="AEndDateLastForwardingPeriod">The latest postable date</param>
        /// <returns>True if the batch was successfully posted</returns>
        public bool PostBatch(ABatchRow ACurrentBatchRow,
                              DateTime AEffectiveDate,
                              DateTime AStartDateCurrentPeriod,
                              DateTime AEndDateLastForwardingPeriod)
        {
            bool RetVal = false;

            if (!SaveBatchForPosting())
            {
                return(RetVal);
            }

            // TODO: display progress of posting
            TVerificationResultCollection Verifications;

            int CurrentBatchNumber = ACurrentBatchRow.BatchNumber;

            if ((AEffectiveDate.Date < AStartDateCurrentPeriod) || (AEffectiveDate.Date > AEndDateLastForwardingPeriod))
            {
                MessageBox.Show(String.Format(Catalog.GetString(
                                                  "The Date Effective is outside the periods available for posting. Enter a date between {0:d} and {1:d}."),
                                              AStartDateCurrentPeriod,
                                              AEndDateLastForwardingPeriod));

                return(RetVal);
            }

            if (MessageBox.Show(String.Format(Catalog.GetString("Are you sure you want to post batch {0}?"),
                                              CurrentBatchNumber),
                                Catalog.GetString("Question"),
                                MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == System.Windows.Forms.DialogResult.Yes)
            {
                try
                {
                    Cursor.Current = Cursors.WaitCursor;

                    if (!TRemote.MFinance.GL.WebConnectors.PostGLBatch(FLedgerNumber, CurrentBatchNumber, out Verifications))
                    {
                        string ErrorMessages = String.Empty;

                        foreach (TVerificationResult verif in Verifications)
                        {
                            ErrorMessages += "[" + verif.ResultContext + "] " +
                                             verif.ResultTextCaption + ": " +
                                             verif.ResultText + Environment.NewLine;
                        }

                        System.Windows.Forms.MessageBox.Show(ErrorMessages, Catalog.GetString("Posting failed"),
                                                             MessageBoxButtons.OK,
                                                             MessageBoxIcon.Error);
                    }
                    else
                    {
//                                                                                          I don't need to call this directly, because the server calls it:
//                        TFrmGLBatch.PrintPostingRegister(FLedgerNumber, CurrentBatchNumber);

                        // TODO: print reports on successfully posted batch
                        MessageBox.Show(Catalog.GetString("The batch has been posted successfully!"),
                                        Catalog.GetString("Success"),
                                        MessageBoxButtons.OK,
                                        MessageBoxIcon.Information);

                        // refresh the grid, to reflect that the batch has been posted
                        FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadABatchAndContent(FLedgerNumber, CurrentBatchNumber));

                        // make sure that the current dataset is clean,
                        // otherwise the next save would try to modify the posted batch, even though no values have been changed
                        FMainDS.AcceptChanges();

                        // Ensure these tabs will ask the server for updates
                        FMyForm.GetJournalsControl().ClearCurrentSelection();
                        FMyForm.GetTransactionsControl().ClearCurrentSelection();

                        FMyUserControl.UpdateDisplay();

                        RetVal = true;
                    }
                }
                finally
                {
                    Cursor.Current = Cursors.Default;
                }
            }

            return(RetVal);
        }
        /// <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);
            }
        }
        /// <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(TFrmGLBatch.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;
        }
Пример #47
0
        /// <summary>
        /// Method to cancel a specified batch
        /// </summary>
        /// <param name="ABatchRowToCancel">The row to cancel</param>
        /// <returns></returns>
        public bool CancelBatch(ABatchRow ABatchRowToCancel)
        {
            //Assign default value(s)
            bool CancellationSuccessful = false;

            if ((ABatchRowToCancel == null))
            {
                return(CancellationSuccessful);
            }

            int CurrentBatchNumber = ABatchRowToCancel.BatchNumber;

            if ((MessageBox.Show(String.Format(Catalog.GetString("You have chosen to cancel this batch ({0}).\n\nDo you really want to cancel it?"),
                                               CurrentBatchNumber),
                                 Catalog.GetString("Confirm Cancel"),
                                 MessageBoxButtons.YesNo,
                                 MessageBoxIcon.Question,
                                 MessageBoxDefaultButton.Button2) != System.Windows.Forms.DialogResult.Yes))
            {
                return(CancellationSuccessful);
            }

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

            BackupMainDS.Merge(FMainDS);

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

            if (!RowToDeleteIsNew)
            {
                //Remove any changes, which may cause validation issues, before cancelling
                FMyForm.GetBatchControl().UndoModifiedBatchRow(ABatchRowToCancel, true);

                if (!(FMyForm.SaveChanges()))
                {
                    MessageBox.Show(Catalog.GetString("Error in trying to save prior to cancelling current Batch!"),
                                    Catalog.GetString("Cancellation Error"),
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);

                    return(CancellationSuccessful);
                }
            }

            try
            {
                FMyForm.Cursor = Cursors.WaitCursor;

                //clear any transactions currently being editied in the Transaction Tab
                FMyForm.GetTransactionsControl().ClearCurrentSelection();
                //clear any journals currently being editied in the Journals Tab
                FMyForm.GetJournalsControl().ClearCurrentSelection();

                //Clear Journals etc for current Batch
                FMainDS.ATransAnalAttrib.Clear();
                FMainDS.ATransaction.Clear();
                FMainDS.AJournal.Clear();

                //Load tables afresh
                FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadAJournal(FLedgerNumber, CurrentBatchNumber));
                FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadATransaction(FLedgerNumber, CurrentBatchNumber));
                FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadATransAnalAttribForBatch(FLedgerNumber, CurrentBatchNumber));
                FMainDS.AcceptChanges();

                //Delete transactions and analysis attributes
                for (int i = FMainDS.ATransAnalAttrib.Count - 1; i >= 0; i--)
                {
                    FMainDS.ATransAnalAttrib[i].Delete();
                }

                for (int i = FMainDS.ATransaction.Count - 1; i >= 0; i--)
                {
                    FMainDS.ATransaction[i].Delete();
                }

                //Update Journal totals and status
                foreach (AJournalRow journal in FMainDS.AJournal.Rows)
                {
                    if (journal.BatchNumber == CurrentBatchNumber)
                    {
                        journal.BeginEdit();
                        journal.JournalStatus         = MFinanceConstants.BATCH_CANCELLED;
                        journal.JournalCreditTotal    = 0;
                        journal.JournalDebitTotal     = 0;
                        journal.LastTransactionNumber = 0;
                        journal.EndEdit();
                    }
                }

                // Edit the batch row
                ABatchRowToCancel.BeginEdit();

                ABatchRowToCancel.BatchCreditTotal  = 0;
                ABatchRowToCancel.BatchDebitTotal   = 0;
                ABatchRowToCancel.BatchControlTotal = 0;
                ABatchRowToCancel.BatchStatus       = MFinanceConstants.BATCH_CANCELLED;

                ABatchRowToCancel.EndEdit();

                FPetraUtilsObject.SetChangedFlag();

                //Need to call save
                if (FMyForm.SaveChanges())
                {
                    MessageBox.Show(Catalog.GetString("The batch has been cancelled successfully!"),
                                    Catalog.GetString("Success"),
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);

                    FMyForm.DisableTransactions();
                    FMyForm.DisableJournals();
                }
                else
                {
                    throw new Exception(Catalog.GetString("The batch failed to save after being cancelled! Reopen the form and retry."));
                }

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

                //Revert to previous state
                FMainDS.Merge(BackupMainDS);
            }
            finally
            {
                FMyForm.Cursor = Cursors.Default;
            }

            return(CancellationSuccessful);
        }
Пример #48
0
        public static void UpdateTotalsOfBatch(ref GLBatchTDS AMainDS,
            ABatchRow ACurrentBatch)
        {
            decimal sumDebits = 0.0M;
            decimal sumCredits = 0.0M;

            DataView jnlDataView = new DataView(AMainDS.AJournal);

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

            foreach (DataRowView journalview in jnlDataView)
            {
                GLBatchTDSAJournalRow journalrow = (GLBatchTDSAJournalRow)journalview.Row;

                UpdateTotalsOfJournal(ref AMainDS, journalrow);

                sumDebits += journalrow.JournalDebitTotal;
                sumCredits += journalrow.JournalCreditTotal;
            }

            ACurrentBatch.BatchDebitTotal = sumDebits;
            ACurrentBatch.BatchCreditTotal = sumCredits;
            ACurrentBatch.BatchRunningTotal = Math.Round(sumDebits - sumCredits, 2);
        }
Пример #49
0
        /// <summary>
        /// mark each journal, each transaction as being posted;
        /// add sums for costcentre/account combinations
        /// </summary>
        /// <param name="AMainDS">can contain several batches and journals and transactions</param>
        /// <param name="APostingDS"></param>
        /// <param name="APostingLevel">the balance changes at the posting level</param>
        /// <param name="ABatchToPost">the batch to post</param>
        /// <returns>a list with the sums for each costcentre/account combination</returns>
        private static SortedList <string, TAmount>MarkAsPostedAndCollectData(GLBatchTDS AMainDS,
            GLPostingTDS APostingDS,
            SortedList <string, TAmount>APostingLevel, ABatchRow ABatchToPost)
        {
            #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 (APostingDS == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString(
                            "Function:{0} - The GL Posting dataset is null!"),
                        Utilities.GetMethodName(true)));
            }
            else if (ABatchToPost == null)
            {
                throw new EFinanceSystemDataObjectNullOrEmptyException(String.Format(Catalog.GetString(
                            "Function:{0} - The GL Batch to post data row is null!"),
                        Utilities.GetMethodName(true)));
            }

            #endregion Validate Arguments

            DataView TransactionsDV = new DataView(AMainDS.ATransaction);

            TransactionsDV.Sort = ATransactionTable.GetJournalNumberDBName();

            foreach (AJournalRow journal in AMainDS.AJournal.Rows)
            {
                if (journal.BatchNumber != ABatchToPost.BatchNumber)
                {
                    continue;
                }

                foreach (DataRowView transactionview in TransactionsDV.FindRows(journal.JournalNumber))
                {
                    ATransactionRow transaction = (ATransactionRow)transactionview.Row;

                    if (transaction.BatchNumber != ABatchToPost.BatchNumber)
                    {
                        continue;
                    }

                    transaction.TransactionStatus = true;

                    // get the account that this transaction is writing to
                    AAccountRow accountRow = (AAccountRow)APostingDS.AAccount.Rows.Find(new object[] { transaction.LedgerNumber,
                                                                                                       transaction.AccountCode });

                    #region Validate Data

                    if (accountRow == null)
                    {
                        throw new EFinanceSystemDataTableReturnedNoDataException(String.Format(Catalog.GetString(
                                    "Function:{0} - Account row data for Account code {1} in Ledger number {2} does not exist or could not be accessed!"),
                                Utilities.GetMethodName(true),
                                transaction.AccountCode,
                                transaction.LedgerNumber));
                    }

                    #endregion Validate Data

                    // Set the sign of the amounts according to the debit/credit indicator
                    decimal SignBaseAmount = transaction.AmountInBaseCurrency;
                    decimal SignIntlAmount = transaction.AmountInIntlCurrency;
                    decimal SignTransAmount = transaction.TransactionAmount;

                    if (accountRow.DebitCreditIndicator != transaction.DebitCreditIndicator)
                    {
                        SignBaseAmount *= -1.0M;
                        SignIntlAmount *= -1.0M;
                        SignTransAmount *= -1.0M;
                    }

                    // TODO: do we need to check for base currency corrections?
                    // or do we get rid of these problems by not having international currency?

                    string key = TAmount.MakeKey(transaction.AccountCode, transaction.CostCentreCode);

                    if (!APostingLevel.ContainsKey(key))
                    {
                        APostingLevel.Add(key, new TAmount());
                    }

                    APostingLevel[key].BaseAmount += SignBaseAmount;
                    APostingLevel[key].IntlAmount += SignIntlAmount;

                    // Only foreign currency accounts store a value in the transaction currency,
                    // if the transaction was actually in the foreign currency.

                    if (accountRow.ForeignCurrencyFlag && (journal.TransactionCurrency == accountRow.ForeignCurrencyCode))
                    {
                        APostingLevel[key].TransAmount += SignTransAmount;
                    }
                }

                journal.JournalStatus = MFinanceConstants.BATCH_POSTED;
            }

            ABatchToPost.BatchStatus = MFinanceConstants.BATCH_POSTED;

            return APostingLevel;
        }
Пример #50
0
        /// <summary>
        /// runs validations on batch, journals and transactions
        /// some things are even modified, eg. batch period etc from date effective
        /// </summary>
        private static bool ValidateBatchAndTransactions(ref GLBatchTDS AGLBatchDS,
            GLPostingTDS APostingDS,
            Int32 ALedgerNumber,
            ABatchRow ABatchToPost,
            out TVerificationResultCollection AVerifications)
        {
            AVerifications = new TVerificationResultCollection();
            TVerificationResultCollection Verifications = AVerifications;

            if ((ABatchToPost.BatchStatus == MFinanceConstants.BATCH_CANCELLED) || (ABatchToPost.BatchStatus == MFinanceConstants.BATCH_POSTED))
            {
                AVerifications.Add(new TVerificationResult(
                        String.Format(Catalog.GetString("Cannot post Batch {0} in Ledger {1}"), ABatchToPost.BatchNumber, ALedgerNumber),
                        String.Format(Catalog.GetString("It has status {0}"), ABatchToPost.BatchStatus),
                        TResultSeverity.Resv_Critical));
            }

            // Calculate the base currency amounts for each transaction, using the exchange rate from the journals.
            // erm - this is done already? I don't want to do it here, since my journal may contain forex-reval elements.

            // Calculate the credit and debit totals
            GLRoutines.UpdateTotalsOfBatch(ref AGLBatchDS, ABatchToPost);

            if (ABatchToPost.BatchCreditTotal != ABatchToPost.BatchDebitTotal)
            {
                AVerifications.Add(new TVerificationResult(
                        String.Format(Catalog.GetString("Cannot post Batch {0} in Ledger {1}"), ABatchToPost.BatchNumber, ALedgerNumber),
                        String.Format(Catalog.GetString("It does not balance: Debit is {0:N2}, Credit is {1:N2}"), ABatchToPost.BatchDebitTotal,
                            ABatchToPost.BatchCreditTotal),
                        TResultSeverity.Resv_Critical));
            }
            else if ((ABatchToPost.BatchCreditTotal == 0) && ((AGLBatchDS.AJournal.Rows.Count == 0) || (AGLBatchDS.ATransaction.Rows.Count == 0)))
            {
                AVerifications.Add(new TVerificationResult(
                        String.Format(Catalog.GetString("Cannot post Batch {0} in Ledger {1}"), ABatchToPost.BatchNumber, ALedgerNumber),
                        Catalog.GetString("The batch has no monetary value. Please cancel it or add transactions."),
                        TResultSeverity.Resv_Critical));
            }
            else if ((ABatchToPost.BatchControlTotal != 0)
                     && (ABatchToPost.BatchControlTotal != ABatchToPost.BatchCreditTotal))
            {
                AVerifications.Add(new TVerificationResult(
                        String.Format(Catalog.GetString("Cannot post Batch {0} in Ledger {1}"), ABatchToPost.BatchNumber, ALedgerNumber),
                        String.Format(Catalog.GetString("The control total {0:n2} does not fit the Credit/Debit Total {1:n2}."),
                            ABatchToPost.BatchControlTotal,
                            ABatchToPost.BatchCreditTotal),
                        TResultSeverity.Resv_Critical));
            }

            Int32 DateEffectivePeriodNumber, DateEffectiveYearNumber;

            TDBTransaction Transaction = null;
            GLBatchTDS GLBatchDS = AGLBatchDS;

            DBAccess.GDBAccessObj.GetNewOrExistingAutoReadTransaction(IsolationLevel.ReadCommitted,
                TEnforceIsolationLevel.eilMinimum,
                ref Transaction,
                delegate
                {
                    if (!TFinancialYear.IsValidPostingPeriod(ABatchToPost.LedgerNumber, ABatchToPost.DateEffective, out DateEffectivePeriodNumber,
                            out DateEffectiveYearNumber,
                            Transaction))
                    {
                        Verifications.Add(new TVerificationResult(
                                String.Format(Catalog.GetString("Cannot post Batch {0} in Ledger {1}"), ABatchToPost.BatchNumber, ALedgerNumber),
                                String.Format(Catalog.GetString("The Date Effective {0:d-MMM-yyyy} does not fit any open accounting period."),
                                    ABatchToPost.DateEffective),
                                TResultSeverity.Resv_Critical));
                    }
                    else
                    {
                        // just make sure that the correct BatchPeriod is used
                        ABatchToPost.BatchPeriod = DateEffectivePeriodNumber;
                        ABatchToPost.BatchYear = DateEffectiveYearNumber;
                    }

                    // check that all transactions are inside the same period as the GL date effective of the batch
                    DateTime PostingPeriodStartDate, PostingPeriodEndDate;
                    TFinancialYear.GetStartAndEndDateOfPeriod(ABatchToPost.LedgerNumber,
                        DateEffectivePeriodNumber,
                        out PostingPeriodStartDate,
                        out PostingPeriodEndDate,
                        Transaction);

                    foreach (ATransactionRow transRow in GLBatchDS.ATransaction.Rows)
                    {
                        if ((transRow.BatchNumber == ABatchToPost.BatchNumber)
                            && (transRow.TransactionDate < PostingPeriodStartDate) || (transRow.TransactionDate > PostingPeriodEndDate))
                        {
                            Verifications.Add(new TVerificationResult(
                                    String.Format(Catalog.GetString("Cannot post Batch {0} in Ledger {1}"), ABatchToPost.BatchNumber, ALedgerNumber),
                                    String.Format(
                                        "invalid transaction date for transaction {0} in Batch {1} Journal {2}: {3:d-MMM-yyyy} must be inside period {4} ({5:d-MMM-yyyy} till {6:d-MMM-yyyy})",
                                        transRow.TransactionNumber, transRow.BatchNumber, transRow.JournalNumber,
                                        transRow.TransactionDate,
                                        DateEffectivePeriodNumber,
                                        PostingPeriodStartDate,
                                        PostingPeriodEndDate),
                                    TResultSeverity.Resv_Critical));
                        }
                    }
                });

            AVerifications = Verifications;

            DataView TransactionsOfJournalView = new DataView(AGLBatchDS.ATransaction);

            foreach (AJournalRow journal in AGLBatchDS.AJournal.Rows)
            {
                journal.DateEffective = ABatchToPost.DateEffective;
                journal.JournalPeriod = ABatchToPost.BatchPeriod;

                if (journal.JournalCreditTotal != journal.JournalDebitTotal)
                {
                    AVerifications.Add(new TVerificationResult(
                            String.Format(Catalog.GetString("Cannot post Batch {0} in Ledger {1}"), ABatchToPost.BatchNumber, ALedgerNumber),
                            String.Format(Catalog.GetString("The journal {0} does not balance: Debit is {1:N2}, Credit is {2:N2}"),
                                journal.JournalNumber,
                                journal.JournalDebitTotal, journal.JournalCreditTotal),
                            TResultSeverity.Resv_Critical));
                }

                TransactionsOfJournalView.RowFilter = ATransactionTable.GetJournalNumberDBName() + " = " + journal.JournalNumber.ToString();

                foreach (DataRowView TransactionViewRow in TransactionsOfJournalView)
                {
                    ATransactionRow transaction = (ATransactionRow)TransactionViewRow.Row;

                    // check that transactions on foreign currency accounts are using the correct currency
                    // (fx reval transactions are an exception because they are posted in base currency)
                    if (!((transaction.Reference == CommonAccountingTransactionTypesEnum.REVAL.ToString())
                          && (journal.TransactionTypeCode == CommonAccountingTransactionTypesEnum.REVAL.ToString())))
                    {
                        // get the account that this transaction is writing to
                        AAccountRow Account = (AAccountRow)APostingDS.AAccount.Rows.Find(new object[] { ALedgerNumber, transaction.AccountCode });

                        if (Account == null)
                        {
                            // should not get here
                            throw new Exception("ValidateBatchAndTransactions: Cannot find account " + transaction.AccountCode);
                        }

                        if (Account.ForeignCurrencyFlag && (journal.TransactionCurrency != Account.ForeignCurrencyCode))
                        {
                            AVerifications.Add(new TVerificationResult(
                                    String.Format(Catalog.GetString("Cannot post Batch {0} in Ledger {1}"), ABatchToPost.BatchNumber, ALedgerNumber),
                                    String.Format(Catalog.GetString(
                                            "Transaction {0} in Journal {1} with currency {2} does not fit the foreign currency {3} of account {4}."),
                                        transaction.TransactionNumber, transaction.JournalNumber, journal.TransactionCurrency,
                                        Account.ForeignCurrencyCode,
                                        transaction.AccountCode),
                                    TResultSeverity.Resv_Critical));
                        }
                    }

                    if ((transaction.AmountInBaseCurrency == 0) && (transaction.TransactionAmount != 0))
                    {
                        AVerifications.Add(new TVerificationResult(
                                String.Format(Catalog.GetString("Cannot post Batch {0} in Ledger {1}"), ABatchToPost.BatchNumber, ALedgerNumber),
                                String.Format(Catalog.GetString("Transaction {0} in Journal {1} has invalid base transaction amount of 0."),
                                    transaction.TransactionNumber, transaction.JournalNumber),
                                TResultSeverity.Resv_Critical));
                    }
                }
            }

            return TVerificationHelper.IsNullOrOnlyNonCritical(AVerifications);
        }
Пример #51
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;
                        }
                    }
                }
            }
        }
Пример #52
0
        private void ShowDetailsManual(ABatchRow ARow)
        {
            AutoEnableTransTabForBatch();
            grdDetails.TabStop = (ARow != null);

            if (ARow == null)
            {
                pnlDetails.Enabled = false;
                ((TFrmGLBatch) this.ParentForm).DisableJournals();
                ((TFrmGLBatch) this.ParentForm).DisableTransactions();
                EnableButtonControl(false);
                ClearDetailControls();
                return;
            }

            FPetraUtilsObject.DetailProtectedMode =
                (ARow.BatchStatus.Equals(MFinanceConstants.BATCH_POSTED)
                 || ARow.BatchStatus.Equals(MFinanceConstants.BATCH_CANCELLED));

            FCurrentEffectiveDate = ARow.DateEffective;

            UpdateBatchPeriod(null, null);

            UpdateChangeableStatus();
            ((TFrmGLBatch) this.ParentForm).EnableJournals();
        }
        public static Int32 CreateGLBatch(BankImportTDS AMainDS,
                                          Int32 ALedgerNumber,
                                          Int32 AStatementKey,
                                          Int32 AGLBatchNumber,
                                          out TVerificationResultCollection AVerificationResult)
        {
            AMainDS.AEpTransaction.DefaultView.RowFilter =
                String.Format("{0}={1}",
                              AEpTransactionTable.GetStatementKeyDBName(),
                              AStatementKey);
            AMainDS.AEpStatement.DefaultView.RowFilter =
                String.Format("{0}={1}",
                              AEpStatementTable.GetStatementKeyDBName(),
                              AStatementKey);
            AEpStatementRow stmt = (AEpStatementRow)AMainDS.AEpStatement.DefaultView[0].Row;

            AVerificationResult = null;

            Int32          DateEffectivePeriodNumber, DateEffectiveYearNumber;
            TDBTransaction Transaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.ReadCommitted);

            if (!TFinancialYear.IsValidPostingPeriod(ALedgerNumber, stmt.Date, out DateEffectivePeriodNumber, out DateEffectiveYearNumber,
                                                     Transaction))
            {
                string msg = String.Format(Catalog.GetString("Cannot create a GL batch for date {0} since it is not in an open period of the ledger."),
                                           stmt.Date.ToShortDateString());
                TLogging.Log(msg);
                AVerificationResult = new TVerificationResultCollection();
                AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Creating GL Batch"), msg, TResultSeverity.Resv_Critical));

                DBAccess.GDBAccessObj.RollbackTransaction();
                return(-1);
            }

            Int32 BatchYear, BatchPeriod;

            // if DateEffective is outside the range of open periods, use the most fitting date
            DateTime DateEffective = stmt.Date;

            TFinancialYear.GetLedgerDatePostingPeriod(ALedgerNumber, ref DateEffective, out BatchYear, out BatchPeriod, Transaction, true);

            ALedgerTable LedgerTable = ALedgerAccess.LoadByPrimaryKey(ALedgerNumber, Transaction);

            DBAccess.GDBAccessObj.RollbackTransaction();

            GLBatchTDS GLDS = TGLTransactionWebConnector.CreateABatch(ALedgerNumber);

            ABatchRow glbatchRow = GLDS.ABatch[0];

            glbatchRow.BatchPeriod      = BatchPeriod;
            glbatchRow.DateEffective    = DateEffective;
            glbatchRow.BatchDescription = String.Format(Catalog.GetString("bank import for date {0}"), stmt.Date.ToShortDateString());

            decimal HashTotal   = 0.0M;
            decimal DebitTotal  = 0.0M;
            decimal CreditTotal = 0.0M;

            // TODO: support several journals
            // TODO: support several currencies, support other currencies than the base currency
            AJournalRow gljournalRow = GLDS.AJournal.NewRowTyped();

            gljournalRow.LedgerNumber        = glbatchRow.LedgerNumber;
            gljournalRow.BatchNumber         = glbatchRow.BatchNumber;
            gljournalRow.JournalNumber       = glbatchRow.LastJournal + 1;
            gljournalRow.TransactionCurrency = LedgerTable[0].BaseCurrency;
            glbatchRow.LastJournal++;
            gljournalRow.JournalPeriod       = glbatchRow.BatchPeriod;
            gljournalRow.DateEffective       = glbatchRow.DateEffective;
            gljournalRow.JournalDescription  = glbatchRow.BatchDescription;
            gljournalRow.SubSystemCode       = CommonAccountingSubSystemsEnum.GL.ToString();
            gljournalRow.TransactionTypeCode = CommonAccountingTransactionTypesEnum.STD.ToString();
            gljournalRow.ExchangeRateToBase  = 1.0m;
            GLDS.AJournal.Rows.Add(gljournalRow);

            foreach (DataRowView dv in AMainDS.AEpTransaction.DefaultView)
            {
                AEpTransactionRow transactionRow = (AEpTransactionRow)dv.Row;

                DataView v = AMainDS.AEpMatch.DefaultView;
                v.RowFilter = AEpMatchTable.GetActionDBName() + " = '" + MFinanceConstants.BANK_STMT_STATUS_MATCHED_GL + "' and " +
                              AEpMatchTable.GetMatchTextDBName() + " = '" + transactionRow.MatchText + "'";

                if (v.Count > 0)
                {
                    AEpMatchRow     match = (AEpMatchRow)v[0].Row;
                    ATransactionRow trans = GLDS.ATransaction.NewRowTyped();
                    trans.LedgerNumber      = glbatchRow.LedgerNumber;
                    trans.BatchNumber       = glbatchRow.BatchNumber;
                    trans.JournalNumber     = gljournalRow.JournalNumber;
                    trans.TransactionNumber = gljournalRow.LastTransactionNumber + 1;
                    trans.AccountCode       = match.AccountCode;
                    trans.CostCentreCode    = match.CostCentreCode;
                    trans.Reference         = match.Reference;
                    trans.Narrative         = match.Narrative;
                    trans.TransactionDate   = transactionRow.DateEffective;

                    if (transactionRow.TransactionAmount < 0)
                    {
                        trans.AmountInBaseCurrency = -1 * transactionRow.TransactionAmount;
                        trans.TransactionAmount    = -1 * transactionRow.TransactionAmount;
                        trans.DebitCreditIndicator = true;
                        DebitTotal += trans.AmountInBaseCurrency;
                    }
                    else
                    {
                        trans.AmountInBaseCurrency = transactionRow.TransactionAmount;
                        trans.TransactionAmount    = transactionRow.TransactionAmount;
                        trans.DebitCreditIndicator = false;
                        CreditTotal += trans.AmountInBaseCurrency;
                    }

                    GLDS.ATransaction.Rows.Add(trans);
                    gljournalRow.LastTransactionNumber++;

                    // add one transaction for the bank as well
                    trans = GLDS.ATransaction.NewRowTyped();
                    trans.LedgerNumber      = glbatchRow.LedgerNumber;
                    trans.BatchNumber       = glbatchRow.BatchNumber;
                    trans.JournalNumber     = gljournalRow.JournalNumber;
                    trans.TransactionNumber = gljournalRow.LastTransactionNumber + 1;
                    trans.AccountCode       = stmt.BankAccountCode;
                    trans.CostCentreCode    = TLedgerInfo.GetStandardCostCentre(ALedgerNumber);
                    trans.Reference         = match.Reference;
                    trans.Narrative         = match.Narrative;
                    trans.TransactionDate   = transactionRow.DateEffective;

                    if (transactionRow.TransactionAmount < 0)
                    {
                        trans.AmountInBaseCurrency = -1 * transactionRow.TransactionAmount;
                        trans.TransactionAmount    = -1 * transactionRow.TransactionAmount;
                        trans.DebitCreditIndicator = false;
                        CreditTotal += trans.AmountInBaseCurrency;
                    }
                    else
                    {
                        trans.AmountInBaseCurrency = transactionRow.TransactionAmount;
                        trans.TransactionAmount    = transactionRow.TransactionAmount;
                        trans.DebitCreditIndicator = true;
                        DebitTotal += trans.AmountInBaseCurrency;
                    }

                    GLDS.ATransaction.Rows.Add(trans);
                    gljournalRow.LastTransactionNumber++;
                }
            }

            gljournalRow.JournalDebitTotal  = DebitTotal;
            gljournalRow.JournalCreditTotal = CreditTotal;
            glbatchRow.BatchDebitTotal      = DebitTotal;
            glbatchRow.BatchCreditTotal     = CreditTotal;
            glbatchRow.BatchControlTotal    = HashTotal;

            TVerificationResultCollection VerificationResult;

            TSubmitChangesResult result = TGLTransactionWebConnector.SaveGLBatchTDS(ref GLDS,
                                                                                    out VerificationResult);

            if (result == TSubmitChangesResult.scrOK)
            {
                return(glbatchRow.BatchNumber);
            }

            TLogging.Log("Problems storing GL Batch");
            return(-1);
        }
        /// <summary>
        /// Reverses the specified batch
        /// </summary>
        /// <param name="ACurrentBatchRow">The DataRow for the batch to be reversed</param>
        /// <param name="ADateForReverseBatch">The reversal date - this will get checked to ensure the date is valid</param>
        /// <param name="AStartDateCurrentPeriod">The earliest date that can be used as reversal date</param>
        /// <param name="AEndDateLastForwardingPeriod">The latest date that can be used as a reversal date</param>
        /// <returns></returns>
        public bool ReverseBatch(ABatchRow ACurrentBatchRow,
            DateTime ADateForReverseBatch,
            DateTime AStartDateCurrentPeriod,
            DateTime AEndDateLastForwardingPeriod)
        {
            //TODO: Allow the user in a dialog to specify the reverse date

            TVerificationResultCollection Verifications;

            if (FPetraUtilsObject.HasChanges)
            {
                // save first, then post
                if (!FMyForm.SaveChanges())
                {
                    // saving failed, therefore do not try to reverse
                    MessageBox.Show(Catalog.GetString("The batch was not reversed due to problems during saving; ") + Environment.NewLine +
                        Catalog.GetString("Please first save the batch, and then you can reverse it!"),
                        Catalog.GetString("Failure"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }

            try
            {
                FMyForm.Cursor = Cursors.WaitCursor;

                int SelectedBatchNumber = ACurrentBatchRow.BatchNumber;
                string Msg = string.Empty;

                // load journals belonging to batch
                GLBatchTDS TempDS = TRemote.MFinance.GL.WebConnectors.LoadAJournalAndContent(FLedgerNumber, ACurrentBatchRow.BatchNumber);
                FMainDS.Merge(TempDS);

                foreach (AJournalRow Journal in TempDS.AJournal.Rows)
                {
                    // if at least one journal in the batch has already been reversed then confirm with user
                    if (Journal.Reversed)
                    {
                        Msg = String.Format(Catalog.GetString("One or more of the Journals in Batch {0} have already been reversed. " +
                                "Are you sure you want to continue?"),
                            SelectedBatchNumber);
                        break;
                    }
                }

                if (Msg == string.Empty)
                {
                    Msg = String.Format(Catalog.GetString("Are you sure you want to reverse Batch {0}?"),
                        SelectedBatchNumber);
                }

                if (MessageBox.Show(Msg, Catalog.GetString("GL Batch Reversal"),
                        MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
                {
                    TFrmBatchDateDialog Form = new TFrmBatchDateDialog(FMyForm);
                    Form.SetParameters(AStartDateCurrentPeriod, AEndDateLastForwardingPeriod, SelectedBatchNumber);

                    if (Form.ShowDialog() == DialogResult.Cancel)
                    {
                        return false;
                    }

                    ADateForReverseBatch = Form.BatchDate;

                    int ReversalGLBatch;

                    if (!TRemote.MFinance.GL.WebConnectors.ReverseBatch(FLedgerNumber, SelectedBatchNumber,
                            ADateForReverseBatch,
                            out ReversalGLBatch,
                            out Verifications,
                            false))
                    {
                        string ErrorMessages = String.Empty;

                        foreach (TVerificationResult verif in Verifications)
                        {
                            ErrorMessages += "[" + verif.ResultContext + "] " +
                                             verif.ResultTextCaption + ": " +
                                             verif.ResultText + Environment.NewLine;
                        }

                        System.Windows.Forms.MessageBox.Show(ErrorMessages, Catalog.GetString("Reversal failed"),
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Error);
                    }
                    else
                    {
                        MessageBox.Show(
                            String.Format(Catalog.GetString("A reversal batch has been created, with batch number {0}!"), ReversalGLBatch),
                            Catalog.GetString("Success"),
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);

                        // refresh the grid, to reflect that the batch has been reversed
                        FMainDS.Merge(TRemote.MFinance.GL.WebConnectors.LoadABatchAndContent(FLedgerNumber, ReversalGLBatch));

                        // make sure that the current dataset is clean,
                        // otherwise the next save would try to modify the posted batch, even though no values have been changed
                        FMainDS.AcceptChanges();

                        // Ensure these tabs will ask the server for updates
                        FMyForm.GetJournalsControl().ClearCurrentSelection();
                        FMyForm.GetTransactionsControl().ClearCurrentSelection();

                        FMyUserControl.UpdateDisplay();

                        return true;
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                FMyForm.Cursor = Cursors.Default;
            }

            return false;
        }
        /// <summary>
        /// Runs a test on posting a batch
        /// </summary>
        /// <param name="ACurrentBatchRow">The data row corresponding to the batch to post</param>
        public void TestPostBatch(ABatchRow ACurrentBatchRow)
        {
            if (!SaveBatchForPosting())
            {
                return;
            }

            TVerificationResultCollection Verifications;

            FMyForm.Cursor = Cursors.WaitCursor;

            List <TVariant> Result = TRemote.MFinance.GL.WebConnectors.TestPostGLBatch(FLedgerNumber, ACurrentBatchRow.BatchNumber, out Verifications);

            try
            {
                if ((Verifications != null) && (Verifications.Count > 0))
                {
                    string ErrorMessages = string.Empty;

                    foreach (TVerificationResult verif in Verifications)
                    {
                        ErrorMessages += "[" + verif.ResultContext + "] " +
                                         verif.ResultTextCaption + ": " +
                                         verif.ResultText + Environment.NewLine;
                    }

                    System.Windows.Forms.MessageBox.Show(ErrorMessages, Catalog.GetString("Posting failed"),
                                                         MessageBoxButtons.OK,
                                                         MessageBoxIcon.Error);
                }
                else if (Result.Count < 25)
                {
                    string message = string.Empty;

                    foreach (TVariant value in Result)
                    {
                        ArrayList compValues = value.ToComposite();

                        message +=
                            string.Format(
                                Catalog.GetString("{1}/{0} ({3}/{2}) is: {4} and would be: {5}"),
                                ((TVariant)compValues[0]).ToString(),
                                ((TVariant)compValues[2]).ToString(),
                                ((TVariant)compValues[1]).ToString(),
                                ((TVariant)compValues[3]).ToString(),
                                StringHelper.FormatCurrency((TVariant)compValues[4], "currency"),
                                StringHelper.FormatCurrency((TVariant)compValues[5], "currency")) +
                            Environment.NewLine;
                    }

                    MessageBox.Show(message, Catalog.GetString("Result of Test Posting"));
                }
                else
                {
                    // store to CSV file
                    string message = string.Empty;

                    foreach (TVariant value in Result)
                    {
                        ArrayList compValues = value.ToComposite();

                        string[] columns = new string[] {
                            ((TVariant)compValues[0]).ToString(),
                            ((TVariant)compValues[1]).ToString(),
                            ((TVariant)compValues[2]).ToString(),
                            ((TVariant)compValues[3]).ToString(),
                            StringHelper.FormatCurrency((TVariant)compValues[4], "CurrencyCSV"),
                            StringHelper.FormatCurrency((TVariant)compValues[5], "CurrencyCSV")
                        };

                        message += StringHelper.StrMerge(columns,
                                                         Thread.CurrentThread.CurrentCulture.TextInfo.ListSeparator[0]) +
                                   Environment.NewLine;
                    }

                    string CSVFilePath = TClientSettings.PathLog + Path.DirectorySeparatorChar + "Batch" + ACurrentBatchRow.BatchNumber.ToString() +
                                         "_TestPosting.csv";
                    StreamWriter sw = new StreamWriter(CSVFilePath, false, System.Text.Encoding.UTF8);
                    sw.Write(message);
                    sw.Close();

                    MessageBox.Show(
                        String.Format(Catalog.GetString("Please see file {0} for the result of the test posting"), CSVFilePath),
                        Catalog.GetString("Result of Test Posting"));
                }
            }
            finally
            {
                FMyForm.Cursor = Cursors.Default;
            }
        }
Пример #56
0
        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;
        }
Пример #57
0
 /// <summary>
 /// Load Journals for current Batch
 /// </summary>
 /// <param name="ACurrentBatchRow"></param>
 public void LoadJournals(ABatchRow ACurrentBatchRow)
 {
     this.ucoJournals.LoadJournals(ACurrentBatchRow);
 }
Пример #58
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>
        /// <param name="AAmountsChanged"></param>
        public static void UpdateTotalsOfBatch(ref GLBatchTDS AMainDS,
            ABatchRow ACurrentBatch, out bool AAmountsChanged)
        {
            AAmountsChanged = false;

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

            DataView jnlDataView = new DataView(AMainDS.AJournal);
            jnlDataView.RowFilter = String.Format("{0}={1}",
                AJournalTable.GetBatchNumberDBName(),
                ACurrentBatch.BatchNumber);

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

                bool journalUpdated;
                UpdateTotalsOfJournal(ref AMainDS, ref journalRow, out journalUpdated);

                if (journalUpdated && !AAmountsChanged)
                {
                    AAmountsChanged = true;
                }

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

            if ((ACurrentBatch.BatchDebitTotal != BatchDebitTotal)
                || (ACurrentBatch.BatchCreditTotal != BatchCreditTotal))
            {
                ACurrentBatch.BatchDebitTotal = BatchDebitTotal;
                ACurrentBatch.BatchCreditTotal = BatchCreditTotal;
            }
        }
Пример #59
0
 void WriteBatchLine(ABatchRow batch)
 {
     WriteStringQuoted("B");
     WriteStringQuoted(batch.BatchDescription);
     WriteCurrency(batch.BatchControlTotal);
     WriteDate(batch.DateEffective, true);
 }
Пример #60
0
        private void ParseHashTotal(ABatchRow ARow)
        {
            if (ARow.BatchStatus != MFinanceConstants.BATCH_UNPOSTED)
            {
                return;
            }

            if ((txtDetailBatchControlTotal.NumberValueDecimal == null) || !txtDetailBatchControlTotal.NumberValueDecimal.HasValue)
            {
                bool prev = FPetraUtilsObject.SuppressChangeDetection;
                FPetraUtilsObject.SuppressChangeDetection = true;
                txtDetailBatchControlTotal.NumberValueDecimal = 0m;
                FPetraUtilsObject.SuppressChangeDetection = prev;
            }

            if (ARow.BatchControlTotal != txtDetailBatchControlTotal.NumberValueDecimal.Value)
            {
                ARow.BatchControlTotal = txtDetailBatchControlTotal.NumberValueDecimal.Value;
            }
        }