/// <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); } }
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); }
/// <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); }
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]); }
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); }
/// <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); }
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); }
/// <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); }
/// <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); }
/// <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); }
/// <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(); } }
/// <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); }
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; }
/// <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; }
/// <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; }
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; } }
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; }
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; }
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> /// 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(); } }
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)); }
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; }
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; }
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; }
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; }
/// <summary> /// Load the AP documents and see if they are ready to be posted /// </summary> /// <param name="ALedgerNumber"></param> /// <param name="AAPDocumentIds"></param> /// <param name="APostingDate"></param> /// <param name="Reversal"></param> /// <param name="MustBeApproved"></param> /// <param name="AVerifications"></param> /// <returns> The TDS for posting</returns> private static AccountsPayableTDS LoadDocumentsAndCheck(Int32 ALedgerNumber, List <Int32>AAPDocumentIds, DateTime APostingDate, Boolean Reversal, out Boolean MustBeApproved, out TVerificationResultCollection AVerifications) { AccountsPayableTDS MainDS = new AccountsPayableTDS(); AVerifications = new TVerificationResultCollection(); bool IsMyOwnTransaction; // If I create a transaction here, then I need to rollback when I'm done. TDBTransaction Transaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction (IsolationLevel.ReadCommitted, TEnforceIsolationLevel.eilMinimum, out IsMyOwnTransaction); // collect the AP documents from the database foreach (Int32 APDocumentId in AAPDocumentIds) { AApDocumentAccess.LoadByPrimaryKey(MainDS, APDocumentId, Transaction); AApDocumentDetailAccess.LoadViaAApDocument(MainDS, APDocumentId, Transaction); } MustBeApproved = LedgerRquiresDocumentApproval(ALedgerNumber, Transaction); // do some checks on state of AP documents foreach (AApDocumentRow document in MainDS.AApDocument.Rows) { if (Reversal) { if (document.DocumentStatus != MFinanceConstants.AP_DOCUMENT_POSTED) { AVerifications.Add(new TVerificationResult( Catalog.GetString("Error during reversal of posted AP document"), String.Format(Catalog.GetString("Document Number {0} cannot be reversed since the status is {1}."), document.ApNumber, document.DocumentStatus), TResultSeverity.Resv_Critical)); } } else { if ( (MustBeApproved && (document.DocumentStatus != MFinanceConstants.AP_DOCUMENT_APPROVED)) || (!MustBeApproved && ((document.DocumentStatus != MFinanceConstants.AP_DOCUMENT_OPEN) && (document.DocumentStatus != MFinanceConstants.AP_DOCUMENT_APPROVED))) ) { AVerifications.Add(new TVerificationResult( Catalog.GetString("Error during posting of AP document"), String.Format(Catalog.GetString("Document Number {0} cannot be posted since the status is {1}."), document.ApNumber, document.DocumentStatus), TResultSeverity.Resv_Critical)); } } // TODO: also check if details are filled, and they each have a costcentre and account? // TODO: check for document.apaccount, if not set, get the default apaccount from the supplier, and save the ap document // Check that the amount of the document equals the totals of details if (!DocumentBalanceOK(MainDS, document.ApDocumentId, Transaction)) { AVerifications.Add(new TVerificationResult( String.Format(Catalog.GetString("Cannot post the AP document {0} in Ledger {1}"), document.ApNumber, ALedgerNumber), String.Format(Catalog.GetString("The value does not match the sum of the details.")), TResultSeverity.Resv_Critical)); } // Load Analysis Attributes and check they're all present. if (!AttributesAllOK(MainDS, ALedgerNumber, document.ApDocumentId, Transaction)) { AVerifications.Add(new TVerificationResult( String.Format(Catalog.GetString("Cannot post the AP document {0} in Ledger {1}"), document.ApNumber, ALedgerNumber), String.Format(Catalog.GetString("Analysis Attributes are required.")), TResultSeverity.Resv_Critical)); } } //foreach // is APostingDate inside the valid posting periods? Int32 DateEffectivePeriodNumber, DateEffectiveYearNumber; if (!TFinancialYear.IsValidPostingPeriod(ALedgerNumber, APostingDate, out DateEffectivePeriodNumber, out DateEffectiveYearNumber, Transaction)) { AVerifications.Add(new TVerificationResult( String.Format(Catalog.GetString("Cannot post the AP documents in Ledger {0}"), ALedgerNumber), String.Format(Catalog.GetString("The Date Effective {0:d-MMM-yyyy} does not fit any open accounting period."), APostingDate), TResultSeverity.Resv_Critical)); } if (IsMyOwnTransaction) { DBAccess.GDBAccessObj.RollbackTransaction(); } return MainDS; }
public static 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; }
/// <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; }
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; }
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); } }