From 7ab26b4af2875e8db611ac3c72876ad0051a4cf2 Mon Sep 17 00:00:00 2001 From: v-rohangarg20 Date: Sat, 25 Jul 2026 11:39:09 +0530 Subject: [PATCH 1/2] Fix with Automation --- .../Purchases/Posting/PurchPost.Codeunit.al | 32 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 6 + .../Tests/ERM/PurchaseDocuments.Codeunit.al | 138 ++++++++++++++++++ 4 files changed, 181 insertions(+), 7 deletions(-) diff --git a/src/Layers/W1/BaseApp/Purchases/Posting/PurchPost.Codeunit.al b/src/Layers/W1/BaseApp/Purchases/Posting/PurchPost.Codeunit.al index e31b4f5b0cd..6e5fa7073d9 100644 --- a/src/Layers/W1/BaseApp/Purchases/Posting/PurchPost.Codeunit.al +++ b/src/Layers/W1/BaseApp/Purchases/Posting/PurchPost.Codeunit.al @@ -511,6 +511,7 @@ codeunit 90 "Purch.-Post" ItemChargeZeroAmountErr: Label 'The amount for item charge %1 cannot be 0.', Comment = '%1 = Item Charge No.'; ConfirmUsageWithBlankLineTypeQst: Label 'Usage will not be linked to the project planning line because the Line Type field is empty.\\Do you want to continue?'; ConfirmUsageWithBlankJobPlanningLineNoQst: Label 'Usage will not be linked to the project planning line because the Project Planning Line No field is empty.\\Do you want to continue?'; + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; /// /// Generates a record id for an 'empty' line @@ -3041,10 +3042,7 @@ codeunit 90 "Purch.-Post" ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Credit Memo Nos.") else if (PurchHeader."Document Type" <> PurchHeader."Document Type"::"Credit Memo") then - if PurchHeader."Self-Billing Invoice" then - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Self-Billing Inv. Nos.") - else - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); + ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); if PurchHeader."Document Type" = PurchHeader."Document Type"::"Credit Memo" then if (PurchSetup."Posted Credit Memo Nos." <> '') and (PurchHeader."Posting No. Series" = '') then CheckDefaultNoSeries(PurchSetup."Posted Credit Memo Nos."); @@ -8903,18 +8901,38 @@ codeunit 90 "Purch.-Post" local procedure UpdateVendorInvoiceNoForSelfBilling(var PurchHeader: Record "Purchase Header") var + Vendor: Record Vendor; NoSeries: Codeunit "No. Series"; + SelfBillingNoSeriesCode: Code[20]; begin if not (PurchHeader."Document Type" in [PurchHeader."Document Type"::Invoice, PurchHeader."Document Type"::Order]) then exit; - PurchSetup.GetRecordOnce(); - PurchSetup.TestField("Posted Self-Billing Inv. Nos."); + SelfBillingNoSeriesCode := GetSelfBillingInvoiceNoSeries(PurchHeader); + if SelfBillingNoSeriesCode = '' then + Error( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + PurchHeader."Buy-from Vendor No.", + PurchSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchSetup.TableCaption()); if PreviewMode then PurchHeader."Vendor Invoice No." := PostingPreviewNoTok else - PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(PurchSetup."Posted Self-Billing Inv. Nos.", PurchHeader."Posting Date"); + PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(SelfBillingNoSeriesCode, PurchHeader."Posting Date"); + end; + + local procedure GetSelfBillingInvoiceNoSeries(PurchHeader: Record "Purchase Header"): Code[20] + var + Vendor: Record Vendor; + begin + Vendor.SetLoadFields("Self-Billing Invoice Nos."); + if Vendor.Get(PurchHeader."Buy-from Vendor No.") and (Vendor."Self-Billing Invoice Nos." <> '') then + exit(Vendor."Self-Billing Invoice Nos."); + + PurchSetup.GetRecordOnce(); + exit(PurchSetup."Posted Self-Billing Inv. Nos."); end; local procedure SelfBillingInvoiceDocument(PurchHeader: Record "Purchase Header"): Boolean diff --git a/src/Layers/W1/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/W1/BaseApp/Purchases/Vendor/Vendor.Table.al index 54fa306632c..13f3799d139 100644 --- a/src/Layers/W1/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/W1/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1279,6 +1279,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/W1/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/W1/BaseApp/Purchases/Vendor/VendorCard.Page.al index 7754307aef3..1b9b013c7aa 100644 --- a/src/Layers/W1/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/W1/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -365,6 +365,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/W1/Tests/ERM/PurchaseDocuments.Codeunit.al b/src/Layers/W1/Tests/ERM/PurchaseDocuments.Codeunit.al index e821e6427f4..31ba9fe367a 100644 --- a/src/Layers/W1/Tests/ERM/PurchaseDocuments.Codeunit.al +++ b/src/Layers/W1/Tests/ERM/PurchaseDocuments.Codeunit.al @@ -39,6 +39,7 @@ codeunit 134099 "Purchase Documents" DocAmountFieldVisibleErr: Label 'The field %1 should be visible on the purchase invoice page.', Comment = '%1 = Field Caption'; PurchaseInvoiceSelfBillingErr: Label 'Posted purchase invoice is not marked as self-billing invoice'; SelfBillingInvoiceReportCaptionLbl: Label 'Self Billing Invoice '; + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; [Test] [HandlerFunctions('RecallNotificationHandler,SendNotificationHandler')] @@ -2163,6 +2164,143 @@ codeunit 134099 "Purchase Documents" LibraryReportDataset.AssertElementWithValueExists('SelfBillingCaption', SelfBillingInvoiceReportCaptionLbl); end; + [Test] + procedure PurchPostUsesVendorSelfBillingNoSeriesOverGlobal() + var + PurchHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchInvHeader: Record "Purch. Inv. Header"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + VendorNoSeriesLine: Record "No. Series Line"; + GlobalNoSeriesLine: Record "No. Series Line"; + GlobalNoSeriesCode: Code[20]; + VendorNoSeriesCode: Code[20]; + SelfBillingInvoiceNo: Code[20]; + begin + // [FEATURE] [Self-Billing] + // [SCENARIO 626320] When a vendor has "Self-Billing Invoice Nos.", posting uses the vendor series instead of the setup series. + Initialize(); + + // [GIVEN] A global number series is set in "Posted Self-Billing Inv. Nos." in Purchases & Payables Setup. + GlobalNoSeriesCode := LibraryERM.CreateNoSeriesCode(); + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", GlobalNoSeriesCode); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] A self-billing vendor has its own value in "Self-Billing Invoice Nos.". + VendorNoSeriesCode := LibraryERM.CreateNoSeriesCode(); + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Validate("Self-Billing Invoice Nos.", VendorNoSeriesCode); + Vendor.Modify(true); + + // [GIVEN] A purchase invoice is created for the vendor with an empty "Vendor Invoice No.". + LibraryPurchase.CreatePurchHeader(PurchHeader, PurchHeader."Document Type"::Invoice, Vendor."No."); + LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), 1); + + // [WHEN] The purchase document is posted. + SelfBillingInvoiceNo := LibraryPurchase.PostPurchaseDocument(PurchHeader, true, true); + + // [THEN] "Vendor Invoice No." is assigned from the vendor-specific number series. + PurchInvHeader.Get(SelfBillingInvoiceNo); + VendorNoSeriesLine.SetRange("Series Code", VendorNoSeriesCode); + VendorNoSeriesLine.FindFirst(); + Assert.AreEqual(VendorNoSeriesLine."Last No. Used", PurchInvHeader."Vendor Invoice No.", PurchInvHeader.FieldCaption("Vendor Invoice No.")); + + // [THEN] The global self-billing number series is not used. + GlobalNoSeriesLine.SetRange("Series Code", GlobalNoSeriesCode); + GlobalNoSeriesLine.FindFirst(); + Assert.AreEqual('', GlobalNoSeriesLine."Last No. Used", 'The global self-billing number series should not be used when the vendor has its own series.'); + end; + + [Test] + procedure PurchPostSelfBillingFailsWithoutAnyNoSeries() + var + PurchHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + begin + // [FEATURE] [Self-Billing] + // [SCENARIO 626320] Posting fails when neither vendor nor setup defines a self-billing number series. + Initialize(); + + // [GIVEN] "Posted Self-Billing Inv. Nos." in Purchases & Payables Setup is empty. + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", ''); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] A self-billing vendor has no value in "Self-Billing Invoice Nos." + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Modify(true); + + // [GIVEN] A purchase invoice is created for the vendor. + LibraryPurchase.CreatePurchHeader(PurchHeader, PurchHeader."Document Type"::Invoice, Vendor."No."); + LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), 1); + + // [WHEN] The purchase document is posted. + asserterror LibraryPurchase.PostPurchaseDocument(PurchHeader, true, true); + + // [THEN] Posting fails with the self-billing number series error that identifies the vendor and setup fields. + Assert.ExpectedError( + StrSubstNo( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + Vendor."No.", + PurchasesPayablesSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchasesPayablesSetup.TableCaption())); + end; + + [Test] + procedure SelfBillingAgreementCannotBeDisabledWhileNoSeriesIsSet() + var + Vendor: Record Vendor; + begin + // [FEATURE] [Self-Billing] + // [SCENARIO 626320] "Self-Billing Agreement" cannot be turned off while the vendor still has a "Self-Billing Invoice Nos." series. + Initialize(); + + // [GIVEN] A self-billing vendor that has a vendor-specific "Self-Billing Invoice Nos." series assigned. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Validate("Self-Billing Invoice Nos.", LibraryERM.CreateNoSeriesCode()); + Vendor.Modify(true); + + // [WHEN] Disabling "Self-Billing Agreement" without first clearing the number series. + asserterror Vendor.Validate("Self-Billing Agreement", false); + + // [THEN] Validation fails, requiring "Self-Billing Invoice Nos." to be blank before the agreement can be disabled. + Assert.ExpectedError(Vendor.FieldCaption("Self-Billing Invoice Nos.")); + end; + + [Test] + procedure SelfBillingAgreementCanBeDisabledAfterClearingNoSeries() + var + Vendor: Record Vendor; + begin + // [FEATURE] [Self-Billing] + // [SCENARIO 626320] "Self-Billing Agreement" can be turned off once the "Self-Billing Invoice Nos." series is cleared. + Initialize(); + + // [GIVEN] A self-billing vendor that has a vendor-specific "Self-Billing Invoice Nos." series assigned. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Validate("Self-Billing Invoice Nos.", LibraryERM.CreateNoSeriesCode()); + Vendor.Modify(true); + + // [GIVEN] The vendor-specific number series is cleared. + Vendor.Validate("Self-Billing Invoice Nos.", ''); + + // [WHEN] Disabling "Self-Billing Agreement". + Vendor.Validate("Self-Billing Agreement", false); + + // [THEN] The agreement is disabled and the number series stays blank. + Vendor.TestField("Self-Billing Agreement", false); + Vendor.TestField("Self-Billing Invoice Nos.", ''); + end; + local procedure Initialize() var ReportSelections: Record "Report Selections"; From dea5c41f1565a68214297450c998ce3bd7effd49 Mon Sep 17 00:00:00 2001 From: v-rohangarg20 Date: Sat, 25 Jul 2026 12:59:13 +0530 Subject: [PATCH 2/2] Invoke-miapp --- .../Purchases/Posting/PurchPost.Codeunit.al | 32 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 8 +- .../Purchases/Posting/PurchPost.Codeunit.al | 32 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 6 + .../Tests/ERM/PurchaseDocuments.Codeunit.al | 138 ++++++++++++++++++ .../Purchases/Posting/PurchPost.Codeunit.al | 32 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 6 + .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 6 + .../Purchases/Posting/PurchPost.Codeunit.al | 32 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 6 + .../Purchases/Posting/PurchPost.Codeunit.al | 32 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 6 + .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 6 + .../Purchases/Posting/PurchPost.Codeunit.al | 32 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 6 + .../Purchases/Vendor/VendorCard.Page.al | 6 + .../Purchases/Posting/PurchPost.Codeunit.al | 34 ++++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 8 +- .../Purchases/Posting/PurchPost.Codeunit.al | 32 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 6 + .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 6 + .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 6 + .../Purchases/Posting/PurchPost.Codeunit.al | 32 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 12 ++ .../Purchases/Vendor/VendorCard.Page.al | 6 + .../Tests/ERM/PurchaseDocuments.Codeunit.al | 138 ++++++++++++++++++ 38 files changed, 744 insertions(+), 66 deletions(-) diff --git a/src/Layers/APAC/BaseApp/Purchases/Posting/PurchPost.Codeunit.al b/src/Layers/APAC/BaseApp/Purchases/Posting/PurchPost.Codeunit.al index 10cd9282081..76da11f123f 100644 --- a/src/Layers/APAC/BaseApp/Purchases/Posting/PurchPost.Codeunit.al +++ b/src/Layers/APAC/BaseApp/Purchases/Posting/PurchPost.Codeunit.al @@ -527,6 +527,7 @@ codeunit 90 "Purch.-Post" ItemChargeZeroAmountErr: Label 'The amount for item charge %1 cannot be 0.', Comment = '%1 = Item Charge No.'; ConfirmUsageWithBlankLineTypeQst: Label 'Usage will not be linked to the project planning line because the Line Type field is empty.\\Do you want to continue?'; ConfirmUsageWithBlankJobPlanningLineNoQst: Label 'Usage will not be linked to the project planning line because the Project Planning Line No field is empty.\\Do you want to continue?'; + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; /// /// Generates a record id for an 'empty' line @@ -3073,10 +3074,7 @@ codeunit 90 "Purch.-Post" ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Credit Memo Nos.") else if (PurchHeader."Document Type" <> PurchHeader."Document Type"::"Credit Memo") then - if PurchHeader."Self-Billing Invoice" then - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Self-Billing Inv. Nos.") - else - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); + ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); if PurchHeader."Document Type" = PurchHeader."Document Type"::"Credit Memo" then if (PurchSetup."Posted Credit Memo Nos." <> '') and (PurchHeader."Posting No. Series" = '') then CheckDefaultNoSeries(PurchSetup."Posted Credit Memo Nos."); @@ -9385,18 +9383,38 @@ codeunit 90 "Purch.-Post" local procedure UpdateVendorInvoiceNoForSelfBilling(var PurchHeader: Record "Purchase Header") var + Vendor: Record Vendor; NoSeries: Codeunit "No. Series"; + SelfBillingNoSeriesCode: Code[20]; begin if not (PurchHeader."Document Type" in [PurchHeader."Document Type"::Invoice, PurchHeader."Document Type"::Order]) then exit; - PurchSetup.GetRecordOnce(); - PurchSetup.TestField("Posted Self-Billing Inv. Nos."); + SelfBillingNoSeriesCode := GetSelfBillingInvoiceNoSeries(PurchHeader); + if SelfBillingNoSeriesCode = '' then + Error( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + PurchHeader."Buy-from Vendor No.", + PurchSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchSetup.TableCaption()); if PreviewMode then PurchHeader."Vendor Invoice No." := PostingPreviewNoTok else - PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(PurchSetup."Posted Self-Billing Inv. Nos.", PurchHeader."Posting Date"); + PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(SelfBillingNoSeriesCode, PurchHeader."Posting Date"); + end; + + local procedure GetSelfBillingInvoiceNoSeries(PurchHeader: Record "Purchase Header"): Code[20] + var + Vendor: Record Vendor; + begin + Vendor.SetLoadFields("Self-Billing Invoice Nos."); + if Vendor.Get(PurchHeader."Buy-from Vendor No.") and (Vendor."Self-Billing Invoice Nos." <> '') then + exit(Vendor."Self-Billing Invoice Nos."); + + PurchSetup.GetRecordOnce(); + exit(PurchSetup."Posted Self-Billing Inv. Nos."); end; local procedure SelfBillingInvoiceDocument(PurchHeader: Record "Purchase Header"): Boolean diff --git a/src/Layers/APAC/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/APAC/BaseApp/Purchases/Vendor/Vendor.Table.al index 12205213e2a..da83fdfc021 100644 --- a/src/Layers/APAC/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/APAC/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1280,6 +1280,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/APAC/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/APAC/BaseApp/Purchases/Vendor/VendorCard.Page.al index 2c43cf76df2..1300a71733f 100644 --- a/src/Layers/APAC/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/APAC/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -1,4 +1,4 @@ -// ------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. // ------------------------------------------------------------------------------------------------ @@ -388,6 +388,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/BE/BaseApp/Purchases/Posting/PurchPost.Codeunit.al b/src/Layers/BE/BaseApp/Purchases/Posting/PurchPost.Codeunit.al index d18b1cde202..0cc142f1b2a 100644 --- a/src/Layers/BE/BaseApp/Purchases/Posting/PurchPost.Codeunit.al +++ b/src/Layers/BE/BaseApp/Purchases/Posting/PurchPost.Codeunit.al @@ -514,6 +514,7 @@ codeunit 90 "Purch.-Post" ItemChargeZeroAmountErr: Label 'The amount for item charge %1 cannot be 0.', Comment = '%1 = Item Charge No.'; ConfirmUsageWithBlankLineTypeQst: Label 'Usage will not be linked to the project planning line because the Line Type field is empty.\\Do you want to continue?'; ConfirmUsageWithBlankJobPlanningLineNoQst: Label 'Usage will not be linked to the project planning line because the Project Planning Line No field is empty.\\Do you want to continue?'; + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; /// /// Generates a record id for an 'empty' line @@ -3044,10 +3045,7 @@ codeunit 90 "Purch.-Post" ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Credit Memo Nos.") else if (PurchHeader."Document Type" <> PurchHeader."Document Type"::"Credit Memo") then - if PurchHeader."Self-Billing Invoice" then - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Self-Billing Inv. Nos.") - else - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); + ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); if PurchHeader."Document Type" = PurchHeader."Document Type"::"Credit Memo" then if (PurchSetup."Posted Credit Memo Nos." <> '') and (PurchHeader."Posting No. Series" = '') then CheckDefaultNoSeries(PurchSetup."Posted Credit Memo Nos."); @@ -8951,18 +8949,38 @@ codeunit 90 "Purch.-Post" local procedure UpdateVendorInvoiceNoForSelfBilling(var PurchHeader: Record "Purchase Header") var + Vendor: Record Vendor; NoSeries: Codeunit "No. Series"; + SelfBillingNoSeriesCode: Code[20]; begin if not (PurchHeader."Document Type" in [PurchHeader."Document Type"::Invoice, PurchHeader."Document Type"::Order]) then exit; - PurchSetup.GetRecordOnce(); - PurchSetup.TestField("Posted Self-Billing Inv. Nos."); + SelfBillingNoSeriesCode := GetSelfBillingInvoiceNoSeries(PurchHeader); + if SelfBillingNoSeriesCode = '' then + Error( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + PurchHeader."Buy-from Vendor No.", + PurchSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchSetup.TableCaption()); if PreviewMode then PurchHeader."Vendor Invoice No." := PostingPreviewNoTok else - PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(PurchSetup."Posted Self-Billing Inv. Nos.", PurchHeader."Posting Date"); + PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(SelfBillingNoSeriesCode, PurchHeader."Posting Date"); + end; + + local procedure GetSelfBillingInvoiceNoSeries(PurchHeader: Record "Purchase Header"): Code[20] + var + Vendor: Record Vendor; + begin + Vendor.SetLoadFields("Self-Billing Invoice Nos."); + if Vendor.Get(PurchHeader."Buy-from Vendor No.") and (Vendor."Self-Billing Invoice Nos." <> '') then + exit(Vendor."Self-Billing Invoice Nos."); + + PurchSetup.GetRecordOnce(); + exit(PurchSetup."Posted Self-Billing Inv. Nos."); end; local procedure SelfBillingInvoiceDocument(PurchHeader: Record "Purchase Header"): Boolean diff --git a/src/Layers/BE/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/BE/BaseApp/Purchases/Vendor/Vendor.Table.al index a6a4af0c2e1..8668ca78a1e 100644 --- a/src/Layers/BE/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/BE/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1282,6 +1282,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/BE/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/BE/BaseApp/Purchases/Vendor/VendorCard.Page.al index 4942a4931ce..0892691c8e8 100644 --- a/src/Layers/BE/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/BE/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -365,6 +365,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/CA/Tests/ERM/PurchaseDocuments.Codeunit.al b/src/Layers/CA/Tests/ERM/PurchaseDocuments.Codeunit.al index cc130f59005..80160cd62f5 100644 --- a/src/Layers/CA/Tests/ERM/PurchaseDocuments.Codeunit.al +++ b/src/Layers/CA/Tests/ERM/PurchaseDocuments.Codeunit.al @@ -39,6 +39,7 @@ codeunit 134099 "Purchase Documents" DocAmountFieldVisibleErr: Label 'The field %1 should be visible on the purchase invoice page.', Comment = '%1 = Field Caption'; PurchaseInvoiceSelfBillingErr: Label 'Posted purchase invoice is not marked as self-billing invoice'; SelfBillingInvoiceReportCaptionLbl: Label 'Self Billing Invoice '; + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; [Test] [HandlerFunctions('RecallNotificationHandler,SendNotificationHandler')] @@ -2173,6 +2174,143 @@ codeunit 134099 "Purchase Documents" LibraryReportDataset.AssertElementWithValueExists('SelfBillingCaption', SelfBillingInvoiceReportCaptionLbl); end; + [Test] + procedure PurchPostUsesVendorSelfBillingNoSeriesOverGlobal() + var + PurchHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchInvHeader: Record "Purch. Inv. Header"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + VendorNoSeriesLine: Record "No. Series Line"; + GlobalNoSeriesLine: Record "No. Series Line"; + GlobalNoSeriesCode: Code[20]; + VendorNoSeriesCode: Code[20]; + SelfBillingInvoiceNo: Code[20]; + begin + // [FEATURE] [Self-Billing] + // [SCENARIO 626320] When a vendor has "Self-Billing Invoice Nos.", posting uses the vendor series instead of the setup series. + Initialize(); + + // [GIVEN] A global number series is set in "Posted Self-Billing Inv. Nos." in Purchases & Payables Setup. + GlobalNoSeriesCode := LibraryERM.CreateNoSeriesCode(); + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", GlobalNoSeriesCode); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] A self-billing vendor has its own value in "Self-Billing Invoice Nos.". + VendorNoSeriesCode := LibraryERM.CreateNoSeriesCode(); + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Validate("Self-Billing Invoice Nos.", VendorNoSeriesCode); + Vendor.Modify(true); + + // [GIVEN] A purchase invoice is created for the vendor with an empty "Vendor Invoice No.". + LibraryPurchase.CreatePurchHeader(PurchHeader, PurchHeader."Document Type"::Invoice, Vendor."No."); + LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), 1); + + // [WHEN] The purchase document is posted. + SelfBillingInvoiceNo := LibraryPurchase.PostPurchaseDocument(PurchHeader, true, true); + + // [THEN] "Vendor Invoice No." is assigned from the vendor-specific number series. + PurchInvHeader.Get(SelfBillingInvoiceNo); + VendorNoSeriesLine.SetRange("Series Code", VendorNoSeriesCode); + VendorNoSeriesLine.FindFirst(); + Assert.AreEqual(VendorNoSeriesLine."Last No. Used", PurchInvHeader."Vendor Invoice No.", PurchInvHeader.FieldCaption("Vendor Invoice No.")); + + // [THEN] The global self-billing number series is not used. + GlobalNoSeriesLine.SetRange("Series Code", GlobalNoSeriesCode); + GlobalNoSeriesLine.FindFirst(); + Assert.AreEqual('', GlobalNoSeriesLine."Last No. Used", 'The global self-billing number series should not be used when the vendor has its own series.'); + end; + + [Test] + procedure PurchPostSelfBillingFailsWithoutAnyNoSeries() + var + PurchHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + begin + // [FEATURE] [Self-Billing] + // [SCENARIO 626320] Posting fails when neither vendor nor setup defines a self-billing number series. + Initialize(); + + // [GIVEN] "Posted Self-Billing Inv. Nos." in Purchases & Payables Setup is empty. + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", ''); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] A self-billing vendor has no value in "Self-Billing Invoice Nos." + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Modify(true); + + // [GIVEN] A purchase invoice is created for the vendor. + LibraryPurchase.CreatePurchHeader(PurchHeader, PurchHeader."Document Type"::Invoice, Vendor."No."); + LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), 1); + + // [WHEN] The purchase document is posted. + asserterror LibraryPurchase.PostPurchaseDocument(PurchHeader, true, true); + + // [THEN] Posting fails with the self-billing number series error that identifies the vendor and setup fields. + Assert.ExpectedError( + StrSubstNo( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + Vendor."No.", + PurchasesPayablesSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchasesPayablesSetup.TableCaption())); + end; + + [Test] + procedure SelfBillingAgreementCannotBeDisabledWhileNoSeriesIsSet() + var + Vendor: Record Vendor; + begin + // [FEATURE] [Self-Billing] + // [SCENARIO 626320] "Self-Billing Agreement" cannot be turned off while the vendor still has a "Self-Billing Invoice Nos." series. + Initialize(); + + // [GIVEN] A self-billing vendor that has a vendor-specific "Self-Billing Invoice Nos." series assigned. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Validate("Self-Billing Invoice Nos.", LibraryERM.CreateNoSeriesCode()); + Vendor.Modify(true); + + // [WHEN] Disabling "Self-Billing Agreement" without first clearing the number series. + asserterror Vendor.Validate("Self-Billing Agreement", false); + + // [THEN] Validation fails, requiring "Self-Billing Invoice Nos." to be blank before the agreement can be disabled. + Assert.ExpectedError(Vendor.FieldCaption("Self-Billing Invoice Nos.")); + end; + + [Test] + procedure SelfBillingAgreementCanBeDisabledAfterClearingNoSeries() + var + Vendor: Record Vendor; + begin + // [FEATURE] [Self-Billing] + // [SCENARIO 626320] "Self-Billing Agreement" can be turned off once the "Self-Billing Invoice Nos." series is cleared. + Initialize(); + + // [GIVEN] A self-billing vendor that has a vendor-specific "Self-Billing Invoice Nos." series assigned. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Validate("Self-Billing Invoice Nos.", LibraryERM.CreateNoSeriesCode()); + Vendor.Modify(true); + + // [GIVEN] The vendor-specific number series is cleared. + Vendor.Validate("Self-Billing Invoice Nos.", ''); + + // [WHEN] Disabling "Self-Billing Agreement". + Vendor.Validate("Self-Billing Agreement", false); + + // [THEN] The agreement is disabled and the number series stays blank. + Vendor.TestField("Self-Billing Agreement", false); + Vendor.TestField("Self-Billing Invoice Nos.", ''); + end; + local procedure Initialize() var ReportSelections: Record "Report Selections"; diff --git a/src/Layers/CH/BaseApp/Purchases/Posting/PurchPost.Codeunit.al b/src/Layers/CH/BaseApp/Purchases/Posting/PurchPost.Codeunit.al index d7e0620747d..a29880f9254 100644 --- a/src/Layers/CH/BaseApp/Purchases/Posting/PurchPost.Codeunit.al +++ b/src/Layers/CH/BaseApp/Purchases/Posting/PurchPost.Codeunit.al @@ -516,6 +516,7 @@ codeunit 90 "Purch.-Post" ItemChargeZeroAmountErr: Label 'The amount for item charge %1 cannot be 0.', Comment = '%1 = Item Charge No.'; ConfirmUsageWithBlankLineTypeQst: Label 'Usage will not be linked to the project planning line because the Line Type field is empty.\\Do you want to continue?'; ConfirmUsageWithBlankJobPlanningLineNoQst: Label 'Usage will not be linked to the project planning line because the Project Planning Line No field is empty.\\Do you want to continue?'; + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; /// /// Generates a record id for an 'empty' line @@ -3048,10 +3049,7 @@ codeunit 90 "Purch.-Post" ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Credit Memo Nos.") else if (PurchHeader."Document Type" <> PurchHeader."Document Type"::"Credit Memo") then - if PurchHeader."Self-Billing Invoice" then - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Self-Billing Inv. Nos.") - else - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); + ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); if PurchHeader."Document Type" = PurchHeader."Document Type"::"Credit Memo" then if (PurchSetup."Posted Credit Memo Nos." <> '') and (PurchHeader."Posting No. Series" = '') then CheckDefaultNoSeries(PurchSetup."Posted Credit Memo Nos."); @@ -8934,18 +8932,38 @@ codeunit 90 "Purch.-Post" local procedure UpdateVendorInvoiceNoForSelfBilling(var PurchHeader: Record "Purchase Header") var + Vendor: Record Vendor; NoSeries: Codeunit "No. Series"; + SelfBillingNoSeriesCode: Code[20]; begin if not (PurchHeader."Document Type" in [PurchHeader."Document Type"::Invoice, PurchHeader."Document Type"::Order]) then exit; - PurchSetup.GetRecordOnce(); - PurchSetup.TestField("Posted Self-Billing Inv. Nos."); + SelfBillingNoSeriesCode := GetSelfBillingInvoiceNoSeries(PurchHeader); + if SelfBillingNoSeriesCode = '' then + Error( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + PurchHeader."Buy-from Vendor No.", + PurchSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchSetup.TableCaption()); if PreviewMode then PurchHeader."Vendor Invoice No." := PostingPreviewNoTok else - PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(PurchSetup."Posted Self-Billing Inv. Nos.", PurchHeader."Posting Date"); + PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(SelfBillingNoSeriesCode, PurchHeader."Posting Date"); + end; + + local procedure GetSelfBillingInvoiceNoSeries(PurchHeader: Record "Purchase Header"): Code[20] + var + Vendor: Record Vendor; + begin + Vendor.SetLoadFields("Self-Billing Invoice Nos."); + if Vendor.Get(PurchHeader."Buy-from Vendor No.") and (Vendor."Self-Billing Invoice Nos." <> '') then + exit(Vendor."Self-Billing Invoice Nos."); + + PurchSetup.GetRecordOnce(); + exit(PurchSetup."Posted Self-Billing Inv. Nos."); end; local procedure SelfBillingInvoiceDocument(PurchHeader: Record "Purchase Header"): Boolean diff --git a/src/Layers/CH/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/CH/BaseApp/Purchases/Vendor/Vendor.Table.al index 96ea6ff06fb..8f5ff77321c 100644 --- a/src/Layers/CH/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/CH/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1279,6 +1279,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/CH/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/CH/BaseApp/Purchases/Vendor/VendorCard.Page.al index de2a288dd22..4dfc1e03e4a 100644 --- a/src/Layers/CH/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/CH/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -364,6 +364,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/DACH/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/DACH/BaseApp/Purchases/Vendor/Vendor.Table.al index e6788cd99a6..0728f4e0039 100644 --- a/src/Layers/DACH/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/DACH/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1279,6 +1279,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/DACH/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/DACH/BaseApp/Purchases/Vendor/VendorCard.Page.al index bb3bcb1cd19..a771ad8ffe6 100644 --- a/src/Layers/DACH/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/DACH/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -364,6 +364,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/ES/BaseApp/Purchases/Posting/PurchPost.Codeunit.al b/src/Layers/ES/BaseApp/Purchases/Posting/PurchPost.Codeunit.al index 9e8964bb530..a6827d335be 100644 --- a/src/Layers/ES/BaseApp/Purchases/Posting/PurchPost.Codeunit.al +++ b/src/Layers/ES/BaseApp/Purchases/Posting/PurchPost.Codeunit.al @@ -547,6 +547,7 @@ codeunit 90 "Purch.-Post" ItemChargeZeroAmountErr: Label 'The amount for item charge %1 cannot be 0.', Comment = '%1 = Item Charge No.'; ConfirmUsageWithBlankLineTypeQst: Label 'Usage will not be linked to the project planning line because the Line Type field is empty.\\Do you want to continue?'; ConfirmUsageWithBlankJobPlanningLineNoQst: Label 'Usage will not be linked to the project planning line because the Project Planning Line No field is empty.\\Do you want to continue?'; + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; /// /// Generates a record id for an 'empty' line @@ -3129,10 +3130,7 @@ codeunit 90 "Purch.-Post" ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Credit Memo Nos.") else if (PurchHeader."Document Type" <> PurchHeader."Document Type"::"Credit Memo") then - if PurchHeader."Self-Billing Invoice" then - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Self-Billing Inv. Nos.") - else - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); + ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); if PurchHeader."Document Type" = PurchHeader."Document Type"::"Credit Memo" then if (PurchSetup."Posted Credit Memo Nos." <> '') and (PurchHeader."Posting No. Series" = '') then CheckDefaultNoSeries(PurchSetup."Posted Credit Memo Nos."); @@ -9109,18 +9107,38 @@ codeunit 90 "Purch.-Post" local procedure UpdateVendorInvoiceNoForSelfBilling(var PurchHeader: Record "Purchase Header") var + Vendor: Record Vendor; NoSeries: Codeunit "No. Series"; + SelfBillingNoSeriesCode: Code[20]; begin if not (PurchHeader."Document Type" in [PurchHeader."Document Type"::Invoice, PurchHeader."Document Type"::Order]) then exit; - PurchSetup.GetRecordOnce(); - PurchSetup.TestField("Posted Self-Billing Inv. Nos."); + SelfBillingNoSeriesCode := GetSelfBillingInvoiceNoSeries(PurchHeader); + if SelfBillingNoSeriesCode = '' then + Error( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + PurchHeader."Buy-from Vendor No.", + PurchSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchSetup.TableCaption()); if PreviewMode then PurchHeader."Vendor Invoice No." := PostingPreviewNoTok else - PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(PurchSetup."Posted Self-Billing Inv. Nos.", PurchHeader."Posting Date"); + PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(SelfBillingNoSeriesCode, PurchHeader."Posting Date"); + end; + + local procedure GetSelfBillingInvoiceNoSeries(PurchHeader: Record "Purchase Header"): Code[20] + var + Vendor: Record Vendor; + begin + Vendor.SetLoadFields("Self-Billing Invoice Nos."); + if Vendor.Get(PurchHeader."Buy-from Vendor No.") and (Vendor."Self-Billing Invoice Nos." <> '') then + exit(Vendor."Self-Billing Invoice Nos."); + + PurchSetup.GetRecordOnce(); + exit(PurchSetup."Posted Self-Billing Inv. Nos."); end; local procedure SelfBillingInvoiceDocument(PurchHeader: Record "Purchase Header"): Boolean diff --git a/src/Layers/ES/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/ES/BaseApp/Purchases/Vendor/Vendor.Table.al index e4b730820b3..dbdb723fd98 100644 --- a/src/Layers/ES/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/ES/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1282,6 +1282,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/ES/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/ES/BaseApp/Purchases/Vendor/VendorCard.Page.al index 1ecb216f733..e6c49b9fb4d 100644 --- a/src/Layers/ES/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/ES/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -364,6 +364,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/FI/BaseApp/Purchases/Posting/PurchPost.Codeunit.al b/src/Layers/FI/BaseApp/Purchases/Posting/PurchPost.Codeunit.al index c29ebb02d40..a17e16c5973 100644 --- a/src/Layers/FI/BaseApp/Purchases/Posting/PurchPost.Codeunit.al +++ b/src/Layers/FI/BaseApp/Purchases/Posting/PurchPost.Codeunit.al @@ -514,6 +514,7 @@ codeunit 90 "Purch.-Post" ItemChargeZeroAmountErr: Label 'The amount for item charge %1 cannot be 0.', Comment = '%1 = Item Charge No.'; ConfirmUsageWithBlankLineTypeQst: Label 'Usage will not be linked to the project planning line because the Line Type field is empty.\\Do you want to continue?'; ConfirmUsageWithBlankJobPlanningLineNoQst: Label 'Usage will not be linked to the project planning line because the Project Planning Line No field is empty.\\Do you want to continue?'; + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; /// /// Generates a record id for an 'empty' line @@ -3047,10 +3048,7 @@ codeunit 90 "Purch.-Post" ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Credit Memo Nos.") else if (PurchHeader."Document Type" <> PurchHeader."Document Type"::"Credit Memo") then - if PurchHeader."Self-Billing Invoice" then - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Self-Billing Inv. Nos.") - else - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); + ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); if PurchHeader."Document Type" = PurchHeader."Document Type"::"Credit Memo" then if (PurchSetup."Posted Credit Memo Nos." <> '') and (PurchHeader."Posting No. Series" = '') then CheckDefaultNoSeries(PurchSetup."Posted Credit Memo Nos."); @@ -8909,18 +8907,38 @@ codeunit 90 "Purch.-Post" local procedure UpdateVendorInvoiceNoForSelfBilling(var PurchHeader: Record "Purchase Header") var + Vendor: Record Vendor; NoSeries: Codeunit "No. Series"; + SelfBillingNoSeriesCode: Code[20]; begin if not (PurchHeader."Document Type" in [PurchHeader."Document Type"::Invoice, PurchHeader."Document Type"::Order]) then exit; - PurchSetup.GetRecordOnce(); - PurchSetup.TestField("Posted Self-Billing Inv. Nos."); + SelfBillingNoSeriesCode := GetSelfBillingInvoiceNoSeries(PurchHeader); + if SelfBillingNoSeriesCode = '' then + Error( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + PurchHeader."Buy-from Vendor No.", + PurchSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchSetup.TableCaption()); if PreviewMode then PurchHeader."Vendor Invoice No." := PostingPreviewNoTok else - PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(PurchSetup."Posted Self-Billing Inv. Nos.", PurchHeader."Posting Date"); + PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(SelfBillingNoSeriesCode, PurchHeader."Posting Date"); + end; + + local procedure GetSelfBillingInvoiceNoSeries(PurchHeader: Record "Purchase Header"): Code[20] + var + Vendor: Record Vendor; + begin + Vendor.SetLoadFields("Self-Billing Invoice Nos."); + if Vendor.Get(PurchHeader."Buy-from Vendor No.") and (Vendor."Self-Billing Invoice Nos." <> '') then + exit(Vendor."Self-Billing Invoice Nos."); + + PurchSetup.GetRecordOnce(); + exit(PurchSetup."Posted Self-Billing Inv. Nos."); end; local procedure SelfBillingInvoiceDocument(PurchHeader: Record "Purchase Header"): Boolean diff --git a/src/Layers/FI/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/FI/BaseApp/Purchases/Vendor/Vendor.Table.al index 5f590b29d39..1b0ba8c36b0 100644 --- a/src/Layers/FI/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/FI/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1279,6 +1279,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/FI/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/FI/BaseApp/Purchases/Vendor/VendorCard.Page.al index c8b58510ceb..0138f04c5ac 100644 --- a/src/Layers/FI/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/FI/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -369,6 +369,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/FR/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/FR/BaseApp/Purchases/Vendor/Vendor.Table.al index 2c16fb8d42f..a943b016257 100644 --- a/src/Layers/FR/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/FR/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1282,6 +1282,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/FR/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/FR/BaseApp/Purchases/Vendor/VendorCard.Page.al index 97200d5aef9..45d40d12b2f 100644 --- a/src/Layers/FR/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/FR/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -367,6 +367,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/GB/BaseApp/Purchases/Posting/PurchPost.Codeunit.al b/src/Layers/GB/BaseApp/Purchases/Posting/PurchPost.Codeunit.al index 3ee76260ac6..a91394cd9ff 100644 --- a/src/Layers/GB/BaseApp/Purchases/Posting/PurchPost.Codeunit.al +++ b/src/Layers/GB/BaseApp/Purchases/Posting/PurchPost.Codeunit.al @@ -525,6 +525,7 @@ codeunit 90 "Purch.-Post" ReverseChargeFeatureNameTok: Label 'Reverse Charge GB', Locked = true; ReverseChargeEventNameTok: Label 'Reverse Charge GB has been used', Locked = true; #endif + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; /// /// Generates a record id for an 'empty' line @@ -3074,10 +3075,7 @@ codeunit 90 "Purch.-Post" ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Credit Memo Nos.") else if (PurchHeader."Document Type" <> PurchHeader."Document Type"::"Credit Memo") then - if PurchHeader."Self-Billing Invoice" then - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Self-Billing Inv. Nos.") - else - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); + ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); if PurchHeader."Document Type" = PurchHeader."Document Type"::"Credit Memo" then if (PurchSetup."Posted Credit Memo Nos." <> '') and (PurchHeader."Posting No. Series" = '') then CheckDefaultNoSeries(PurchSetup."Posted Credit Memo Nos."); @@ -8936,18 +8934,38 @@ codeunit 90 "Purch.-Post" local procedure UpdateVendorInvoiceNoForSelfBilling(var PurchHeader: Record "Purchase Header") var + Vendor: Record Vendor; NoSeries: Codeunit "No. Series"; + SelfBillingNoSeriesCode: Code[20]; begin if not (PurchHeader."Document Type" in [PurchHeader."Document Type"::Invoice, PurchHeader."Document Type"::Order]) then exit; - PurchSetup.GetRecordOnce(); - PurchSetup.TestField("Posted Self-Billing Inv. Nos."); + SelfBillingNoSeriesCode := GetSelfBillingInvoiceNoSeries(PurchHeader); + if SelfBillingNoSeriesCode = '' then + Error( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + PurchHeader."Buy-from Vendor No.", + PurchSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchSetup.TableCaption()); if PreviewMode then PurchHeader."Vendor Invoice No." := PostingPreviewNoTok else - PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(PurchSetup."Posted Self-Billing Inv. Nos.", PurchHeader."Posting Date"); + PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(SelfBillingNoSeriesCode, PurchHeader."Posting Date"); + end; + + local procedure GetSelfBillingInvoiceNoSeries(PurchHeader: Record "Purchase Header"): Code[20] + var + Vendor: Record Vendor; + begin + Vendor.SetLoadFields("Self-Billing Invoice Nos."); + if Vendor.Get(PurchHeader."Buy-from Vendor No.") and (Vendor."Self-Billing Invoice Nos." <> '') then + exit(Vendor."Self-Billing Invoice Nos."); + + PurchSetup.GetRecordOnce(); + exit(PurchSetup."Posted Self-Billing Inv. Nos."); end; local procedure SelfBillingInvoiceDocument(PurchHeader: Record "Purchase Header"): Boolean diff --git a/src/Layers/GB/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/GB/BaseApp/Purchases/Vendor/Vendor.Table.al index df2a8a2f0b9..1fbea9d63fc 100644 --- a/src/Layers/GB/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/GB/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1279,6 +1279,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/GB/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/GB/BaseApp/Purchases/Vendor/VendorCard.Page.al index 5102dd814bb..bb7cd8359b4 100644 --- a/src/Layers/GB/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/GB/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -409,6 +409,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/IS/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/IS/BaseApp/Purchases/Vendor/VendorCard.Page.al index 649a9bf230f..cbbc0db5dd4 100644 --- a/src/Layers/IS/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/IS/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -364,6 +364,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/IT/BaseApp/Purchases/Posting/PurchPost.Codeunit.al b/src/Layers/IT/BaseApp/Purchases/Posting/PurchPost.Codeunit.al index 08d01188af3..c8ea922beb0 100644 --- a/src/Layers/IT/BaseApp/Purchases/Posting/PurchPost.Codeunit.al +++ b/src/Layers/IT/BaseApp/Purchases/Posting/PurchPost.Codeunit.al @@ -1,4 +1,4 @@ -// ------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. // ------------------------------------------------------------------------------------------------ @@ -536,6 +536,7 @@ codeunit 90 "Purch.-Post" ItemChargeZeroAmountErr: Label 'The amount for item charge %1 cannot be 0.', Comment = '%1 = Item Charge No.'; ConfirmUsageWithBlankLineTypeQst: Label 'Usage will not be linked to the project planning line because the Line Type field is empty.\\Do you want to continue?'; ConfirmUsageWithBlankJobPlanningLineNoQst: Label 'Usage will not be linked to the project planning line because the Project Planning Line No field is empty.\\Do you want to continue?'; + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; /// /// Generates a record id for an 'empty' line @@ -3163,10 +3164,7 @@ codeunit 90 "Purch.-Post" ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Credit Memo Nos.") else if (PurchHeader."Document Type" <> PurchHeader."Document Type"::"Credit Memo") then - if PurchHeader."Self-Billing Invoice" then - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Self-Billing Inv. Nos.") - else - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); + ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); if PurchHeader."Document Type" = PurchHeader."Document Type"::"Credit Memo" then if (PurchSetup."Posted Credit Memo Nos." <> '') and (PurchHeader."Posting No. Series" = '') then CheckDefaultNoSeries(PurchSetup."Posted Credit Memo Nos."); @@ -9274,18 +9272,38 @@ codeunit 90 "Purch.-Post" local procedure UpdateVendorInvoiceNoForSelfBilling(var PurchHeader: Record "Purchase Header") var + Vendor: Record Vendor; NoSeries: Codeunit "No. Series"; + SelfBillingNoSeriesCode: Code[20]; begin if not (PurchHeader."Document Type" in [PurchHeader."Document Type"::Invoice, PurchHeader."Document Type"::Order]) then exit; - PurchSetup.GetRecordOnce(); - PurchSetup.TestField("Posted Self-Billing Inv. Nos."); + SelfBillingNoSeriesCode := GetSelfBillingInvoiceNoSeries(PurchHeader); + if SelfBillingNoSeriesCode = '' then + Error( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + PurchHeader."Buy-from Vendor No.", + PurchSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchSetup.TableCaption()); if PreviewMode then PurchHeader."Vendor Invoice No." := PostingPreviewNoTok else - PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(PurchSetup."Posted Self-Billing Inv. Nos.", PurchHeader."Posting Date"); + PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(SelfBillingNoSeriesCode, PurchHeader."Posting Date"); + end; + + local procedure GetSelfBillingInvoiceNoSeries(PurchHeader: Record "Purchase Header"): Code[20] + var + Vendor: Record Vendor; + begin + Vendor.SetLoadFields("Self-Billing Invoice Nos."); + if Vendor.Get(PurchHeader."Buy-from Vendor No.") and (Vendor."Self-Billing Invoice Nos." <> '') then + exit(Vendor."Self-Billing Invoice Nos."); + + PurchSetup.GetRecordOnce(); + exit(PurchSetup."Posted Self-Billing Inv. Nos."); end; local procedure SelfBillingInvoiceDocument(PurchHeader: Record "Purchase Header"): Boolean diff --git a/src/Layers/IT/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/IT/BaseApp/Purchases/Vendor/Vendor.Table.al index 91d4180a0bd..1c8aa7ab35d 100644 --- a/src/Layers/IT/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/IT/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1293,6 +1293,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/IT/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/IT/BaseApp/Purchases/Vendor/VendorCard.Page.al index a3c042c284b..0a9f0bccb4d 100644 --- a/src/Layers/IT/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/IT/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -1,4 +1,4 @@ -// ------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. // ------------------------------------------------------------------------------------------------ @@ -384,6 +384,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/NA/BaseApp/Purchases/Posting/PurchPost.Codeunit.al b/src/Layers/NA/BaseApp/Purchases/Posting/PurchPost.Codeunit.al index 0277f162c4f..836229c4bb4 100644 --- a/src/Layers/NA/BaseApp/Purchases/Posting/PurchPost.Codeunit.al +++ b/src/Layers/NA/BaseApp/Purchases/Posting/PurchPost.Codeunit.al @@ -553,6 +553,7 @@ codeunit 90 "Purch.-Post" ItemChargeZeroAmountErr: Label 'The amount for item charge %1 cannot be 0.', Comment = '%1 = Item Charge No.'; ConfirmUsageWithBlankLineTypeQst: Label 'Usage will not be linked to the project planning line because the Line Type field is empty.\\Do you want to continue?'; ConfirmUsageWithBlankJobPlanningLineNoQst: Label 'Usage will not be linked to the project planning line because the Project Planning Line No field is empty.\\Do you want to continue?'; + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; /// /// Generates a record id for an 'empty' line @@ -3146,10 +3147,7 @@ codeunit 90 "Purch.-Post" ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Credit Memo Nos.") else if (PurchHeader."Document Type" <> PurchHeader."Document Type"::"Credit Memo") then - if PurchHeader."Self-Billing Invoice" then - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Self-Billing Inv. Nos.") - else - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); + ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); if PurchHeader."Document Type" = PurchHeader."Document Type"::"Credit Memo" then if (PurchSetup."Posted Credit Memo Nos." <> '') and (PurchHeader."Posting No. Series" = '') then CheckDefaultNoSeries(PurchSetup."Posted Credit Memo Nos."); @@ -9646,18 +9644,38 @@ codeunit 90 "Purch.-Post" local procedure UpdateVendorInvoiceNoForSelfBilling(var PurchHeader: Record "Purchase Header") var + Vendor: Record Vendor; NoSeries: Codeunit "No. Series"; + SelfBillingNoSeriesCode: Code[20]; begin if not (PurchHeader."Document Type" in [PurchHeader."Document Type"::Invoice, PurchHeader."Document Type"::Order]) then exit; - PurchSetup.GetRecordOnce(); - PurchSetup.TestField("Posted Self-Billing Inv. Nos."); + SelfBillingNoSeriesCode := GetSelfBillingInvoiceNoSeries(PurchHeader); + if SelfBillingNoSeriesCode = '' then + Error( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + PurchHeader."Buy-from Vendor No.", + PurchSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchSetup.TableCaption()); if PreviewMode then PurchHeader."Vendor Invoice No." := PostingPreviewNoTok else - PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(PurchSetup."Posted Self-Billing Inv. Nos.", PurchHeader."Posting Date"); + PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(SelfBillingNoSeriesCode, PurchHeader."Posting Date"); + end; + + local procedure GetSelfBillingInvoiceNoSeries(PurchHeader: Record "Purchase Header"): Code[20] + var + Vendor: Record Vendor; + begin + Vendor.SetLoadFields("Self-Billing Invoice Nos."); + if Vendor.Get(PurchHeader."Buy-from Vendor No.") and (Vendor."Self-Billing Invoice Nos." <> '') then + exit(Vendor."Self-Billing Invoice Nos."); + + PurchSetup.GetRecordOnce(); + exit(PurchSetup."Posted Self-Billing Inv. Nos."); end; local procedure SelfBillingInvoiceDocument(PurchHeader: Record "Purchase Header"): Boolean diff --git a/src/Layers/NA/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/NA/BaseApp/Purchases/Vendor/Vendor.Table.al index 461f22c8914..f3e8740515f 100644 --- a/src/Layers/NA/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/NA/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1279,6 +1279,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/NA/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/NA/BaseApp/Purchases/Vendor/VendorCard.Page.al index bb96dd129d2..0992062da54 100644 --- a/src/Layers/NA/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/NA/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -367,6 +367,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/NL/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/NL/BaseApp/Purchases/Vendor/Vendor.Table.al index 7f5d1df4e74..55bb3f7cfa4 100644 --- a/src/Layers/NL/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/NL/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1319,6 +1319,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/NL/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/NL/BaseApp/Purchases/Vendor/VendorCard.Page.al index 1ca16c705b1..ef359a3b1cf 100644 --- a/src/Layers/NL/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/NL/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -364,6 +364,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/NO/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/NO/BaseApp/Purchases/Vendor/Vendor.Table.al index bc1b99e3d15..a096a16a2a9 100644 --- a/src/Layers/NO/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/NO/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1279,6 +1279,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/NO/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/NO/BaseApp/Purchases/Vendor/VendorCard.Page.al index f5b34916bd7..5df448a97a4 100644 --- a/src/Layers/NO/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/NO/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -364,6 +364,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/RU/BaseApp/Purchases/Posting/PurchPost.Codeunit.al b/src/Layers/RU/BaseApp/Purchases/Posting/PurchPost.Codeunit.al index 8e3e1a4cdfd..b8451ea957b 100644 --- a/src/Layers/RU/BaseApp/Purchases/Posting/PurchPost.Codeunit.al +++ b/src/Layers/RU/BaseApp/Purchases/Posting/PurchPost.Codeunit.al @@ -535,6 +535,7 @@ codeunit 90 "Purch.-Post" ItemChargeZeroAmountErr: Label 'The amount for item charge %1 cannot be 0.', Comment = '%1 = Item Charge No.'; ConfirmUsageWithBlankLineTypeQst: Label 'Usage will not be linked to the project planning line because the Line Type field is empty.\\Do you want to continue?'; ConfirmUsageWithBlankJobPlanningLineNoQst: Label 'Usage will not be linked to the project planning line because the Project Planning Line No field is empty.\\Do you want to continue?'; + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; /// /// Generates a record id for an 'empty' line @@ -3207,10 +3208,7 @@ codeunit 90 "Purch.-Post" ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Credit Memo Nos.") else if (PurchHeader."Document Type" <> PurchHeader."Document Type"::"Credit Memo") then - if PurchHeader."Self-Billing Invoice" then - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Self-Billing Inv. Nos.") - else - ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); + ResetPostingNoSeriesFromSetup(PurchHeader."Posting No. Series", PurchSetup."Posted Invoice Nos."); if PurchHeader."Document Type" = PurchHeader."Document Type"::"Credit Memo" then if (PurchSetup."Posted Credit Memo Nos." <> '') and (PurchHeader."Posting No. Series" = '') then CheckDefaultNoSeries(PurchSetup."Posted Credit Memo Nos."); @@ -9682,18 +9680,38 @@ codeunit 90 "Purch.-Post" local procedure UpdateVendorInvoiceNoForSelfBilling(var PurchHeader: Record "Purchase Header") var + Vendor: Record Vendor; NoSeries: Codeunit "No. Series"; + SelfBillingNoSeriesCode: Code[20]; begin if not (PurchHeader."Document Type" in [PurchHeader."Document Type"::Invoice, PurchHeader."Document Type"::Order]) then exit; - PurchSetup.GetRecordOnce(); - PurchSetup.TestField("Posted Self-Billing Inv. Nos."); + SelfBillingNoSeriesCode := GetSelfBillingInvoiceNoSeries(PurchHeader); + if SelfBillingNoSeriesCode = '' then + Error( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + PurchHeader."Buy-from Vendor No.", + PurchSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchSetup.TableCaption()); if PreviewMode then PurchHeader."Vendor Invoice No." := PostingPreviewNoTok else - PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(PurchSetup."Posted Self-Billing Inv. Nos.", PurchHeader."Posting Date"); + PurchHeader."Vendor Invoice No." := NoSeries.GetNextNo(SelfBillingNoSeriesCode, PurchHeader."Posting Date"); + end; + + local procedure GetSelfBillingInvoiceNoSeries(PurchHeader: Record "Purchase Header"): Code[20] + var + Vendor: Record Vendor; + begin + Vendor.SetLoadFields("Self-Billing Invoice Nos."); + if Vendor.Get(PurchHeader."Buy-from Vendor No.") and (Vendor."Self-Billing Invoice Nos." <> '') then + exit(Vendor."Self-Billing Invoice Nos."); + + PurchSetup.GetRecordOnce(); + exit(PurchSetup."Posted Self-Billing Inv. Nos."); end; local procedure SelfBillingInvoiceDocument(PurchHeader: Record "Purchase Header"): Boolean diff --git a/src/Layers/RU/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/RU/BaseApp/Purchases/Vendor/Vendor.Table.al index 47a73a987a3..6c6813a1aed 100644 --- a/src/Layers/RU/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/RU/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1327,6 +1327,18 @@ table 23 Vendor { Caption = 'Self-Billing Agreement'; ToolTip = 'Specifies the value of the Self-Billing Agreement field.'; + + trigger OnValidate() + begin + if not Rec."Self-Billing Agreement" then + Rec.TestField("Self-Billing Invoice Nos.", ''); + end; + } + field(181; "Self-Billing Invoice Nos."; Code[20]) + { + Caption = 'Self-Billing Invoice Nos.'; + ToolTip = 'Specifies the number series that is used to assign numbers to self-billed purchase invoices for this vendor. If it is empty, the number series from the Posted Self-Billing Inv. Nos. field in Purchases & Payables Setup is used.'; + TableRelation = "No. Series"; } field(288; "Preferred Bank Account Code"; Code[20]) { diff --git a/src/Layers/RU/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/RU/BaseApp/Purchases/Vendor/VendorCard.Page.al index 2787fad4b7a..04d04b883e6 100644 --- a/src/Layers/RU/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/RU/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -388,6 +388,12 @@ page 26 "Vendor Card" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Self-Billing Invoice Nos."; Rec."Self-Billing Invoice Nos.") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + Enabled = Rec."Self-Billing Agreement"; + } field("Price Calculation Method"; Rec."Price Calculation Method") { Visible = ExtendedPriceEnabled; diff --git a/src/Layers/US/Tests/ERM/PurchaseDocuments.Codeunit.al b/src/Layers/US/Tests/ERM/PurchaseDocuments.Codeunit.al index cc130f59005..80160cd62f5 100644 --- a/src/Layers/US/Tests/ERM/PurchaseDocuments.Codeunit.al +++ b/src/Layers/US/Tests/ERM/PurchaseDocuments.Codeunit.al @@ -39,6 +39,7 @@ codeunit 134099 "Purchase Documents" DocAmountFieldVisibleErr: Label 'The field %1 should be visible on the purchase invoice page.', Comment = '%1 = Field Caption'; PurchaseInvoiceSelfBillingErr: Label 'Posted purchase invoice is not marked as self-billing invoice'; SelfBillingInvoiceReportCaptionLbl: Label 'Self Billing Invoice '; + SelfBillingNoSeriesMissingErr: Label 'Specify a number series for self-billing invoices in the %1 field on vendor %2, or in the %3 field in %4.', Comment = '%1 = Self-Billing Invoice Nos. field caption, %2 = Vendor No., %3 = Posted Self-Billing Inv. Nos. field caption, %4 = Purchases & Payables Setup table caption'; [Test] [HandlerFunctions('RecallNotificationHandler,SendNotificationHandler')] @@ -2173,6 +2174,143 @@ codeunit 134099 "Purchase Documents" LibraryReportDataset.AssertElementWithValueExists('SelfBillingCaption', SelfBillingInvoiceReportCaptionLbl); end; + [Test] + procedure PurchPostUsesVendorSelfBillingNoSeriesOverGlobal() + var + PurchHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchInvHeader: Record "Purch. Inv. Header"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + VendorNoSeriesLine: Record "No. Series Line"; + GlobalNoSeriesLine: Record "No. Series Line"; + GlobalNoSeriesCode: Code[20]; + VendorNoSeriesCode: Code[20]; + SelfBillingInvoiceNo: Code[20]; + begin + // [FEATURE] [Self-Billing] + // [SCENARIO 626320] When a vendor has "Self-Billing Invoice Nos.", posting uses the vendor series instead of the setup series. + Initialize(); + + // [GIVEN] A global number series is set in "Posted Self-Billing Inv. Nos." in Purchases & Payables Setup. + GlobalNoSeriesCode := LibraryERM.CreateNoSeriesCode(); + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", GlobalNoSeriesCode); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] A self-billing vendor has its own value in "Self-Billing Invoice Nos.". + VendorNoSeriesCode := LibraryERM.CreateNoSeriesCode(); + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Validate("Self-Billing Invoice Nos.", VendorNoSeriesCode); + Vendor.Modify(true); + + // [GIVEN] A purchase invoice is created for the vendor with an empty "Vendor Invoice No.". + LibraryPurchase.CreatePurchHeader(PurchHeader, PurchHeader."Document Type"::Invoice, Vendor."No."); + LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), 1); + + // [WHEN] The purchase document is posted. + SelfBillingInvoiceNo := LibraryPurchase.PostPurchaseDocument(PurchHeader, true, true); + + // [THEN] "Vendor Invoice No." is assigned from the vendor-specific number series. + PurchInvHeader.Get(SelfBillingInvoiceNo); + VendorNoSeriesLine.SetRange("Series Code", VendorNoSeriesCode); + VendorNoSeriesLine.FindFirst(); + Assert.AreEqual(VendorNoSeriesLine."Last No. Used", PurchInvHeader."Vendor Invoice No.", PurchInvHeader.FieldCaption("Vendor Invoice No.")); + + // [THEN] The global self-billing number series is not used. + GlobalNoSeriesLine.SetRange("Series Code", GlobalNoSeriesCode); + GlobalNoSeriesLine.FindFirst(); + Assert.AreEqual('', GlobalNoSeriesLine."Last No. Used", 'The global self-billing number series should not be used when the vendor has its own series.'); + end; + + [Test] + procedure PurchPostSelfBillingFailsWithoutAnyNoSeries() + var + PurchHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + begin + // [FEATURE] [Self-Billing] + // [SCENARIO 626320] Posting fails when neither vendor nor setup defines a self-billing number series. + Initialize(); + + // [GIVEN] "Posted Self-Billing Inv. Nos." in Purchases & Payables Setup is empty. + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", ''); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] A self-billing vendor has no value in "Self-Billing Invoice Nos." + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Modify(true); + + // [GIVEN] A purchase invoice is created for the vendor. + LibraryPurchase.CreatePurchHeader(PurchHeader, PurchHeader."Document Type"::Invoice, Vendor."No."); + LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), 1); + + // [WHEN] The purchase document is posted. + asserterror LibraryPurchase.PostPurchaseDocument(PurchHeader, true, true); + + // [THEN] Posting fails with the self-billing number series error that identifies the vendor and setup fields. + Assert.ExpectedError( + StrSubstNo( + SelfBillingNoSeriesMissingErr, + Vendor.FieldCaption("Self-Billing Invoice Nos."), + Vendor."No.", + PurchasesPayablesSetup.FieldCaption("Posted Self-Billing Inv. Nos."), + PurchasesPayablesSetup.TableCaption())); + end; + + [Test] + procedure SelfBillingAgreementCannotBeDisabledWhileNoSeriesIsSet() + var + Vendor: Record Vendor; + begin + // [FEATURE] [Self-Billing] + // [SCENARIO 626320] "Self-Billing Agreement" cannot be turned off while the vendor still has a "Self-Billing Invoice Nos." series. + Initialize(); + + // [GIVEN] A self-billing vendor that has a vendor-specific "Self-Billing Invoice Nos." series assigned. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Validate("Self-Billing Invoice Nos.", LibraryERM.CreateNoSeriesCode()); + Vendor.Modify(true); + + // [WHEN] Disabling "Self-Billing Agreement" without first clearing the number series. + asserterror Vendor.Validate("Self-Billing Agreement", false); + + // [THEN] Validation fails, requiring "Self-Billing Invoice Nos." to be blank before the agreement can be disabled. + Assert.ExpectedError(Vendor.FieldCaption("Self-Billing Invoice Nos.")); + end; + + [Test] + procedure SelfBillingAgreementCanBeDisabledAfterClearingNoSeries() + var + Vendor: Record Vendor; + begin + // [FEATURE] [Self-Billing] + // [SCENARIO 626320] "Self-Billing Agreement" can be turned off once the "Self-Billing Invoice Nos." series is cleared. + Initialize(); + + // [GIVEN] A self-billing vendor that has a vendor-specific "Self-Billing Invoice Nos." series assigned. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Validate("Self-Billing Invoice Nos.", LibraryERM.CreateNoSeriesCode()); + Vendor.Modify(true); + + // [GIVEN] The vendor-specific number series is cleared. + Vendor.Validate("Self-Billing Invoice Nos.", ''); + + // [WHEN] Disabling "Self-Billing Agreement". + Vendor.Validate("Self-Billing Agreement", false); + + // [THEN] The agreement is disabled and the number series stays blank. + Vendor.TestField("Self-Billing Agreement", false); + Vendor.TestField("Self-Billing Invoice Nos.", ''); + end; + local procedure Initialize() var ReportSelections: Record "Report Selections";