diff --git a/src/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorLedgerEntry.TableExt.al b/src/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorLedgerEntry.TableExt.al index 2218fea2b3b..840ec65b88e 100644 --- a/src/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorLedgerEntry.TableExt.al +++ b/src/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorLedgerEntry.TableExt.al @@ -24,6 +24,8 @@ tableextension 10035 "IRS 1099 Vendor Ledger Entry" extends "Vendor Ledger Entry trigger OnValidate() begin IRS1099FormDocument.CheckIfVendLedgEntryAllowed(Rec."Entry No."); + if "IRS 1099 Reporting Period" <> '' then + IRS1099VendorFormBox.CheckVendorSubjectFor1099Reporting(Rec."Vendor No.", "IRS 1099 Reporting Period"); Validate("IRS 1099 Form No.", ''); end; } @@ -35,6 +37,8 @@ tableextension 10035 "IRS 1099 Vendor Ledger Entry" extends "Vendor Ledger Entry trigger OnValidate() begin IRS1099FormDocument.CheckIfVendLedgEntryAllowed(Rec."Entry No."); + if "IRS 1099 Form No." <> '' then + IRS1099VendorFormBox.CheckVendorSubjectFor1099Reporting(Rec."Vendor No.", "IRS 1099 Reporting Period"); Validate("IRS 1099 Form Box No.", ''); Validate("IRS 1099 Reporting Amount", 0); end; @@ -47,6 +51,8 @@ tableextension 10035 "IRS 1099 Vendor Ledger Entry" extends "Vendor Ledger Entry trigger OnValidate() begin IRS1099FormDocument.CheckIfVendLedgEntryAllowed(Rec."Entry No."); + if "IRS 1099 Form Box No." <> '' then + IRS1099VendorFormBox.CheckVendorSubjectFor1099Reporting(Rec."Vendor No.", "IRS 1099 Reporting Period"); "IRS 1099 Subject For Reporting" := "IRS 1099 Form Box No." <> ''; IRS1099VendorFormBox.UpdatePurchDocFormBoxNoFromVendLedgEntry(Rec); end; diff --git a/src/Apps/US/IRSForms/app/src/VendorFormBox/IRS1099VendorFormBox.Codeunit.al b/src/Apps/US/IRSForms/app/src/VendorFormBox/IRS1099VendorFormBox.Codeunit.al index 9e867b687ee..f773ae77a4e 100644 --- a/src/Apps/US/IRSForms/app/src/VendorFormBox/IRS1099VendorFormBox.Codeunit.al +++ b/src/Apps/US/IRSForms/app/src/VendorFormBox/IRS1099VendorFormBox.Codeunit.al @@ -141,6 +141,24 @@ codeunit 10037 "IRS 1099 Vendor Form Box" end; end; + procedure CheckVendorSubjectFor1099Reporting(VendorNo: Code[20]; PeriodNo: Code[20]) + var + IRS1099VendorFormBoxSetup: Record "IRS 1099 Vendor Form Box Setup"; + VendorNotSetupErrorInfo: ErrorInfo; + VendorNotSetupFor1099Err: Label 'Vendor %1 is not set up for IRS 1099 reporting in the reporting period %2.', Comment = '%1 = Vendor No., %2 = Period No.'; + OpenVendorFormBoxSetupLbl: Label 'Open IRS 1099 Vendor Form Box Setup'; + begin + if PeriodNo = '' then + exit; + if IRS1099VendorFormBoxSetup.Get(PeriodNo, VendorNo) then + exit; + + VendorNotSetupErrorInfo.Message := StrSubstNo(VendorNotSetupFor1099Err, VendorNo, PeriodNo); + VendorNotSetupErrorInfo.PageNo := Page::"IRS 1099 Vendor Form Box Setup"; + VendorNotSetupErrorInfo.AddNavigationAction(OpenVendorFormBoxSetupLbl); + Error(VendorNotSetupErrorInfo); + end; + local procedure ShowIfVendorHas1099CodePrevPeriodButNotCurrNotificationId(): Guid begin exit('4b87dd95-f7ba-4e72-909b-76ca6a1d8b6a'); diff --git a/src/Apps/US/IRSForms/test/src/IRS1099DocumentTests.Codeunit.al b/src/Apps/US/IRSForms/test/src/IRS1099DocumentTests.Codeunit.al index a0ac5bc3937..21297f0e147 100644 --- a/src/Apps/US/IRSForms/test/src/IRS1099DocumentTests.Codeunit.al +++ b/src/Apps/US/IRSForms/test/src/IRS1099DocumentTests.Codeunit.al @@ -39,6 +39,7 @@ codeunit 148010 "IRS 1099 Document Tests" PeriodNoFieldVisibleErr: Label 'Field Period No. should be visible.'; PeriodNoNotVisibleErr: Label 'Field Period No. should not be visible.'; ChangingPostingDateInPurchHeaderWhileHavingLineMsg: Label 'You have changed the Posting Date on the purchase header, which might affect the prices and discounts on the purchase lines.\You should review the lines and manually update prices and discounts if needed'; + VendorNotSetupForIRS1099Err: Label 'Vendor %1 is not set up for IRS 1099 reporting in the reporting period %2.', Comment = '%1 = Vendor No., %2 = Period No.'; trigger OnRun() @@ -1380,6 +1381,162 @@ codeunit 148010 "IRS 1099 Document Tests" Assert.AreEqual(FormBoxNo[2], PurchCrMemoHdr."IRS 1099 Form Box No.", 'IRS 1099 Form Box No. in Purch. Cr. Memo Hdr. should be updated'); end; + [Test] + procedure ValidateIRS1099PeriodOnVendLedgEntryForNon1099Vendor() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + VendorLedgEntry: Record "Vendor Ledger Entry"; + VendNo: Code[20]; + FormNo: Code[20]; + PeriodNo: Code[20]; + InvNo: Code[20]; + begin + // [FEATURE] [AI test] + // [SCENARIO 620132] Setting IRS 1099 Reporting Period on vendor ledger entry of a vendor with no 1099 setup raises an error + + Initialize(); + // [GIVEN] IRS Reporting Period "P" with form "F" and form box "FB" + PeriodNo := LibraryIRSReportingPeriod.CreateOneDayReportingPeriod(WorkDate()); + FormNo := LibraryIRS1099FormBox.CreateSingleFormInReportingPeriod(WorkDate(), WorkDate()); + LibraryIRS1099FormBox.CreateSingleFormBoxInReportingPeriod(WorkDate(), WorkDate(), FormNo); + + // [GIVEN] Vendor "V" with NO IRS 1099 form box setup (plain vendor) + VendNo := LibraryPurchase.CreateVendorNo(); + + // [GIVEN] Posted purchase invoice for vendor "V" + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Invoice, VendNo); + LibraryPurchase.CreatePurchaseLineWithUnitCost(PurchaseLine, PurchaseHeader, LibraryInventory.CreateItemNo(), 1, 100); + InvNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + + // [WHEN] Validate "IRS 1099 Reporting Period" in the vendor ledger entry + LibraryERM.FindVendorLedgerEntry(VendorLedgEntry, VendorLedgEntry."Document Type"::Invoice, InvNo); + // [THEN] An error is raised because vendor "V" has no 1099 setup for the period + asserterror VendorLedgEntry.Validate("IRS 1099 Reporting Period", PeriodNo); + Assert.ExpectedError(StrSubstNo(VendorNotSetupForIRS1099Err, VendNo, PeriodNo)); + end; + + [Test] + procedure ValidateIRS1099FormBoxOnVendLedgEntryFor1099Vendor() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + VendorLedgEntry: Record "Vendor Ledger Entry"; + VendNo: Code[20]; + FormNo: Code[20]; + FormBoxNo: Code[20]; + PeriodNo: Code[20]; + InvNo: Code[20]; + begin + // [FEATURE] [AI test] + // [SCENARIO 620132] Vendor WITH 1099 setup can still validate form box on its ledger entry without error + + Initialize(); + // [GIVEN] IRS Reporting Period with Form "F" and Form Box "FB" + PeriodNo := LibraryIRSReportingPeriod.CreateOneDayReportingPeriod(WorkDate()); + FormNo := LibraryIRS1099FormBox.CreateSingleFormInReportingPeriod(WorkDate(), WorkDate()); + FormBoxNo := LibraryIRS1099FormBox.CreateSingleFormBoxInReportingPeriod(WorkDate(), WorkDate(), FormNo); + + // [GIVEN] Vendor "V" WITH IRS 1099 form box setup + VendNo := LibraryIRS1099FormBox.CreateVendorNoWithFormBox(WorkDate(), WorkDate(), FormNo, FormBoxNo); + + // [GIVEN] Posted purchase invoice for vendor "V" + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Invoice, VendNo); + LibraryPurchase.CreatePurchaseLineWithUnitCost(PurchaseLine, PurchaseHeader, LibraryInventory.CreateItemNo(), 1, 100); + InvNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + + // [WHEN] Validate the IRS 1099 fields in the vendor ledger entry + LibraryERM.FindVendorLedgerEntry(VendorLedgEntry, VendorLedgEntry."Document Type"::Invoice, InvNo); + // [THEN] No error is raised for a vendor that has 1099 setup + VendorLedgEntry.Validate("IRS 1099 Reporting Period", PeriodNo); + VendorLedgEntry.Validate("IRS 1099 Form No.", FormNo); + VendorLedgEntry.Validate("IRS 1099 Form Box No.", FormBoxNo); + VendorLedgEntry.TestField("IRS 1099 Form Box No.", FormBoxNo); + end; + + [Test] + procedure ValidateIRS1099FormAndFormBoxOnVendLedgEntryForNon1099Vendor() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + VendorLedgEntry: Record "Vendor Ledger Entry"; + VendNo: Code[20]; + FormNo: Code[20]; + FormBoxNo: Code[20]; + PeriodNo: Code[20]; + InvNo: Code[20]; + begin + // [FEATURE] [AI test] + // [SCENARIO 620132] Setting IRS 1099 Form No. or Form Box No. on vendor ledger entry of a vendor with no 1099 setup raises an error + + Initialize(); + // [GIVEN] IRS Reporting Period "P" with form "F" and form box "FB" + PeriodNo := LibraryIRSReportingPeriod.CreateOneDayReportingPeriod(WorkDate()); + FormNo := LibraryIRS1099FormBox.CreateSingleFormInReportingPeriod(WorkDate(), WorkDate()); + FormBoxNo := LibraryIRS1099FormBox.CreateSingleFormBoxInReportingPeriod(WorkDate(), WorkDate(), FormNo); + + // [GIVEN] Vendor "V" with NO IRS 1099 form box setup (plain vendor) + VendNo := LibraryPurchase.CreateVendorNo(); + + // [GIVEN] Posted purchase invoice for vendor "V", with IRS period set directly (bypassing validation) + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Invoice, VendNo); + LibraryPurchase.CreatePurchaseLineWithUnitCost(PurchaseLine, PurchaseHeader, LibraryInventory.CreateItemNo(), 1, 100); + InvNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + LibraryERM.FindVendorLedgerEntry(VendorLedgEntry, VendorLedgEntry."Document Type"::Invoice, InvNo); + VendorLedgEntry."IRS 1099 Reporting Period" := PeriodNo; + VendorLedgEntry.Modify(); + + // [WHEN] Validate "IRS 1099 Form No." in the vendor ledger entry + // [THEN] An error is raised because vendor "V" has no 1099 setup for the period + asserterror VendorLedgEntry.Validate("IRS 1099 Form No.", FormNo); + Assert.ExpectedError(StrSubstNo(VendorNotSetupForIRS1099Err, VendNo, PeriodNo)); + + // [WHEN] Validate "IRS 1099 Form Box No." in the vendor ledger entry + // [THEN] An error is raised because vendor "V" has no 1099 setup for the period + LibraryERM.FindVendorLedgerEntry(VendorLedgEntry, VendorLedgEntry."Document Type"::Invoice, InvNo); + VendorLedgEntry."IRS 1099 Reporting Period" := PeriodNo; + VendorLedgEntry."IRS 1099 Form No." := FormNo; + asserterror VendorLedgEntry.Validate("IRS 1099 Form Box No.", FormBoxNo); + Assert.ExpectedError(StrSubstNo(VendorNotSetupForIRS1099Err, VendNo, PeriodNo)); + end; + + [Test] + procedure ClearIRS1099PeriodOnVendLedgEntryForNon1099Vendor() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + VendorLedgEntry: Record "Vendor Ledger Entry"; + VendNo: Code[20]; + FormNo: Code[20]; + PeriodNo: Code[20]; + InvNo: Code[20]; + begin + // [FEATURE] [AI test] + // [SCENARIO 620132] Clearing IRS 1099 Reporting Period on a non-1099 vendor ledger entry does not raise an error + + Initialize(); + // [GIVEN] IRS Reporting Period "P" with form "F" and form box "FB" + PeriodNo := LibraryIRSReportingPeriod.CreateOneDayReportingPeriod(WorkDate()); + FormNo := LibraryIRS1099FormBox.CreateSingleFormInReportingPeriod(WorkDate(), WorkDate()); + LibraryIRS1099FormBox.CreateSingleFormBoxInReportingPeriod(WorkDate(), WorkDate(), FormNo); + + // [GIVEN] Vendor "V" with NO IRS 1099 form box setup + VendNo := LibraryPurchase.CreateVendorNo(); + + // [GIVEN] Posted purchase invoice for vendor "V", with IRS period set directly (bypassing validation) + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Invoice, VendNo); + LibraryPurchase.CreatePurchaseLineWithUnitCost(PurchaseLine, PurchaseHeader, LibraryInventory.CreateItemNo(), 1, 100); + InvNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + LibraryERM.FindVendorLedgerEntry(VendorLedgEntry, VendorLedgEntry."Document Type"::Invoice, InvNo); + VendorLedgEntry."IRS 1099 Reporting Period" := PeriodNo; + VendorLedgEntry.Modify(); + + // [WHEN] Clear "IRS 1099 Reporting Period" by validating with '' + // [THEN] No error is raised (clearing must always be allowed) + VendorLedgEntry.Validate("IRS 1099 Reporting Period", ''); + VendorLedgEntry.TestField("IRS 1099 Reporting Period", ''); + end; + local procedure Initialize() var IRSReportingPeriod: Record "IRS Reporting Period"; diff --git a/src/Apps/US/IRSForms/test/src/IRS1099VendorTests.Codeunit.al b/src/Apps/US/IRSForms/test/src/IRS1099VendorTests.Codeunit.al index a599a5b40aa..c4e945ae7dd 100644 --- a/src/Apps/US/IRSForms/test/src/IRS1099VendorTests.Codeunit.al +++ b/src/Apps/US/IRSForms/test/src/IRS1099VendorTests.Codeunit.al @@ -168,7 +168,7 @@ codeunit 148011 "IRS 1099 Vendor Tests" var VendorLedgerEntry: Record "Vendor Ledger Entry"; VendorLedgerEntriesPage: TestPage "Vendor Ledger Entries"; - NewPeriodNo, FormNo, NewFormNo, FormBoxNo, NewFormBoxNo : Code[20]; + VendNo, NewPeriodNo, FormNo, NewFormNo, FormBoxNo, NewFormBoxNo : Code[20]; IRSAmount: Decimal; NewDate: Date; begin @@ -187,7 +187,13 @@ codeunit 148011 "IRS 1099 Vendor Tests" NewPeriodNo := LibraryIRSReportingPeriod.CreateOneDayReportingPeriod(NewDate); NewFormNo := LibraryIRS1099FormBox.CreateSingleFormInReportingPeriod(NewDate); NewFormBoxNo := LibraryIRS1099FormBox.CreateSingleFormBoxInReportingPeriod(NewDate, NewFormNo); - IRSAmount := IRSAmount / 3; + // [GIVEN] The entry belongs to a vendor set up for IRS 1099 reporting in both periods + VendNo := LibraryIRS1099FormBox.CreateVendorNoWithFormBox(WorkDate(), FormNo, FormBoxNo); + LibraryIRS1099FormBox.AssignFormBoxForVendorInPeriod(VendNo, NewDate, NewDate, NewFormNo, NewFormBoxNo); + VendorLedgerEntry."Vendor No." := VendNo; + VendorLedgerEntry.Modify(); + + IRSAmount := Round(IRSAmount / 3); // [GIVEN] Vendor Ledger Entries page opened and filtered by Entry No. VendorLedgerEntriesPage.OpenEdit(); VendorLedgerEntriesPage.Filter.SetFilter("Entry No.", Format(VendorLedgerEntry."Entry No."));