/// <summary>
        ///
        /// </summary>
        /// <param name="Atds"></param>
        /// <param name="AApDocument"></param>
        /// <returns>true if the document TotalAmount equals the sum of its parts!</returns>
        public static bool BatchBalancesOK(AccountsPayableTDS Atds, AApDocumentRow AApDocument)
        {
            decimal DocumentBalance = AApDocument.TotalAmount;

            if (DocumentBalance == 0)
            {
                System.Windows.Forms.MessageBox.Show(
                    String.Format(Catalog.GetString("The document {0} is empty."), AApDocument.DocumentCode),
                    Catalog.GetString("Balance Problem"));
                return(false);
            }

            foreach (AApDocumentDetailRow Row in Atds.AApDocumentDetail.Rows)
            {
                if (Row.ApDocumentId == AApDocument.ApDocumentId) // NOTE: When called from elsewhere, the TDS could contain data for several documents.
                {
                    DocumentBalance -= Row.Amount;
                }
            }

            if (DocumentBalance == 0.0m)
            {
                return(true);
            }
            else
            {
                System.Windows.Forms.MessageBox.Show(
                    String.Format(Catalog.GetString("The document {0} Amount does not equal the sum of the detail lines."), AApDocument.DocumentCode),
                    Catalog.GetString("Balance Problem"));
                return(false);
            }
        }
Example #2
0
        private TVerificationResultCollection PostAPDocument(AccountsPayableTDS AMainDS, DateTime APostingDate,
                                                             ref List <int> ADocumentIds, bool AReversal = false)
        {
            string AssertFailMessage = AReversal ? "Failed to post AP document reversal: " : "Problems posting AP document: ";
            TVerificationResultCollection VerificationResult;

            if (!AReversal)
            {
                ADocumentIds.Add(AMainDS.AApDocument[0].ApDocumentId);
            }

            Int32 glBatchNumber;

            if (!TAPTransactionWebConnector.PostAPDocuments(FLedgerNumber,
                                                            ADocumentIds,
                                                            APostingDate,
                                                            AReversal,
                                                            out glBatchNumber,
                                                            out VerificationResult))
            {
                Assert.Fail(AssertFailMessage +
                            VerificationResult.BuildVerificationResultString());
            }

            CommonNUnitFunctions.EnsureNullOrEmptyVerificationResult(VerificationResult, AssertFailMessage);   // Guard Assert

            return(VerificationResult);
        }
Example #3
0
        /// <summary>
        /// Pay all tagged documents
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void PayAllTagged(object sender, EventArgs e)
        {
            string MsgTitle = Catalog.GetString("Document Payment");

            this.Cursor = Cursors.WaitCursor;
            AccountsPayableTDS TempDS        = LoadTaggedDocuments();
            TFrmAPPayment      PaymentScreen = new TFrmAPPayment(FMainForm);

            List <int> PayTheseDocs = new List <int>();

            foreach (DataRowView rv in grdInvoices.PagedDataTable.DefaultView)
            {
                if ((rv.Row["Selected"].Equals(true) &&
                     ("|POSTED|PARTPAID|".IndexOf("|" + rv.Row["DocumentStatus"].ToString() + "|") >= 0)))
                {
                    PayTheseDocs.Add(Convert.ToInt32(rv.Row["ApDocumentId"]));
                }
            }

            if (PayTheseDocs.Count > 0)
            {
                if (PaymentScreen.AddDocumentsToPayment(TempDS, FMainForm.LedgerNumber, PayTheseDocs))
                {
                    this.Cursor = Cursors.Default;
                    PaymentScreen.Show();
                }

                this.Cursor = Cursors.Default;
            }
            else
            {
                this.Cursor = Cursors.Default;
                MessageBox.Show(Catalog.GetString("There are no tagged documents to be paid."), MsgTitle);
            }
        }
        /// create new AP info
        public static AApDocumentRow CreateNewAPInfo(Int64 APartnerKey, ref AccountsPayableTDS AMainDS)
        {
            ALedgerTable LedgerTable = ALedgerAccess.LoadAll(DBAccess.GDBAccessObj.Transaction);

            AMainDS = TAPTransactionWebConnector.CreateAApDocument(((ALedgerRow)LedgerTable.Rows[0]).LedgerNumber, APartnerKey, true);

            // Create a new RecurringGiftBatch
            AApDocumentRow Document = AMainDS.AApDocument[0];

            Document.DocumentCode     = "TEST";
            Document.CreditNoteFlag   = false;
            Document.DateIssued       = DateTime.Today;
            Document.DateEntered      = DateTime.Today;
            Document.TotalAmount      = 0;
            Document.CurrencyCode     = "EUR";
            Document.LastDetailNumber = 0;

            // Create a new RecurringGift record
            AApSupplierRow ApSupplierRow = AMainDS.AApSupplier.NewRowTyped();

            ApSupplierRow.PartnerKey   = APartnerKey;
            ApSupplierRow.CurrencyCode = "EUR";
            AMainDS.AApSupplier.Rows.Add(ApSupplierRow);

            return(Document);
        }
        /// <summary>
        /// This static function is called from several places
        /// </summary>
        /// <param name="Atds"></param>
        /// <param name="Adocument"></param>
        /// <returns>true if this document seems OK to post.</returns>
        public static bool ApDocumentCanPost(AccountsPayableTDS Atds, AApDocumentRow Adocument)
        {
            // If the batch will not balance, or required attributes are missing, I'll stop right here..

            if (!BatchBalancesOK(Atds, Adocument))
            {
                return(false);
            }

            if (!AllLinesAccountsOK(Atds, Adocument))
            {
                return(false);
            }

            if (!AllLinesHaveAttributes(Atds, Adocument))
            {
                return(false);
            }

            if (!ExchangeRateIsOk(Atds, Adocument))
            {
                return(false);
            }

            if (!CurrencyIsOkForPosting(Atds, Adocument))
            {
                return(false);
            }

            return(true);
        }
        /// create new AP info
        public static AApDocumentRow CreateNewAPInfo(Int64 APartnerKey, ref AccountsPayableTDS AMainDS, TDataBase ADataBase = null)
        {
            TDataBase      db          = DBAccess.Connect("CreateNewAPInfo", ADataBase);
            TDBTransaction Transaction = db.BeginTransaction(IsolationLevel.Serializable);

            ALedgerTable LedgerTable = ALedgerAccess.LoadAll(Transaction);

            AMainDS = TAPTransactionWebConnector.CreateAApDocument(((ALedgerRow)LedgerTable.Rows[0]).LedgerNumber, APartnerKey, true, db);

            // Create a new RecurringGiftBatch
            AApDocumentRow Document = AMainDS.AApDocument[0];

            Document.DocumentCode     = "TEST";
            Document.CreditNoteFlag   = false;
            Document.DateIssued       = DateTime.Today;
            Document.DateEntered      = DateTime.Today;
            Document.TotalAmount      = 0;
            Document.CurrencyCode     = "EUR";
            Document.LastDetailNumber = 0;

            // Create a new RecurringGift record
            AApSupplierRow ApSupplierRow = AMainDS.AApSupplier.NewRowTyped();

            ApSupplierRow.PartnerKey   = APartnerKey;
            ApSupplierRow.CurrencyCode = "EUR";
            AMainDS.AApSupplier.Rows.Add(ApSupplierRow);

            Transaction.Commit();

            return(Document);
        }
Example #7
0
 private void SetupSupplierAndDocumentInfo(AccountsPayableTDS AMainDS, out string ABankAccount, out string ACurrencyCode,
                                           out string AApAccountCode, out string ACostCentreCode)
 {
     ABankAccount    = AMainDS.AApSupplier[0].DefaultBankAccount;
     ACurrencyCode   = AMainDS.AApDocument[0].CurrencyCode;
     AApAccountCode  = AMainDS.AApDocument[0].ApAccount;
     ACostCentreCode = AMainDS.AApDocumentDetail[0].CostCentreCode;
 }
        /// <summary>
        /// post and pay all invoices in the given period, but leave some (or none) unposted
        /// </summary>
        public static bool PostAndPayInvoices(int AYear, int APeriod, int ALeaveInvoicesUnposted = 0)
        {
            TLogging.LogAtLevel(1, "PostAndPayInvoices for year " + AYear.ToString() + " / period " + APeriod.ToString());

            AccountsPayableTDS MainDS = new AccountsPayableTDS();

            string sqlLoadDocuments =
                "SELECT * FROM PUB_a_ap_document WHERE a_ledger_number_i = ? AND a_date_issued_d >= ? AND a_date_issued_d <= ? AND a_document_status_c='APPROVED'";

            DateTime PeriodStartDate, PeriodEndDate;

            TFinancialYear.GetStartAndEndDateOfPeriod(FLedgerNumber, APeriod, out PeriodStartDate, out PeriodEndDate, null);

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

            OdbcParameter parameter;

            parameter       = new OdbcParameter("ledgernumber", OdbcType.Int);
            parameter.Value = FLedgerNumber;
            parameters.Add(parameter);
            parameter       = new OdbcParameter("startDate", OdbcType.DateTime);
            parameter.Value = PeriodStartDate;
            parameters.Add(parameter);
            parameter       = new OdbcParameter("endDate", OdbcType.DateTime);
            parameter.Value = PeriodEndDate;
            parameters.Add(parameter);

            DBAccess.GDBAccessObj.SelectDT(MainDS.AApDocument, sqlLoadDocuments, null, parameters.ToArray(), -1, -1);

            int countUnPosted = MainDS.AApDocument.Count;

            List <int> DocumentIdsToPost = new List <int>();

            foreach (AApDocumentRow invoice in MainDS.AApDocument.Rows)
            {
                if (countUnPosted <= ALeaveInvoicesUnposted)
                {
                    break;
                }

                DocumentIdsToPost.Add(invoice.ApDocumentId);

                countUnPosted--;
            }

            TVerificationResultCollection VerificationResult;

            if ((DocumentIdsToPost.Count > 0) &&
                !TAPTransactionWebConnector.PostAPDocuments(FLedgerNumber, DocumentIdsToPost, PeriodEndDate, false, out VerificationResult))
            {
                TLogging.Log(VerificationResult.BuildVerificationResultString());
                return(false);
            }

            // TODO pay the invoices as well

            return(true);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="ALedgerNumber"></param>
        /// <param name="APaymentNumber"></param>
        public void ReloadPayment(Int32 ALedgerNumber, Int32 APaymentNumber)
        {
            FMainDS       = TRemote.MFinance.AP.WebConnectors.LoadAPPayment(ALedgerNumber, APaymentNumber);
            FLedgerNumber = FMainDS.AApPayment[0].LedgerNumber;
            ALedgerTable Tbl = TRemote.MFinance.AP.WebConnectors.GetLedgerInfo(FLedgerNumber);

            FLedgerRow = Tbl[0];
            ShowData(FMainDS.AApSupplier[0]);
        }
Example #10
0
        private static void LoadAnalysisAttributes(AccountsPayableTDS AMainDS, Int32 ALedgerNumber, TDBTransaction ATransaction)
        {
            {   // Load via template...
                AAnalysisAttributeRow TemplateRow = AMainDS.AAnalysisAttribute.NewRowTyped(false);
                TemplateRow.LedgerNumber = ALedgerNumber;
                TemplateRow.Active = true;
                AAnalysisAttributeAccess.LoadUsingTemplate(AMainDS, TemplateRow, ATransaction);
            }

            AFreeformAnalysisAccess.LoadViaALedger(AMainDS, ALedgerNumber, ATransaction);
        }
Example #11
0
        /// <summary>
        /// Creates a AP document for the supplier specified with APartnerKey.
        /// </summary>
        /// <param name="APartnerKey"></param>
        /// <param name="AAmount"></param>
        /// <param name="AExchangeRatePosting"></param>
        /// <param name="ADocumentCode"></param>
        /// <param name="ANarrative"></param>
        /// <param name="AMainDS"></param>
        /// <param name="ADataBase"></param>
        /// <returns></returns>
        private TVerificationResultCollection CreateAPDocument(Int64 APartnerKey, decimal AAmount, decimal?AExchangeRatePosting,
                                                               string ADocumentCode, string ANarrative, out AccountsPayableTDS AMainDS, TDataBase ADataBase)
        {
            string AssertFailMessage = "Problems saving AP document: ";
            TSubmitChangesResult          SubmRes;
            TVerificationResultCollection VerificationResult;

            TDataBase db = DBAccess.Connect("CreateAPDocument", ADataBase);

            AMainDS = TAPTransactionWebConnector.CreateAApDocument(FLedgerNumber, APartnerKey, false, db);
            AccountsPayableTDS MainDS = AMainDS;

            TDBTransaction Transaction = new TDBTransaction();

            db.ReadTransaction(
                ref Transaction,
                delegate
            {
                AApSupplierAccess.LoadByPrimaryKey(MainDS, APartnerKey, Transaction);
            });

            AMainDS.AApDocument[0].DocumentCode = ADocumentCode + DateTime.Now.Ticks.ToString();

            AMainDS.Merge(TAPTransactionWebConnector.CreateAApDocumentDetail(
                              FLedgerNumber,
                              AMainDS.AApDocument[0].ApDocumentId,
                              AMainDS.AApSupplier[0].DefaultExpAccount,
                              AMainDS.AApSupplier[0].DefaultCostCentre,
                              AAmount,
                              AMainDS.AApDocument[0].LastDetailNumber + 1));

            AMainDS.AApDocument[0].LastDetailNumber++;
            AMainDS.AApDocument[0].TotalAmount     = AAmount;
            AMainDS.AApDocument[0].DocumentStatus  = MFinanceConstants.AP_DOCUMENT_APPROVED;
            AMainDS.AApDocumentDetail[0].Narrative = ANarrative;

            if (AExchangeRatePosting.HasValue)
            {
                AMainDS.AApDocument[0].ExchangeRateToBase = AExchangeRatePosting.Value;
            }

            SubmRes = TAPTransactionWebConnector.SaveAApDocument(ref AMainDS, out VerificationResult, db);

            if (SubmRes != TSubmitChangesResult.scrOK)
            {
                Assert.Fail(AssertFailMessage + String.Format(" - (SaveAApDocument return value: {0}) - ", SubmRes) +
                            VerificationResult.BuildVerificationResultString());
            }

            CommonNUnitFunctions.EnsureNullOrEmptyVerificationResult(VerificationResult, AssertFailMessage);   // Guard Assert

            return(VerificationResult);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="Atds"></param>
        /// <param name="AApDocument"></param>
        /// <returns></returns>
        public static bool ExchangeRateIsOk(AccountsPayableTDS Atds, AApDocumentRow AApDocument)
        {
            if (AApDocument.ExchangeRateToBase == 0)
            {
                System.Windows.Forms.MessageBox.Show(
                    String.Format(Catalog.GetString("No Exchange Rate has been set."), AApDocument.DocumentCode),
                    Catalog.GetString("Post Document"));
                return(false);
            }

            return(true);
        }
        private static bool CurrencyIsOkForPosting(AccountsPayableTDS Atds, AApDocumentRow AApDocument)
        {
            if (AApDocument.CurrencyCode != Atds.AApSupplier[0].CurrencyCode)
            {
                System.Windows.Forms.MessageBox.Show(
                    String.Format(Catalog.GetString("Document {0} cannot be posted because the supplier currency has been changed."),
                                  AApDocument.DocumentCode),
                    Catalog.GetString("Post Document"));
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Set which payments should be paid; initialises the data of this screen
        /// </summary>
        /// <param name="ADataset"></param>
        /// <param name="ALedgerNumber"></param>
        /// <param name="ADocumentsToPay"></param>
        /// <returns>true if there's something to pay</returns>
        public bool AddDocumentsToPayment(AccountsPayableTDS ADataset, Int32 ALedgerNumber, List <Int32> ADocumentsToPay)
        {
            FMainDS       = ADataset;
            FLedgerNumber = ALedgerNumber;
            ALedgerTable Tbl = TRemote.MFinance.AP.WebConnectors.GetLedgerInfo(FLedgerNumber);

            FLedgerRow = Tbl[0];

            if (FMainDS.AApPayment == null)
            {
                FMainDS.Merge(new AccountsPayableTDSAApPaymentTable()); // Because of these lines, AddDocumentsToPayment may only be called once per payment.
            }
            else
            {
                FMainDS.AApPayment.Clear();
            }

            if (FMainDS.AApDocumentPayment == null)
            {
                FMainDS.Merge(new AccountsPayableTDSAApDocumentPaymentTable());
            }
            else
            {
                FMainDS.AApDocumentPayment.Clear();
            }

            // I want to check that it'll be OK to pay these documents:
            for (Int32 Idx = ADocumentsToPay.Count - 1; Idx >= 0; Idx--)
            {
                Int32 DocId = ADocumentsToPay[Idx];
                AccountsPayableTDS tempDs = TRemote.MFinance.AP.WebConnectors.LoadAApDocument(ALedgerNumber, DocId);

                if (!ApDocumentCanPay(tempDs, tempDs.AApDocument[0]))
                {
                    ADocumentsToPay.Remove(DocId);
                }
            }

            if (ADocumentsToPay.Count == 0)
            {
                return(false);
            }

            TRemote.MFinance.AP.WebConnectors.CreatePaymentTableEntries(ref FMainDS, ALedgerNumber, ADocumentsToPay);
            chkPrintRemittance.Checked = true;
            chkClaimDiscount.Enabled   = false;
            chkPrintCheque.Enabled     = false;
            chkPrintLabel.Enabled      = false;
            ShowDataManual();
            return(true);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="Atds"></param>
        /// <param name="AdocumentRow"></param>
        /// <returns></returns>
        public static bool ApDocumentCanPay(AccountsPayableTDS Atds, AApDocumentRow AdocumentRow)
        {
            if (!CurrencyIsOkForPaying(Atds, AdocumentRow))
            {
                return(false);
            }

            if ("|POSTED|PARTPAID|".IndexOf("|" + AdocumentRow.DocumentStatus) < 0)
            {
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Load all tagged documents into a typed data set.  (Used for posting and paying)
        /// </summary>
        /// <returns></returns>
        private AccountsPayableTDS LoadTaggedDocuments()
        {
            AccountsPayableTDS LoadDs = new AccountsPayableTDS();

            foreach (DataRowView rv in grdInvoices.PagedDataTable.DefaultView)
            {
                if (rv.Row["Selected"].Equals(true))
                {
                    LoadDs.Merge(TRemote.MFinance.AP.WebConnectors.LoadAApDocument(FMainForm.LedgerNumber, Convert.ToInt32(rv.Row["ApDocumentId"])));
                }
            }

            return(LoadDs);
        }
Example #17
0
        private TVerificationResultCollection PayAPDocument(int AApDocumentId, decimal AAmount, string ABankAccount,
                                                            string ACurrencyCode, DateTime APeriodEndDate, out int APaymentNumber, decimal?AExchangeRatePayment = null, TDataBase ADataBase = null)
        {
            string AssertFailMessage = "Problems paying AP document: ";
            TVerificationResultCollection VerificationResult;
            AccountsPayableTDS            MainDS = new AccountsPayableTDS();

            AApPaymentRow Payment = MainDS.AApPayment.NewRowTyped();

            Payment.LedgerNumber  = FLedgerNumber;
            Payment.PaymentNumber = -1;
            Payment.Amount        = AAmount;
            Payment.BankAccount   = ABankAccount;
            Payment.CurrencyCode  = ACurrencyCode;

            if (AExchangeRatePayment.HasValue)
            {
                Payment.ExchangeRateToBase = AExchangeRatePayment.Value;
            }

            MainDS.AApPayment.Rows.Add(Payment);

            AApDocumentPaymentRow DocPayment = MainDS.AApDocumentPayment.NewRowTyped();

            DocPayment.LedgerNumber  = FLedgerNumber;
            DocPayment.ApDocumentId  = AApDocumentId;
            DocPayment.Amount        = AAmount;
            DocPayment.PaymentNumber = Payment.PaymentNumber;
            MainDS.AApDocumentPayment.Rows.Add(DocPayment);
            Int32 glBatchNumber;
            AccountsPayableTDSAApPaymentTable newPayments;

            if (!TAPTransactionWebConnector.PostAPPayments(ref MainDS, APeriodEndDate,
                                                           out glBatchNumber,
                                                           out newPayments,
                                                           out VerificationResult,
                                                           ADataBase))
            {
                Assert.Fail(AssertFailMessage +
                            VerificationResult.BuildVerificationResultString());
            }

            CommonNUnitFunctions.EnsureNullOrEmptyVerificationResult(VerificationResult, AssertFailMessage);   // Guard Assert

            APaymentNumber = DocPayment.PaymentNumber;

            return(VerificationResult);
        }
Example #18
0
        /// <summary>
        /// Load the supplier and all the transactions (invoices and payments) that relate to it.
        /// </summary>
        /// <param name="ALedgerNumber"></param>
        /// <param name="APartnerKey"></param>
        public void LoadSupplier(Int32 ALedgerNumber, Int64 APartnerKey)
        {
            this.Cursor = Cursors.WaitCursor;

            FLedgerNumber = ALedgerNumber;
            FPartnerKey   = APartnerKey;
            FMainDS       = TRemote.MFinance.AP.WebConnectors.LoadAApSupplier(ALedgerNumber, APartnerKey);

            FSupplierRow = FMainDS.AApSupplier[0];

            txtFilteredBalance.CurrencyCode = FSupplierRow.CurrencyCode;
            txtSupplierBalance.CurrencyCode = FSupplierRow.CurrencyCode;
            txtTaggedBalance.CurrencyCode   = FSupplierRow.CurrencyCode;
            lblExcludedItems.Text           = string.Format(lblExcludedItems.Text, FSupplierRow.CurrencyCode);

            // Get our AP ledger settings and enable/disable the corresponding search option on the filter panel
            TFrmLedgerSettingsDialog settings = new TFrmLedgerSettingsDialog(this, ALedgerNumber);

            FRequireApprovalBeforePosting = settings.APRequiresApprovalBeforePosting;
            Control rbtForApproval = FFilterAndFindObject.FilterPanelControls.FindControlByName("rbtForApproval");

            rbtForApproval.Enabled = FRequireApprovalBeforePosting;

            //
            // Transactions older than
            DateTime AgedOlderThan = DateTime.Now;

            if (!FSupplierRow.IsPreferredScreenDisplayNull())
            {
                AgedOlderThan = AgedOlderThan.AddMonths(0 - FSupplierRow.PreferredScreenDisplay);
            }

            FAgedOlderThan = AgedOlderThan.ToString("u");

            txtSupplierName.Text     = FMainDS.PPartner[0].PartnerShortName;
            txtSupplierCurrency.Text = FSupplierRow.CurrencyCode;
            FFindObject = TRemote.MFinance.AP.UIConnectors.Find();

            FFindObject.FindSupplierTransactions(FLedgerNumber, FPartnerKey);

            // Start thread that checks for the end of the search operation on the PetraServer
            FKeepUpSearchFinishedCheck = true;
            Thread FinishedCheckThread = new Thread(new ThreadStart(SearchFinishedCheckThread));

            FinishedCheckThread.Start();

            this.Text = Catalog.GetString("Supplier Transactions") + " - " + TFinanceControls.GetLedgerNumberAndName(FLedgerNumber);
        }
        /// <summary>
        /// Post a list of AP documents
        /// This static function is called from several places
        /// /// </summary>
        /// <returns>true if everything went OK</returns>
        public static bool PostApDocumentList(AccountsPayableTDS Atds, int ALedgerNumber, List <int> AApDocumentIds, Form AOwnerForm)
        {
            TVerificationResultCollection Verifications;

            TDlgGLEnterDateEffective dateEffectiveDialog = new TDlgGLEnterDateEffective(
                ALedgerNumber,
                Catalog.GetString("Select posting date"),
                Catalog.GetString("The date effective for posting") + ":");

            if (dateEffectiveDialog.ShowDialog() != DialogResult.OK)
            {
                MessageBox.Show(Catalog.GetString("Posting was cancelled."), Catalog.GetString(
                                    "No Success"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }

            DateTime PostingDate = dateEffectiveDialog.SelectedDate;

            AOwnerForm.Cursor = Cursors.WaitCursor;

            if (TRemote.MFinance.AP.WebConnectors.PostAPDocuments(
                    ALedgerNumber,
                    AApDocumentIds,
                    PostingDate,
                    false,
                    out Verifications))
            {
                AOwnerForm.Cursor = Cursors.Default;
                return(true);
            }
            else
            {
                AOwnerForm.Cursor = Cursors.Default;
                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"));
            }

            return(false);
        }
Example #20
0
        /// <summary>
        /// Passes data as a Typed DataSet to the Supplier Edit Screen
        /// </summary>
        public AccountsPayableTDS GetData(Int64 APartnerKey)
        {
            TDBTransaction ReadTransaction;

            // create the DataSet that will later be passed to the Client
            AccountsPayableTDS MainDS = new AccountsPayableTDS();

            ReadTransaction = FDataBase.BeginTransaction(IsolationLevel.RepeatableRead, 5);

            try
            {
                try
                {
                    // Supplier
                    AApSupplierAccess.LoadByPrimaryKey(MainDS, APartnerKey, ReadTransaction);

                    if (MainDS.AApSupplier.Rows.Count == 0)
                    {
                        // Supplier does not exist
                        throw new Exception("supplier does not exist");
                    }
                }
                catch (Exception Exp)
                {
                    ReadTransaction.Rollback();
                    ReadTransaction = new TDBTransaction();
                    TLogging.Log("TSupplierEditUIConnector.LoadData exception: " + Exp.ToString(), TLoggingType.ToLogfile);
                    TLogging.Log(Exp.StackTrace, TLoggingType.ToLogfile);
                    throw;
                }
            }
            finally
            {
                if (ReadTransaction != null)
                {
                    ReadTransaction.Commit();
                }
            }

            // Accept row changes here so that the Client gets 'unmodified' rows
            MainDS.AcceptChanges();

            // Remove all Tables that were not filled with data before remoting them.
            MainDS.RemoveEmptyTables();

            return(MainDS);
        }
Example #21
0
        /// <summary>
        /// store the AP supplier
        ///
        /// All DataTables contained in the Typed DataSet are inspected for added,
        /// changed or deleted rows by submitting them to the DataStore.
        /// </summary>
        /// <param name="AInspectDS">Typed DataSet that needs to contain known DataTables</param>
        /// <returns>TSubmitChangesResult.scrOK in case everything went fine, otherwise throws an Exception.</returns>
        public TSubmitChangesResult SubmitChanges(ref AccountsPayableTDS AInspectDS)
        {
            TDBTransaction SubmitChangesTransaction;

            if (AInspectDS != null)
            {
                // I won't allow any null fields related to discount:

                if (AInspectDS.AApSupplier[0].IsDefaultDiscountDaysNull())
                {
                    AInspectDS.AApSupplier[0].DefaultDiscountDays = 0;
                }

                if (AInspectDS.AApSupplier[0].IsDefaultDiscountPercentageNull())
                {
                    AInspectDS.AApSupplier[0].DefaultDiscountPercentage = 0;
                }

                bool NewTransaction;
                SubmitChangesTransaction = FDataBase.GetNewOrExistingTransaction(IsolationLevel.Serializable, out NewTransaction);

                try
                {
                    AApSupplierAccess.SubmitChanges(AInspectDS.AApSupplier, SubmitChangesTransaction);

                    if (NewTransaction)
                    {
                        SubmitChangesTransaction.Commit();
                    }
                }
                catch (Exception Exc)
                {
                    TLogging.Log("An Exception occured during the storing of the AP Supplier):" + Environment.NewLine + Exc.ToString());

                    if (NewTransaction)
                    {
                        SubmitChangesTransaction.Rollback();
                    }

                    throw;
                }
            }

            return(TSubmitChangesResult.scrOK);
        }
Example #22
0
        /// <summary>
        /// Post all tagged documents in one GL Batch
        /// Uses static functions from TFrmAPEditDocument
        /// </summary>
        private void PostTaggedDocuments(object sender, EventArgs e)
        {
            List <Int32>       TaggedDocuments = new List <Int32>();
            AccountsPayableTDS TempDS          = new AccountsPayableTDS();

            foreach (DataRowView rv in FPagedDataTable.DefaultView)
            {
                if ((rv.Row["Tagged"].Equals(true)) && (rv.Row["Status"].ToString().Length > 0) && // Invoices have status, Payments don't.
                    ("|POSTED|PARTPAID|PAID".IndexOf("|" + rv.Row["Status"].ToString()) < 0) &&
                    (rv.Row["Currency"].ToString() == txtSupplierCurrency.Text)
                    )
                {
                    Int32 DocumentId = Convert.ToInt32(rv.Row["ApDocumentId"]);
                    TempDS.Merge(TRemote.MFinance.AP.WebConnectors.LoadAApDocument(FLedgerNumber, DocumentId));

                    // I've loaded this record in my DS, but I was not given a handle to it, so I need to find it!
                    TempDS.AApDocument.DefaultView.Sort = "a_ap_document_id_i";
                    Int32          Idx         = TempDS.AApDocument.DefaultView.Find(DocumentId);
                    AApDocumentRow DocumentRow = TempDS.AApDocument[Idx];

                    if (TFrmAPEditDocument.ApDocumentCanPost(TempDS, DocumentRow))
                    {
                        TaggedDocuments.Add(DocumentId);
                    }
                }
            }

            if (TaggedDocuments.Count == 0)
            {
                return;
            }

            if (TFrmAPEditDocument.PostApDocumentList(TempDS, FLedgerNumber, TaggedDocuments, this))
            {
                // TODO: print reports on successfully posted batch
                MessageBox.Show(Catalog.GetString("The AP documents have been posted successfully!"));

                // TODO: show posting register of GL Batch?

                LoadSupplier(FLedgerNumber, FPartnerKey);
            }
        }
Example #23
0
        /// Add all selected invoices to the payment list and show that list so that the user can make the payment
        private void AddTaggedToPayment(object sender, EventArgs e)
        {
            List <Int32>       TaggedDocuments = new List <Int32>();
            AccountsPayableTDS TempDS          = new AccountsPayableTDS();

            foreach (DataRowView rv in FPagedDataTable.DefaultView)
            {
                if (
                    (rv.Row["Tagged"].Equals(true)) &&
                    (rv.Row["Currency"].ToString() == txtSupplierCurrency.Text) &&
                    ("|POSTED|PARTPAID|".IndexOf("|" + rv.Row["Status"].ToString()) >= 0)
                    )
                {
                    Int32 DocumentId = Convert.ToInt32(rv.Row["ApDocumentId"]);
                    TempDS.Merge(TRemote.MFinance.AP.WebConnectors.LoadAApDocument(FLedgerNumber, DocumentId));

                    // I've loaded this record in my DS, but I was not given a handle to it, so I need to find it!
                    TempDS.AApDocument.DefaultView.Sort = AApDocumentTable.GetApDocumentIdDBName();
                    Int32          Idx         = TempDS.AApDocument.DefaultView.Find(DocumentId);
                    AApDocumentRow DocumentRow = TempDS.AApDocument[Idx];

                    if ("|POSTED|PARTPAID|".IndexOf("|" + DocumentRow["a_document_status_c"].ToString()) >= 0)
                    {
                        TaggedDocuments.Add(DocumentId);
                    }
                }
            }

            if (TaggedDocuments.Count == 0)
            {
                return;
            }

            TFrmAPPayment frm = new TFrmAPPayment(this);

            if (frm.AddDocumentsToPayment(TempDS, FLedgerNumber, TaggedDocuments))
            {
                frm.Show();
            }
        }
        /// <summary>
        /// Pay all tagged documents
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void PayAllTagged(object sender, EventArgs e)
        {
            // This will throw an exception if insufficient permissions
            TSecurityChecks.CheckUserModulePermissions("FINANCE-2", "PayAllTagged [raised by Client Proxy for ModuleAccessManager]");

            string MsgTitle = Catalog.GetString("Document Payment");

            this.Cursor = Cursors.WaitCursor;
            AccountsPayableTDS TempDS        = LoadTaggedDocuments();
            TFrmAPPayment      PaymentScreen = new TFrmAPPayment(FMainForm);

            List <int> PayTheseDocs = new List <int>();

            foreach (DataRowView rv in grdInvoices.PagedDataTable.DefaultView)
            {
                if ((rv.Row["Selected"].Equals(true) &&
                     ("|POSTED|PARTPAID|".IndexOf("|" + rv.Row["DocumentStatus"].ToString() + "|") >= 0)))
                {
                    PayTheseDocs.Add(Convert.ToInt32(rv.Row["ApDocumentId"]));
                }
            }

            if (PayTheseDocs.Count > 0)
            {
                if (PaymentScreen.AddDocumentsToPayment(TempDS, FMainForm.LedgerNumber, PayTheseDocs))
                {
                    this.Cursor = Cursors.Default;
                    PaymentScreen.Show();
                }

                this.Cursor = Cursors.Default;
            }
            else
            {
                this.Cursor = Cursors.Default;
                MessageBox.Show(Catalog.GetString("There are no tagged documents to be paid."), MsgTitle);
            }
        }
        /// <summary>
        /// Check that the cost centres referred to are OK with the accounts I'm using. If not a message is displayed.
        /// </summary>
        /// <param name="Atds"></param>
        /// <param name="AApDocument"></param>
        /// <returns>false if any detail lines have incompatible cost centres.</returns>
        public static bool AllLinesAccountsOK(AccountsPayableTDS Atds, AApDocumentRow AApDocument)
        {
            List <String> AccountCodesCostCentres = new List <string>();

            foreach (AApDocumentDetailRow Row in Atds.AApDocumentDetail.Rows)
            {
                if (Row.ApDocumentId == AApDocument.ApDocumentId)  // NOTE: When called from elsewhere, the TDS could contain data for several documents.
                {
                    if ((Row.AccountCode == "") || (Row.CostCentreCode == ""))
                    {
                        MessageBox.Show(
                            String.Format(Catalog.GetString("Account and Cost Centre must be specified in Document {0}."), AApDocument.DocumentCode),
                            Catalog.GetString("Post Document"), MessageBoxButtons.OK, MessageBoxIcon.Stop);
                        return(false);
                    }

                    String AccountCostCentre = Row.AccountCode + "|" + Row.CostCentreCode;

                    if (!AccountCodesCostCentres.Contains(AccountCostCentre))
                    {
                        AccountCodesCostCentres.Add(AccountCostCentre);
                    }
                }
            }

            //
            // The check is done on the server..

            String ReportMsg = TRemote.MFinance.AP.WebConnectors.CheckAccountsAndCostCentres(AApDocument.LedgerNumber, AccountCodesCostCentres);

            if (ReportMsg != "")
            {
                MessageBox.Show(ReportMsg, Catalog.GetString("Invalid Account"), MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Check the required analysis attributes for the detail lines in this invoice
        /// </summary>
        /// <param name="Atds"></param>
        /// <param name="AApDocument"></param>
        /// <returns>false if any lines don't have the analysis attributes they require</returns>
        public static bool AllLinesHaveAttributes(AccountsPayableTDS Atds, AApDocumentRow AApDocument)
        {
            foreach (AApDocumentDetailRow Row in Atds.AApDocumentDetail.Rows)
            {
                if (Row.ApDocumentId == AApDocument.ApDocumentId)  // NOTE: When called from elsewhere, the TDS could contain data for several documents.
                {
                    bool AllPresent = true;

                    if (DetailLineAttributesRequired(ref AllPresent, Atds, Row))
                    {
                        if (!AllPresent)
                        {
                            System.Windows.Forms.MessageBox.Show(
                                String.Format(Catalog.GetString("Analysis Attributes are required for account {0} in Document {1}."),
                                              Row.AccountCode, AApDocument.DocumentCode),
                                Catalog.GetString("Analysis Attributes"));
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }
        /// <summary>
        /// Load the supplier and all the transactions (invoices and payments) that relate to it.
        /// </summary>
        /// <param name="ALedgerNumber"></param>
        /// <param name="APartnerKey"></param>
        public void LoadSupplier(Int32 ALedgerNumber, Int64 APartnerKey)
        {
            this.Cursor = Cursors.WaitCursor;

            FLedgerNumber = ALedgerNumber;
            FPartnerKey = APartnerKey;
            FMainDS = TRemote.MFinance.AP.WebConnectors.LoadAApSupplier(ALedgerNumber, APartnerKey);

            FSupplierRow = FMainDS.AApSupplier[0];

            // Get our AP ledger settings and enable/disable the corresponding search option on the filter panel
            TFrmLedgerSettingsDialog settings = new TFrmLedgerSettingsDialog(this, ALedgerNumber);
            FRequireApprovalBeforePosting = settings.APRequiresApprovalBeforePosting;
            Control rbtForApproval = FFilterAndFindObject.FilterPanelControls.FindControlByName("rbtForApproval");
            rbtForApproval.Enabled = FRequireApprovalBeforePosting;

            //
            // Transactions older than
            DateTime AgedOlderThan = DateTime.Now;

            if (!FSupplierRow.IsPreferredScreenDisplayNull())
            {
                AgedOlderThan = AgedOlderThan.AddMonths(0 - FSupplierRow.PreferredScreenDisplay);
            }

            FAgedOlderThan = AgedOlderThan.ToString("u");

            txtSupplierName.Text = FMainDS.PPartner[0].PartnerShortName;
            txtSupplierCurrency.Text = FSupplierRow.CurrencyCode;
            FFindObject = TRemote.MFinance.AP.UIConnectors.Find();

            FFindObject.FindSupplierTransactions(FLedgerNumber, FPartnerKey);

            // Start thread that checks for the end of the search operation on the PetraServer
            FKeepUpSearchFinishedCheck = true;
            Thread FinishedCheckThread = new Thread(new ThreadStart(SearchFinishedCheckThread));
            FinishedCheckThread.Start();

            this.Text = Catalog.GetString("Supplier Transactions") + " - " + TFinanceControls.GetLedgerNumberAndName(FLedgerNumber);
        }
Example #28
0
        public static bool ApproveAPDocuments(Int32 ALedgerNumber,
            List <Int32>AApproveTheseDocs,
            out TVerificationResultCollection AVerificationResult)
        {
            AVerificationResult = new TVerificationResultCollection();
            bool ResultValue = false;

            AccountsPayableTDS TempDS = new AccountsPayableTDS();

            if (AApproveTheseDocs.Count == 0)
            {
                AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Approve AP Documents"),
                        Catalog.GetString("Nothing to do - the document list is empty"),
                        TResultSeverity.Resv_Noncritical));
                return false;
            }

            foreach (Int32 ApDocumentId in AApproveTheseDocs)
            {
                TempDS.Merge(LoadAApDocument(ALedgerNumber, ApDocumentId)); // This gives me documents, details, and potentially ap_anal_attrib records.
            }

            foreach (AApDocumentRow ApDocumentRow in TempDS.AApDocument.Rows)
            {
                if (ApDocumentRow.DocumentStatus == MFinanceConstants.AP_DOCUMENT_OPEN)
                {
                    ApDocumentRow.DocumentStatus = MFinanceConstants.AP_DOCUMENT_APPROVED;
                }
                else
                {
                    AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Approve AP Documents"),
                            Catalog.GetString("Only OPEN documents can be approved"),
                            TResultSeverity.Resv_Noncritical));
                    return false;
                }
            }

            TDBTransaction SubmitChangesTransaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.Serializable);

            try
            {
                AApDocumentAccess.SubmitChanges(TempDS.AApDocument, SubmitChangesTransaction);
                DBAccess.GDBAccessObj.CommitTransaction();
                ResultValue = true;
            }
            catch (Exception Exc)
            {
                TLogging.Log("An Exception occured during the approval of AP Documents:" + Environment.NewLine + Exc.ToString());

                DBAccess.GDBAccessObj.RollbackTransaction();

                AVerificationResult.Add(new TVerificationResult(Catalog.GetString("Approve AP Documents"), Exc.Message, TResultSeverity.Resv_Critical));

                throw;
            }

            return ResultValue;
        }
        /// create new AP info
        public static AApDocumentRow CreateNewAPInfo(Int64 APartnerKey, ref AccountsPayableTDS AMainDS)
        {
            ALedgerTable LedgerTable = ALedgerAccess.LoadAll(DBAccess.GDBAccessObj.Transaction);

            AMainDS = TAPTransactionWebConnector.CreateAApDocument(((ALedgerRow)LedgerTable.Rows[0]).LedgerNumber, APartnerKey, true);

            // Create a new RecurringGiftBatch
            AApDocumentRow Document = AMainDS.AApDocument[0];
            Document.DocumentCode = "TEST";
            Document.CreditNoteFlag = false;
            Document.DateIssued = DateTime.Today;
            Document.DateEntered = DateTime.Today;
            Document.TotalAmount = 0;
            Document.CurrencyCode = "EUR";
            Document.LastDetailNumber = 0;

            // Create a new RecurringGift record
            AApSupplierRow ApSupplierRow = AMainDS.AApSupplier.NewRowTyped();
            ApSupplierRow.PartnerKey = APartnerKey;
            ApSupplierRow.CurrencyCode = "EUR";
            AMainDS.AApSupplier.Rows.Add(ApSupplierRow);

            return Document;
        }
Example #30
0
        /// <summary>
        /// Load the Analysis Attributes for this document
        /// </summary>
        /// <param name="AMainDS"></param>
        /// <param name="ALedgerNumber"></param>
        /// <param name="AApDocumentId"></param>
        /// <param name="ATransaction"></param>
        /// <returns>true if all required attributes are present</returns>
        private static bool AttributesAllOK(AccountsPayableTDS AMainDS, Int32 ALedgerNumber, int AApDocumentId, TDBTransaction ATransaction)
        {
            AMainDS.AApDocumentDetail.DefaultView.RowFilter =
                String.Format("{0}={1}", AApDocumentDetailTable.GetApDocumentIdDBName(), AApDocumentId);

            LoadAnalysisAttributes(AMainDS, ALedgerNumber, ATransaction);

            AApAnalAttribAccess.LoadViaAApDocument(AMainDS, AApDocumentId, ATransaction);

            foreach (DataRowView rv in AMainDS.AApDocumentDetail.DefaultView)
            {
                AApDocumentDetailRow DetailRow = (AApDocumentDetailRow)rv.Row;
                AMainDS.AAnalysisAttribute.DefaultView.RowFilter =
                    String.Format("{0}='{1}'", AAnalysisAttributeTable.GetAccountCodeDBName(), DetailRow.AccountCode);

                if (AMainDS.AAnalysisAttribute.DefaultView.Count > 0)
                {
                    foreach (DataRowView aa_rv in AMainDS.AAnalysisAttribute.DefaultView)
                    {
                        AAnalysisAttributeRow AttrRow = (AAnalysisAttributeRow)aa_rv.Row;

                        AMainDS.AApAnalAttrib.DefaultView.RowFilter =
                            String.Format("{0}={1} AND {2}='{3}'",
                                AApAnalAttribTable.GetDetailNumberDBName(), DetailRow.DetailNumber,
                                AApAnalAttribTable.GetAccountCodeDBName(), AttrRow.AccountCode);

                        if (AMainDS.AApAnalAttrib.DefaultView.Count == 0)
                        {
                            return false;
                        }
                    }
                }
            }

            return true;
        }
Example #31
0
        /// <summary>
        /// creates the GL batch needed for posting the AP Documents
        /// </summary>
        /// <param name="ALedgerNumber"></param>
        /// <param name="APostingDate"></param>
        /// <param name="Reversal"></param>
        /// <param name="APDataset"></param>
        /// <returns>Batch for posting</returns>
        private static GLBatchTDS CreateGLBatchAndTransactionsForPosting(
            Int32 ALedgerNumber,
            DateTime APostingDate,
            Boolean Reversal,
            ref AccountsPayableTDS APDataset)
        {
            // create one GL batch
            GLBatchTDS GLDataset = TGLTransactionWebConnector.CreateABatch(ALedgerNumber);

            ABatchRow batch = GLDataset.ABatch[0];

            batch.BatchDescription = Catalog.GetString("Accounts Payable");

            if (Reversal)
            {
                batch.BatchDescription = Catalog.GetString("Reversal: ") + batch.BatchDescription;
            }

            batch.DateEffective = APostingDate;
            batch.BatchStatus = MFinanceConstants.BATCH_UNPOSTED;

            // since the list of documents can be for several suppliers, the currency might be different; group by currency first
            SortedList <string, List <AApDocumentRow>>DocumentsByCurrency = new SortedList <string, List <AApDocumentRow>>();

            foreach (AApDocumentRow row in APDataset.AApDocument.Rows)
            {
                string CurrencyCode = (row.CurrencyCode + "|" + row.ExchangeRateToBase.ToString());  // If douments with the same currency are using different

                // exchange rates, I'm going to handle them separately.
                if (!DocumentsByCurrency.ContainsKey(CurrencyCode))
                {
                    DocumentsByCurrency.Add(CurrencyCode, new List <AApDocumentRow>());
                }

                DocumentsByCurrency[CurrencyCode].Add(row);
            }

            Int32 CounterJournals = 1;

            // Add journal for each currency / Exchange Rate and the transactions
            foreach (string CurrencyCode in DocumentsByCurrency.Keys)
            {
                AJournalRow journal = GLDataset.AJournal.NewRowTyped();
                journal.LedgerNumber = batch.LedgerNumber;
                journal.BatchNumber = batch.BatchNumber;
                journal.JournalNumber = CounterJournals++;
                journal.DateEffective = batch.DateEffective;
                journal.TransactionCurrency = CurrencyCode.Substring(0, CurrencyCode.IndexOf("|"));
                journal.JournalDescription = "AP";

                int baseCurrencyDecimalPlaces = 0; // This will not be used unless this is a foreign journal.
                int intlCurrencyDecimalPlaces = 0;

                if (journal.TransactionCurrency != GLDataset.ALedger[0].BaseCurrency)
                {
                    baseCurrencyDecimalPlaces = StringHelper.DecimalPlacesForCurrency(GLDataset.ALedger[0].BaseCurrency);
                    intlCurrencyDecimalPlaces = StringHelper.DecimalPlacesForCurrency(GLDataset.ALedger[0].IntlCurrency);
                }

                if (Reversal)
                {
                    journal.JournalDescription = "Reversal: AP";
                }

                journal.TransactionTypeCode = CommonAccountingTransactionTypesEnum.INV.ToString();
                journal.SubSystemCode = CommonAccountingSubSystemsEnum.AP.ToString();
                journal.DateOfEntry = DateTime.Now;

                // I'm not using the Daily Exchange Rate, since the exchange rate has been specified by the user in the document.
                // using the exchange rate from the first ap document in this set of documents with same currency and exchange rate
                journal.ExchangeRateToBase = DocumentsByCurrency[CurrencyCode][0].ExchangeRateToBase;
                journal.ExchangeRateTime = 0;
                GLDataset.AJournal.Rows.Add(journal);

                Int32 TransactionCounter = 1;

                foreach (AApDocumentRow document in DocumentsByCurrency[CurrencyCode])
                {
                    ATransactionRow transaction = null;
                    DataView DocumentDetails = APDataset.AApDocumentDetail.DefaultView;
                    DocumentDetails.RowFilter = AApDocumentDetailTable.GetApDocumentIdDBName() + " = " + document.ApDocumentId.ToString();

                    string SupplierShortName;
                    TPartnerClass SupplierPartnerClass;
                    TPartnerServerLookups.GetPartnerShortName(document.PartnerKey, out SupplierShortName, out SupplierPartnerClass);

                    foreach (DataRowView rowview in DocumentDetails)
                    {
                        AApDocumentDetailRow documentDetail = (AApDocumentDetailRow)rowview.Row;


                        transaction = GLDataset.ATransaction.NewRowTyped();
                        transaction.LedgerNumber = journal.LedgerNumber;
                        transaction.BatchNumber = journal.BatchNumber;
                        transaction.JournalNumber = journal.JournalNumber;
                        transaction.TransactionNumber = TransactionCounter++;
                        transaction.TransactionAmount = documentDetail.Amount;
                        transaction.TransactionDate = batch.DateEffective;
                        transaction.SystemGenerated = true;

                        // Analysis Attributes - Any attributes linked to this row,
                        // I need to create equivalents in the Transaction DS.

                        APDataset.AApAnalAttrib.DefaultView.RowFilter = String.Format("{0}={1} AND {2}={3}",
                            AApAnalAttribTable.GetDetailNumberDBName(), documentDetail.DetailNumber,
                            AApAnalAttribTable.GetApDocumentIdDBName(), document.ApDocumentId);

                        foreach (DataRowView rv in APDataset.AApAnalAttrib.DefaultView)
                        {
                            AApAnalAttribRow RowSource = (AApAnalAttribRow)rv.Row;
                            ATransAnalAttribRow RowDest = GLDataset.ATransAnalAttrib.NewRowTyped();

                            RowDest.LedgerNumber = RowSource.LedgerNumber;
                            RowDest.BatchNumber = journal.BatchNumber;
                            RowDest.JournalNumber = journal.JournalNumber;
                            RowDest.TransactionNumber = transaction.TransactionNumber;
                            RowDest.AccountCode = RowSource.AccountCode;
                            RowDest.CostCentreCode = documentDetail.CostCentreCode;
                            RowDest.AnalysisTypeCode = RowSource.AnalysisTypeCode;
                            RowDest.AnalysisAttributeValue = RowSource.AnalysisAttributeValue;

                            GLDataset.ATransAnalAttrib.Rows.Add(RowDest);
                        }

                        if (document.CreditNoteFlag)
                        {
                            transaction.TransactionAmount *= -1;
                        }

                        if (Reversal)
                        {
                            transaction.TransactionAmount *= -1; // this is going to post everything backwards for me.
                        }

                        transaction.DebitCreditIndicator = (transaction.TransactionAmount > 0);

                        if (transaction.TransactionAmount < 0)
                        {
                            transaction.TransactionAmount *= -1;
                        }

                        transaction.AmountInBaseCurrency = GLRoutines.Divide(transaction.TransactionAmount,
                            journal.ExchangeRateToBase, baseCurrencyDecimalPlaces);

                        transaction.AmountInIntlCurrency = GLRoutines.Divide(transaction.AmountInBaseCurrency,
                            TExchangeRateTools.GetDailyExchangeRate(
                                GLDataset.ALedger[0].BaseCurrency,
                                GLDataset.ALedger[0].IntlCurrency,
                                transaction.TransactionDate),
                            intlCurrencyDecimalPlaces);

                        transaction.AccountCode = documentDetail.AccountCode;
                        transaction.CostCentreCode = documentDetail.CostCentreCode;
                        transaction.Narrative = "AP " + document.ApNumber.ToString() + " - " + documentDetail.Narrative + " - " + SupplierShortName;

                        if (Reversal)
                        {
                            transaction.Narrative = "Reversal: " + transaction.Narrative;
                        }

                        transaction.Reference = documentDetail.ItemRef;
//                      transaction.Reference = "AP " + document.ApNumber.ToString() + " - " + document.DocumentCode;

                        transaction.DetailNumber = documentDetail.DetailNumber;

                        GLDataset.ATransaction.Rows.Add(transaction);
                    }

                    // create one transaction for the AP account
                    transaction = GLDataset.ATransaction.NewRowTyped();
                    transaction.LedgerNumber = journal.LedgerNumber;
                    transaction.BatchNumber = journal.BatchNumber;
                    transaction.JournalNumber = journal.JournalNumber;
                    transaction.TransactionNumber = TransactionCounter++;
                    transaction.TransactionAmount = document.TotalAmount;
                    transaction.TransactionDate = batch.DateEffective;
                    transaction.SystemGenerated = true;

                    if (!document.CreditNoteFlag)
                    {
                        transaction.TransactionAmount *= -1;
                    }

                    if (Reversal)
                    {
                        transaction.TransactionAmount *= -1; // this is going to post everything backwards for me.
                    }

                    transaction.DebitCreditIndicator = (transaction.TransactionAmount > 0);

                    if (transaction.TransactionAmount < 0)
                    {
                        transaction.TransactionAmount *= -1;
                    }

                    transaction.AmountInIntlCurrency = GLRoutines.Divide(transaction.TransactionAmount,
                        TExchangeRateTools.GetDailyExchangeRate(
                            journal.TransactionCurrency,
                            GLDataset.ALedger[0].IntlCurrency,
                            transaction.TransactionDate), intlCurrencyDecimalPlaces);

                    transaction.AmountInBaseCurrency = GLRoutines.Divide(transaction.TransactionAmount,
                        journal.ExchangeRateToBase, baseCurrencyDecimalPlaces);

                    transaction.AccountCode = document.ApAccount;
                    transaction.CostCentreCode = TGLTransactionWebConnector.GetStandardCostCentre(ALedgerNumber);
                    transaction.Reference = "AP " + document.ApNumber.ToString() + " - " + document.DocumentCode;
                    transaction.Narrative = transaction.Reference + " - " + SupplierShortName;

                    if (Reversal)
                    {
                        transaction.Narrative = "Reversal: " + transaction.Narrative;
                    }

                    transaction.DetailNumber = 0;

                    GLDataset.ATransaction.Rows.Add(transaction);
                }

                journal.LastTransactionNumber = TransactionCounter - 1;
            }

            batch.LastJournal = CounterJournals - 1;

            return GLDataset;
        }
Example #32
0
        public static bool ReversePayment(Int32 ALedgerNumber,
            Int32 APaymentNumber,
            DateTime APostingDate,
            out TVerificationResultCollection AVerifications)
        {
            //
            // I need to create new documents and post them.

            // First, a squeaky clean TDS, and also one with the existing payment:
            AccountsPayableTDS ReverseDS = new AccountsPayableTDS();
            AccountsPayableTDS TempDS = LoadAPPayment(ALedgerNumber, APaymentNumber);

            Int32 NewApNum = -1;

            AVerifications = new TVerificationResultCollection();

            // This transaction encloses the entire operation.
            // I can call lower-level functions, so long as they use
            // GetNewOrExistingTransaction.

            TDBTransaction ReversalTransaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.Serializable);
            Boolean MustBeApproved = LedgerRquiresDocumentApproval(ALedgerNumber, ReversalTransaction);

            List <Int32>PostTheseDocs = new List <Int32>();
            try
            {
                //
                // Now produce a reversed copy of each referenced document
                //
                TempDS.AApDocument.DefaultView.Sort = AApDocumentTable.GetApDocumentIdDBName();
                TempDS.AApPayment.DefaultView.Sort = AApPaymentTable.GetPaymentNumberDBName();

                foreach (AApDocumentPaymentRow DocPaymentRow in TempDS.AApDocumentPayment.Rows)
                {
                    Int32 DocIdx = TempDS.AApDocument.DefaultView.Find(DocPaymentRow.ApDocumentId);
                    AApDocumentRow OldDocumentRow = TempDS.AApDocument[DocIdx];
                    AccountsPayableTDSAApDocumentRow NewDocumentRow = ReverseDS.AApDocument.NewRowTyped();
                    DocIdx = TempDS.AApPayment.DefaultView.Find(DocPaymentRow.PaymentNumber);
                    AApPaymentRow OldPaymentRow = TempDS.AApPayment[DocIdx];
                    DataUtilities.CopyAllColumnValues(OldDocumentRow, NewDocumentRow);
                    NewDocumentRow.ApDocumentId = (Int32)TSequenceWebConnector.GetNextSequence(TSequenceNames.seq_ap_document);

                    PostTheseDocs.Add(NewDocumentRow.ApDocumentId);

                    NewDocumentRow.CreditNoteFlag = !OldDocumentRow.CreditNoteFlag; // Here's the actual reversal!
                    NewDocumentRow.DocumentCode = "Reversal " + OldDocumentRow.DocumentCode;
                    NewDocumentRow.Reference = "Reversal " + OldDocumentRow.Reference;
                    NewDocumentRow.DocumentStatus = MustBeApproved ? MFinanceConstants.AP_DOCUMENT_APPROVED : MFinanceConstants.AP_DOCUMENT_OPEN;

                    NewDocumentRow.DateCreated = DateTime.Now;
                    NewDocumentRow.DateEntered = DateTime.Now;
                    NewDocumentRow.ApNumber = NextApDocumentNumber(ALedgerNumber, ReversalTransaction);
                    NewDocumentRow.ExchangeRateToBase = OldDocumentRow.ExchangeRateToBase;
                    NewDocumentRow.SavedExchangeRate = OldPaymentRow.ExchangeRateToBase;
                    ReverseDS.AApDocument.Rows.Add(NewDocumentRow);

                    TempDS.AApDocumentDetail.DefaultView.RowFilter = String.Format("{0}={1}",
                        AApDocumentDetailTable.GetApDocumentIdDBName(), OldDocumentRow.ApDocumentId);

                    foreach (DataRowView rv in TempDS.AApDocumentDetail.DefaultView)
                    {
                        AApDocumentDetailRow OldDetailRow = (AApDocumentDetailRow)rv.Row;
                        AApDocumentDetailRow NewDetailRow = ReverseDS.AApDocumentDetail.NewRowTyped();
                        DataUtilities.CopyAllColumnValues(OldDetailRow, NewDetailRow);
                        NewDetailRow.ApDocumentId = NewDocumentRow.ApDocumentId;
                        ReverseDS.AApDocumentDetail.Rows.Add(NewDetailRow);
                    }

                    //
                    // if the original invoice has AnalAttrib records attached, I need to copy those over..
                    TempDS.AApAnalAttrib.DefaultView.RowFilter = String.Format("{0}={1}",
                        AApAnalAttribTable.GetApDocumentIdDBName(), OldDocumentRow.ApDocumentId);

                    foreach (DataRowView rv in TempDS.AApAnalAttrib.DefaultView)
                    {
                        AApAnalAttribRow OldAttribRow = (AApAnalAttribRow)rv.Row;
                        AApAnalAttribRow NewAttribRow = ReverseDS.AApAnalAttrib.NewRowTyped();
                        DataUtilities.CopyAllColumnValues(OldAttribRow, NewAttribRow);
                        NewAttribRow.ApDocumentId = NewDocumentRow.ApDocumentId;
                        ReverseDS.AApAnalAttrib.Rows.Add(NewAttribRow);
                    }
                }

                //
                // Save these new documents, with their details and analAttribs.
                if (SaveAApDocument(ref ReverseDS, out AVerifications) != TSubmitChangesResult.scrOK)
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();
                    return false;
                }

                //
                // Now I can post these new documents, and pay them:
                //

                foreach (AccountsPayableTDSAApDocumentRow DocumentRow in ReverseDS.AApDocument.Rows)
                {
                    //
                    // For foreign invoices,
                    // I need to ensure that the reverse payment uses the exchange rate that was used
                    // when the original document was paid.
                    //
                    Decimal PaymentExchangeRate = DocumentRow.SavedExchangeRate;
                    DocumentRow.SavedExchangeRate = DocumentRow.ExchangeRateToBase;
                    DocumentRow.ExchangeRateToBase = PaymentExchangeRate;
                }

                if (!PostAPDocuments(
                        ALedgerNumber,
                        PostTheseDocs,
                        APostingDate,
                        false,
                        out AVerifications))
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();
                    return false;
                }

                CreatePaymentTableEntries(ref ReverseDS, ALedgerNumber, PostTheseDocs);
//              AccountsPayableTDSAApPaymentTable AApPayment = ReverseDS.AApPayment;
//              AccountsPayableTDSAApDocumentPaymentTable AApDocumentPayment = ReverseDS.AApDocumentPayment;

                //
                // For foreign invoices,
                // I need to ensure that the invoice shows the exchange rate that was used
                // when the original document was posted.
                //

                foreach (AccountsPayableTDSAApDocumentRow DocumentRow in ReverseDS.AApDocument.Rows)
                {
                    //
                    // I'll restore the exchange rates I save above...
                    DocumentRow.ExchangeRateToBase = DocumentRow.SavedExchangeRate; // If this exchange rate is different to the one
                                                                                    // used in the payment, a "Forex Reval" transaction will be
                                                                                    // created to balance the books.
                }

                if (!PostAPPayments(
                        ref ReverseDS,
                        APostingDate,
                        out AVerifications))
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();
                    return false;
                }

                //
                // Now I need to re-create and Post new documents that match the previous ones that were reversed!
                //

                AccountsPayableTDS CreateDs = new AccountsPayableTDS();
                NewApNum = -1;

                foreach (AApDocumentPaymentRow PaymentRow in TempDS.AApDocumentPayment.Rows)
                {
                    Int32 DocIdx = TempDS.AApDocument.DefaultView.Find(PaymentRow.ApDocumentId);
                    AApDocumentRow OldDocumentRow = TempDS.AApDocument[DocIdx];
                    AApDocumentRow NewDocumentRow = CreateDs.AApDocument.NewRowTyped();

                    DataUtilities.CopyAllColumnValues(OldDocumentRow, NewDocumentRow);
                    NewDocumentRow.ApDocumentId = (Int32)TSequenceWebConnector.GetNextSequence(TSequenceNames.seq_ap_document);
                    NewDocumentRow.DocumentCode = "Duplicate " + OldDocumentRow.DocumentCode;
                    NewDocumentRow.Reference = "Duplicate " + OldDocumentRow.Reference;
                    NewDocumentRow.DateEntered = APostingDate;
                    NewDocumentRow.ApNumber = NewApNum;
                    NewDocumentRow.DocumentStatus = MustBeApproved ? MFinanceConstants.AP_DOCUMENT_APPROVED : MFinanceConstants.AP_DOCUMENT_OPEN;
                    CreateDs.AApDocument.Rows.Add(NewDocumentRow);

                    TempDS.AApDocumentDetail.DefaultView.RowFilter = String.Format("{0}={1}",
                        AApDocumentDetailTable.GetApDocumentIdDBName(), OldDocumentRow.ApDocumentId);

                    foreach (DataRowView rv in TempDS.AApDocumentDetail.DefaultView)
                    {
                        AApDocumentDetailRow OldDetailRow = (AApDocumentDetailRow)rv.Row;
                        AApDocumentDetailRow NewDetailRow = CreateDs.AApDocumentDetail.NewRowTyped();
                        DataUtilities.CopyAllColumnValues(OldDetailRow, NewDetailRow);
                        NewDetailRow.ApDocumentId = NewDocumentRow.ApDocumentId;
                        CreateDs.AApDocumentDetail.Rows.Add(NewDetailRow);
                    }

                    //
                    // if the invoice had AnalAttrib records attached, I need to copy those over..
                    TempDS.AApAnalAttrib.DefaultView.RowFilter = String.Format("{0}={1}",
                        AApAnalAttribTable.GetApDocumentIdDBName(), OldDocumentRow.ApDocumentId);

                    foreach (DataRowView rv in TempDS.AApAnalAttrib.DefaultView)
                    {
                        AApAnalAttribRow OldAttribRow = (AApAnalAttribRow)rv.Row;
                        AApAnalAttribRow NewAttribRow = CreateDs.AApAnalAttrib.NewRowTyped();
                        DataUtilities.CopyAllColumnValues(OldAttribRow, NewAttribRow);
                        NewAttribRow.ApDocumentId = NewDocumentRow.ApDocumentId;
                        CreateDs.AApAnalAttrib.Rows.Add(NewAttribRow);
                    }

                    NewApNum--; // These negative record numbers should be replaced on posting.
                }

                if (SaveAApDocument(ref CreateDs, out AVerifications) != TSubmitChangesResult.scrOK)
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();
                    return false;
                }

                //
                // The process of saving those new documents should have given them all shiny new ApNumbers,
                // So finally I need to make a list of those Document numbers, and post them.
                PostTheseDocs.Clear();

                foreach (AApDocumentRow DocumentRow in CreateDs.AApDocument.Rows)
                {
                    PostTheseDocs.Add(DocumentRow.ApDocumentId);
                }

                if (!PostAPDocuments(ALedgerNumber, PostTheseDocs, APostingDate, false, out AVerifications))
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();
                    return false;
                }

                DBAccess.GDBAccessObj.CommitTransaction();
                return true;
            }
            catch (Exception e)
            {
                DBAccess.GDBAccessObj.RollbackTransaction(); // throw away all that...
                AVerifications = new TVerificationResultCollection();
                TLogging.Log("In ReversePayment: exception " + e.Message);
                TLogging.Log(e.StackTrace);

                TVerificationResult Res = new TVerificationResult("Exception", e.Message + "\r\n" + e.StackTrace, TResultSeverity.Resv_Critical);
                AVerifications.Add(Res);
                return false;
            }
        }
Example #33
0
        public static AccountsPayableTDS CreateAApDocumentDetail(Int32 ALedgerNumber,
            Int32 AApDocumentId,
            string AApSupplier_DefaultExpAccount,
            string AApSupplier_DefaultCostCentre,
            decimal AAmount,
            Int32 ALastDetailNumber)
        {
            // create the DataSet that will later be passed to the Client
            AccountsPayableTDS MainDS = new AccountsPayableTDS();

            AApDocumentDetailRow NewRow = MainDS.AApDocumentDetail.NewRowTyped();

            NewRow.ApDocumentId = AApDocumentId;
            NewRow.LedgerNumber = ALedgerNumber;
            NewRow.DetailNumber = ALastDetailNumber + 1;
            NewRow.Amount = AAmount;
            NewRow.CostCentreCode = AApSupplier_DefaultCostCentre;
            NewRow.AccountCode = AApSupplier_DefaultExpAccount;

            MainDS.AApDocumentDetail.Rows.Add(NewRow);

            // Remove all Tables that were not filled with data before remoting them.
            MainDS.RemoveEmptyTables();

            return MainDS;
        }
Example #34
0
        public static bool CreatePaymentTableEntries(ref AccountsPayableTDS ADataset, Int32 ALedgerNumber, List <Int32>ADocumentsToPay)
        {
            ADataset.AApDocument.DefaultView.Sort = AApDocumentTable.GetApDocumentIdDBName();

            foreach (Int32 ApDocId in ADocumentsToPay)
            {
                int indexDocument = ADataset.AApDocument.DefaultView.Find(ApDocId);
                //
                // I might not have the document loaded - if not I'll load it now.

                if (indexDocument == -1)
                {
                    ADataset.Merge(LoadAApDocument(ALedgerNumber, ApDocId));
                    indexDocument = ADataset.AApDocument.DefaultView.Find(ApDocId);
                }

                if (indexDocument != -1)  // If it's not loaded now, something really bad has happened!
                {
                    AccountsPayableTDSAApDocumentRow apDocumentRow =
                        (AccountsPayableTDSAApDocumentRow)ADataset.AApDocument.DefaultView[indexDocument].Row;

                    AApSupplierRow supplierRow = GetSupplier(ADataset.AApSupplier, apDocumentRow.PartnerKey);

                    if (supplierRow == null)
                    {
                        // I need to load the supplier record into the TDS...
                        ADataset.Merge(LoadAApSupplier(apDocumentRow.LedgerNumber, apDocumentRow.PartnerKey));
                        supplierRow = GetSupplier(ADataset.AApSupplier, apDocumentRow.PartnerKey);
                    }

                    if (supplierRow != null)
                    {
                        AccountsPayableTDSAApPaymentRow supplierPaymentsRow = null;

                        // My TDS may already have a AApPayment row for this supplier.
                        ADataset.AApPayment.DefaultView.RowFilter = String.Format("{0}='{1}'", AccountsPayableTDSAApPaymentTable.GetSupplierKeyDBName(
                                ), supplierRow.PartnerKey);

                        if (ADataset.AApPayment.DefaultView.Count > 0)
                        {
                            supplierPaymentsRow = (AccountsPayableTDSAApPaymentRow)ADataset.AApPayment.DefaultView[0].Row;

                            if (apDocumentRow.CreditNoteFlag)
                            {
                                supplierPaymentsRow.TotalAmountToPay -= apDocumentRow.OutstandingAmount;
                            }
                            else
                            {
                                supplierPaymentsRow.TotalAmountToPay += apDocumentRow.OutstandingAmount;
                            }

                            supplierPaymentsRow.Amount = supplierPaymentsRow.TotalAmountToPay; // The user may choose to change the amount paid.
                        }
                        else
                        {
                            supplierPaymentsRow = ADataset.AApPayment.NewRowTyped();
                            supplierPaymentsRow.LedgerNumber = ADataset.AApDocument[0].LedgerNumber;
                            supplierPaymentsRow.PaymentNumber = -1 * (ADataset.AApPayment.Count + 1);
                            supplierPaymentsRow.SupplierKey = supplierRow.PartnerKey;
                            supplierPaymentsRow.MethodOfPayment = supplierRow.PaymentType;
                            supplierPaymentsRow.BankAccount = supplierRow.DefaultBankAccount;

                            supplierPaymentsRow.CurrencyCode = apDocumentRow.CurrencyCode;
                            supplierPaymentsRow.ExchangeRateToBase = apDocumentRow.ExchangeRateToBase; // The client may change this.

                            TPartnerClass partnerClass;
                            string partnerShortName;
                            TPartnerServerLookups.GetPartnerShortName(
                                supplierRow.PartnerKey,
                                out partnerShortName,
                                out partnerClass);
                            supplierPaymentsRow.SupplierName = Ict.Petra.Shared.MPartner.Calculations.FormatShortName(partnerShortName,
                                eShortNameFormat.eReverseWithoutTitle);

                            supplierPaymentsRow.ListLabel = supplierPaymentsRow.SupplierName + " (" + supplierPaymentsRow.MethodOfPayment + ")";

                            if (apDocumentRow.CreditNoteFlag)
                            {
                                supplierPaymentsRow.TotalAmountToPay = 0 - apDocumentRow.OutstandingAmount;
                            }
                            else
                            {
                                supplierPaymentsRow.TotalAmountToPay = apDocumentRow.OutstandingAmount;
                            }

                            supplierPaymentsRow.Amount = supplierPaymentsRow.TotalAmountToPay; // The user may choose to change the amount paid.

                            ADataset.AApPayment.Rows.Add(supplierPaymentsRow);
                        }

                        AccountsPayableTDSAApDocumentPaymentRow DocumentPaymentRow = ADataset.AApDocumentPayment.NewRowTyped();
                        DocumentPaymentRow.LedgerNumber = supplierPaymentsRow.LedgerNumber;
                        DocumentPaymentRow.PaymentNumber = supplierPaymentsRow.PaymentNumber;
                        DocumentPaymentRow.ApDocumentId = ApDocId;
                        DocumentPaymentRow.Amount = apDocumentRow.TotalAmount;
                        DocumentPaymentRow.InvoiceTotal = apDocumentRow.OutstandingAmount;

                        if (apDocumentRow.CreditNoteFlag)
                        {
                            DocumentPaymentRow.Amount = 0 - DocumentPaymentRow.Amount;
                            DocumentPaymentRow.InvoiceTotal = 0 - DocumentPaymentRow.InvoiceTotal;
                        }

                        DocumentPaymentRow.PayFullInvoice = true;

                        // TODO: discounts
                        DocumentPaymentRow.HasValidDiscount = false;
                        DocumentPaymentRow.DiscountPercentage = 0;
                        DocumentPaymentRow.UseDiscount = false;
                        DocumentPaymentRow.DocumentCode = apDocumentRow.DocumentCode;
                        DocumentPaymentRow.DocType = (apDocumentRow.CreditNoteFlag ? "CREDIT" : "INVOICE");
                        ADataset.AApDocumentPayment.Rows.Add(DocumentPaymentRow);
                    } // supplierRow != null

                } // indexDocument != -1

            }  // foreach document

            ADataset.AApPayment.DefaultView.RowFilter = "";
            return true;
        }
Example #35
0
        public static AccountsPayableTDS CreateAApDocument(Int32 ALedgerNumber, Int64 APartnerKey, bool ACreditNoteOrInvoice)
        {
            // create the DataSet that will later be passed to the Client
            AccountsPayableTDS MainDS = new AccountsPayableTDS();

            AApDocumentRow NewDocumentRow = MainDS.AApDocument.NewRowTyped();

            NewDocumentRow.ApDocumentId = (Int32)TSequenceWebConnector.GetNextSequence(TSequenceNames.seq_ap_document);
            NewDocumentRow.ApNumber = -1; // This will be assigned later.
            NewDocumentRow.LedgerNumber = ALedgerNumber;
            NewDocumentRow.PartnerKey = APartnerKey;
            NewDocumentRow.CreditNoteFlag = ACreditNoteOrInvoice;
            NewDocumentRow.DocumentStatus = MFinanceConstants.AP_DOCUMENT_OPEN;
            NewDocumentRow.LastDetailNumber = 0;

            bool IsMyOwnTransaction = false; // If I create a transaction here, then I need to rollback when I'm done.
            TDBTransaction Transaction = null;
            try
            {
                Transaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction
                                  (IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out IsMyOwnTransaction);

                ALedgerTable LedgerTbl = ALedgerAccess.LoadByPrimaryKey(ALedgerNumber, Transaction);
                // get the supplier defaults
                AApSupplierRow SupplierRow = AApSupplierAccess.LoadByPrimaryKey(MainDS, APartnerKey, Transaction);

                if (SupplierRow != null)
                {
                    if (!SupplierRow.IsDefaultCreditTermsNull())
                    {
                        NewDocumentRow.CreditTerms = SupplierRow.DefaultCreditTerms;
                    }

                    if (!SupplierRow.IsDefaultDiscountDaysNull())
                    {
                        NewDocumentRow.DiscountDays = SupplierRow.DefaultDiscountDays;
                        NewDocumentRow.DiscountPercentage = 0;
                    }

                    if (!SupplierRow.IsDefaultDiscountPercentageNull())
                    {
                        NewDocumentRow.DiscountPercentage = SupplierRow.DefaultDiscountPercentage;
                    }

                    if (!SupplierRow.IsDefaultApAccountNull())
                    {
                        NewDocumentRow.ApAccount = SupplierRow.DefaultApAccount;
                    }

                    NewDocumentRow.CurrencyCode = SupplierRow.CurrencyCode;
                    NewDocumentRow.ExchangeRateToBase = TExchangeRateTools.GetDailyExchangeRate(NewDocumentRow.CurrencyCode,
                        LedgerTbl[0].BaseCurrency,
                        DateTime.Now);
                }

                MainDS.AApDocument.Rows.Add(NewDocumentRow);

                // I also need a full list of analysis attributes that could apply to this document

                LoadAnalysisAttributes(MainDS, ALedgerNumber, Transaction);
            } // try
            finally
            {
                if ((Transaction != null) && IsMyOwnTransaction)
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();
                }
            }

            return MainDS;
        }
        private static bool DetailLineAttributesRequired(ref bool AllPresent, AccountsPayableTDS Atds, AApDocumentDetailRow DetailRow)
        {
            Atds.AAnalysisAttribute.DefaultView.RowFilter =
                String.Format("{0}='{1}'", AAnalysisAttributeTable.GetAccountCodeDBName(), DetailRow.AccountCode);

            if (Atds.AAnalysisAttribute.DefaultView.Count > 0)
            {
                bool IhaveAllMyAttributes = true;

                //
                // It's possible that my TDS doesn't even have an AnalAttrib table...

                if (Atds.AApAnalAttrib == null)
                {
                    Atds.Merge(new AApAnalAttribTable());
                }

                foreach (DataRowView rv in Atds.AAnalysisAttribute.DefaultView)
                {
                    AAnalysisAttributeRow AttrRow = (AAnalysisAttributeRow)rv.Row;

                    Atds.AApAnalAttrib.DefaultView.RowFilter =
                        String.Format("{0}={1} AND {2}='{3}'",
                                      AApAnalAttribTable.GetDetailNumberDBName(), DetailRow.DetailNumber,
                                      AApAnalAttribTable.GetAccountCodeDBName(), AttrRow.AccountCode);

                    if (Atds.AApAnalAttrib.DefaultView.Count == 0)
                    {
                        IhaveAllMyAttributes = false;
                        break;
                    }

                    foreach (DataRowView rv2 in Atds.AApAnalAttrib.DefaultView)
                    {
                        AApAnalAttribRow AttribValueRow = (AApAnalAttribRow)rv2.Row;

                        if (AttribValueRow.AnalysisAttributeValue == "")
                        {
                            IhaveAllMyAttributes = false;
                            break;
                        }

                        // Is the referenced AttribValue active?
                        AFreeformAnalysisRow referencedRow = (AFreeformAnalysisRow)Atds.AFreeformAnalysis.Rows.Find(
                            new Object[] { AttribValueRow.LedgerNumber, AttribValueRow.AnalysisTypeCode, AttribValueRow.AnalysisAttributeValue }
                            );

                        if ((referencedRow == null) || !referencedRow.Active)
                        {
                            IhaveAllMyAttributes = false;
                            break;
                        }
                    }

                    if (IhaveAllMyAttributes == false)  // because of the test above..
                    {
                        break;
                    }
                }

                AllPresent = IhaveAllMyAttributes;
                return(true);
            }
            else
            {
                AllPresent = true; // This detail line is fully specified
                return(false);     // No attributes are required
            }
        }
        /// <summary>
        /// Set which payments should be paid; initialises the data of this screen
        /// </summary>
        /// <param name="ADataset"></param>
        /// <param name="ALedgerNumber"></param>
        /// <param name="ADocumentsToPay"></param>
        /// <returns>true if there's something to pay</returns>
        public bool AddDocumentsToPayment(AccountsPayableTDS ADataset, Int32 ALedgerNumber, List <Int32>ADocumentsToPay)
        {
            FMainDS = ADataset;
            FLedgerNumber = ALedgerNumber;
            ALedgerTable Tbl = TRemote.MFinance.AP.WebConnectors.GetLedgerInfo(FLedgerNumber);
            FLedgerRow = Tbl[0];

            if (FMainDS.AApPayment == null)
            {
                FMainDS.Merge(new AccountsPayableTDSAApPaymentTable()); // Because of these lines, AddDocumentsToPayment may only be called once per payment.
            }
            else
            {
                FMainDS.AApPayment.Clear();
            }

            if (FMainDS.AApDocumentPayment == null)
            {
                FMainDS.Merge(new AccountsPayableTDSAApDocumentPaymentTable());
            }
            else
            {
                FMainDS.AApDocumentPayment.Clear();
            }

            // I want to check that it'll be OK to pay these documents:
            for (Int32 Idx = ADocumentsToPay.Count - 1; Idx >= 0; Idx--)
            {
                Int32 DocId = ADocumentsToPay[Idx];
                AccountsPayableTDS tempDs = TRemote.MFinance.AP.WebConnectors.LoadAApDocument(ALedgerNumber, DocId);

                if (!ApDocumentCanPay(tempDs, tempDs.AApDocument[0]))
                {
                    ADocumentsToPay.Remove(DocId);
                }
            }

            if (ADocumentsToPay.Count == 0)
            {
                return false;
            }

            TRemote.MFinance.AP.WebConnectors.CreatePaymentTableEntries(ref FMainDS, ALedgerNumber, ADocumentsToPay);
            chkPrintRemittance.Checked = true;
            chkClaimDiscount.Enabled = false;
            chkPrintCheque.Enabled = false;
            chkPrintLabel.Enabled = false;
            ShowDataManual();
            return true;
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="ALedgerNumber"></param>
 /// <param name="APaymentNumber"></param>
 public void ReloadPayment(Int32 ALedgerNumber, Int32 APaymentNumber)
 {
     FMainDS = TRemote.MFinance.AP.WebConnectors.LoadAPPayment(ALedgerNumber, APaymentNumber);
     FLedgerNumber = FMainDS.AApPayment[0].LedgerNumber;
     ALedgerTable Tbl = TRemote.MFinance.AP.WebConnectors.GetLedgerInfo(FLedgerNumber);
     FLedgerRow = Tbl[0];
     ShowData(FMainDS.AApSupplier[0]);
 }
 /// <summary>
 /// todoComment
 /// </summary>
 public void InitializeManualCode()
 {
     FMainDS = new AccountsPayableTDS();
 }
        /// <summary>
        /// Post all tagged documents in one GL Batch
        /// Uses static functions from TFrmAPEditDocument
        /// </summary>
        private void PostTaggedDocuments(object sender, EventArgs e)
        {
            List <Int32>TaggedDocuments = new List <Int32>();
            AccountsPayableTDS TempDS = new AccountsPayableTDS();

            foreach (DataRowView rv in FPagedDataTable.DefaultView)
            {
                if ((rv.Row["Tagged"].Equals(true)) && (rv.Row["Status"].ToString().Length > 0)   // Invoices have status, Payments don't.
                    && ("|POSTED|PARTPAID|PAID".IndexOf("|" + rv.Row["Status"].ToString()) < 0)
                    && (rv.Row["Currency"].ToString() == txtSupplierCurrency.Text)
                    )
                {
                    Int32 DocumentId = Convert.ToInt32(rv.Row["ApDocumentId"]);
                    TempDS.Merge(TRemote.MFinance.AP.WebConnectors.LoadAApDocument(FLedgerNumber, DocumentId));

                    // I've loaded this record in my DS, but I was not given a handle to it, so I need to find it!
                    TempDS.AApDocument.DefaultView.Sort = "a_ap_document_id_i";
                    Int32 Idx = TempDS.AApDocument.DefaultView.Find(DocumentId);
                    AApDocumentRow DocumentRow = TempDS.AApDocument[Idx];

                    if (TFrmAPEditDocument.ApDocumentCanPost(TempDS, DocumentRow))
                    {
                        TaggedDocuments.Add(DocumentId);
                    }
                }
            }

            if (TaggedDocuments.Count == 0)
            {
                return;
            }

            if (TFrmAPEditDocument.PostApDocumentList(TempDS, FLedgerNumber, TaggedDocuments, this))
            {
                // TODO: print reports on successfully posted batch
                MessageBox.Show(Catalog.GetString("The AP documents have been posted successfully!"));

                // TODO: show posting register of GL Batch?

                LoadSupplier(FLedgerNumber, FPartnerKey);
            }
        }
        /// Add all selected invoices to the payment list and show that list so that the user can make the payment
        private void AddTaggedToPayment(object sender, EventArgs e)
        {
            List <Int32>TaggedDocuments = new List <Int32>();
            AccountsPayableTDS TempDS = new AccountsPayableTDS();

            foreach (DataRowView rv in FPagedDataTable.DefaultView)
            {
                if (
                    (rv.Row["Tagged"].Equals(true))
                    && (rv.Row["Currency"].ToString() == txtSupplierCurrency.Text)
                    && ("|POSTED|PARTPAID|".IndexOf("|" + rv.Row["Status"].ToString()) >= 0)
                    )
                {
                    Int32 DocumentId = Convert.ToInt32(rv.Row["ApDocumentId"]);
                    TempDS.Merge(TRemote.MFinance.AP.WebConnectors.LoadAApDocument(FLedgerNumber, DocumentId));

                    // I've loaded this record in my DS, but I was not given a handle to it, so I need to find it!
                    TempDS.AApDocument.DefaultView.Sort = AApDocumentTable.GetApDocumentIdDBName();
                    Int32 Idx = TempDS.AApDocument.DefaultView.Find(DocumentId);
                    AApDocumentRow DocumentRow = TempDS.AApDocument[Idx];

                    if ("|POSTED|PARTPAID|".IndexOf("|" + DocumentRow["a_document_status_c"].ToString()) >= 0)
                    {
                        TaggedDocuments.Add(DocumentId);
                    }
                }
            }

            if (TaggedDocuments.Count == 0)
            {
                return;
            }

            TFrmAPPayment frm = new TFrmAPPayment(this);

            if (frm.AddDocumentsToPayment(TempDS, FLedgerNumber, TaggedDocuments))
            {
                frm.Show();
            }
        }
Example #42
0
        private TVerificationResultCollection ReversePayment(int APaymentNumber, DateTime APeriodEndDate,
                                                             List <int> ADocumentIds, AccountsPayableTDS AApDS)
        {
            string AssertFailMessage = "Failed to reverse AP payment: ";
            TVerificationResultCollection VerificationResult;

            List <Int32> glBatchNumbers;

            // "Un-pay" the specified invoice
            if (!TAPTransactionWebConnector.ReversePayment(FLedgerNumber,
                                                           APaymentNumber,
                                                           APeriodEndDate,
                                                           out glBatchNumbers,
                                                           out VerificationResult))
            {
                Assert.Fail(AssertFailMessage +
                            VerificationResult.BuildVerificationResultString());
            }

            CommonNUnitFunctions.EnsureNullOrEmptyVerificationResult(VerificationResult, AssertFailMessage);   // Guard Assert

            // "Un-post" the specified invoice - returning it to "Approved" status!
            ADocumentIds[0] += 2; // The invoice I posted was reversed, and a duplicate now exists with an Id 2 greater than the original.

            return(PostAPDocument(AApDS, APeriodEndDate, ref ADocumentIds, true));
        }
Example #43
0
        public static bool PostAPPayments(
            ref AccountsPayableTDS MainDS,
            DateTime APostingDate,
            out TVerificationResultCollection AVerificationResult)
        {
            bool NewTransaction;
            TDBTransaction ReadTransaction;

            AVerificationResult = new TVerificationResultCollection();
            bool ResultValue = false;

            if ((MainDS.AApPayment.Rows.Count < 1) || (MainDS.AApDocumentPayment.Rows.Count < 1))
            {
                AVerificationResult = new TVerificationResultCollection();
                AVerificationResult.Add(new TVerificationResult("Post Payment",
                        String.Format("Nothing to do - Payments has {0} rows, Documents has {1} rows.",
                            MainDS.AApPayment.Rows.Count, MainDS.AApDocumentPayment.Rows.Count), TResultSeverity.Resv_Noncritical));
                return false;
            }

            ReadTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.ReadCommitted,
                TEnforceIsolationLevel.eilMinimum, out NewTransaction);

            foreach (AccountsPayableTDSAApDocumentPaymentRow row in MainDS.AApDocumentPayment.Rows)
            {
                AccountsPayableTDSAApDocumentRow documentRow = (AccountsPayableTDSAApDocumentRow)MainDS.AApDocument.Rows.Find(row.ApDocumentId);

                if (documentRow != null)
                {
                    MainDS.AApDocument.Rows.Remove(documentRow);
                }

                documentRow = (AccountsPayableTDSAApDocumentRow)
                              AApDocumentAccess.LoadByPrimaryKey(MainDS, row.ApDocumentId, ReadTransaction);

                SetOutstandingAmount(documentRow, documentRow.LedgerNumber, MainDS.AApDocumentPayment);

                //
                // If the amount paid is negative, this is a refund..
                if (row.Amount < 0)
                {
                    if (row.Amount <= documentRow.OutstandingAmount)
                    {
                        documentRow.DocumentStatus = MFinanceConstants.AP_DOCUMENT_PAID;
                    }
                    else
                    {
                        documentRow.DocumentStatus = MFinanceConstants.AP_DOCUMENT_PARTIALLY_PAID;
                    }
                }
                else
                {
                    if ((row.Amount >= documentRow.OutstandingAmount) || (documentRow.OutstandingAmount == 0.0m))
                    {
                        documentRow.DocumentStatus = MFinanceConstants.AP_DOCUMENT_PAID;
                    }
                    else
                    {
                        documentRow.DocumentStatus = MFinanceConstants.AP_DOCUMENT_PARTIALLY_PAID;
                    }
                }
            }

            // Get max payment number for this ledger
            // PROBLEM: what if two payments are happening at the same time? do we need locking?
            // see also http://sourceforge.net/apps/mantisbt/openpetraorg/view.php?id=50
            object maxPaymentCanBeNull = DBAccess.GDBAccessObj.ExecuteScalar(
                "SELECT MAX(PUB_a_ap_payment.a_payment_number_i) FROM PUB_a_ap_payment WHERE PUB_a_ap_payment.a_ledger_number_i = " +
                MainDS.AApPayment[0].LedgerNumber.ToString(),
                ReadTransaction);
            Int32 maxPaymentNumberInLedger = (maxPaymentCanBeNull == System.DBNull.Value ? 0 : Convert.ToInt32(maxPaymentCanBeNull));

            if (NewTransaction)
            {
                DBAccess.GDBAccessObj.RollbackTransaction();
            }

            foreach (AccountsPayableTDSAApPaymentRow paymentRow in MainDS.AApPayment.Rows)
            {
                paymentRow.PaymentDate = APostingDate;

                paymentRow.Amount = 0.0M;
                Int32 NewPaymentNumber = maxPaymentNumberInLedger + (-1 * paymentRow.PaymentNumber);

                foreach (AccountsPayableTDSAApDocumentPaymentRow docPaymentRow in MainDS.AApDocumentPayment.Rows)
                {
                    if (docPaymentRow.PaymentNumber == paymentRow.PaymentNumber)
                    {
                        paymentRow.Amount += docPaymentRow.Amount;
                        docPaymentRow.PaymentNumber = NewPaymentNumber;
                    }
                }

                paymentRow.PaymentNumber = NewPaymentNumber;
            }

            TDBTransaction SubmitChangesTransaction = null;

            try
            {
                // create GL batch
                GLBatchTDS GLDataset = CreateGLBatchAndTransactionsForPaying(MainDS.AApPayment[0].LedgerNumber,
                    APostingDate,
                    ref MainDS);

                ABatchRow batch = GLDataset.ABatch[0];

                // save the batch
                Boolean PostingWorkedOk = (TGLTransactionWebConnector.SaveGLBatchTDS(ref GLDataset,
                                               out AVerificationResult) == TSubmitChangesResult.scrOK);

                if (PostingWorkedOk)
                {
                    // post the batch
                    PostingWorkedOk = TGLPosting.PostGLBatch(MainDS.AApPayment[0].LedgerNumber, batch.BatchNumber,
                        out AVerificationResult);
                }

                if (!PostingWorkedOk)
                {
                    TVerificationResultCollection MoreResults;

                    TGLPosting.DeleteGLBatch(
                        MainDS.AApPayment[0].LedgerNumber,
                        batch.BatchNumber,
                        out MoreResults);
                    AVerificationResult.AddCollection(MoreResults);

                    return false;
                }

                SubmitChangesTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction
                                               (IsolationLevel.Serializable, TEnforceIsolationLevel.eilMinimum, out NewTransaction);

                // store ApPayment and ApDocumentPayment to database
                AApPaymentAccess.SubmitChanges(MainDS.AApPayment, SubmitChangesTransaction);
                AApDocumentPaymentAccess.SubmitChanges(MainDS.AApDocumentPayment, SubmitChangesTransaction);

                // save changed status of AP documents to database
                AApDocumentAccess.SubmitChanges(MainDS.AApDocument, SubmitChangesTransaction);

                ResultValue = true;
            }
            catch (Exception e)
            {
                // Now I've got payment entries in the GL, and "unposted" payment records.

                TLogging.Log("Posting AP payments: exception " + e.Message);

                if ((SubmitChangesTransaction != null) && NewTransaction)
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();
                }

                AVerificationResult.Add(new TVerificationResult("Post AP Payment",
                        e.Message, TResultSeverity.Resv_Critical));

                throw;
            }

            if ((SubmitChangesTransaction != null) && NewTransaction)
            {
                if (ResultValue)
                {
                    DBAccess.GDBAccessObj.CommitTransaction();
                }
                else
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();
                }
            }

            return ResultValue;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="Atds"></param>
        /// <param name="AdocumentRow"></param>
        /// <returns></returns>
        public static bool ApDocumentCanPay(AccountsPayableTDS Atds, AApDocumentRow AdocumentRow)
        {
            if (!CurrencyIsOkForPaying(Atds, AdocumentRow))
            {
                return false;
            }

            if ("|POSTED|PARTPAID|".IndexOf("|" + AdocumentRow.DocumentStatus) < 0)
            {
                return false;
            }

            return true;
        }
Example #45
0
        public static AccountsPayableTDS LoadAPPayment(Int32 ALedgerNumber, Int32 APaymentNumber)
        {
            bool IsMyOwnTransaction; // If I create a transaction here, then I need to rollback when I'm done.
            TDBTransaction ReadTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction
                                                 (IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out IsMyOwnTransaction);
            AccountsPayableTDS MainDs = new AccountsPayableTDS();

            AccountsPayableTDSAApPaymentRow supplierPaymentsRow = (AccountsPayableTDSAApPaymentRow)
                                                                  AApPaymentAccess.LoadByPrimaryKey(MainDs,
                ALedgerNumber,
                APaymentNumber,
                ReadTransaction);

            if (MainDs.AApPayment.Rows.Count > 0) // If I can load the referenced payment, I'll also load related documents.
            {
                AApDocumentPaymentAccess.LoadViaAApPayment(MainDs, ALedgerNumber, APaymentNumber, ReadTransaction);

                // There may be a batch of several invoices in this payment,
                // but they must be to the same supplier, and in the same currency!
                Int64 PartnerKey = 0;
                AApDocumentRow DocumentRow = null;

                foreach (AccountsPayableTDSAApDocumentPaymentRow Row in MainDs.AApDocumentPayment.Rows)
                {
                    DocumentRow =
                        AApDocumentAccess.LoadByPrimaryKey(MainDs, Row.ApDocumentId, ReadTransaction);

                    PartnerKey = DocumentRow.PartnerKey;
                    Row.InvoiceTotal = DocumentRow.TotalAmount;
                    Row.PayFullInvoice = (MainDs.AApDocumentPayment[0].Amount == DocumentRow.TotalAmount);
                    Row.DocumentCode = DocumentRow.DocumentCode;
                    Row.DocType = (DocumentRow.CreditNoteFlag ? "CREDIT" : "INVOICE");

                    AApDocumentDetailAccess.LoadViaAApDocument(MainDs, Row.ApDocumentId, ReadTransaction);

                    // Then I also need to get any referenced AnalAttrib records
                    MainDs.AApDocumentDetail.DefaultView.RowFilter = String.Format("{0}={1}",
                        AApDocumentDetailTable.GetApDocumentIdDBName(), Row.ApDocumentId);

                    foreach (DataRowView rv in MainDs.AApDocumentDetail.DefaultView)
                    {
                        AApDocumentDetailRow DetailRow = (AApDocumentDetailRow)rv.Row;
                        AApAnalAttribAccess.LoadViaAApDocumentDetail(MainDs, Row.ApDocumentId, DetailRow.DetailNumber, ReadTransaction);
                    }
                }

                PPartnerRow PartnerRow =
                    PPartnerAccess.LoadByPrimaryKey(MainDs, PartnerKey, ReadTransaction);
                supplierPaymentsRow.SupplierKey = PartnerKey;
                supplierPaymentsRow.SupplierName = PartnerRow.PartnerShortName;
                supplierPaymentsRow.CurrencyCode = DocumentRow.CurrencyCode;
                supplierPaymentsRow.ListLabel = supplierPaymentsRow.SupplierName + " (" + supplierPaymentsRow.MethodOfPayment + ")";
                PPartnerLocationAccess.LoadViaPPartner(MainDs, PartnerKey, ReadTransaction);
                PLocationAccess.LoadViaPPartner(MainDs, PartnerKey, ReadTransaction);
                AApSupplierAccess.LoadByPrimaryKey(MainDs, PartnerKey, ReadTransaction);
            }

            if (IsMyOwnTransaction)
            {
                DBAccess.GDBAccessObj.RollbackTransaction();
            }

            return MainDs;
        }
        private static bool CurrencyIsOkForPaying(AccountsPayableTDS Atds, AApDocumentRow AApDocument)
        {
            if (AApDocument.CurrencyCode != Atds.AApSupplier[0].CurrencyCode)
            {
                System.Windows.Forms.MessageBox.Show(
                    String.Format(Catalog.GetString("Document {0} cannot be paid because the supplier's currency has been changed to {1}."),
                        AApDocument.DocumentCode, Atds.AApSupplier[0].CurrencyCode),
                    Catalog.GetString("Pay Document"));
                return false;
            }

            return true;
        }
Example #47
0
        public static TSubmitChangesResult SaveAApDocument(ref AccountsPayableTDS AInspectDS,
            out TVerificationResultCollection AVerificationResult)
        {
            bool IsMyOwnTransaction = false; // If I create a transaction here, then I need to commit it when I'm done.

            AVerificationResult = new TVerificationResultCollection();
            TVerificationResultCollection LocalVerificationResults = new TVerificationResultCollection();
            TSubmitChangesResult SubmitChangesResult = TSubmitChangesResult.scrError;

            if (AInspectDS == null)
            {
                return TSubmitChangesResult.scrNothingToBeSaved;
            }

            TDBTransaction SubmitChangesTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction
                                                          (IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out IsMyOwnTransaction);

            if ((AInspectDS.AApDocument != null) && (AInspectDS.AApDocument.Rows.Count > 0))
            {
                // I want to check that the Invoice numbers are not blank,
                // and that none of the documents already exist in the database.

                foreach (AApDocumentRow NewDocRow in AInspectDS.AApDocument.Rows)
                {
                    if (NewDocRow.DocumentCode.Length == 0)
                    {
                        LocalVerificationResults.Add(new TVerificationResult(Catalog.GetString("Save Document"),
                                Catalog.GetString("The Document has no Document number."),
                                TResultSeverity.Resv_Noncritical));
                        return TSubmitChangesResult.scrInfoNeeded;
                    }

                    AApDocumentRow DocTemplateRow = AInspectDS.AApDocument.NewRowTyped(false);
                    DocTemplateRow.LedgerNumber = NewDocRow.LedgerNumber;
                    DocTemplateRow.PartnerKey = NewDocRow.PartnerKey;
                    DocTemplateRow.DocumentCode = NewDocRow.DocumentCode;
                    AApDocumentTable MatchingRecords = AApDocumentAccess.LoadUsingTemplate(DocTemplateRow, SubmitChangesTransaction);

                    foreach (AApDocumentRow MatchingRow in MatchingRecords.Rows) // Generally I expect this table is empty..
                    {
                        if (MatchingRow.ApDocumentId != NewDocRow.ApDocumentId) // This Document Code is in use, and not by me!
                        {
                            LocalVerificationResults.Add(new TVerificationResult(Catalog.GetString("Save Document"),
                                    String.Format(Catalog.GetString("Document Code {0} already exists."), NewDocRow.DocumentCode),
                                    TResultSeverity.Resv_Noncritical));
                            return TSubmitChangesResult.scrInfoNeeded;
                        }
                    }
                } // foreach (document)

            } // if {there's actually a document}

            try
            {
                if (AInspectDS.AApDocument != null)
                {
                    foreach (AccountsPayableTDSAApDocumentRow NewDocRow in AInspectDS.AApDocument.Rows)
                    {
                        // Set AP Number if it has not been set yet.
                        if (NewDocRow.ApNumber < 0)
                        {
                            NewDocRow.ApNumber = NextApDocumentNumber(NewDocRow.LedgerNumber, SubmitChangesTransaction);
                        }

                        SetOutstandingAmount(NewDocRow, NewDocRow.LedgerNumber, AInspectDS.AApDocumentPayment);
                    }

                    AApDocumentAccess.SubmitChanges(AInspectDS.AApDocument, SubmitChangesTransaction);
                }

                if (AInspectDS.AApDocumentDetail != null) // Document detail lines
                {
                    ValidateApDocumentDetail(ref LocalVerificationResults, AInspectDS.AApDocumentDetail);
                    ValidateApDocumentDetailManual(ref LocalVerificationResults, AInspectDS.AApDocumentDetail);

                    if (TVerificationHelper.IsNullOrOnlyNonCritical(LocalVerificationResults))
                    {
                        AApDocumentDetailAccess.SubmitChanges(AInspectDS.AApDocumentDetail, SubmitChangesTransaction);
                    }
                }

                if (AInspectDS.AApAnalAttrib != null) // Analysis attributes
                {
                    AApAnalAttribAccess.SubmitChanges(AInspectDS.AApAnalAttrib, SubmitChangesTransaction);
                }

                SubmitChangesResult = TSubmitChangesResult.scrOK;
            }
            catch (Exception Exc)
            {
                TLogging.Log("An Exception occured while saving an AP Document:" + Environment.NewLine + Exc.ToString());

                if (LocalVerificationResults == null) // This shouldn't be possible?
                {
                    LocalVerificationResults = new TVerificationResultCollection();
                }

                LocalVerificationResults.Add(new TVerificationResult("Save AP Document", Exc.Message,
                        TResultSeverity.Resv_Critical));
                throw;
            }
            finally
            {
                if (IsMyOwnTransaction)
                {
                    if (SubmitChangesResult == TSubmitChangesResult.scrOK)
                    {
                        DBAccess.GDBAccessObj.CommitTransaction();
                    }
                    else
                    {
                        DBAccess.GDBAccessObj.RollbackTransaction();
                    }
                }
            }

            if ((LocalVerificationResults != null) && (LocalVerificationResults.Count > 0))
            {
                // Downgrade TScreenVerificationResults to TVerificationResults in order to allow
                // Serialisation (needed for .NET Remoting).
                AVerificationResult = LocalVerificationResults;
                TVerificationResultCollection.DowngradeScreenVerificationResults(AVerificationResult);
            }

            return SubmitChangesResult;
        }
        /// <summary>
        /// Post a list of AP documents
        /// This static function is called from several places
        /// /// </summary>
        /// <returns>true if everything went OK</returns>
        public static bool PostApDocumentList(AccountsPayableTDS Atds, int ALedgerNumber, List <int>AApDocumentIds, Form AOwnerForm)
        {
            TVerificationResultCollection Verifications;

            TDlgGLEnterDateEffective dateEffectiveDialog = new TDlgGLEnterDateEffective(
                ALedgerNumber,
                Catalog.GetString("Select posting date"),
                Catalog.GetString("The date effective for posting") + ":");

            if (dateEffectiveDialog.ShowDialog() != DialogResult.OK)
            {
                MessageBox.Show(Catalog.GetString("Posting was cancelled."), Catalog.GetString(
                        "No Success"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            DateTime PostingDate = dateEffectiveDialog.SelectedDate;

            AOwnerForm.Cursor = Cursors.WaitCursor;

            if (TRemote.MFinance.AP.WebConnectors.PostAPDocuments(
                    ALedgerNumber,
                    AApDocumentIds,
                    PostingDate,
                    false,
                    out Verifications))
            {
                AOwnerForm.Cursor = Cursors.Default;
                return true;
            }
            else
            {
                AOwnerForm.Cursor = Cursors.Default;
                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"));
            }

            return false;
        }
Example #49
0
        private static bool DocumentBalanceOK(AccountsPayableTDS AMainDS, int AApDocumentId, TDBTransaction ATransaction)
        {
            AccountsPayableTDSAApDocumentRow DocumentRow = (AccountsPayableTDSAApDocumentRow)
                                                           AApDocumentAccess.LoadByPrimaryKey(AMainDS, AApDocumentId, ATransaction);
            decimal DocumentBalance = DocumentRow.TotalAmount;

            AMainDS.AApDocumentDetail.DefaultView.RowFilter
                = String.Format("{0}={1}",
                AApDocumentDetailTable.GetApDocumentIdDBName(), AApDocumentId);

            foreach (DataRowView rv in AMainDS.AApDocumentDetail.DefaultView)
            {
                AApDocumentDetailRow Row = (AApDocumentDetailRow)rv.Row;
                DocumentBalance -= Row.Amount;
            }

            return DocumentBalance == 0.0m;
        }
        /// <summary>
        /// This static function is called from several places
        /// </summary>
        /// <param name="Atds"></param>
        /// <param name="Adocument"></param>
        /// <returns>true if this document seems OK to post.</returns>
        public static bool ApDocumentCanPost(AccountsPayableTDS Atds, AApDocumentRow Adocument)
        {
            // If the batch will not balance, or required attributes are missing, I'll stop right here..

            if (!BatchBalancesOK(Atds, Adocument))
            {
                return false;
            }

            if (!AllLinesAccountsOK(Atds, Adocument))
            {
                return false;
            }

            if (!AllLinesHaveAttributes(Atds, Adocument))
            {
                return false;
            }

            if (!ExchangeRateIsOk(Atds, Adocument))
            {
                return false;
            }

            if (!CurrencyIsOkForPosting(Atds, Adocument))
            {
                return false;
            }

            return true;
        }
Example #51
0
        /// <summary>
        /// Load the AP documents and see if they are ready to be posted
        /// </summary>
        /// <param name="ALedgerNumber"></param>
        /// <param name="AAPDocumentIds"></param>
        /// <param name="APostingDate"></param>
        /// <param name="Reversal"></param>
        /// <param name="MustBeApproved"></param>
        /// <param name="AVerifications"></param>
        /// <returns> The TDS for posting</returns>
        private static AccountsPayableTDS LoadDocumentsAndCheck(Int32 ALedgerNumber,
            List <Int32>AAPDocumentIds,
            DateTime APostingDate,
            Boolean Reversal,
            out Boolean MustBeApproved,
            out TVerificationResultCollection AVerifications)
        {
            AccountsPayableTDS MainDS = new AccountsPayableTDS();

            AVerifications = new TVerificationResultCollection();
            bool IsMyOwnTransaction; // If I create a transaction here, then I need to rollback when I'm done.
            TDBTransaction Transaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction
                                             (IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out IsMyOwnTransaction);

            // collect the AP documents from the database
            foreach (Int32 APDocumentId in AAPDocumentIds)
            {
                AApDocumentAccess.LoadByPrimaryKey(MainDS, APDocumentId, Transaction);
                AApDocumentDetailAccess.LoadViaAApDocument(MainDS, APDocumentId, Transaction);
            }

            MustBeApproved = LedgerRquiresDocumentApproval(ALedgerNumber, Transaction);

            // do some checks on state of AP documents
            foreach (AApDocumentRow document in MainDS.AApDocument.Rows)
            {
                if (Reversal)
                {
                    if (document.DocumentStatus != MFinanceConstants.AP_DOCUMENT_POSTED)
                    {
                        AVerifications.Add(new TVerificationResult(
                                Catalog.GetString("Error during reversal of posted AP document"),
                                String.Format(Catalog.GetString("Document Number {0} cannot be reversed since the status is {1}."),
                                    document.ApNumber, document.DocumentStatus), TResultSeverity.Resv_Critical));
                    }
                }
                else
                {
                    if (
                        (MustBeApproved && (document.DocumentStatus != MFinanceConstants.AP_DOCUMENT_APPROVED))
                        || (!MustBeApproved
                            && ((document.DocumentStatus != MFinanceConstants.AP_DOCUMENT_OPEN)
                                && (document.DocumentStatus != MFinanceConstants.AP_DOCUMENT_APPROVED)))
                        )
                    {
                        AVerifications.Add(new TVerificationResult(
                                Catalog.GetString("Error during posting of AP document"),
                                String.Format(Catalog.GetString("Document Number {0} cannot be posted since the status is {1}."),
                                    document.ApNumber, document.DocumentStatus), TResultSeverity.Resv_Critical));
                    }
                }

                // TODO: also check if details are filled, and they each have a costcentre and account?

                // TODO: check for document.apaccount, if not set, get the default apaccount from the supplier, and save the ap document

                // Check that the amount of the document equals the totals of details
                if (!DocumentBalanceOK(MainDS, document.ApDocumentId, Transaction))
                {
                    AVerifications.Add(new TVerificationResult(
                            String.Format(Catalog.GetString("Cannot post the AP document {0} in Ledger {1}"), document.ApNumber, ALedgerNumber),
                            String.Format(Catalog.GetString("The value does not match the sum of the details.")),
                            TResultSeverity.Resv_Critical));
                }

                // Load Analysis Attributes and check they're all present.
                if (!AttributesAllOK(MainDS, ALedgerNumber, document.ApDocumentId, Transaction))
                {
                    AVerifications.Add(new TVerificationResult(
                            String.Format(Catalog.GetString("Cannot post the AP document {0} in Ledger {1}"), document.ApNumber, ALedgerNumber),
                            String.Format(Catalog.GetString("Analysis Attributes are required.")),
                            TResultSeverity.Resv_Critical));
                }
            }  //foreach

            // is APostingDate inside the valid posting periods?
            Int32 DateEffectivePeriodNumber, DateEffectiveYearNumber;

            if (!TFinancialYear.IsValidPostingPeriod(ALedgerNumber, APostingDate, out DateEffectivePeriodNumber, out DateEffectiveYearNumber,
                    Transaction))
            {
                AVerifications.Add(new TVerificationResult(
                        String.Format(Catalog.GetString("Cannot post the AP documents in Ledger {0}"), ALedgerNumber),
                        String.Format(Catalog.GetString("The Date Effective {0:d-MMM-yyyy} does not fit any open accounting period."),
                            APostingDate),
                        TResultSeverity.Resv_Critical));
            }

            if (IsMyOwnTransaction)
            {
                DBAccess.GDBAccessObj.RollbackTransaction();
            }

            return MainDS;
        }
Example #52
0
        public static void DeleteAPDocuments(Int32 ALedgerNumber, List <Int32>ADeleteTheseDocs)
        {
            AccountsPayableTDS TempDS = new AccountsPayableTDS();

            foreach (Int32 ApDocumentId in ADeleteTheseDocs)
            {
                TempDS.Merge(LoadAApDocument(ALedgerNumber, ApDocumentId)); // This gives me documents, details, and potentially ap_anal_attrib records.
            }

            foreach (AApAnalAttribRow AnalAttribRow in TempDS.AApAnalAttrib.Rows)
            {
                AnalAttribRow.Delete();
            }

            foreach (AApDocumentDetailRow DetailRow in TempDS.AApDocumentDetail.Rows)
            {
                DetailRow.Delete();
            }

            foreach (AApDocumentRow DocRow in TempDS.AApDocument.Rows)
            {
                DocRow.Delete();
            }

            TDBTransaction SubmitChangesTransaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.Serializable);

            try
            {
                AApAnalAttribAccess.SubmitChanges(TempDS.AApAnalAttrib, SubmitChangesTransaction);

                AApDocumentDetailAccess.SubmitChanges(TempDS.AApDocumentDetail, SubmitChangesTransaction);

                AApDocumentAccess.SubmitChanges(TempDS.AApDocument, SubmitChangesTransaction);

                DBAccess.GDBAccessObj.CommitTransaction();
            }
            catch (Exception Exc)
            {
                TLogging.Log("An Exception occured during the deletion of AP Documents:" + Environment.NewLine + Exc.ToString());

                DBAccess.GDBAccessObj.RollbackTransaction();

                throw;
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="Atds"></param>
        /// <param name="AApDocument"></param>
        /// <returns></returns>
        public static bool ExchangeRateIsOk(AccountsPayableTDS Atds, AApDocumentRow AApDocument)
        {
            if (AApDocument.ExchangeRateToBase == 0)
            {
                System.Windows.Forms.MessageBox.Show(
                    String.Format(Catalog.GetString("No Exchange Rate has been set."), AApDocument.DocumentCode),
                    Catalog.GetString("Post Document"));
                return false;
            }

            return true;
        }
Example #54
0
        /// <summary>
        /// Creates the GL batch needed for paying the AP Documents
        /// </summary>
        /// <param name="ALedgerNumber"></param>
        /// <param name="APostingDate"></param>
        /// <param name="APDataset"></param>
        /// <returns></returns>
        private static GLBatchTDS CreateGLBatchAndTransactionsForPaying(Int32 ALedgerNumber, DateTime APostingDate, ref AccountsPayableTDS APDataset)
        {
            // create one GL batch
            GLBatchTDS GLDataset = TGLTransactionWebConnector.CreateABatch(ALedgerNumber);

            ABatchRow batch = GLDataset.ABatch[0];

            batch.BatchDescription = Catalog.GetString("Accounts Payable Payment");
            batch.DateEffective = APostingDate;
            batch.BatchStatus = MFinanceConstants.BATCH_UNPOSTED;

            // since the list of documents can be for several suppliers, there could be more than one currency; group by currency first
            SortedList <string,
                        List <AccountsPayableTDSAApPaymentRow>>DocumentsByCurrency = new SortedList <string, List <AccountsPayableTDSAApPaymentRow>>();

            foreach (AccountsPayableTDSAApPaymentRow row in APDataset.AApPayment.Rows)
            {
                // Get the currency from the supplier, from the first documentpayment of this payment; we need the currency
                APDataset.AApDocumentPayment.DefaultView.RowFilter = AApDocumentPaymentTable.GetPaymentNumberDBName() + " = " +
                                                                     row.PaymentNumber.ToString();
                APDataset.AApDocument.DefaultView.RowFilter = AApDocumentTable.GetApDocumentIdDBName() + " = " +
                                                              ((AApDocumentPaymentRow)APDataset.AApDocumentPayment.DefaultView[0].Row).ApDocumentId.
                                                              ToString();
                AApDocumentRow documentRow = (AApDocumentRow)APDataset.AApDocument.DefaultView[0].Row;
                row.SupplierKey = documentRow.PartnerKey;

                string CurrencyCode = documentRow.CurrencyCode;

                if (row.IsExchangeRateToBaseNull())
                {
                    CurrencyCode += "|1.0m";
                }
                else
                {
                    CurrencyCode += ("|" + row.ExchangeRateToBase.ToString());  // If documents with the same currency are using different
                                                                                // exchange rates, I'm going to handle them separately.
                }

                TPartnerClass SupplierPartnerClass;
                string supplierName;
                TPartnerServerLookups.GetPartnerShortName(row.SupplierKey, out supplierName, out SupplierPartnerClass);
                row.SupplierName = supplierName;

                if (!DocumentsByCurrency.ContainsKey(CurrencyCode))
                {
                    DocumentsByCurrency.Add(CurrencyCode, new List <AccountsPayableTDSAApPaymentRow>());
                }

                DocumentsByCurrency[CurrencyCode].Add(row);
            }

            Int32 CounterJournals = 1;

            // Add a journal for each currency/exchangeRate, and the transactions.
            // Most likely only one currency/exchangeRate will be used!

            foreach (string CurrencyCode in DocumentsByCurrency.Keys)
            {
                String StandardCostCentre = TLedgerInfo.GetStandardCostCentre(batch.LedgerNumber);
                Dictionary <String, Decimal>ForexGain = new Dictionary <string, decimal>(); // ForexGain is recorded for each AP account in use.

                AJournalRow journalRow = GLDataset.AJournal.NewRowTyped();
                journalRow.LedgerNumber = batch.LedgerNumber;
                journalRow.BatchNumber = batch.BatchNumber;
                journalRow.JournalNumber = CounterJournals++;
                journalRow.DateEffective = batch.DateEffective;
                journalRow.TransactionCurrency = CurrencyCode.Substring(0, CurrencyCode.IndexOf("|"));
                journalRow.JournalDescription = "AP";
                journalRow.TransactionTypeCode = CommonAccountingTransactionTypesEnum.INV.ToString();
                journalRow.SubSystemCode = CommonAccountingSubSystemsEnum.AP.ToString();
                journalRow.DateOfEntry = DateTime.Now;

                int baseCurrencyDecimalPlaces = 0; // This will not be used unless this is a foreign journal.
                int intlCurrencyDecimalPlaces = 0;

                if (journalRow.TransactionCurrency != GLDataset.ALedger[0].BaseCurrency)
                {
                    baseCurrencyDecimalPlaces = StringHelper.DecimalPlacesForCurrency(GLDataset.ALedger[0].BaseCurrency);
                    intlCurrencyDecimalPlaces = StringHelper.DecimalPlacesForCurrency(GLDataset.ALedger[0].IntlCurrency);
                }

                // I'm not using the Daily Exchange Rate, since the exchange rate has been specified by the user in the payment.
                // using the exchange rate from the first payment in this set of payments with same currency and exchange rate
                journalRow.ExchangeRateTime = 0;

                if (DocumentsByCurrency[CurrencyCode][0].IsExchangeRateToBaseNull())
                {
                    journalRow.ExchangeRateToBase = 1.0m;
                }
                else
                {
                    journalRow.ExchangeRateToBase = DocumentsByCurrency[CurrencyCode][0].ExchangeRateToBase;
                }

                GLDataset.AJournal.Rows.Add(journalRow);

                Int32 TransactionCounter = 1;

                foreach (AccountsPayableTDSAApPaymentRow paymentRow in DocumentsByCurrency[CurrencyCode])
                {
                    DataView DocumentPaymentView = APDataset.AApDocumentPayment.DefaultView;
                    DocumentPaymentView.RowFilter = AApDocumentPaymentTable.GetPaymentNumberDBName() + " = " + paymentRow.PaymentNumber.ToString();

                    foreach (DataRowView rowview in DocumentPaymentView)
                    {
                        AApDocumentPaymentRow documentPaymentRow = (AApDocumentPaymentRow)rowview.Row;
                        APDataset.AApDocument.DefaultView.RowFilter = AApDocumentTable.GetApDocumentIdDBName() + " = " +
                                                                      documentPaymentRow.ApDocumentId.ToString();
                        AApDocumentRow documentRow = (AApDocumentRow)APDataset.AApDocument.DefaultView[0].Row;

                        ATransactionRow transactionRowBank = null;
                        GLDataset.ATransaction.DefaultView.RowFilter =
                            "a_account_code_c='" + paymentRow.BankAccount +
                            "' AND a_journal_number_i=" + journalRow.JournalNumber.ToString();

                        if (GLDataset.ATransaction.DefaultView.Count > 0)
                        {
                            transactionRowBank = (ATransactionRow)GLDataset.ATransaction.DefaultView[0].Row;
                            transactionRowBank.TransactionAmount += documentPaymentRow.Amount; // This TransactionAmount is unsigned until later.
                            transactionRowBank.Narrative = "AP Payment: Multiple suppliers";
                        }
                        else
                        {
                            transactionRowBank = GLDataset.ATransaction.NewRowTyped();
                            transactionRowBank.LedgerNumber = journalRow.LedgerNumber;
                            transactionRowBank.BatchNumber = journalRow.BatchNumber;
                            transactionRowBank.JournalNumber = journalRow.JournalNumber;
                            transactionRowBank.TransactionNumber = TransactionCounter++;
                            transactionRowBank.TransactionAmount = documentPaymentRow.Amount; // This TransactionAmount is unsigned until later.
                            transactionRowBank.AmountInBaseCurrency = 0; // This will be corrected later, after this nested loop.
                            transactionRowBank.TransactionDate = batch.DateEffective;
                            transactionRowBank.SystemGenerated = true;
                            transactionRowBank.AccountCode = paymentRow.BankAccount;
                            transactionRowBank.CostCentreCode = StandardCostCentre;
                            transactionRowBank.Narrative = "AP Payment: " + paymentRow.PaymentNumber.ToString() + " - " +
                                                           Ict.Petra.Shared.MPartner.Calculations.FormatShortName(paymentRow.SupplierName,
                                eShortNameFormat.eReverseWithoutTitle);
                            transactionRowBank.Reference = paymentRow.Reference;
                            GLDataset.ATransaction.Rows.Add(transactionRowBank);
                        }

                        ATransactionRow transactionRowAp = null;
                        GLDataset.ATransaction.DefaultView.RowFilter =
                            "a_account_code_c='" + documentRow.ApAccount +
                            "' AND a_journal_number_i=" + journalRow.JournalNumber.ToString();

                        if (GLDataset.ATransaction.DefaultView.Count > 0)
                        {
                            transactionRowAp = (ATransactionRow)GLDataset.ATransaction.DefaultView[0].Row;
                            transactionRowAp.TransactionAmount -= documentPaymentRow.Amount; // This TransactionAmount is unsigned until later.
                            transactionRowAp.Narrative += ", " + documentRow.ApNumber.ToString();
                        }
                        else
                        {
                            transactionRowAp = GLDataset.ATransaction.NewRowTyped();
                            transactionRowAp.LedgerNumber = journalRow.LedgerNumber;
                            transactionRowAp.BatchNumber = journalRow.BatchNumber;
                            transactionRowAp.JournalNumber = journalRow.JournalNumber;
                            transactionRowAp.TransactionNumber = TransactionCounter++;
                            transactionRowAp.TransactionAmount = 0 - documentPaymentRow.Amount;  // This TransactionAmount is unsigned until later.
                            transactionRowAp.TransactionDate = batch.DateEffective;
                            transactionRowAp.SystemGenerated = true;
                            transactionRowAp.AccountCode = documentRow.ApAccount;
                            transactionRowAp.CostCentreCode = StandardCostCentre;
                            transactionRowAp.Narrative = "AP Payment:" + paymentRow.PaymentNumber.ToString() + " AP: " +
                                                         documentRow.ApNumber.ToString();
                            transactionRowAp.Reference = paymentRow.Reference;
                            transactionRowAp.AmountInBaseCurrency = 0; // This will be corrected later, after this nested loop.
                            GLDataset.ATransaction.Rows.Add(transactionRowAp);
                        }

                        if (journalRow.TransactionCurrency != GLDataset.ALedger[0].BaseCurrency)
                        {
                            // This invoice is in a non-base currency, and the value of it in my base currency
                            // may have changed since it was first posted. To keep the ledger balanced,
                            // adjusting entries will made to the AP accounts,
                            // and a single balancing entry will made to the ForexGainsLossesAccount account.
                            // (Most often only one AP account per currency will be used.)

                            Decimal BaseAmountAtPosting = GLRoutines.Divide(documentPaymentRow.Amount,
                                documentRow.ExchangeRateToBase,
                                baseCurrencyDecimalPlaces);
                            Decimal BaseAmountNow = GLRoutines.Divide(documentPaymentRow.Amount,
                                paymentRow.ExchangeRateToBase,
                                baseCurrencyDecimalPlaces);
                            Decimal ForexDelta = (BaseAmountNow - BaseAmountAtPosting);

                            if (ForexDelta != 0)  // There's a good chance this will be 0!
                            {
                                if (ForexGain.ContainsKey(documentRow.ApAccount))
                                {
                                    ForexGain[documentRow.ApAccount] += ForexDelta;
                                }
                                else
                                {
                                    ForexGain.Add(documentRow.ApAccount, ForexDelta);
                                }
                            }
                        }
                    } // foreach DocumentPayment

                } // foreach Payment

                journalRow.LastTransactionNumber = TransactionCounter - 1;

                // So now I have one bank transaction per Bank Account credited
                // (Which is likely to be one per currency, but it could be more...)
                // and one AP transaction per AP account used
                // (Probably also one per currency.)
                // I need to set the international fields on the consolidated transaction rows:
                GLDataset.ATransaction.DefaultView.RowFilter = "a_journal_number_i=" + journalRow.JournalNumber.ToString();

                foreach (DataRowView rv in GLDataset.ATransaction.DefaultView)
                {
                    ATransactionRow tempTransRow = (ATransactionRow)rv.Row;

                    if (tempTransRow.AmountInBaseCurrency == 0) // I left this blank earlier as a marker.
                    {                                           // If any other rows have 0 here, (a) that's a fault, and (b) it's OK - it won't do any harm!
                        tempTransRow.DebitCreditIndicator = (tempTransRow.TransactionAmount < 0);

                        if (tempTransRow.TransactionAmount < 0)
                        {
                            tempTransRow.TransactionAmount *= -1;
                        }

                        if (journalRow.TransactionCurrency == GLDataset.ALedger[0].BaseCurrency)
                        {
                            tempTransRow.AmountInBaseCurrency = tempTransRow.TransactionAmount;
                        }
                        else
                        {
                            tempTransRow.AmountInBaseCurrency = GLRoutines.Divide(tempTransRow.TransactionAmount,
                                journalRow.ExchangeRateToBase,
                                baseCurrencyDecimalPlaces);

                            tempTransRow.AmountInIntlCurrency = GLRoutines.Divide(tempTransRow.AmountInBaseCurrency,
                                TExchangeRateTools.GetDailyExchangeRate(
                                    GLDataset.ALedger[0].BaseCurrency,
                                    GLDataset.ALedger[0].IntlCurrency,
                                    tempTransRow.TransactionDate),
                                intlCurrencyDecimalPlaces);
                        }
                    }
                }

                // The'base value' of these invoices may have changed since they were posted -
                // if this is the case I need a 'reval' journal to keep the books straight.
                // NOTE if the payment is already in Base Currency, the ForexGain dictionary will be empty.

                if (ForexGain.Count > 0) // One ForexGain per foreign currency would be normal, but there could be multiple AP accounts.
                {
                    Decimal TotalForexCorrection = 0;
                    // this goes into a separate REVAL journal in Base Currency.

                    AJournalRow RevalJournal = GLDataset.AJournal.NewRowTyped();
                    RevalJournal.LedgerNumber = batch.LedgerNumber;
                    RevalJournal.BatchNumber = batch.BatchNumber;
                    RevalJournal.JournalNumber = CounterJournals++;
                    RevalJournal.DateEffective = batch.DateEffective;
                    RevalJournal.TransactionCurrency = GLDataset.ALedger[0].BaseCurrency;
                    RevalJournal.JournalDescription = "AP Reval";
                    RevalJournal.TransactionTypeCode = CommonAccountingTransactionTypesEnum.REVAL.ToString();
                    RevalJournal.SubSystemCode = CommonAccountingSubSystemsEnum.GL.ToString();
                    RevalJournal.DateOfEntry = DateTime.Now;
                    RevalJournal.ExchangeRateToBase = 1.0m;
                    RevalJournal.ExchangeRateTime = 0;
                    GLDataset.AJournal.Rows.Add(RevalJournal);

                    TransactionCounter = 1;

                    foreach (String ApAccount in ForexGain.Keys)
                    {
                        // One transaction for each AP Account used:
                        ATransactionRow transactionApReval = GLDataset.ATransaction.NewRowTyped();
                        transactionApReval.LedgerNumber = RevalJournal.LedgerNumber;
                        transactionApReval.BatchNumber = RevalJournal.BatchNumber;
                        transactionApReval.JournalNumber = RevalJournal.JournalNumber;
                        transactionApReval.TransactionNumber = TransactionCounter++;
                        transactionApReval.Narrative = "AP expense reval";
                        transactionApReval.Reference = "";
                        transactionApReval.AccountCode = ApAccount;
                        transactionApReval.CostCentreCode = StandardCostCentre;
                        transactionApReval.TransactionAmount = 0; // no real value
                        transactionApReval.AmountInIntlCurrency = 0; // no real value
                        transactionApReval.TransactionDate = batch.DateEffective;
                        transactionApReval.SystemGenerated = true;
                        transactionApReval.DebitCreditIndicator = (ForexGain[ApAccount] < 0);
                        transactionApReval.AmountInBaseCurrency = Math.Abs(ForexGain[ApAccount]);
                        GLDataset.ATransaction.Rows.Add(transactionApReval);

                        TotalForexCorrection += ForexGain[ApAccount];
                    }

                    // A single transaction to the ForexGainsLossesAccount:
                    ATransactionRow transactionReval = GLDataset.ATransaction.NewRowTyped();
                    transactionReval.LedgerNumber = RevalJournal.LedgerNumber;
                    transactionReval.BatchNumber = RevalJournal.BatchNumber;
                    transactionReval.JournalNumber = RevalJournal.JournalNumber;
                    transactionReval.TransactionNumber = TransactionCounter++;
                    transactionReval.Narrative = "AP expense reval";
                    transactionReval.Reference = "";
                    transactionReval.AccountCode = GLDataset.ALedger[0].ForexGainsLossesAccount;
                    transactionReval.CostCentreCode = StandardCostCentre;
                    transactionReval.TransactionDate = batch.DateEffective;
                    transactionReval.SystemGenerated = true;
                    transactionReval.TransactionAmount = 0; // no real value
                    transactionReval.AmountInIntlCurrency = 0; // no real value
                    transactionReval.DebitCreditIndicator = (TotalForexCorrection > 0); // Opposite sign to those used above
                    transactionReval.AmountInBaseCurrency = Math.Abs(TotalForexCorrection);
                    GLDataset.ATransaction.Rows.Add(transactionReval);

                    RevalJournal.LastTransactionNumber = TransactionCounter - 1;
                }
            } // foreach currency

            batch.LastJournal = CounterJournals - 1;

            return GLDataset;
        }
Example #55
0
        public static AccountsPayableTDS LoadAApSupplier(Int32 ALedgerNumber, Int64 APartnerKey)
        {
            // create the DataSet that will be passed to the Client
            AccountsPayableTDS MainDS = new AccountsPayableTDS();

            bool IsMyOwnTransaction; // If I create a transaction here, then I need to rollback when I'm done.
            TDBTransaction Transaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction
                                             (IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out IsMyOwnTransaction);

            AApSupplierAccess.LoadByPrimaryKey(MainDS, APartnerKey, Transaction);
            PPartnerAccess.LoadByPrimaryKey(MainDS, APartnerKey, Transaction);
            // Accept row changes here so that the Client gets 'unmodified' rows
            MainDS.AcceptChanges();

            if (IsMyOwnTransaction)
            {
                DBAccess.GDBAccessObj.RollbackTransaction();
            }

            // Remove any Tables that were not filled with data before remoting them.
            MainDS.RemoveEmptyTables();

            return MainDS;
        }
Example #56
0
        public static AccountsPayableTDS LoadAApDocument(Int32 ALedgerNumber, Int32 AApDocumentId)
        {
            // create the DataSet that will be passed to the Client
            AccountsPayableTDS MainDS = new AccountsPayableTDS();

            bool IsMyOwnTransaction; // If I create a transaction here, then I need to rollback when I'm done.
            TDBTransaction Transaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction
                                             (IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out IsMyOwnTransaction);

            AccountsPayableTDSAApDocumentRow DocumentRow = (AccountsPayableTDSAApDocumentRow)
                                                           AApDocumentAccess.LoadByPrimaryKey(MainDS, AApDocumentId, Transaction);

            // If the load didn't work, don't bother with anything else..
            if (MainDS.AApDocument.Count > 0)
            {
                SetOutstandingAmount(DocumentRow, ALedgerNumber, MainDS.AApDocumentPayment);

                AApDocumentDetailAccess.LoadViaAApDocument(MainDS, AApDocumentId, Transaction);
                AApSupplierAccess.LoadByPrimaryKey(MainDS, DocumentRow.PartnerKey, Transaction);

                AApAnalAttribAccess.LoadViaAApDocument(MainDS, AApDocumentId, Transaction);

                // Accept row changes here so that the Client gets 'unmodified' rows
                MainDS.AcceptChanges();

                // I also need a full list of analysis attributes that could apply to this document
                // (although if it's already been posted I don't need to get this...)

                LoadAnalysisAttributes(MainDS, ALedgerNumber, Transaction);
            }

            if (IsMyOwnTransaction)
            {
                DBAccess.GDBAccessObj.RollbackTransaction();
            }

            // Remove all Tables that were not filled with data before remoting them.
            MainDS.RemoveEmptyTables();

            return MainDS;
        }
 /// <summary>
 /// edit an existing supplier
 /// </summary>
 /// <param name="APartnerKey"></param>
 public void EditSupplier(Int64 APartnerKey)
 {
     FMainDS = FUIConnector.GetData(APartnerKey);
     ShowData(FMainDS.AApSupplier[0]);
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="APaymentNum"></param>
        /// <param name="ALedgerNumber"></param>
        public void PrintRemittanceAdvice(Int32 APaymentNum, Int32 ALedgerNumber)
        {
            FLedgerNumber = ALedgerNumber;

            txtPaymentNum.NumberValueInt = APaymentNum;
            AccountsPayableTDS PaymentDetails = TRemote.MFinance.AP.WebConnectors.LoadAPPayment(ALedgerNumber, APaymentNum);

            if (PaymentDetails.AApPayment.Rows.Count == 0) // unable to load this payment..
            {
                lblLoadStatus.Text = String.Format(Catalog.GetString("Error - can't load Payment number {0}."), APaymentNum);
                return;
            }

            SortedList <string, List <string> > FormValues = new SortedList <string, List <string> >();

            //
            // load my own country code, so I don't print it on letters to my own country.
            //
            string LocalCountryCode = TRemote.MPartner.Partner.ServerLookups.WebConnectors.GetCountryCodeFromSiteLedger();

            //
            // These are the fields that I will pull out of the TDS...
            //
            FormValues.Add("SupplierName", new List <string>());
            FormValues.Add("SupplierAddress", new List <string>());
            FormValues.Add("PaymentDate", new List <string>());
            FormValues.Add("OurReference", new List <string>());
            FormValues.Add("InvoiceDate", new List <string>());
            FormValues.Add("InvoiceNumber", new List <string>());
            FormValues.Add("InvoiceAmount", new List <string>());
            FormValues.Add("TotalPayment", new List <string>());

            FormValues["SupplierName"].Add(PaymentDetails.PPartner[0].PartnerShortName);

            if (PaymentDetails.PLocation[0].CountryCode == LocalCountryCode)
            {
                PaymentDetails.PLocation[0].CountryCode = ""; // Don't print country code it it's the same as my own.
            }

            FormValues["SupplierAddress"].Add(Calculations.DetermineLocationString(PaymentDetails.PLocation[0],
                                                                                   Calculations.TPartnerLocationFormatEnum.plfHtmlLineBreak));

            String DatePattern = Thread.CurrentThread.CurrentCulture.DateTimeFormat.LongDatePattern;

            DatePattern = "dd MMMM yyyy"; // The long pattern above is no good in UK, although it might be OK in other cultures...

            FormValues["PaymentDate"].Add(PaymentDetails.AApPayment[0].PaymentDate.Value.ToString(DatePattern));
            FormValues["OurReference"].Add(PaymentDetails.AApSupplier[0].OurReference);

            foreach (AApDocumentRow Row in PaymentDetails.AApDocument.Rows)
            {
                FormValues["InvoiceDate"].Add(Row.DateIssued.ToString(DatePattern));
                FormValues["InvoiceNumber"].Add(Row.DocumentCode);
                FormValues["InvoiceAmount"].Add(Row.TotalAmount.ToString("n2") + " " + PaymentDetails.AApSupplier[0].CurrencyCode);
            }

            FormValues["TotalPayment"].Add(PaymentDetails.AApPayment[0].Amount.ToString("n2") + " " + PaymentDetails.AApSupplier[0].CurrencyCode);

            String TemplateFilename = TAppSettingsManager.GetValue("Formletters.Path") + "\\ApRemittanceAdvice.html";

            if (!File.Exists(TemplateFilename))
            {
                lblLoadStatus.Text = String.Format(Catalog.GetString("Error - unable to load HTML template from {0}"), TemplateFilename);
                return;
            }

            FHtmlDoc = TFormLettersTools.PrintSimpleHTMLLetter(TemplateFilename, FormValues);

            System.Drawing.Printing.PrintDocument printDocument = new System.Drawing.Printing.PrintDocument();
            bool printerInstalled = printDocument.PrinterSettings.IsValid;

            if (!printerInstalled)
            {
                lblLoadStatus.Text = Catalog.GetString("There is no printer, so printing is not possible");
                return;
            }

            FGfxPrinter = new TGfxPrinter(printDocument, TGfxPrinter.ePrinterBehaviour.eFormLetter);
            try
            {
                TPrinterHtml htmlPrinter = new TPrinterHtml(FHtmlDoc,
                                                            TAppSettingsManager.GetValue("Formletters.Path"),
                                                            FGfxPrinter);
                FGfxPrinter.Init(eOrientation.ePortrait, htmlPrinter, eMarginType.ePrintableArea);
                this.ppvLetters.InvalidatePreview();
                this.ppvLetters.Document = FGfxPrinter.Document;
                this.ppvLetters.Zoom     = 1;
                // GfxPrinter.Document.EndPrint += new PrintEventHandler(this.EndPrint);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            btnPDF.Visible  = true;
            btnCopy.Visible = true;

            lblLoadStatus.Text = "";
        }
        /// <summary>
        /// Post all tagged documents
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void PostAllTagged(object sender, EventArgs e)
        {
            // This will throw an exception if insufficient permissions
            TSecurityChecks.CheckUserModulePermissions("FINANCE-2", "PostAllTagged [raised by Client Proxy for ModuleAccessManager]");

            string MsgTitle = Catalog.GetString("Document Posting");

            AccountsPayableTDS TempDS = LoadTaggedDocuments();

            List <int> PostTheseDocs = new List <int>();

            TempDS.AApDocument.DefaultView.Sort = AApDocumentDetailTable.GetApDocumentIdDBName();

            string testString = "|CANCELLED|POSTED|PARTPAID|PAID|";

            if (FRequireApprovalBeforePosting)
            {
                testString += "OPEN|";
            }

            foreach (DataRowView rv in grdInvoices.PagedDataTable.DefaultView)
            {
                if ((rv.Row["Selected"].Equals(true) && (testString.IndexOf("|" + rv.Row["DocumentStatus"].ToString()) < 0)))
                {
                    int DocId = Convert.ToInt32(rv.Row["ApDocumentId"]);

                    int RowIdx = TempDS.AApDocument.DefaultView.Find(DocId);

                    if (RowIdx >= 0)
                    {
                        AApDocumentRow DocumentRow = (AApDocumentRow)TempDS.AApDocument.DefaultView[RowIdx].Row;

                        if (TFrmAPEditDocument.ApDocumentCanPost(TempDS, DocumentRow)) // This will produce an message box if there's a problem.
                        {
                            PostTheseDocs.Add(DocId);
                        }
                    }
                }
            }

            if (PostTheseDocs.Count > 0)
            {
                string msg = String.Format(Catalog.GetString("Are you sure that you want to post the {0} tagged document(s)?"), PostTheseDocs.Count);

                if (MessageBox.Show(msg, MsgTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question,
                                    MessageBoxDefaultButton.Button2) == DialogResult.No)
                {
                    return;
                }

                if (TFrmAPEditDocument.PostApDocumentList(TempDS, FMainForm.LedgerNumber, PostTheseDocs, FMainForm))
                {
                    // TODO: print reports on successfully posted batch
                    MessageBox.Show(Catalog.GetString("The tagged documents have been posted successfully!"), MsgTitle);
                    FMainForm.IsInvoiceDataChanged = true;

                    LoadInvoices();

                    // TODO: show posting register of GL Batch?
                }
            }
            else
            {
                MessageBox.Show(Catalog.GetString("There are no tagged documents to be posted."), MsgTitle);
            }
        }
 /// <summary>
 /// todoComment
 /// </summary>
 public void InitializeManualCode()
 {
     FMainDS = new AccountsPayableTDS();
 }