diff --git a/src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30.Codeunit.al b/src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30.Codeunit.al index 0f27e44426..ae9a0fa8a6 100644 --- a/src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30.Codeunit.al +++ b/src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30.Codeunit.al @@ -1057,5 +1057,23 @@ codeunit 37200 "PEPPOL30" implements "PEPPOL Attachment Provider" exit(PEPPOLManagementImpl.MapServiceLineTypeToSalesLineType(ServiceLineType)); end; - + /// + /// Gets allowance charge information for payment discounts from VAT amount line and sales header. + /// + /// The VAT amount line record containing allowance charge information. + /// The sales header record. + /// Returns the charge indicator. + /// Returns the allowance charge reason code. + /// Returns the allowance charge list ID. + /// Returns the allowance charge reason. + /// Returns the amount. + /// Returns the allowance charge currency ID. + /// Returns the tax category ID. + /// Returns the tax category scheme ID. + /// Returns the percent. + /// Returns the allowance charge tax scheme ID. + procedure GetAllowanceChargeInfoPaymentDiscount(VATAmtLine: Record "VAT Amount Line"; SalesHeader: Record "Sales Header"; var ChargeIndicator: Text; var AllowanceChargeReasonCode: Text; var AllowanceChargeListID: Text; var AllowanceChargeReason: Text; var Amount: Text; var AllowanceChargeCurrencyID: Text; var TaxCategoryID: Text; var TaxCategorySchemeID: Text; var Percent: Text; var AllowanceChargeTaxSchemeID: Text) + begin + PEPPOLManagementImpl.GetAllowanceChargeInfoPaymentDiscount(VATAmtLine, SalesHeader, ChargeIndicator, AllowanceChargeReasonCode, AllowanceChargeListID, AllowanceChargeReason, Amount, AllowanceChargeCurrencyID, TaxCategoryID, TaxCategorySchemeID, Percent, AllowanceChargeTaxSchemeID); + end; } diff --git a/src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30Impl.Codeunit.al b/src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30Impl.Codeunit.al index fccbec1fe7..e581fd9aa1 100644 --- a/src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30Impl.Codeunit.al +++ b/src/Apps/W1/PEPPOL/App/src/Common/PEPPOL30Impl.Codeunit.al @@ -47,6 +47,8 @@ codeunit 37201 "PEPPOL30 Impl." SalespersonTxt: Label 'Salesperson'; UoMforPieceINUNECERec20ListIDTxt: Label 'EA', Locked = true; VATTxt: Label 'VAT', Locked = true; + PaymentDisAmtTxt: Label 'Payment Discount Amount'; + AllowanceChargePaymentDiscountReasonCodeTxt: Label '95', Locked = true; procedure GetGeneralInfo(SalesHeader: Record "Sales Header"; var ID: Text; var IssueDate: Text; var InvoiceTypeCode: Text; var InvoiceTypeCodeListID: Text; var Note: Text; var TaxPointDate: Text; var DocumentCurrencyCode: Text; var DocumentCurrencyCodeListID: Text; var TaxCurrencyCode: Text; var TaxCurrencyCodeListID: Text; var AccountingCost: Text) var @@ -676,7 +678,7 @@ codeunit 37201 "PEPPOL30 Impl." var GLSetup: Record "General Ledger Setup"; begin - TaxableAmount := Format(VATAmtLine."VAT Base", 0, 9); + TaxableAmount := Format(VATAmtLine."VAT Base" - VATAmtLine."Pmt. Discount Amount", 0, 9); TaxAmountCurrencyID := GetSalesDocCurrencyCode(SalesHeader); SubtotalTaxAmount := Format(VATAmtLine."VAT Amount", 0, 9); TaxSubtotalCurrencyID := GetSalesDocCurrencyCode(SalesHeader); @@ -737,13 +739,13 @@ codeunit 37201 "PEPPOL30 Impl." Format(VATAmtLine."Amount Including VAT" - Round(VATAmtLine."Amount Including VAT", 0.01), 0, 9); PayableRndingAmountCurrencyID := GetSalesDocCurrencyCode(SalesHeader); - PayableAmount := Format(Round(VATAmtLine."Amount Including VAT", 0.01), 0, 9); + PayableAmount := Format(Round(VATAmtLine."Amount Including VAT" - VATAmtLine."Pmt. Discount Amount", 0.01), 0, 9); PayableAmountCurrencyID := GetSalesDocCurrencyCode(SalesHeader); end else begin PayableRoundingAmount := Format(TempSalesLine."Amount Including VAT", 0, 9); PayableRndingAmountCurrencyID := GetSalesDocCurrencyCode(SalesHeader); - PayableAmount := Format(Round(VATAmtLine."Amount Including VAT" + TempSalesLine."Amount Including VAT", 0.01), 0, 9); + PayableAmount := Format(Round(VATAmtLine."Amount Including VAT" + TempSalesLine."Amount Including VAT" - VATAmtLine."Pmt. Discount Amount", 0.01), 0, 9); PayableAmountCurrencyID := GetSalesDocCurrencyCode(SalesHeader); end; end; @@ -753,13 +755,13 @@ codeunit 37201 "PEPPOL30 Impl." LineExtensionAmount := Format(Round(VATAmtLine."VAT Base", 0.01) + Round(VATAmtLine."Invoice Discount Amount", 0.01), 0, 9); LegalMonetaryTotalCurrencyID := GetSalesDocCurrencyCode(SalesHeader); - TaxExclusiveAmount := Format(Round(VATAmtLine."VAT Base", 0.01), 0, 9); + TaxExclusiveAmount := Format(Round(VATAmtLine."VAT Base" - VATAmtLine."Pmt. Discount Amount", 0.01), 0, 9); TaxExclusiveAmountCurrencyID := GetSalesDocCurrencyCode(SalesHeader); - TaxInclusiveAmount := Format(Round(VATAmtLine."Amount Including VAT", 0.01, '>'), 0, 9); // Should be two decimal places + TaxInclusiveAmount := Format(Round(VATAmtLine."Amount Including VAT" - VATAmtLine."Pmt. Discount Amount", 0.01, '>'), 0, 9); // Should be two decimal places TaxInclusiveAmountCurrencyID := GetSalesDocCurrencyCode(SalesHeader); - AllowanceTotalAmount := Format(Round(VATAmtLine."Invoice Discount Amount", 0.01), 0, 9); + AllowanceTotalAmount := Format(Round(VATAmtLine."Invoice Discount Amount" + VATAmtLine."Pmt. Discount Amount", 0.01), 0, 9); AllowanceTotalAmountCurrencyID := GetSalesDocCurrencyCode(SalesHeader); TaxInclusiveAmountCurrencyID := GetSalesDocCurrencyCode(SalesHeader); @@ -768,11 +770,14 @@ codeunit 37201 "PEPPOL30 Impl." end; procedure GetLineGeneralInfo(SalesLine: Record "Sales Line"; SalesHeader: Record "Sales Header"; var InvoiceLineID: Text; var InvoiceLineNote: Text; var InvoicedQuantity: Text; var InvoiceLineExtensionAmount: Text; var LineExtensionAmountCurrencyID: Text; var InvoiceLineAccountingCost: Text) + var + SalesLineLineAmount: Decimal; begin InvoiceLineID := Format(SalesLine."Line No.", 0, 9); InvoiceLineNote := DelChr(Format(SalesLine.Type), '<>'); InvoicedQuantity := Format(SalesLine.Quantity, 0, 9); - InvoiceLineExtensionAmount := Format(SalesLine."VAT Base Amount" + SalesLine."Inv. Discount Amount", 0, 9); + SalesLineLineAmount := SalesLine."Line Amount"; + InvoiceLineExtensionAmount := Format(SalesLineLineAmount, 0, 9); LineExtensionAmountCurrencyID := GetSalesDocCurrencyCode(SalesHeader); InvoiceLineAccountingCost := ''; end; @@ -1337,4 +1342,23 @@ codeunit 37201 "PEPPOL30 Impl." exit("Sales Line Type"::"G/L Account"); end; end; + + procedure GetAllowanceChargeInfoPaymentDiscount(VATAmtLine: Record "VAT Amount Line"; SalesHeader: Record "Sales Header"; var ChargeIndicator: Text; var AllowanceChargeReasonCode: Text; var AllowanceChargeListID: Text; var AllowanceChargeReason: Text; var Amount: Text; var AllowanceChargeCurrencyID: Text; var TaxCategoryID: Text; var TaxCategorySchemeID: Text; var Percent: Text; var AllowanceChargeTaxSchemeID: Text) + begin + if VATAmtLine."Pmt. Discount Amount" = 0 then begin + ChargeIndicator := ''; + exit; + end; + + ChargeIndicator := 'false'; + AllowanceChargeReasonCode := AllowanceChargePaymentDiscountReasonCodeTxt; + AllowanceChargeListID := GetUNCL4465ListID(); + AllowanceChargeReason := PaymentDisAmtTxt; + Amount := Format(VATAmtLine."Pmt. Discount Amount", 0, 9); + AllowanceChargeCurrencyID := GetSalesDocCurrencyCode(SalesHeader); + TaxCategoryID := VATAmtLine."Tax Category"; + TaxCategorySchemeID := ''; + Percent := Format(VATAmtLine."VAT %", 0, 9); + AllowanceChargeTaxSchemeID := VATTxt; + end; } \ No newline at end of file diff --git a/src/Apps/W1/PEPPOL/App/src/Interfaces/PEPPOLPaymentInfoProvider.Interface.al b/src/Apps/W1/PEPPOL/App/src/Interfaces/PEPPOLPaymentInfoProvider.Interface.al index dfc91131e3..aa9a5dbaf4 100644 --- a/src/Apps/W1/PEPPOL/App/src/Interfaces/PEPPOLPaymentInfoProvider.Interface.al +++ b/src/Apps/W1/PEPPOL/App/src/Interfaces/PEPPOLPaymentInfoProvider.Interface.al @@ -5,6 +5,7 @@ namespace Microsoft.Peppol; using Microsoft.Sales.Document; +using Microsoft.Finance.VAT.Calculation; interface "PEPPOL Payment Info Provider" { @@ -58,4 +59,21 @@ interface "PEPPOL Payment Info Provider" /// The sales header record. /// Return value: Payment terms note. procedure GetPaymentTermsInfo(SalesHeader: Record "Sales Header"; var PaymentTermsNote: Text) + + /// + /// Gets allowance charge information for payment discounts from VAT amount line and sales header. + /// + /// The VAT amount line record containing allowance charge information. + /// The sales header record. + /// Returns the charge indicator. + /// Returns the allowance charge reason code. + /// Returns the allowance charge list ID. + /// Returns the allowance charge reason. + /// Returns the amount. + /// Returns the allowance charge currency ID. + /// Returns the tax category ID. + /// Returns the tax category scheme ID. + /// Returns the percent. + /// Returns the allowance charge tax scheme ID. + procedure GetAllowanceChargeInfoPaymentDiscount(VATAmtLine: Record "VAT Amount Line"; SalesHeader: Record "Sales Header"; var ChargeIndicator: Text; var AllowanceChargeReasonCode: Text; var AllowanceChargeListID: Text; var AllowanceChargeReason: Text; var Amount: Text; var AllowanceChargeCurrencyID: Text; var TaxCategoryID: Text; var TaxCategorySchemeID: Text; var Percent: Text; var AllowanceChargeTaxSchemeID: Text) } \ No newline at end of file diff --git a/src/Apps/W1/PEPPOL/App/src/Sales/XmlPorts/SalesCrMemoPEPPOL30.XmlPort.al b/src/Apps/W1/PEPPOL/App/src/Sales/XmlPorts/SalesCrMemoPEPPOL30.XmlPort.al index 3838ec7271..974f5d06ba 100644 --- a/src/Apps/W1/PEPPOL/App/src/Sales/XmlPorts/SalesCrMemoPEPPOL30.XmlPort.al +++ b/src/Apps/W1/PEPPOL/App/src/Sales/XmlPorts/SalesCrMemoPEPPOL30.XmlPort.al @@ -1343,6 +1343,93 @@ xmlport 37200 "Sales Cr.Memo - PEPPOL30" currXMLport.Skip(); end; } + tableelement(allowancechargepaymentdiscountloop; Integer) + { + NamespacePrefix = 'cac'; + XmlName = 'AllowanceCharge'; + SourceTableView = sorting(Number) where(Number = filter(1 ..)); + textelement(ChargeIndicatorPaymentDiscount) + { + XmlName = 'ChargeIndicator'; + NamespacePrefix = 'cbc'; + } + textelement(AllowanceChargeReasonCodePaymentDiscount) + { + XmlName = 'AllowanceChargeReasonCode'; + NamespacePrefix = 'cbc'; + } + textelement(AllowanceChargeReasonPaymentDiscount) + { + XmlName = 'AllowanceChargeReason'; + NamespacePrefix = 'cbc'; + } + textelement(AmountPaymentDiscount) + { + XmlName = 'Amount'; + NamespacePrefix = 'cbc'; + textattribute(allowancechargecurrencyidPaymentDiscount) + { + XmlName = 'currencyID'; + } + } + textelement(TaxCategoryPaymentDiscount) + { + XmlName = 'TaxCategory'; + NamespacePrefix = 'cac'; + textelement(taxcategoryidPaymentDiscount) + { + NamespacePrefix = 'cbc'; + XmlName = 'ID'; + } + textelement(PercentPaymentDiscount) + { + XmlName = 'Percent'; + NamespacePrefix = 'cbc'; + + trigger OnBeforePassVariable() + begin + if PercentPaymentDiscount = '' then + currXMLport.Skip(); + end; + } + textelement(TaxSchemePaymentDiscount) + { + XmlName = 'TaxScheme'; + NamespacePrefix = 'cac'; + textelement(allowancechargetaxschemeidPaymentDiscount) + { + NamespacePrefix = 'cbc'; + XmlName = 'ID'; + } + } + } + + trigger OnAfterGetRecord() + var + PEPPOLPaymentInfoProvider: Interface "PEPPOL Payment Info Provider"; + begin + if not FindNextVATAmtRec(TempVATAmtLine, AllowanceChargePaymentDiscountLoop.Number) then + currXMLport.Break(); + + PEPPOLPaymentInfoProvider := GetFormat(); + PEPPOLPaymentInfoProvider.GetAllowanceChargeInfoPaymentDiscount( + TempVATAmtLine, + SalesHeader, + ChargeIndicatorPaymentDiscount, + AllowanceChargeReasonCodePaymentDiscount, + DummyVar, + AllowanceChargeReasonPaymentDiscount, + AmountPaymentDiscount, + AllowanceChargeCurrencyIDPaymentDiscount, + TaxCategoryIDPaymentDiscount, + DummyVar, + PercentPaymentDiscount, + AllowanceChargeTaxSchemeIDPaymentDiscount); + + if ChargeIndicatorPaymentDiscount = '' then + currXMLport.Skip(); + end; + } textelement(TaxTotal) { NamespacePrefix = 'cac'; diff --git a/src/Apps/W1/PEPPOL/App/src/Sales/XmlPorts/SalesInvoicePEPPOL30.XmlPort.al b/src/Apps/W1/PEPPOL/App/src/Sales/XmlPorts/SalesInvoicePEPPOL30.XmlPort.al index 17864f300a..ba99931fcf 100644 --- a/src/Apps/W1/PEPPOL/App/src/Sales/XmlPorts/SalesInvoicePEPPOL30.XmlPort.al +++ b/src/Apps/W1/PEPPOL/App/src/Sales/XmlPorts/SalesInvoicePEPPOL30.XmlPort.al @@ -1294,6 +1294,93 @@ xmlport 37201 "Sales Invoice - PEPPOL30" currXMLport.Skip(); end; } + tableelement(allowancechargepaymentdiscountloop; Integer) + { + NamespacePrefix = 'cac'; + XmlName = 'AllowanceCharge'; + SourceTableView = sorting(Number) where(Number = filter(1 ..)); + textelement(ChargeIndicatorPaymentDiscount) + { + XmlName = 'ChargeIndicator'; + NamespacePrefix = 'cbc'; + } + textelement(AllowanceChargeReasonCodePaymentDiscount) + { + XmlName = 'AllowanceChargeReasonCode'; + NamespacePrefix = 'cbc'; + } + textelement(AllowanceChargeReasonPaymentDiscount) + { + XmlName = 'AllowanceChargeReason'; + NamespacePrefix = 'cbc'; + } + textelement(AmountPaymentDiscount) + { + XmlName = 'Amount'; + NamespacePrefix = 'cbc'; + textattribute(allowancechargecurrencyidPaymentDiscount) + { + XmlName = 'currencyID'; + } + } + textelement(TaxCategoryPaymentDiscount) + { + XmlName = 'TaxCategory'; + NamespacePrefix = 'cac'; + textelement(taxcategoryidPaymentDiscount) + { + NamespacePrefix = 'cbc'; + XmlName = 'ID'; + } + textelement(PercentPaymentDiscount) + { + XmlName = 'Percent'; + NamespacePrefix = 'cbc'; + + trigger OnBeforePassVariable() + begin + if PercentPaymentDiscount = '' then + currXMLport.Skip(); + end; + } + textelement(TaxSchemePaymentDiscount) + { + XmlName = 'TaxScheme'; + NamespacePrefix = 'cac'; + textelement(allowancechargetaxschemeidPaymentDiscount) + { + NamespacePrefix = 'cbc'; + XmlName = 'ID'; + } + } + } + + trigger OnAfterGetRecord() + var + PEPPOLPaymentInfoProvider: Interface "PEPPOL Payment Info Provider"; + begin + if not FindNextVATAmtRec(TempVATAmtLine, AllowanceChargePaymentDiscountLoop.Number) then + currXMLport.Break(); + + PEPPOLPaymentInfoProvider := GetFormat(); + PEPPOLPaymentInfoProvider.GetAllowanceChargeInfoPaymentDiscount( + TempVATAmtLine, + SalesHeader, + ChargeIndicatorPaymentDiscount, + AllowanceChargeReasonCodePaymentDiscount, + DummyVar, + AllowanceChargeReasonPaymentDiscount, + AmountPaymentDiscount, + AllowanceChargeCurrencyIDPaymentDiscount, + TaxCategoryIDPaymentDiscount, + DummyVar, + PercentPaymentDiscount, + AllowanceChargeTaxSchemeIDPaymentDiscount); + + if ChargeIndicatorPaymentDiscount = '' then + currXMLport.Skip(); + end; + } textelement(TaxTotal) { NamespacePrefix = 'cac'; diff --git a/src/Apps/W1/PEPPOL/Test/src/PEPPOL30ManagementTests.Codeunit.al b/src/Apps/W1/PEPPOL/Test/src/PEPPOL30ManagementTests.Codeunit.al index ffb73c40e9..cf66f2d825 100644 --- a/src/Apps/W1/PEPPOL/Test/src/PEPPOL30ManagementTests.Codeunit.al +++ b/src/Apps/W1/PEPPOL/Test/src/PEPPOL30ManagementTests.Codeunit.al @@ -3954,6 +3954,7 @@ codeunit 139235 "PEPPOL30 Management Tests" LineExtensionAmountCurrencyID: Text; unitCode: Text; unitCodeListID: Text; + SalesInvoiceLineLineAmount: Decimal; begin SalesInvoiceHeader.Get(PostedInvoiceNo); SalesHeader.TransferFields(SalesInvoiceHeader); @@ -3975,9 +3976,8 @@ codeunit 139235 "PEPPOL30 Management Tests" Assert.AreEqual(Format(SalesInvoiceLine.Quantity, 0, 9), InvoicedQuantity, ''); Assert.AreEqual(UnitOfMeasure."International Standard Code", unitCode, ''); Assert.AreEqual('UNECERec20', unitCodeListID, ''); - Assert.AreEqual( - Format(SalesInvoiceLine."VAT Base Amount" + SalesInvoiceLine."Inv. Discount Amount", 0, 9), - InvoiceLineExtensionAmount, ''); + SalesInvoiceLineLineAmount := SalesInvoiceLine."Line Amount"; + Assert.AreEqual(Format(SalesInvoiceLineLineAmount, 0, 9), InvoiceLineExtensionAmount, ''); Assert.AreEqual(SalesHeader."Currency Code", LineExtensionAmountCurrencyID, ''); Assert.AreEqual('', InvoiceLineAccountingCost, ''); end;