diff --git a/src/Apps/CZ/AdvancePaymentsLocalization/app/Src/TableExtensions/CashDocumentLineCZZ.TableExt.al b/src/Apps/CZ/AdvancePaymentsLocalization/app/Src/TableExtensions/CashDocumentLineCZZ.TableExt.al index f8c580444dc..40a8bf05842 100644 --- a/src/Apps/CZ/AdvancePaymentsLocalization/app/Src/TableExtensions/CashDocumentLineCZZ.TableExt.al +++ b/src/Apps/CZ/AdvancePaymentsLocalization/app/Src/TableExtensions/CashDocumentLineCZZ.TableExt.al @@ -21,7 +21,13 @@ tableextension 31028 "Cash Document Line CZZ" extends "Cash Document Line CZP" var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; PurchAdvLetterHeaderCZZ: Record "Purch. Adv. Letter Header CZZ"; + IsHandled: Boolean; begin + IsHandled := false; + OnBeforeValidateAdvanceLetterNoCZZ(Rec, IsHandled); + if IsHandled then + exit; + if "Advance Letter No. CZZ" <> '' then begin TestField("Gen. Document Type", "Gen. Document Type"::Payment); case "Document Type" of @@ -59,7 +65,13 @@ tableextension 31028 "Cash Document Line CZZ" extends "Cash Document Line CZP" var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; PurchAdvLetterHeaderCZZ: Record "Purch. Adv. Letter Header CZZ"; + IsHandled: Boolean; begin + IsHandled := false; + OnBeforeLookupAdvanceLetterNoCZZ(Rec, IsHandled); + if IsHandled then + exit; + TestField("Gen. Document Type", "Gen. Document Type"::Payment); if not ((("Document Type" = "Document Type"::Receipt) and ("Account Type" = "Account Type"::Customer)) or (("Document Type" = "Document Type"::Withdrawal) and ("Account Type" = "Account Type"::Vendor))) then @@ -145,4 +157,14 @@ tableextension 31028 "Cash Document Line CZZ" extends "Cash Document Line CZP" ("Applies-To Doc. Type" = "Applies-To Doc. Type"::Payment) and ("Applies-To Doc. No." <> '')); end; + + [IntegrationEvent(false, false)] + local procedure OnBeforeValidateAdvanceLetterNoCZZ(var CashDocumentLineCZP: Record "Cash Document Line CZP"; var IsHandled: Boolean) + begin + end; + + [IntegrationEvent(false, false)] + local procedure OnBeforeLookupAdvanceLetterNoCZZ(var CashDocumentLineCZP: Record "Cash Document Line CZP"; var IsHandled: Boolean) + begin + end; } diff --git a/src/Apps/CZ/AdvancePaymentsLocalization/test/Src/CashDocLineTestHandlerCZZ.Codeunit.al b/src/Apps/CZ/AdvancePaymentsLocalization/test/Src/CashDocLineTestHandlerCZZ.Codeunit.al new file mode 100644 index 00000000000..d3b90fa7289 --- /dev/null +++ b/src/Apps/CZ/AdvancePaymentsLocalization/test/Src/CashDocLineTestHandlerCZZ.Codeunit.al @@ -0,0 +1,40 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Finance.AdvancePayments; + +using Microsoft.Finance.CashDesk; + +codeunit 148132 "Cash Doc Line Test Handler CZZ" +{ + EventSubscriberInstance = Manual; + + var + ValidateAdvanceLetterNoEventRaised: Boolean; + LookupAdvanceLetterNoEventRaised: Boolean; + + [EventSubscriber(ObjectType::Table, Database::"Cash Document Line CZP", 'OnBeforeValidateAdvanceLetterNoCZZ', '', false, false)] + local procedure HandleOnBeforeValidateAdvanceLetterNoCZZ(var CashDocumentLineCZP: Record "Cash Document Line CZP"; var IsHandled: Boolean) + begin + ValidateAdvanceLetterNoEventRaised := true; + IsHandled := true; + end; + + [EventSubscriber(ObjectType::Table, Database::"Cash Document Line CZP", 'OnBeforeLookupAdvanceLetterNoCZZ', '', false, false)] + local procedure HandleOnBeforeLookupAdvanceLetterNoCZZ(var CashDocumentLineCZP: Record "Cash Document Line CZP"; var IsHandled: Boolean) + begin + LookupAdvanceLetterNoEventRaised := true; + IsHandled := true; + end; + + procedure GetValidateAdvanceLetterNoEventRaised(): Boolean + begin + exit(ValidateAdvanceLetterNoEventRaised); + end; + + procedure GetLookupAdvanceLetterNoEventRaised(): Boolean + begin + exit(LookupAdvanceLetterNoEventRaised); + end; +} \ No newline at end of file diff --git a/src/Apps/CZ/AdvancePaymentsLocalization/test/Src/CashDocumentLineCZZ.Codeunit.al b/src/Apps/CZ/AdvancePaymentsLocalization/test/Src/CashDocumentLineCZZ.Codeunit.al new file mode 100644 index 00000000000..1e309dc1faa --- /dev/null +++ b/src/Apps/CZ/AdvancePaymentsLocalization/test/Src/CashDocumentLineCZZ.Codeunit.al @@ -0,0 +1,92 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Finance.AdvancePayments; + +using Microsoft.Finance.CashDesk; +using Microsoft.Finance.GeneralLedger.Setup; +using Microsoft.Sales.Customer; + +codeunit 148133 "Cash Document Line CZZ" +{ + Subtype = Test; + TestPermissions = Disabled; + + var + Assert: Codeunit Assert; + CashDocLineTestHandlerCZZ: Codeunit "Cash Doc Line Test Handler CZZ"; + LibraryCashDeskCZP: Codeunit "Library - Cash Desk CZP"; + LibraryCashDocumentCZP: Codeunit "Library - Cash Document CZP"; + LibraryUtility: Codeunit "Library - Utility"; + LibrarySales: Codeunit "Library - Sales"; + + [Test] + procedure ValidateAdvanceLetterNoCanBeHandled() + var + CashDocumentLineCZP: Record "Cash Document Line CZP"; + AdvanceLetterNo: Code[20]; + begin + // [SCENARIO] Validation of the advance letter number can be handled by a subscriber + Initialize(); + AdvanceLetterNo := CopyStr(LibraryUtility.GenerateRandomCode( + CashDocumentLineCZP.FieldNo("Advance Letter No. CZZ"), Database::"Cash Document Line CZP"), 1, MaxStrLen(CashDocumentLineCZP."Advance Letter No. CZZ")); + BindSubscription(CashDocLineTestHandlerCZZ); + + // [WHEN] An advance letter number is validated on an otherwise invalid cash document line + CashDocumentLineCZP.Validate("Advance Letter No. CZZ", AdvanceLetterNo); + UnbindSubscription(CashDocLineTestHandlerCZZ); + + // [THEN] The subscriber handles the validation before the standard checks are run + Assert.IsTrue(CashDocLineTestHandlerCZZ.GetValidateAdvanceLetterNoEventRaised(), 'The before validate event must be raised.'); + CashDocumentLineCZP.TestField("Advance Letter No. CZZ", AdvanceLetterNo); + end; + + [Test] + procedure LookupAdvanceLetterNoCanBeHandled() + var + CashDeskCZP: Record "Cash Desk CZP"; + CashDeskUserCZP: Record "Cash Desk User CZP"; + CashDocumentHeaderCZP: Record "Cash Document Header CZP"; + CashDocumentLineCZP: Record "Cash Document Line CZP"; + Customer: Record Customer; + CashDocumentSubformCZP: TestPage "Cash Document Subform CZP"; + begin + // [SCENARIO] Lookup of the advance letter number can be handled by a subscriber + Initialize(); + LibrarySales.CreateCustomer(Customer); + LibraryCashDeskCZP.CreateCashDeskCZP(CashDeskCZP); + LibraryCashDeskCZP.SetupCashDeskCZP(CashDeskCZP, false); + LibraryCashDeskCZP.CreateCashDeskUserCZP(CashDeskUserCZP, CashDeskCZP."No.", true, true, true); + LibraryCashDocumentCZP.CreateCashDocumentHeaderCZP(CashDocumentHeaderCZP, CashDocumentHeaderCZP."Document Type"::Receipt, CashDeskCZP."No."); + LibraryCashDocumentCZP.CreateCashDocumentLineCZP( + CashDocumentLineCZP, CashDocumentHeaderCZP, + Enum::"Cash Document Account Type CZP"::Customer, Customer."No.", 0); + CashDocumentLineCZP."Gen. Document Type" := CashDocumentLineCZP."Gen. Document Type"::" "; + CashDocumentLineCZP.Modify(); + BindSubscription(CashDocLineTestHandlerCZZ); + + // [WHEN] The advance letter number lookup is invoked on an otherwise invalid cash document line + CashDocumentSubformCZP.OpenEdit(); + CashDocumentSubformCZP.GoToRecord(CashDocumentLineCZP); + CashDocumentSubformCZP."Advance Letter No. CZZ".Lookup(); + CashDocumentSubformCZP.Close(); + UnbindSubscription(CashDocLineTestHandlerCZZ); + + // [THEN] The subscriber handles the lookup before the standard checks are run + Assert.IsTrue(CashDocLineTestHandlerCZZ.GetLookupAdvanceLetterNoEventRaised(), 'The before lookup event must be raised.'); + end; + + local procedure Initialize() + var + GeneralLedgerSetup: Record "General Ledger Setup"; + begin + Clear(CashDocLineTestHandlerCZZ); + + GeneralLedgerSetup.Get(); + if GeneralLedgerSetup."Cash Desk Nos. CZP" = '' then begin + GeneralLedgerSetup.Validate("Cash Desk Nos. CZP", LibraryUtility.GetGlobalNoSeriesCode()); + GeneralLedgerSetup.Modify(true); + end; + end; +} diff --git a/src/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/CashDocumentReleaseCZP.Codeunit.al b/src/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/CashDocumentReleaseCZP.Codeunit.al index 1197ca0c7ac..56ec3e85b20 100644 --- a/src/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/CashDocumentReleaseCZP.Codeunit.al +++ b/src/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/CashDocumentReleaseCZP.Codeunit.al @@ -202,16 +202,21 @@ codeunit 11725 "Cash Document-Release CZP" local procedure CheckMandatoryFields(CashDocumentHeaderCZP: Record "Cash Document Header CZP") var SkipPaymentPurposeTestField: Boolean; + SkipAmountsTestFields: Boolean; begin SkipPaymentPurposeTestField := false; + SkipAmountsTestFields := false; OnBeforeCheckMandatoryFields(CashDocumentHeaderCZP, SkipPaymentPurposeTestField); + OnBeforeCheckMandatoryFieldsSkipAmounts(CashDocumentHeaderCZP, SkipAmountsTestFields); CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."No."); CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Posting Date"); CashDocumentHeaderCZP.VATRounding(); - CashDocumentHeaderCZP.CalcFields(CashDocumentHeaderCZP."Amount Including VAT", CashDocumentHeaderCZP."Amount Including VAT (LCY)"); - CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Amount Including VAT"); - CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Amount Including VAT (LCY)"); + if not SkipAmountsTestFields then begin + CashDocumentHeaderCZP.CalcFields(CashDocumentHeaderCZP."Amount Including VAT", CashDocumentHeaderCZP."Amount Including VAT (LCY)"); + CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Amount Including VAT"); + CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Amount Including VAT (LCY)"); + end; CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Document Date"); if not SkipPaymentPurposeTestField then CashDocumentHeaderCZP.TestField(CashDocumentHeaderCZP."Payment Purpose"); @@ -376,4 +381,9 @@ codeunit 11725 "Cash Document-Release CZP" local procedure OnBeforeCheckMandatoryFields(CashDocumentHeaderCZP: Record "Cash Document Header CZP"; var SkipPaymentPurposeTestField: Boolean) begin end; + + [IntegrationEvent(false, false)] + local procedure OnBeforeCheckMandatoryFieldsSkipAmounts(CashDocumentHeaderCZP: Record "Cash Document Header CZP"; var SkipAmountsTestFields: Boolean) + begin + end; } diff --git a/src/Apps/CZ/CashDeskLocalization/test/Src/CashDeskDocumentsCZP.Codeunit.al b/src/Apps/CZ/CashDeskLocalization/test/Src/CashDeskDocumentsCZP.Codeunit.al index 96bf91f58bb..b15de430212 100644 --- a/src/Apps/CZ/CashDeskLocalization/test/Src/CashDeskDocumentsCZP.Codeunit.al +++ b/src/Apps/CZ/CashDeskLocalization/test/Src/CashDeskDocumentsCZP.Codeunit.al @@ -19,15 +19,18 @@ codeunit 148070 "Cash Desk Documents CZP" LibraryRandom: Codeunit "Library - Random"; LibraryCashDeskCZP: Codeunit "Library - Cash Desk CZP"; LibraryCashDocumentCZP: Codeunit "Library - Cash Document CZP"; + LibraryUtility: Codeunit "Library - Utility"; AmountLimitErr: Label 'Cash Document Amount exceeded maximal limit (%1).', Comment = '%1 = Cash Desk Maximal Limit'; PostCashDocNotExistErr: Label 'Posted Cash Document does not exist.'; CashDocStatusErr: Label 'Status in Cash Document must be Released.'; NoOfEntriesMustBeEqualErr: Label 'Number of entries must be equal.'; AmountMustBePositiveErr: Label 'Amount Including VAT must be positive in Cash Document Header Cash Desk No.=''%1'',No.=''%2''.', Comment = '%1 = Cash Desk No., %2 = Cash Document No.'; + LinesNotExistsErr: Label 'There are no Cash Document Lines to release.'; isInitialized: Boolean; local procedure Initialize() var + GeneralLedgerSetup: Record "General Ledger Setup"; LibraryTestInitialize: Codeunit "Library - Test Initialize"; begin LibraryTestInitialize.OnTestInitialize(Codeunit::"Cash Desk Documents CZP"); @@ -35,6 +38,11 @@ codeunit 148070 "Cash Desk Documents CZP" if isInitialized then exit; LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"Cash Desk Documents CZP"); + GeneralLedgerSetup.Get(); + if GeneralLedgerSetup."Cash Desk Nos. CZP" = '' then begin + GeneralLedgerSetup.Validate("Cash Desk Nos. CZP", LibraryUtility.GetGlobalNoSeriesCode()); + GeneralLedgerSetup.Modify(true); + end; LibraryCashDeskCZP.CreateCashDeskCZP(CashDeskCZP); LibraryCashDeskCZP.SetupCashDeskCZP(CashDeskCZP, true); @@ -390,6 +398,55 @@ codeunit 148070 "Cash Desk Documents CZP" Assert.ExpectedError(StrSubstNo(AmountMustBePositiveErr, CashDeskCZP."No.", CashDocumentHeaderCZP."No.")); end; + [Test] + [HandlerFunctions('YesConfirmHandler')] + procedure ReleaseCashDocumentChecksAmountsByDefault() + var + CashDocumentHeaderCZP: Record "Cash Document Header CZP"; + CashDocumentLineCZP: Record "Cash Document Line CZP"; + begin + // [SCENARIO] Amount mandatory fields are checked on release when no subscriber skips them + Initialize(); + + // [GIVEN] Create Receipt Cash Document with zero amount + CreateCashDocument(CashDocumentHeaderCZP, CashDocumentLineCZP, CashDocumentHeaderCZP."Document Type"::Receipt, CashDeskCZP."No."); + CashDocumentLineCZP.Validate(Amount, 0); + CashDocumentLineCZP.Modify(); + + // [WHEN] Release Cash Document + asserterror ReleaseCashDocumentCZP(CashDocumentHeaderCZP); + + // [THEN] Error on empty Amount Including VAT occurs + Assert.ExpectedTestFieldError(CashDocumentHeaderCZP.FieldCaption("Amount Including VAT"), ''); + end; + + [Test] + [HandlerFunctions('YesConfirmHandler')] + procedure ReleaseCashDocumentSkipsAmountsWithSubscriber() + var + CashDocumentHeaderCZP: Record "Cash Document Header CZP"; + CashDocumentLineCZP: Record "Cash Document Line CZP"; + CashDocReleaseHandlerCZP: Codeunit "Cash Doc. Release Handler CZP"; + begin + // [SCENARIO] Amount mandatory fields are skipped on release when a subscriber sets SkipAmountsTestFields + Initialize(); + + // [GIVEN] Create Receipt Cash Document with zero amount + CreateCashDocument(CashDocumentHeaderCZP, CashDocumentLineCZP, CashDocumentHeaderCZP."Document Type"::Receipt, CashDeskCZP."No."); + CashDocumentLineCZP.Validate(Amount, 0); + CashDocumentLineCZP.Modify(); + + // [GIVEN] Subscriber that skips the amount mandatory fields is bound + BindSubscription(CashDocReleaseHandlerCZP); + + // [WHEN] Release Cash Document + asserterror ReleaseCashDocumentCZP(CashDocumentHeaderCZP); + UnbindSubscription(CashDocReleaseHandlerCZP); + + // [THEN] Amount check is skipped and release fails later on the missing lines instead + Assert.ExpectedError(LinesNotExistsErr); + end; + [Test] procedure CreateCashDocumentWithoutPermissions() var diff --git a/src/Apps/CZ/CashDeskLocalization/test/Src/CashDocReleaseHandlerCZP.Codeunit.al b/src/Apps/CZ/CashDeskLocalization/test/Src/CashDocReleaseHandlerCZP.Codeunit.al new file mode 100644 index 00000000000..2fa76b4e770 --- /dev/null +++ b/src/Apps/CZ/CashDeskLocalization/test/Src/CashDocReleaseHandlerCZP.Codeunit.al @@ -0,0 +1,16 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Finance.CashDesk; + +codeunit 148134 "Cash Doc. Release Handler CZP" +{ + EventSubscriberInstance = Manual; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Cash Document-Release CZP", 'OnBeforeCheckMandatoryFieldsSkipAmounts', '', false, false)] + local procedure SetSkipAmountsTestFieldsOnBeforeCheckMandatoryFieldsSkipAmounts(CashDocumentHeaderCZP: Record "Cash Document Header CZP"; var SkipAmountsTestFields: Boolean) + begin + SkipAmountsTestFields := true; + end; +}