private void ReverseSelected(object sender, EventArgs e) { DataRowView[] SelectedGridRow = grdResult.SelectedDataRowsAsDataRowView; if (SelectedGridRow.Length >= 1) { if (SelectedGridRow[0]["Status"].ToString().Length > 0) // invoices have status, and payments don't. { // Reverse invoice to a previous (unposted) state string barstatus = "|" + SelectedGridRow[0]["Status"].ToString(); if (barstatus == "|POSTED") { TVerificationResultCollection Verifications; Int32 DocumentId = Convert.ToInt32(SelectedGridRow[0]["ApDocumentId"]); List <Int32>ApDocumentIds = new List <Int32>(); ApDocumentIds.Add(DocumentId); TDlgGLEnterDateEffective dateEffectiveDialog = new TDlgGLEnterDateEffective( FLedgerNumber, Catalog.GetString("Select reversal date"), Catalog.GetString("The date effective for this reversal") + ":"); if (dateEffectiveDialog.ShowDialog() != DialogResult.OK) { MessageBox.Show(Catalog.GetString("Reversal was cancelled."), Catalog.GetString( "No Success"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } DateTime PostingDate = dateEffectiveDialog.SelectedDate; if (TRemote.MFinance.AP.WebConnectors.PostAPDocuments( FLedgerNumber, ApDocumentIds, PostingDate, true, out Verifications)) { System.Windows.Forms.MessageBox.Show("Invoice reversed to Approved status.", Catalog.GetString("Reversal")); Reload(); return; } else { string ErrorMessages = String.Empty; foreach (TVerificationResult verif in Verifications) { ErrorMessages += "[" + verif.ResultContext + "] " + verif.ResultTextCaption + ": " + verif.ResultText + Environment.NewLine; } System.Windows.Forms.MessageBox.Show(ErrorMessages, Catalog.GetString("Reversal")); } return; } // reverse posted invoice if ("|PAID|PARTPAID".IndexOf(barstatus) >= 0) { MessageBox.Show("Can't reverse a paid invoice. Reverse the payment instead.", "Reverse"); } } else // Reverse payment { Int32 PaymentNum = (Int32)SelectedGridRow[0]["ApNum"]; TFrmAPPayment PaymentScreen = new TFrmAPPayment(this); PaymentScreen.ReversePayment(FLedgerNumber, PaymentNum); } } }
/// <summary> /// A payment made to a supplier needs to be reversed. /// It's done by creating and posting a set of matching "negatives" - /// In the simplest case this is a single credit note matching an invoice /// but it could be more complex. These negative documents are payed using /// a standard call to PostAPPayments. /// /// After the reversal, I'll also create and post new copies of all /// the invoices / credit notes that made up the original payment. /// </summary> /// <param name="ALedgerNumber"></param> /// <param name="APaymentNumber"></param> public void ReversePayment(Int32 ALedgerNumber, Int32 APaymentNumber) { AccountsPayableTDS TempDS = TRemote.MFinance.AP.WebConnectors.LoadAPPayment(ALedgerNumber, APaymentNumber); if (TempDS.AApPayment.Rows.Count == 0) // Invalid Payment number? { MessageBox.Show(Catalog.GetString("The referenced payment Connot be loaded."), Catalog.GetString("Error")); return; } TempDS.AApDocument.DefaultView.Sort = AApDocumentTable.GetApDocumentIdDBName(); // // First I'll check that the amounts add up: // Decimal PaidDocumentsTotal = 0.0m; foreach (AApDocumentPaymentRow PaymentRow in TempDS.AApDocumentPayment.Rows) { Int32 DocIdx = TempDS.AApDocument.DefaultView.Find(PaymentRow.ApDocumentId); AApDocumentRow DocumentRow = TempDS.AApDocument[DocIdx]; if (DocumentRow.CreditNoteFlag) { PaidDocumentsTotal -= DocumentRow.TotalAmount; } else { PaidDocumentsTotal += DocumentRow.TotalAmount; } } // // If this is a partial payment, I can't deal with that here... // if (PaidDocumentsTotal != TempDS.AApPayment[0].Amount) { String ErrorMsg = String.Format(Catalog.GetString( "This Payment cannot be reversed automatically because the total amount of the referenced documents ({0:n2} {1}) differs from the amount in the payment ({2:n2} {3})."), PaidDocumentsTotal, TempDS.AApSupplier[0].CurrencyCode, TempDS.AApPayment[0].Amount, TempDS.AApSupplier[0].CurrencyCode); MessageBox.Show(ErrorMsg, Catalog.GetString("Reverse Payment"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // Find out if this payment was already reversed, // because if it was, perhaps the user doesn't really want to // reverse it again? this.Cursor = Cursors.WaitCursor; if (TRemote.MFinance.AP.WebConnectors.WasThisPaymentReversed(ALedgerNumber, APaymentNumber)) { this.Cursor = Cursors.Default; MessageBox.Show(Catalog.GetString("Cannot reverse Payment - there is already a matching reverse transaction."), Catalog.GetString("Reverse Payment"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } this.Cursor = Cursors.Default; // // Ask the user to confirm reversal of this payment // String PaymentMsg = Catalog.GetString("Do you want to reverse this payment?"); PaymentMsg += ("\r\n" + String.Format("Payment made {0} to {1}\r\n\r\nRelated invoices:", TDate.DateTimeToLongDateString2(TempDS.AApPayment[0].PaymentDate.Value), TempDS.PPartner[0].PartnerShortName)); foreach (AApDocumentPaymentRow PaymentRow in TempDS.AApDocumentPayment.Rows) { Int32 DocIdx = TempDS.AApDocument.DefaultView.Find(PaymentRow.ApDocumentId); AApDocumentRow DocumentRow = TempDS.AApDocument[DocIdx]; PaymentMsg += ("\r\n" + String.Format(" {2} ({3}) {0:n2} {1}", DocumentRow.TotalAmount, TempDS.AApSupplier[0].CurrencyCode, DocumentRow.DocumentCode, DocumentRow.Reference)); } PaymentMsg += ("\r\n\r\n" + String.Format("Total payment {0:n2} {1}", TempDS.AApPayment[0].Amount, TempDS.AApSupplier[0].CurrencyCode)); DialogResult YesNo = MessageBox.Show(PaymentMsg, Catalog.GetString("Reverse Payment"), MessageBoxButtons.YesNo); if (YesNo == DialogResult.No) { return; } TDlgGLEnterDateEffective dateEffectiveDialog = new TDlgGLEnterDateEffective( ALedgerNumber, Catalog.GetString("Select posting date"), Catalog.GetString("The date effective for the reversal") + ":"); if (dateEffectiveDialog.ShowDialog() != DialogResult.OK) { MessageBox.Show(Catalog.GetString("Reversal was cancelled."), Catalog.GetString("Reverse Payment"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } DateTime PostingDate = dateEffectiveDialog.SelectedDate; TVerificationResultCollection Verifications; this.Cursor = Cursors.WaitCursor; if (TRemote.MFinance.AP.WebConnectors.ReversePayment(ALedgerNumber, APaymentNumber, PostingDate, out Verifications)) { this.Cursor = Cursors.Default; // TODO: print reports on successfully posted batch MessageBox.Show(Catalog.GetString("The AP payment has been reversed."), Catalog.GetString("Reverse Payment")); TFormsMessage broadcastMessage = new TFormsMessage(TFormsMessageClassEnum.mcAPTransactionChanged); broadcastMessage.SetMessageDataAPTransaction(String.Empty); TFormsList.GFormsList.BroadcastFormMessage(broadcastMessage); } else { this.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("Reverse Payment Failed")); } }
/// <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 void MakePayment(object sender, EventArgs e) { FSelectedDocumentRow.Amount = Decimal.Parse(txtAmountToPay.Text); FSelectedPaymentRow.BankAccount = cmbBankAccount.GetSelectedString(); AccountsPayableTDSAApPaymentTable AApPayment = FMainDS.AApPayment; // // I want to check whether the user is paying more than the due amount on any of these payments... // foreach (AccountsPayableTDSAApPaymentRow PaymentRow in AApPayment.Rows) { FMainDS.AApDocumentPayment.DefaultView.RowFilter = String.Format("{0}={1}", AApDocumentPaymentTable.GetPaymentNumberDBName(), PaymentRow.PaymentNumber); foreach (DataRowView rv in FMainDS.AApDocumentPayment.DefaultView) { AccountsPayableTDSAApDocumentPaymentRow DocPaymentRow = (AccountsPayableTDSAApDocumentPaymentRow)rv.Row; Boolean overPayment = (DocPaymentRow.DocType == "INVOICE") ? (DocPaymentRow.Amount > DocPaymentRow.InvoiceTotal) : (DocPaymentRow.Amount < DocPaymentRow.InvoiceTotal); if (overPayment) { String strMessage = String.Format(Catalog.GetString( "Payment of {0} {1} to {2}: Payment cannot be more than the due amount."), StringHelper.FormatUsingCurrencyCode(DocPaymentRow.Amount, PaymentRow.CurrencyCode), PaymentRow.CurrencyCode, PaymentRow.SupplierName); System.Windows.Forms.MessageBox.Show(strMessage, Catalog.GetString("OverPayment")); return; } } } TDlgGLEnterDateEffective dateEffectiveDialog = new TDlgGLEnterDateEffective( FMainDS.AApDocument[0].LedgerNumber, Catalog.GetString("Select payment date"), Catalog.GetString("The date effective for the payment") + ":"); if (dateEffectiveDialog.ShowDialog() != DialogResult.OK) { MessageBox.Show(Catalog.GetString("The payment was cancelled."), Catalog.GetString( "No Success"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } DateTime PaymentDate = dateEffectiveDialog.SelectedDate; TVerificationResultCollection Verifications; this.Cursor = Cursors.WaitCursor; if (!TRemote.MFinance.AP.WebConnectors.PostAPPayments( ref FMainDS, PaymentDate, out Verifications)) { this.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("Payment failed")); } else { this.Cursor = Cursors.Default; PrintPaymentReport(sender, e); PrintRemittanceAdvice(); // TODO: show posting register of GL Batch? // After the payments screen, The status of this document may have changed. TFormsMessage broadcastMessage = new TFormsMessage(TFormsMessageClassEnum.mcAPTransactionChanged); broadcastMessage.SetMessageDataAPTransaction(String.Empty); TFormsList.GFormsList.BroadcastFormMessage(broadcastMessage); Close(); } }
/// <summary> /// Reverse all tagged rows /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void ReverseAllTagged(object sender, EventArgs e) { string MsgTitle = Catalog.GetString("Document Reversal"); // I can only reverse invoices that are POSTED. // This method is only enabled when the grid shows rows for paying // This will include rows that are PARTPAID - we need to test for those List <int>ReverseTheseDocs = new List <int>(); int taggedCount = 0; foreach (DataRowView rv in grdInvoices.PagedDataTable.DefaultView) { if (rv.Row["Selected"].Equals(true)) { taggedCount++; if ("POSTED" == rv.Row["DocumentStatus"].ToString()) { ReverseTheseDocs.Add(Convert.ToInt32(rv.Row["ApDocumentId"])); } } } if (ReverseTheseDocs.Count < taggedCount) { string msg = Catalog.GetString("A document cannot be reversed if it has been part-paid."); if (ReverseTheseDocs.Count == 0) { MessageBox.Show(msg, MsgTitle); } else { msg += Environment.NewLine + Environment.NewLine; msg += Catalog.GetString("Do you want to continue and reverse the 'Posted' documents?"); if (MessageBox.Show(msg, MsgTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) { return; } } } if (ReverseTheseDocs.Count > 0) { TVerificationResultCollection Verifications; TDlgGLEnterDateEffective dateEffectiveDialog = new TDlgGLEnterDateEffective( FMainForm.LedgerNumber, Catalog.GetString("Select reversal date"), Catalog.GetString("The date effective for this reversal") + ":"); if (dateEffectiveDialog.ShowDialog(FMainForm) != DialogResult.OK) { MessageBox.Show(Catalog.GetString("Reversal was cancelled."), MsgTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } DateTime PostingDate = dateEffectiveDialog.SelectedDate; this.Cursor = Cursors.WaitCursor; if (TRemote.MFinance.AP.WebConnectors.PostAPDocuments( FMainForm.LedgerNumber, ReverseTheseDocs, PostingDate, true, out Verifications)) { this.Cursor = Cursors.Default; MessageBox.Show(Catalog.GetString("The tagged invoices have been reversed to 'Approved' status."), MsgTitle); FMainForm.IsInvoiceDataChanged = true; LoadInvoices(); return; } else { this.Cursor = Cursors.Default; string ErrorMessages = Verifications.BuildVerificationResultString(); MessageBox.Show(ErrorMessages, MsgTitle); } } else { MessageBox.Show(Catalog.GetString("There are no tagged invoices to be reversed."), MsgTitle); } }