From 6a83e8d2ee51b390f75b793ac60b957f71bec173 Mon Sep 17 00:00:00 2001 From: Jesper Schulz-Wedde Date: Wed, 10 Dec 2025 16:30:02 +0100 Subject: [PATCH] Syncing with version 28.0.43307.0 --- .github/AL-Go-Settings.json | 2 +- .../AltCustVATRegFacadeCZZ.Codeunit.al | 40 + .../AltCustVATRegImplCZZ.Codeunit.al | 288 ++ .../AltCustVATRegOrchCZZ.Codeunit.al | 21 + .../CrossApplicationHandlerCZZ.Codeunit.al | 10 +- .../PurchAdvLetterManagementCZZ.Codeunit.al | 14 - .../PurchAdvLetterPostCZZ.Codeunit.al | 12 - .../SalesAdvLetterManagementCZZ.Codeunit.al | 14 - .../Src/Enums/AltCustVATRegAdvCZZ.Enum.al} | 18 +- .../AltCustVATRegAdvCZZ.Interface.al | 34 + .../PurchaseInvoiceCZZ.PageExt.al | 16 +- .../PurchaseOrderCZZ.PageExt.al | 16 +- .../PageExtensions/SalesInvoiceCZZ.PageExt.al | 16 +- .../PageExtensions/SalesOrderCZZ.PageExt.al | 16 +- .../Src/Pages/PurchAdvUsageFactBoxCZZ.Page.al | 161 - .../Src/Pages/PurchAdvanceLetterCZZ.Page.al | 26 +- .../Src/Pages/PurchAdvanceLettersCZZ.Page.al | 26 +- .../Src/Pages/SalesAdvUsageFactBoxCZZ.Page.al | 161 - .../Src/Pages/SalesAdvanceLetterCZZ.Page.al | 16 +- .../Src/Pages/SalesAdvanceLettersCZZ.Page.al | 15 +- .../CZAdvancePaymentsObjCZZ.PermissionSet.al | 12 +- .../GenJournalLineCZZ.TableExt.al | 31 +- .../TableExtensions/VATSetupCZZ.TableExt.al | 5 + .../Tables/PurchAdvLetterHeaderCZZ.Table.al | 15 - .../Tables/SalesAdvLetterHeaderCZZ.Table.al | 36 +- .../GLEntryPostApplicationCZA.Codeunit.al | 8 +- .../CrossApplicationHandlerCZB.Codeunit.al | 10 +- .../app/Src/Pages/BankStatementCZB.Page.al | 15 +- .../app/Src/Pages/BankStatementsCZB.Page.al | 15 +- .../app/Src/Pages/IssBankStatementCZB.Page.al | 15 +- .../Src/Pages/IssBankStatementsCZB.Page.al | 15 +- .../app/Src/Pages/IssPaymentOrderCZB.Page.al | 15 +- .../app/Src/Pages/IssPaymentOrdersCZB.Page.al | 15 +- .../app/Src/Pages/PaymentOrderCZB.Page.al | 15 +- .../app/Src/Pages/PaymentOrdersCZB.Page.al | 15 +- .../Src/Reports/SuggestPaymentsCZB.Report.al | 34 +- .../Src/Tables/PaymentOrderLineCZB.Table.al | 34 +- .../CashDeskManagementCZP.Codeunit.al | 3 + .../CrossApplicationHandlerCZP.Codeunit.al | 10 +- .../HumanResourcesSetupCZP.PageExt.al | 18 + .../ReconciliationCZP.PageExt.al | 12 +- .../app/Src/Pages/CashDeskUsersCZP.Page.al | 3 +- .../app/Src/Pages/CashDocumentCZP.Page.al | 15 +- .../app/Src/Pages/CashDocumentListCZP.Page.al | 15 +- .../Src/Pages/PostedCashDocumentCZP.Page.al | 15 +- .../Pages/PostedCashDocumentListCZP.Page.al | 15 +- .../Src/Tables/CashDocumentLineCZP.Table.al | 29 +- .../CrossApplicationHandlerCZC.Codeunit.al | 10 +- .../app/Src/Pages/CompensationCardCZC.Page.al | 15 +- .../app/Src/Pages/CompensationListCZC.Page.al | 15 +- .../Pages/PostedCompensationCardCZC.Page.al | 15 +- .../Pages/PostedCompensationListCZC.Page.al | 15 +- .../app/Src/Reports/Compensation.rdl | 12 +- .../app/Src/Reports/PostedCompensation.rdl | 29 +- .../CrossApplicationMgtCZL.Codeunit.al | 141 +- .../FeatureReplaceVATPeriodCZL.Codeunit.al | 22 +- .../ItemJournalLineHandlerCZL.Codeunit.al | 4 +- .../UserSetupAdvManagementCZL.Codeunit.al | 2 +- .../Src/PageExtensions/VATReport.PageExt.al | 8 - .../VATReportListCZL.PageExt.al | 8 - .../Pages/AccountantCZRoleCenterCZL.Page.al | 30 + .../Src/Pages/CompanyOfficialCardCZL.Page.al | 15 +- .../Src/Pages/VATCtrlReportCardCZL.Page.al | 15 +- .../Src/Pages/VATCtrlReportListCZL.Page.al | 15 +- .../app/Src/Pages/VIESDeclarationCZL.Page.al | 15 +- .../app/Src/Pages/VIESDeclarationsCZL.Page.al | 15 +- .../app/Src/Reports/AdjustExchangeRates.rdl | 62 +- .../Reports/AdjustExchangeRatesCZL.Report.al | 8 +- .../app/Src/Reports/CalcAndPostVATSett.rdl | 30 - .../Reports/CalcandPostVATSettlCZL.Report.al | 52 +- .../app/Src/Reports/CashFlowDateList.rdl | 40 +- .../app/Src/Reports/OpenCustEntriestoDate.rdl | 6 +- .../app/Src/Reports/OpenVendEntriestoDate.rdl | 270 +- .../HumanResourcesSetupCZL.TableExt.al | 35 + .../Src/TestInitializeHandlerCZL.Codeunit.al | 4 +- .../SubstituteReportHandlerCZF.Codeunit.al | 8 + .../ZUGFeRD/ExportZUGFeRDDocument.Codeunit.al | 12 - .../ZUGFeRD/PostedSalesCrMemo.ReportExt.al | 5 +- .../ZUGFeRD/PostedSalesInvoice.ReportExt.al | 5 +- ...l => ZUGFeRDReportIntegration.Codeunit.al} | 40 +- .../src/XRechnungXMLDocumentTests.Codeunit.al | 3 +- .../src/ZUGFeRDXMLDocumentTests.Codeunit.al | 1 - .../app/src/items/C5ItemMigrator.Codeunit.al | 20 - .../test/src/C5ItemMigratorTest.Codeunit.al | 29 +- .../Management/OIOUBLSubscribers.Codeunit.al | 11 +- .../ExportEngine/GenerateFileFEC.Codeunit.al | 13 +- .../src/FECAuditFileExportTests.Codeunit.al | 64 + .../Codeunits/GovTalkSubscribers.Codeunit.al | 4 +- Apps/GB/GovTalk/test/app.json | 4 + .../GovTalkVATRequestPageTests.Codeunit.al | 295 ++ .../Codeunits/FeatureReportsGB.Codeunit.al | 2 + .../Codeunits/ReportsSubscribers.Codeunit.al | 18 + .../FixedAssetProjectedValue.ReportExt.al | 4 + .../src/Reports/BlanketOrderSalesGB.Report.al | 7 - .../src/Reports/OrderConfirmation.Report.al | 7 - .../app/src/Reports/OrderGB.Report.al | 7 - .../src/Reports/PurchaseCreditMemo.Report.al | 7 - .../app/src/Reports/PurchaseInvoice.Report.al | 7 - .../app/src/Reports/SalesCreditMemo.Report.al | 7 - .../app/src/Reports/SalesInvoice.Report.al | 7 - .../app/src/Reports/SalesQuoteGB.Report.al | 7 - .../ReverseChargeVATSubscribers.Codeunit.al | 18 - .../TableExtensions/VATAmountLine.TableExt.al | 6 - .../src/PostcodeConfigurationPageGB.Page.al | 3 +- .../app/src/PostcodeSearchGB.Page.al | 5 +- .../app/src/PostcodeServiceLookupGB.Page.al | 3 +- .../src/FinalizeIndiaMigration.Page.al | 6 +- .../21957e13-9751-40a2-b591-67ade93573e7.json | 884 +++--- .../4e1d5479-c527-4295-a0c1-7d82d94860f6.json | 463 ++- .../4f234b8b-1b95-4938-b3df-3d96784eac77.json | 720 +++-- .../A744EF89-44A8-4CE0-81F8-3D8094623CD1.json | 1925 ++++++++++++ .../ccf41113-dc62-47e2-b45b-87af0248af65.json | 728 ++--- .../cf221dcd-487c-4b3c-bbc4-fe16b6667e76.json | 418 +-- .../GSTApplicationLibrary.Codeunit.al | 7 +- .../Codeunit/GSTBaseValidation.Codeunit.al | 7 +- .../GSTDataSenstivityMgmt.Codeunit.al | 10 +- .../GSTTaxConfiguration.Codeunit.al | 10 +- .../GSTBlankPurchOrdArchExt.PageExt.al | 13 - .../GSTPurchOrdArchiveExt.PageExt.al | 13 - .../GSTPurchQuoteArchiveExt.PageExt.al | 13 - .../GSTPurchReturnOrdArchExt.PageExt.al | 13 - .../Codeunit/GSTSalesValidation.Codeunit.al | 27 +- .../GSTBlankSalesOrdArchExt.PageExt.al | 15 +- .../GSTSalesOrdArchiveExt.PageExt.al | 15 +- .../GSTSalesPricesExt.PageExt.al | 33 +- .../GSTSalesQuoteArchiveExt.PageExt.al | 15 +- .../GSTSalesReturnOrdArchExt.PageExt.al | 15 +- .../Page/SubcontractingOrderSubform.Page.al | 32 +- .../33bfbe99-9140-4112-a55b-35ec0d9b61b9.json | 126 +- .../a8e114bf-f8cd-44db-a2b3-614bc18f4442.json | 1285 ++++---- .../TDSTaxConfiguration.Codeunit.al | 4 +- .../PurchaseInvoiceSubform.PageExt.al | 16 - .../PurchaseOrderSubform.PageExt.al | 16 - .../src/Codeunits/EnableISCoreApp.Codeunit.al | 2 +- Apps/NA/Ceridian/{ => app}/ExtensionLogo.png | Bin Apps/NA/Ceridian/{ => app}/app.json | 0 .../{ => app}/src/CeridianInstall.Codeunit.al | 0 .../src/ImportCeridianPayroll.XmlPort.al | 0 .../src/MSCeridianPayrollMgt.Codeunit.al | 0 .../src/MSCeridianPayrollSetup.Page.al | 0 .../src/MSCeridianPayrollSetup.Table.al | 0 .../src/MSCeridianPayrollimport.Codeunit.al | 0 .../src/MSCeridianPayrollupgrade.Codeunit.al | 0 ...65basicceridianpayroll.permissionsetext.al | 0 ...asicisvceridianpayroll.permissionsetext.al | 0 ...laccessceridianpayroll.permissionsetext.al | 0 ...premiumceridianpayroll.permissionsetext.al | 0 ...laccessceridianpayroll.permissionsetext.al | 0 ...365readceridianpayroll.permissionsetext.al | 0 ...mmemberceridianpayroll.permissionsetext.al | 0 ...ntcloudceridianpayroll.permissionsetext.al | 0 .../app/src/MSYodleeBankServiceSetup.Table.al | 5 +- .../app/src/MSYodleeServiceMgt.Codeunit.al | 30 +- .../app/src/YodleeAPIStrings.Codeunit.al | 7 +- .../Permissions/bankrecpost.permissionset.al | 6 +- .../CreateIRS1099FormBoxUS.Codeunit.al | 571 ---- .../CreateUSGLAccounts.Codeunit.al | 13 + .../USContosoLocalization.Codeunit.al | 3 - .../ContosoIRS1099US.Codeunit.al | 50 - .../src/MigrationVendor1099Tests.Codeunit.al | 25 - .../src/Processing/IRS1096FormLine.Table.al | 21 +- .../src/Processing/IRS1096FormMgt.Codeunit.al | 186 +- .../src/Processing/IRS1096FormSubform.Page.al | 10 +- .../test/src/Create1096FormsTest.Codeunit.al | 742 ----- .../IRSFormsObjects.PermissionSet.al | 2 +- .../src/Document/IRS1099FormDocuments.Page.al | 25 + .../IRS1099PostedPurchCrMemo.PageExt.al | 12 +- .../IRS1099PostedPurchInv.PageExt.al | 12 +- .../Extensions/IRS1099PurchCrMemo.PageExt.al | 12 +- .../src/Extensions/IRS1099PurchInv.PageExt.al | 12 +- .../Extensions/IRS1099PurchOrder.PageExt.al | 12 +- .../Extensions/IRS1099VendorCard.PageExt.al | 38 +- .../IRS1099VendorLedgerEntries.PageExt.al | 16 +- .../Extensions/IRS1099VendorList.PageExt.al | 30 +- .../app/src/IRIS/TransmissionIRIS.Table.al | 2 + .../app/src/Printing/IRS 1099 Print.docx | Bin 26122 -> 28100 bytes .../app/src/Printing/IRS1099Print.Report.al | 6 + .../Printing/IRS1099PrintingImpl.Codeunit.al | 23 +- .../IRS1099TransErrorHandler.Codeunit.al | 33 - .../IRS1099TransferFromBaseApp.Codeunit.al | 273 -- .../app/src/Setup/IRS1099Upgrade.Codeunit.al | 179 +- .../app/src/Setup/IRSFormsFeature.Codeunit.al | 123 +- .../app/src/Setup/IRSFormsGuide.Page.al | 3 +- .../src/Setup/UpgradeIRS1099Data.Report.al | 23 - .../src/IRSFormsEnableFeature.Codeunit.al | 21 +- .../test/src/IRS1099DocumentTests.Codeunit.al | 2 +- .../test/src/IRS1099E2ETests.Codeunit.al | 2 +- .../test/src/IRS1099EmailingTests.Codeunit.al | 22 - .../test/src/IRS1099FormCalcTests.Codeunit.al | 2 +- .../test/src/IRS1099LiableTests.Codeunit.al | 2 +- .../test/src/IRS1099PrintingTests.Codeunit.al | 4 +- .../test/src/IRS1099VendorTests.Codeunit.al | 2 +- .../AMCBankServiceRequestMgt.Codeunit.al | 12 +- .../src/pages/APIV2AccountingPeriods.Page.al | 2 +- .../APIV2/app/src/pages/APIV2Accounts.Page.al | 2 +- .../APIV2/app/src/pages/APIV2AgedAP.Page.al | 2 +- .../src/pages/APIV2ApplyVendorEntries.Page.al | 2 +- .../app/src/pages/APIV2Attachments.Page.al | 2 +- .../app/src/pages/APIV2BalanceSheet.Page.al | 2 +- .../src/pages/APIV2CashFlowStatement.Page.al | 2 +- .../pages/APIV2ContactsInformation.Page.al | 2 +- .../pages/APIV2CurrencyExchangeRates.Page.al | 2 +- .../pages/APIV2CustFinancialDetails.Page.al | 2 +- .../src/pages/APIV2DefaultDimensions.Page.al | 2 +- .../src/pages/APIV2DimensionSetLines.Page.al | 2 +- .../pages/APIV2DimensionValuesEntity.Page.al | 2 +- .../app/src/pages/APIV2DisputeStatus.Page.al | 2 +- .../pages/APIV2DocumentAttachments.Page.al | 2 +- .../app/src/pages/APIV2FALocations.Page.al | 2 +- .../src/pages/APIV2IncomeStatement.Page.al | 2 +- .../app/src/pages/APIV2ItemCategories.Page.al | 2 +- .../src/pages/APIV2ItemLedgerEntries.Page.al | 2 +- .../app/src/pages/APIV2JournalLines.Page.al | 2 +- .../APIV2/app/src/pages/APIV2Journals.Page.al | 2 +- .../app/src/pages/APIV2Opportunities.Page.al | 2 +- .../app/src/pages/APIV2PDFDocument.Page.al | 2 +- .../app/src/pages/APIV2PowerBILabels.Page.al | 2 +- .../src/pages/APIV2PurchReceiptLines.Page.al | 2 +- .../src/pages/APIV2RetainedEarnings.Page.al | 2 +- .../src/pages/APIV2SalesShipmentLines.Page.al | 2 +- .../src/pages/APIV2ShipmentMethods.Page.al | 2 +- .../APIV2/app/src/pages/APIV2TaxAreas.Page.al | 2 +- .../app/src/pages/APIV2UnitsofMeasure.Page.al | 2 +- .../UpgTagDefAutoAccCodes.Codeunit.al | 30 - .../Codeunits/UpgradeAutoAccCodes.Codeunit.al | 132 - .../src/BankAccReconciliationExt.PageExt.al | 29 - .../app/src/pages/BankDepositSubform.Page.al | 15 +- .../src/BankDepositPostingTests.Codeunit.al | 97 + Apps/W1/ClientAddIns/{ => app}/.objidconfig | 0 .../ClientAddIns/{ => app}/ExtensionLogo.png | Bin Apps/W1/ClientAddIns/{ => app}/app.json | 0 .../src/oauth/OAuthAddIn.ControlAddin.al | 0 .../src/oauth/js/OAuthIntegration.js | 0 .../2. MasterData/CreateEmployee.Codeunit.al | 13 + .../ContosoHumanResources.Codeunit.al | 9 + .../app/src/OutlookProcessing.Codeunit.al | 66 +- .../test/src/OutlookIntTest.Codeunit.al | 2 +- .../app/src/EmailOutlookAPIHelper.Codeunit.al | 11 - .../OAuth2SMTPAuthentication.Codeunit.al | 49 +- .../SMTPEmailAccountsExt.PageExt.al | 24 + .../Notification/SMTPEmailOutbox.PageExt.al | 24 + .../src/Notification/SMTPSentEmail.PageExt.al | 24 + .../app/src/SMTPAccount.Page.al | 389 ++- .../app/src/SMTPAccount.table.al | 39 +- .../app/src/SMTPAccountWizard.Page.al | 319 +- .../app/src/SMTPConnectorImpl.Codeunit.al | 28 +- .../test/src/SMTPAccountAuthTests.Codeunit.al | 395 ++- .../test/src/SMTPConnectorTest.Codeunit.al | 2 + .../codeunits/EmailLoggingInvoke.Codeunit.al | 6 + .../test/src/DigitalVouchersTests.Codeunit.al | 443 +++ .../app/src/Codeunits/FSInstall.Codeunit.al | 4 - .../app/src/Codeunits/FSUpgrade.Codeunit.al | 4 - .../codeunits/W1Transformation.Codeunit.al | 145 - .../app/src/pages/TableFieldMappings.page.al | 1 - .../Items/GPItemMigrator.codeunit.al | 8 - .../Support/HelperFunctions.codeunit.al | 45 - .../pages/GPMigrationConfiguration.Page.al | 9 - .../TaxEngineSetupWizard.Page.al | 10 +- .../ImageAnalysisObjects.PermissionSet.al | 3 - .../ContactPictureAnalyze.Codeunit.al | 218 -- .../app/src/pages/ImageAnalyzerWizard.Page.al | 30 - .../ContactPicAnalyzerTest.Codeunit.al | 187 -- .../test/src/codeunits/TestRunner.Codeunit.al | 6 - .../IntrastatReportManagement.Codeunit.al | 118 +- .../{ => app}/.objidconfig | 0 .../{ => app}/ExtensionLogo.png | Bin .../NoTransactionsSubscriber.Codeunit.al | 0 .../LibraryNoTransactions/{ => app}/app.json | 0 .../{ => app}/.objidconfig | 0 .../{ => app}/ExtensionLogo.png | Bin .../{ => app}/README.md | 0 .../{ => app}/app.json | 0 .../pages/MSPayPalStandardSettings.Page.al | 9 +- .../src/Support/MSQBODataMigration.Page.al | 23 +- .../src/Support/MigrationQBConfig.Table.al | 39 +- .../MigrationQBHelperFunctions.Codeunit.al | 34 +- .../app/src/pages/ReviewGLEntries.Page.al | 22 +- .../SalesInvoiceSubFormExt.PageExt.al | 30 - .../SalesOrderSubFormExt.PageExt.al | 31 - .../SalesQuoteSubFormExt.PageExt.al | 31 - .../src/Integration/SOAAnnotation.Codeunit.al | 2 +- .../src/Integration/SOADispatcher.Codeunit.al | 2 +- .../app/src/Integration/SOAImpl.Codeunit.al | 2 +- .../src/Integration/SOARecovery.Codeunit.al | 2 +- .../Integration/SOARetrieveEmails.Codeunit.al | 4 +- .../Integration/SOASendReplies.Codeunit.al | 2 +- .../src/Integration/SOAUpgrade.Codeunit.al | 27 + .../src/Profile/SalesOrderAgent.Profile.al | 1 + .../app/src/RoleCenter/SOAKPI.Page.al | 24 +- .../app/src/RoleCenter/SOAKPI.Table.al | 15 +- .../SOAAwarenessNotifications.Codeunit.al | 101 + .../app/src/Setup/SOASetup.Codeunit.al | 118 +- .../app/src/Setup/SOASetup.Page.al | 294 +- .../app/src/Setup/SOASetup.Table.al | 27 +- .../Validation/SOASessionEvents.Codeunit.al | 4 + Apps/W1/SmartList/{ => app}/.objidconfig | 0 Apps/W1/SmartList/{ => app}/ExtensionLogo.png | Bin Apps/W1/SmartList/{ => app}/app.json | 0 .../CodeUnits/SmartListInstall.Codeunit.al | 0 .../CodeUnits/SmartListUpgrade.Codeunit.al | 0 .../src/Queries/AccountSummary.Query.al | 0 .../Queries/BankAcctLedgerEntries.Query.al | 0 .../BlanketPurchaseOrderLines.Query.al | 0 .../Queries/BlanketPurchaseOrders.Query.al | 0 .../src/Queries/BlockedCustomers.Query.al | 0 .../src/Queries/BlockedVendors.Query.al | 0 .../src/Queries/CustomerAndContact.Query.al | 0 .../Queries/CustomerAndSalesperson.Query.al | 0 .../Queries/CustomerShipToAddresses.Query.al | 0 .../Queries/CustomersWithCreditLimit.Query.al | 0 .../Queries/GLEntrieswithDimensions.Query.al | 0 .../src/Queries/GeneralLedgerEntries.Query.al | 0 .../src/Queries/ItemPurchaseReceipts.Query.al | 0 .../src/Queries/ItemQuantities.Query.al | 0 .../{ => app}/src/Queries/Items.Query.al | 0 .../src/Queries/ItemsByLocation.Query.al | 0 .../src/Queries/ItemsDueForCount.Query.al | 0 .../src/Queries/ItemsOverdueForCount.Query.al | 0 .../Queries/NegativeQuantityItems.Query.al | 0 .../Queries/PostedSalesCMemoLineItem.Query.al | 0 .../Queries/PostedSalesCreditMemos.Query.al | 0 .../src/Queries/PostedSalesILineItem.Query.al | 0 .../src/Queries/PostedSalesInvoices.Query.al | 0 .../Queries/PurchaseOrderLineItems.Query.al | 0 .../src/Queries/PurchaseOrders.Query.al | 0 .../PurchasingCrMemoLineItems.Query.al | 0 .../Queries/PurchasingInvLineItems.Query.al | 0 .../Queries/PurchasingRcptLineItems.Query.al | 0 .../Queries/PurchasingTrxCrdtMemos.Query.al | 0 .../Queries/PurchasingTrxInvoices.Query.al | 0 .../UnpostedSalesLineBlktOrdr.Query.al | 0 .../UnpostedSalesLineCrdtMemo.Query.al | 0 .../UnpostedSalesLineInvoices.Query.al | 0 .../Queries/UnpostedSalesLineOrders.Query.al | 0 .../Queries/UnpostedSalesLineQuotes.Query.al | 0 .../Queries/UnpostedSalesLineReturns.Query.al | 0 .../UnpostedSalesTrxBlnktOrdr.Query.al | 0 .../UnpostedSalesTrxCreditMemo.Query.al | 0 .../Queries/UnpostedSalesTrxInvoices.Query.al | 0 .../Queries/UnpostedSalesTrxOrders.Query.al | 0 .../Queries/UnpostedSalesTrxQuotes.Query.al | 0 .../Queries/UnpostedSalesTrxReturns.Query.al | 0 .../src/Queries/VendorAndPurchaser.Query.al | 0 .../src/Queries/VendorBalance.Query.al | 0 .../src/Queries/VendorOrderAddresses.Query.al | 0 .../Journal/SustainabilityJnlLine.Table.al | 4 + .../Ledger/SustainabilityLedgerEntry.Table.al | 4 + .../Ledger/SustainabilityValueEntry.Table.al | 29 + .../SustItemPostSubscriber.Codeunit.al | 8 + .../SustResourcePostSubscriber.Codeunit.al | 55 + .../Posting/SustainabilityPostMgt.Codeunit.al | 25 + .../Service/SustPstdServCrMemoSub.PageExt.al | 49 + .../Service/SustPstdServCrSubfm.PageExt.al | 49 + .../Service/SustPstdServInvSubform.PageExt.al | 49 + .../Service/SustPstdServShptSubfm.PageExt.al | 40 + .../SustResourceJournalLine.TableExt.al | 58 + .../SustServShipmentItemLine.TableExt.al | 28 + .../SustServiceCrMemoHeader.TableExt.al | 37 + .../Service/SustServiceCrMemoLine.TableExt.al | 58 + .../Service/SustServiceCrMemoStats.PageExt.al | 52 + .../SustServiceCrMemoSubform.PageExt.al | 49 + .../SustServiceInvoiceHeader.TableExt.al | 37 + .../SustServiceInvoiceLine.TableExt.al | 58 + .../SustServiceInvoiceStats.PageExt.al | 52 + .../SustServiceInvoiceSubform.PageExt.al | 49 + .../Service/SustServiceItemLine.TableExt.al | 29 + .../src/Service/SustServiceLines.PageExt.al | 49 + .../Service/SustServiceOrderStats.PageExt.al | 59 + .../SustServiceOrderSubform.PageExt.al | 40 + .../Service/SustServiceQuoteLines.PageExt.al | 49 + .../SustServiceShipmentLine.TableExt.al | 58 + .../Service/SustServiceStatistics.PageExt.al | 58 + .../Service/SustServiceSubscriber.Codeunit.al | 371 +++ .../SustainabilityServiceHeader.TableExt.al | 47 + .../SustainabilityServiceLine.TableExt.al | 201 ++ .../test/src/SustCertificateTest.Codeunit.al | 502 ++- .../SustainabilityServiceTests.Codeunit.al | 2690 +++++++++++++++++ Apps/W1/SyncBase/{ => app}/.objidconfig | 0 Apps/W1/SyncBase/{ => app}/ExtensionLogo.png | Bin Apps/W1/SyncBase/{ => app}/app.json | 0 .../{ => app}/src/tables/SyncChange.Table.al | 0 .../{ => app}/src/tables/SyncMapping.Table.al | 0 .../{ => app}/src/tables/SyncSetup.Table.al | 0 .../VATGroupCommunication.Codeunit.al | 34 +- .../src/Enums/VATGroupAuthTypeOnPrem.Enum.al | 18 - .../src/Enums/VATGroupAuthTypeSaas.Enum.al | 9 - .../app/src/Pages/VATGroupSetupGuide.Page.al | 30 - .../Pages/VATReportSetupExtension.PageExt.al | 13 - .../test/.resources/200_blanked.json | 1 + .../.resources/status_batch_released.json | 28 + .../.resources/status_single_released.json | 7 + Apps/W1/VATGroupManagement/test/app.json | 5 +- .../test/src/LibraryVATGroup.Codeunit.al | 5 +- .../src/VATGroupMockServiceTest.Codeunit.al | 43 +- .../src/VATGroupSetupPageTest.Codeunit.al | 60 + Build/Packages.json | 2 +- Build/rulesets/AppSourceCop.ruleset.json | 30 +- Build/rulesets/Compiler.ruleset.json | 6 +- Build/rulesets/PTECop.ruleset.json | 21 +- Build/rulesets/UICop.ruleset.json | 6 +- Build/rulesets/base.ruleset.json | 12 - Build/rulesets/ruleset.json | 109 +- 402 files changed, 13328 insertions(+), 8196 deletions(-) create mode 100644 Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/AltCustVATRegFacadeCZZ.Codeunit.al create mode 100644 Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/AltCustVATRegImplCZZ.Codeunit.al create mode 100644 Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/AltCustVATRegOrchCZZ.Codeunit.al rename Apps/{W1/OnPrem Permissions/app/Permissions/smtpsetup.permissionset.al => CZ/AdvancePaymentsLocalization/app/Src/Enums/AltCustVATRegAdvCZZ.Enum.al} (56%) create mode 100644 Apps/CZ/AdvancePaymentsLocalization/app/Src/Interfaces/AltCustVATRegAdvCZZ.Interface.al delete mode 100644 Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/PurchAdvUsageFactBoxCZZ.Page.al delete mode 100644 Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/SalesAdvUsageFactBoxCZZ.Page.al create mode 100644 Apps/CZ/CashDeskLocalization/app/Src/PageExtensions/HumanResourcesSetupCZP.PageExt.al create mode 100644 Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/HumanResourcesSetupCZL.TableExt.al rename Apps/DE/EDocumentDE/app/src/ZUGFeRD/{ZUGFeRDReportIntegration.al => ZUGFeRDReportIntegration.Codeunit.al} (97%) create mode 100644 Apps/GB/GovTalk/test/src/RegularTests/GovTalkVATRequestPageTests.Codeunit.al create mode 100644 Apps/IN/INGST/app/.resources/GSTUseCases/A744EF89-44A8-4CE0-81F8-3D8094623CD1.json delete mode 100644 Apps/IN/INTaxBase/app/src/pageextension/PurchaseInvoiceSubform.PageExt.al delete mode 100644 Apps/IN/INTaxBase/app/src/pageextension/PurchaseOrderSubform.PageExt.al rename Apps/NA/Ceridian/{ => app}/ExtensionLogo.png (100%) rename Apps/NA/Ceridian/{ => app}/app.json (100%) rename Apps/NA/Ceridian/{ => app}/src/CeridianInstall.Codeunit.al (100%) rename Apps/NA/Ceridian/{ => app}/src/ImportCeridianPayroll.XmlPort.al (100%) rename Apps/NA/Ceridian/{ => app}/src/MSCeridianPayrollMgt.Codeunit.al (100%) rename Apps/NA/Ceridian/{ => app}/src/MSCeridianPayrollSetup.Page.al (100%) rename Apps/NA/Ceridian/{ => app}/src/MSCeridianPayrollSetup.Table.al (100%) rename Apps/NA/Ceridian/{ => app}/src/MSCeridianPayrollimport.Codeunit.al (100%) rename Apps/NA/Ceridian/{ => app}/src/MSCeridianPayrollupgrade.Codeunit.al (100%) rename Apps/NA/Ceridian/{ => app}/src/Permissions/d365basicceridianpayroll.permissionsetext.al (100%) rename Apps/NA/Ceridian/{ => app}/src/Permissions/d365basicisvceridianpayroll.permissionsetext.al (100%) rename Apps/NA/Ceridian/{ => app}/src/Permissions/d365busfullaccessceridianpayroll.permissionsetext.al (100%) rename Apps/NA/Ceridian/{ => app}/src/Permissions/d365buspremiumceridianpayroll.permissionsetext.al (100%) rename Apps/NA/Ceridian/{ => app}/src/Permissions/d365fullaccessceridianpayroll.permissionsetext.al (100%) rename Apps/NA/Ceridian/{ => app}/src/Permissions/d365readceridianpayroll.permissionsetext.al (100%) rename Apps/NA/Ceridian/{ => app}/src/Permissions/d365teammemberceridianpayroll.permissionsetext.al (100%) rename Apps/NA/Ceridian/{ => app}/src/Permissions/intelligentcloudceridianpayroll.permissionsetext.al (100%) delete mode 100644 Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/Finance/1.Setup Data/CreateIRS1099FormBoxUS.Codeunit.al delete mode 100644 Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoTool/Contoso Helpers/ContosoIRS1099US.Codeunit.al delete mode 100644 Apps/US/IRS1096/test/src/Create1096FormsTest.Codeunit.al delete mode 100644 Apps/US/IRSForms/app/src/Setup/IRS1099TransErrorHandler.Codeunit.al delete mode 100644 Apps/US/IRSForms/app/src/Setup/IRS1099TransferFromBaseApp.Codeunit.al delete mode 100644 Apps/W1/AutomaticAccountCodes/app/src/Codeunits/UpgTagDefAutoAccCodes.Codeunit.al delete mode 100644 Apps/W1/AutomaticAccountCodes/app/src/Codeunits/UpgradeAutoAccCodes.Codeunit.al rename Apps/W1/ClientAddIns/{ => app}/.objidconfig (100%) rename Apps/W1/ClientAddIns/{ => app}/ExtensionLogo.png (100%) rename Apps/W1/ClientAddIns/{ => app}/app.json (100%) rename Apps/W1/ClientAddIns/{ => app}/src/oauth/OAuthAddIn.ControlAddin.al (100%) rename Apps/W1/ClientAddIns/{ => app}/src/oauth/js/OAuthIntegration.js (100%) create mode 100644 Apps/W1/Email - SMTP Connector/app/src/Notification/SMTPEmailAccountsExt.PageExt.al create mode 100644 Apps/W1/Email - SMTP Connector/app/src/Notification/SMTPEmailOutbox.PageExt.al create mode 100644 Apps/W1/Email - SMTP Connector/app/src/Notification/SMTPSentEmail.PageExt.al delete mode 100644 Apps/W1/HybridBCLast/app/src/codeunits/W1Transformation.Codeunit.al delete mode 100644 Apps/W1/ImageAnalysis/app/src/codeunits/ContactPictureAnalyze.Codeunit.al delete mode 100644 Apps/W1/ImageAnalysis/test/src/codeunits/ContactPicAnalyzerTest.Codeunit.al rename Apps/W1/LibraryNoTransactions/{ => app}/.objidconfig (100%) rename Apps/W1/LibraryNoTransactions/{ => app}/ExtensionLogo.png (100%) rename Apps/W1/LibraryNoTransactions/{ => app}/NoTransactionsSubscriber.Codeunit.al (100%) rename Apps/W1/LibraryNoTransactions/{ => app}/app.json (100%) rename Apps/W1/MicrosoftUniversalPrint/{ => app}/.objidconfig (100%) rename Apps/W1/MicrosoftUniversalPrint/{ => app}/ExtensionLogo.png (100%) rename Apps/W1/MicrosoftUniversalPrint/{ => app}/README.md (100%) rename Apps/W1/MicrosoftUniversalPrint/{ => app}/app.json (100%) create mode 100644 Apps/W1/SalesOrderAgent/app/src/Setup/SOAAwarenessNotifications.Codeunit.al rename Apps/W1/SmartList/{ => app}/.objidconfig (100%) rename Apps/W1/SmartList/{ => app}/ExtensionLogo.png (100%) rename Apps/W1/SmartList/{ => app}/app.json (100%) rename Apps/W1/SmartList/{ => app}/src/CodeUnits/SmartListInstall.Codeunit.al (100%) rename Apps/W1/SmartList/{ => app}/src/CodeUnits/SmartListUpgrade.Codeunit.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/AccountSummary.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/BankAcctLedgerEntries.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/BlanketPurchaseOrderLines.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/BlanketPurchaseOrders.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/BlockedCustomers.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/BlockedVendors.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/CustomerAndContact.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/CustomerAndSalesperson.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/CustomerShipToAddresses.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/CustomersWithCreditLimit.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/GLEntrieswithDimensions.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/GeneralLedgerEntries.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/ItemPurchaseReceipts.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/ItemQuantities.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/Items.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/ItemsByLocation.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/ItemsDueForCount.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/ItemsOverdueForCount.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/NegativeQuantityItems.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/PostedSalesCMemoLineItem.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/PostedSalesCreditMemos.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/PostedSalesILineItem.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/PostedSalesInvoices.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/PurchaseOrderLineItems.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/PurchaseOrders.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/PurchasingCrMemoLineItems.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/PurchasingInvLineItems.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/PurchasingRcptLineItems.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/PurchasingTrxCrdtMemos.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/PurchasingTrxInvoices.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/UnpostedSalesLineBlktOrdr.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/UnpostedSalesLineCrdtMemo.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/UnpostedSalesLineInvoices.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/UnpostedSalesLineOrders.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/UnpostedSalesLineQuotes.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/UnpostedSalesLineReturns.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/UnpostedSalesTrxBlnktOrdr.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/UnpostedSalesTrxCreditMemo.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/UnpostedSalesTrxInvoices.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/UnpostedSalesTrxOrders.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/UnpostedSalesTrxQuotes.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/UnpostedSalesTrxReturns.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/VendorAndPurchaser.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/VendorBalance.Query.al (100%) rename Apps/W1/SmartList/{ => app}/src/Queries/VendorOrderAddresses.Query.al (100%) create mode 100644 Apps/W1/Sustainability/app/src/Posting/SustResourcePostSubscriber.Codeunit.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustPstdServCrMemoSub.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustPstdServCrSubfm.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustPstdServInvSubform.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustPstdServShptSubfm.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustResourceJournalLine.TableExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServShipmentItemLine.TableExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoHeader.TableExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoLine.TableExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoStats.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoSubform.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceHeader.TableExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceLine.TableExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceStats.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceSubform.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceItemLine.TableExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceLines.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceOrderStats.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceOrderSubform.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceQuoteLines.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceShipmentLine.TableExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceStatistics.PageExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustServiceSubscriber.Codeunit.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustainabilityServiceHeader.TableExt.al create mode 100644 Apps/W1/Sustainability/app/src/Service/SustainabilityServiceLine.TableExt.al create mode 100644 Apps/W1/Sustainability/test/src/SustainabilityServiceTests.Codeunit.al rename Apps/W1/SyncBase/{ => app}/.objidconfig (100%) rename Apps/W1/SyncBase/{ => app}/ExtensionLogo.png (100%) rename Apps/W1/SyncBase/{ => app}/app.json (100%) rename Apps/W1/SyncBase/{ => app}/src/tables/SyncChange.Table.al (100%) rename Apps/W1/SyncBase/{ => app}/src/tables/SyncMapping.Table.al (100%) rename Apps/W1/SyncBase/{ => app}/src/tables/SyncSetup.Table.al (100%) create mode 100644 Apps/W1/VATGroupManagement/test/.resources/200_blanked.json create mode 100644 Apps/W1/VATGroupManagement/test/.resources/status_batch_released.json create mode 100644 Apps/W1/VATGroupManagement/test/.resources/status_single_released.json diff --git a/.github/AL-Go-Settings.json b/.github/AL-Go-Settings.json index e47449e31a..d2c8583a56 100644 --- a/.github/AL-Go-Settings.json +++ b/.github/AL-Go-Settings.json @@ -6,7 +6,7 @@ "runs-on": "windows-latest", "cacheImageName": "", "UsePsSession": false, - "artifact": "https://bcinsider-fvh2ekdjecfjd6gk.b02.azurefd.net/sandbox/28.0.42149.0/base", + "artifact": "https://bcinsider-fvh2ekdjecfjd6gk.b02.azurefd.net/sandbox/28.0.43307.0/base", "country": "base", "useProjectDependencies": true, "repoVersion": "28.0", diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/AltCustVATRegFacadeCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/AltCustVATRegFacadeCZZ.Codeunit.al new file mode 100644 index 0000000000..6dcf4cb251 --- /dev/null +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/AltCustVATRegFacadeCZZ.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.Sales.Customer; + +codeunit 11730 "Alt. Cust. VAT Reg. Facade CZZ" +{ + Access = Public; + + var + AltCustVATRegOrchCZZ: Codeunit "Alt. Cust. VAT Reg. Orch. CZZ"; + + procedure UpdateSetupOnVATCountryChangeInSalesAdvLetterHeader(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; xSalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ") + begin + AltCustVATRegOrchCZZ.GetAltCustVATRegDocImpl().UpdateSetupOnVATCountryChangeInSalesAdvLetterHeader(SalesAdvLetterHeaderCZZ, xSalesAdvLetterHeaderCZZ); + end; + + procedure Init(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; xSalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ") + begin + AltCustVATRegOrchCZZ.GetAltCustVATRegDocImpl().Init(SalesAdvLetterHeaderCZZ, xSalesAdvLetterHeaderCZZ); + end; + + procedure UpdateVATRegNoInCustFromSalesAdvLetterHeader(SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; Customer: Record Customer) ShouldUpdate: Boolean + var + IsHandled: Boolean; + begin + OnBeforeUpdateVATRegNoInCustFromSalesAdvLetterHeader(SalesAdvLetterHeaderCZZ, Customer, ShouldUpdate, IsHandled); + if IsHandled then + exit(ShouldUpdate); + exit((Customer."VAT Registration No." = '') and (not SalesAdvLetterHeaderCZZ."Alt. VAT Registration No.")); + end; + + [IntegrationEvent(false, false)] + local procedure OnBeforeUpdateVATRegNoInCustFromSalesAdvLetterHeader(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; Customer: Record Customer; var ShouldUpdate: Boolean; var IsHandled: Boolean) + begin + end; +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/AltCustVATRegImplCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/AltCustVATRegImplCZZ.Codeunit.al new file mode 100644 index 0000000000..f409706100 --- /dev/null +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/AltCustVATRegImplCZZ.Codeunit.al @@ -0,0 +1,288 @@ +// ------------------------------------------------------------------------------------------------ +// 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.VAT.Registration; +using Microsoft.Sales.Customer; +using System.Telemetry; +using System.Diagnostics; +using System.Environment.Configuration; + +codeunit 11732 "Alt. Cust. VAT Reg. Impl. CZZ" implements "Alt. Cust. VAT Reg. Adv. CZZ" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + var + AltCustVATRegFacade: Codeunit "Alt. Cust. VAT. Reg. Facade"; + FeatureTelemetry: Codeunit "Feature Telemetry"; + InstructionTxt: Label 'The following data is taken from the Alternative VAT Registration setup. It will override values in the document and affect the posting. Do you want to continue?'; + DocumentValueTxt: Label 'Document value'; + AlternativeValueTxt: Label 'Alternative value'; + CannotChangeVATDataWhenVATPaymentErr: Label 'You cannot make this change because it leads to a different VAT Registration No., Gen. Bus. Posting Group or VAT Bus. Posting Group than in the sales advance letter. Since you have posted a VAT payment, such a change will cause an inconsistency in the ledger entries.'; + VATDataTakenFromCustomerMsg: Label 'The VAT Country/Region code has been changed to the value that does not have an alternative VAT registration.\\The following fields have been updated from the customer card: %1', Comment = '%1 = list of the fields'; + FeatureNameTxt: Label 'Alternative Customer VAT Registration', Locked = true; + ConfirmAltCustVATRegNotificationNameTok: Label 'Confirm an alternative customer VAT registration in advance letters'; + ConfirmAltCustVATRegNotificationDescTok: Label 'Show the user the page to confirm an alternative customer VAT registration when choosing the VAT country different from the customer''s'; + AddAlternativeCustVATRegQst: Label 'The VAT country is different than the customer''s. Do you want to add an alternative VAT registration for this VAT country?'; + AddAlternativeCustVATRegMsg: Label 'Add'; + DontShowMsg: Label 'Don''t show'; + AddAltCustVATRegNotificationNameTok: Label 'Suggest an alternative customer VAT registration from sales advance letter'; + AddAltCustVATRegNotificationDescTok: Label 'Suggest the user to add an alternative customer VAT registration when choosing a VAT country different from the customer''s'; + + procedure Init(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; xSalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ") + begin + if xSalesAdvLetterHeaderCZZ."Bill-to Customer No." = '' then + exit; + SalesAdvLetterHeaderCZZ.Validate("Alt. VAT Registration No.", false); + SalesAdvLetterHeaderCZZ.Validate("Alt. VAT Bus Posting Group", false); + end; + + procedure CopyFromCustomer(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; xSalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ") + var + Customer: Record Customer; + begin + if not IsAltVATRegUsed(SalesAdvLetterHeaderCZZ) then + exit; + RunChecks(SalesAdvLetterHeaderCZZ); + Customer.SetLoadFields("Country/Region Code", "VAT Registration No.", "VAT Bus. Posting Group"); + if not Customer.Get(SalesAdvLetterHeaderCZZ."Bill-to Customer No.") then + exit; + CopyFromCustomer(SalesAdvLetterHeaderCZZ, xSalesAdvLetterHeaderCZZ, Customer); + end; + + local procedure CopyFromCustomer(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; xSalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; Customer: Record Customer) + var + ChangedFieldsList: Text; + begin + if (SalesAdvLetterHeaderCZZ."Alt. VAT Registration No." or SalesAdvLetterHeaderCZZ."Alt. VAT Bus Posting Group") and + (SalesAdvLetterHeaderCZZ."VAT Country/Region Code" <> Customer."Country/Region Code") and + (xSalesAdvLetterHeaderCZZ."VAT Country/Region Code" = SalesAdvLetterHeaderCZZ."VAT Country/Region Code") + then begin + SalesAdvLetterHeaderCZZ."VAT Country/Region Code" := Customer."Country/Region Code"; + AddStringToCommaSeparatedList(ChangedFieldsList, SalesAdvLetterHeaderCZZ.FieldCaption("VAT Country/Region Code")); + end; + if SalesAdvLetterHeaderCZZ."Alt. VAT Registration No." then begin + SalesAdvLetterHeaderCZZ.Validate("Alt. VAT Registration No.", false); + SalesAdvLetterHeaderCZZ.Validate("VAT Registration No.", Customer."VAT Registration No."); + AddStringToCommaSeparatedList(ChangedFieldsList, SalesAdvLetterHeaderCZZ.FieldCaption("VAT Registration No.")); + end; + if SalesAdvLetterHeaderCZZ."Alt. VAT Bus Posting Group" then begin + SalesAdvLetterHeaderCZZ.Validate("Alt. VAT Bus Posting Group", false); + SalesAdvLetterHeaderCZZ.Validate("VAT Bus. Posting Group", Customer."VAT Bus. Posting Group"); + AddStringToCommaSeparatedList(ChangedFieldsList, SalesAdvLetterHeaderCZZ.FieldCaption("VAT Bus. Posting Group")); + end; + if GuiAllowed() then + Message(VATDataTakenFromCustomerMsg, ChangedFieldsList); + end; + + procedure UpdateSetupOnVATCountryChangeInSalesAdvLetterHeader(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; xSalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ") + var + Customer: Record Customer; + begin + if AlternativeCustVATRegIsBlank(SalesAdvLetterHeaderCZZ) then begin + CopyFromCustomer(SalesAdvLetterHeaderCZZ, xSalesAdvLetterHeaderCZZ); + if not Customer.Get(SalesAdvLetterHeaderCZZ."Bill-to Customer No.") then + exit; + if Customer."Country/Region Code" = SalesAdvLetterHeaderCZZ."VAT Country/Region Code" then + exit; + ThrowAddAltCustVATRegNotification(Customer."No.", SalesAdvLetterHeaderCZZ."VAT Country/Region Code"); + exit; + end; + RunChecks(SalesAdvLetterHeaderCZZ); + if SalesAdvLetterHeaderCZZ.SystemCreatedAt <> 0DT then + if not ConfirmChanges(SalesAdvLetterHeaderCZZ) then + error(''); + UpdateAltCustVATRegInSalesAdvLetterHeader(SalesAdvLetterHeaderCZZ); + end; + + local procedure IsAltVATRegUsed(SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"): Boolean + begin + exit(SalesAdvLetterHeaderCZZ."Alt. VAT Registration No." or SalesAdvLetterHeaderCZZ."Alt. VAT Bus Posting Group"); + end; + + local procedure AlternativeCustVATRegIsBlank(SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"): Boolean + var + AltCustVATReg: Record "Alt. Cust. VAT Reg."; + begin + exit(not GetAlternativeCustVATReg(AltCustVATReg, SalesAdvLetterHeaderCZZ)); + end; + + local procedure GetAlternativeCustVATReg(var AltCustVATReg: Record "Alt. Cust. VAT Reg."; SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"): Boolean + var + Customer: Record Customer; + begin + Customer.SetLoadFields("No."); + Customer.Get(SalesAdvLetterHeaderCZZ."Bill-to Customer No."); + exit(AltCustVATRegFacade.GetAlternativeCustVATReg(AltCustVATReg, Customer."No.", SalesAdvLetterHeaderCZZ."VAT Country/Region Code")); + end; + + local procedure ConfirmChanges(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ") Confirmed: Boolean + var + TempChangeLogEntry: Record "Change Log Entry" temporary; + ConfirmAltCustVATRegPage: Page "Confirm Alt. Cust. VAT Reg."; + begin + FeatureTelemetry.LogUsage('0000QRW', FeatureNameTxt, 'Confirm changes'); + if not BuildFieldChangeBuffer(TempChangeLogEntry, SalesAdvLetterHeaderCZZ) then + exit(true); + if not GuiAllowed() then + exit(true); + if SalesAdvLetterHeaderCZZ.GetHideValidationDialog() then + exit(true); + if not ShowConfirmation() then + exit(true); + ConfirmAltCustVATRegPage.SetUIControls(InstructionTxt, DocumentValueTxt, AlternativeValueTxt); + ConfirmAltCustVATRegPage.SetSource(TempChangeLogEntry); + Confirmed := ConfirmAltCustVATRegPage.RunModal() = Action::Ok; + if ConfirmAltCustVATRegPage.DontShowAgainOptionSelected() then + DisableConfirmation(); + exit(Confirmed); + end; + + local procedure ShowConfirmation(): Boolean + var + MyNotifications: Record "My Notifications"; + begin + if Database.IsInWriteTransaction() then + exit(false); + exit(MyNotifications.IsEnabled(GetConfirmChangesNotificationId())); + end; + + local procedure DisableConfirmation() + var + MyNotifications: Record "My Notifications"; + begin + if not MyNotifications.Disable(GetConfirmChangesNotificationId()) then + MyNotifications.InsertDefault(GetConfirmChangesNotificationId(), ConfirmAltCustVATRegNotificationNameTok, ConfirmAltCustVATRegNotificationDescTok, false); + end; + + local procedure UpdateAltCustVATRegInSalesAdvLetterHeader(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ") + var + AltCustVATReg: Record "Alt. Cust. VAT Reg."; + begin + GetAlternativeCustVATReg(AltCustVATReg, SalesAdvLetterHeaderCZZ); + if AltCustVATReg."VAT Registration No." <> '' then begin + SalesAdvLetterHeaderCZZ.Validate("Alt. VAT Registration No.", true); + SalesAdvLetterHeaderCZZ.Validate("VAT Registration No.", AltCustVATReg."VAT Registration No."); + end; + if AltCustVATReg."VAT Bus. Posting Group" <> '' then begin + SalesAdvLetterHeaderCZZ.Validate("Alt. VAT Bus Posting Group", true); + SalesAdvLetterHeaderCZZ.Validate("VAT Bus. Posting Group", AltCustVATReg."VAT Bus. Posting Group"); + end; + OnAfterUpdateAltCustVATRegInSalesAdvLetterHeader(SalesAdvLetterHeaderCZZ, AltCustVATReg); + FeatureTelemetry.LogUptake('0000QRV', FeatureNameTxt, Enum::"Feature Uptake Status"::Used); + end; + + local procedure BuildFieldChangeBuffer(var TempChangeLogEntry: Record "Change Log Entry" temporary; SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"): Boolean + var + AltCustVATReg: Record "Alt. Cust. VAT Reg."; + begin + GetAlternativeCustVATReg(AltCustVATReg, SalesAdvLetterHeaderCZZ); + if (AltCustVATReg."VAT Registration No." <> '') and (SalesAdvLetterHeaderCZZ."VAT Registration No." <> AltCustVATReg."VAT Registration No.") then + AddFieldChangeBuffer(TempChangeLogEntry, SalesAdvLetterHeaderCZZ.FieldNo("VAT Registration No."), SalesAdvLetterHeaderCZZ."VAT Registration No.", AltCustVATReg."VAT Registration No."); + if (AltCustVATReg."VAT Bus. Posting Group" <> '') and (SalesAdvLetterHeaderCZZ."VAT Bus. Posting Group" <> AltCustVATReg."VAT Bus. Posting Group") then + AddFieldChangeBuffer(TempChangeLogEntry, SalesAdvLetterHeaderCZZ.FieldNo("VAT Bus. Posting Group"), SalesAdvLetterHeaderCZZ."VAT Bus. Posting Group", AltCustVATReg."VAT Bus. Posting Group"); + OnAfterBuildFieldChangeBuffer(TempChangeLogEntry, SalesAdvLetterHeaderCZZ); + exit(not TempChangeLogEntry.IsEmpty()); + end; + + local procedure AddFieldChangeBuffer(var TempChangeLogEntry: Record "Change Log Entry" temporary; DocFieldNo: Integer; OldValue: Text[2048]; NewValue: Text[2048]) + begin + TempChangeLogEntry."Entry No." += 1; + TempChangeLogEntry."Table No." := Database::"Sales Adv. Letter Header CZZ"; + TempChangeLogEntry."Field No." := DocFieldNo; + TempChangeLogEntry."Old Value" := OldValue; + TempChangeLogEntry."New Value" := NewValue; + TempChangeLogEntry.Insert(); + end; + + local procedure RunChecks(SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ") + begin + CheckVATPayment(SalesAdvLetterHeaderCZZ); + end; + + local procedure CheckVATPayment(SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ") + var + SalesAdvLetterEntryCZZ: Record "Sales Adv. Letter Entry CZZ"; + begin + SalesAdvLetterEntryCZZ.SetRange("Sales Adv. Letter No.", SalesAdvLetterHeaderCZZ."No."); + SalesAdvLetterEntryCZZ.SetRange("Entry Type", SalesAdvLetterEntryCZZ."Entry Type"::"VAT Payment"); + SalesAdvLetterEntryCZZ.SetRange(Cancelled, false); + if not SalesAdvLetterEntryCZZ.IsEmpty() then + error(CannotChangeVATDataWhenVATPaymentErr); + end; + + local procedure GetConfirmChangesNotificationId(): Guid + begin + exit('e564eb18-2c72-4d30-be8d-2050e084f9c2'); + end; + + local procedure AddStringToCommaSeparatedList(var List: Text; Value: Text) + begin + if List <> '' then + List += ', '; + List += Value; + end; + + local procedure ThrowAddAltCustVATRegNotification(CustNo: Code[20]; VATCountryRegionCode: Code[10]) + var + MyNotifications: Record "My Notifications"; + AltCustVATReg: Record "Alt. Cust. VAT Reg."; + Notification: Notification; + begin + if not MyNotifications.IsEnabled(AddAltCustVATRegNotificationId()) then + exit; + Notification.Id(AddAltCustVATRegNotificationId()); + Notification.Message(AddAlternativeCustVATRegQst); + Notification.SetData(AltCustVATReg.FieldName("Customer No."), CustNo); + Notification.SetData(AltCustVATReg.FieldName("VAT Country/Region Code"), VATCountryRegionCode); + Notification.AddAction(AddAlternativeCustVATRegMsg, Codeunit::"Alt. Cust. VAT Reg. Impl. CZZ", 'AddAltCustVATRegFromNotification'); + Notification.AddAction(DontShowMsg, Codeunit::"Alt. Cust. VAT Reg. Impl. CZZ", 'DisableAddAltCustVATRegNotification'); + Notification.Send(); + end; + + procedure AddAltCustVATRegFromNotification(Notification: Notification) + var + AltCustVATReg: Record "Alt. Cust. VAT Reg."; + NewId: Integer; + begin + if AltCustVATReg.FindLast() then + NewId := AltCustVATReg.Id; + NewId += 1; + AltCustVATReg.Init(); + AltCustVATReg.Validate(Id, NewId); + AltCustVATReg.Validate("Customer No.", + CopyStr(Notification.GetData(AltCustVATReg.FieldName("Customer No.")), 1, MaxStrLen(AltCustVATReg."Customer No."))); + AltCustVATReg.Validate("VAT Country/Region Code", + CopyStr(Notification.GetData(AltCustVATReg.FieldName("VAT Country/Region Code")), 1, MaxStrLen(AltCustVATReg."VAT Country/Region Code"))); + AltCustVATReg.Insert(true); + Commit(); + Page.RunModal(0, AltCustVATReg); + end; + + procedure DisableAddAltCustVATRegNotification(Notification: Notification) + var + MyNotifications: Record "My Notifications"; + begin + if not MyNotifications.Disable(Notification.Id()) then + MyNotifications.InsertDefault(Notification.Id(), AddAltCustVATRegNotificationNameTok, AddAltCustVATRegNotificationDescTok, false); + end; + + local procedure AddAltCustVATRegNotificationId(): Text + begin + exit('34c4fa1d-07b6-450b-b524-0d367b1e6221') + end; + + [IntegrationEvent(false, false)] + local procedure OnAfterBuildFieldChangeBuffer(var TempChangeLogEntry: Record "Change Log Entry" temporary; SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"); + begin + end; + + [IntegrationEvent(false, false)] + local procedure OnAfterUpdateAltCustVATRegInSalesAdvLetterHeader(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; var AltCustVATReg: Record "Alt. Cust. VAT Reg.") + begin + end; +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/AltCustVATRegOrchCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/AltCustVATRegOrchCZZ.Codeunit.al new file mode 100644 index 0000000000..96a4dad694 --- /dev/null +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/AltCustVATRegOrchCZZ.Codeunit.al @@ -0,0 +1,21 @@ +// ------------------------------------------------------------------------------------------------ +// 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.VAT.Setup; + +codeunit 11731 "Alt. Cust. VAT Reg. Orch. CZZ" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + procedure GetAltCustVATRegDocImpl(): Interface "Alt. Cust. VAT Reg. Adv. CZZ" + var + VATSetup: Record "VAT Setup"; + begin + exit(VATSetup.Get() ? VATSetup."Alt. Cust. VAT Reg. Adv. CZZ" : "Alt. Cust. VAT Reg. Adv. CZZ"::Default); + end; +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/CrossApplicationHandlerCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/CrossApplicationHandlerCZZ.Codeunit.al index 912164624d..2d215248ca 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/CrossApplicationHandlerCZZ.Codeunit.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/CrossApplicationHandlerCZZ.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. // ------------------------------------------------------------------------------------------------ @@ -11,13 +11,7 @@ using System.Utilities; codeunit 31418 "Cross Application Handler CZZ" { -#if not CLEAN25 - ObsoleteState = Pending; - ObsoleteReason = 'The Access property will be changed to Internal.'; - ObsoleteTag = '25.0'; -#else Access = Internal; -#endif var ConfirmManagement: Codeunit "Confirm Management"; @@ -134,4 +128,4 @@ codeunit 31418 "Cross Application Handler CZZ" if not ConfirmManagement.GetResponseOrDefault(StrSubstNo(SuggestedAmountToApplyQst, CashDocumentLineCZP."Advance Letter No. CZZ"), false) then Error(''); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/PurchAdvLetterManagementCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/PurchAdvLetterManagementCZZ.Codeunit.al index 502f3cc9c3..1033ef8ce1 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/PurchAdvLetterManagementCZZ.Codeunit.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/PurchAdvLetterManagementCZZ.Codeunit.al @@ -299,20 +299,6 @@ codeunit 31019 "PurchAdvLetterManagement CZZ" PurchAdvLetterPostCZZ.PostAdvancePayment( VendorLedgerEntry, PostedGenJournalLine, GenJnlPostLine, AdvancePostingParametersCZZ); end; -#if not CLEAN25 - [Obsolete('Replaced by GetAdvanceGLAccountNoCZZ function in GenJournalLine.', '25.0')] - procedure GetAdvanceGLAccount(var GenJournalLine: Record "Gen. Journal Line"): Code[20] - var - PurchAdvLetterHeaderCZZ: Record "Purch. Adv. Letter Header CZZ"; - AdvanceLetterTemplateCZZ: Record "Advance Letter Template CZZ"; - begin - PurchAdvLetterHeaderCZZ.Get(GenJournalLine."Adv. Letter No. (Entry) CZZ"); - PurchAdvLetterHeaderCZZ.TestField("Advance Letter Code"); - AdvanceLetterTemplateCZZ.Get(PurchAdvLetterHeaderCZZ."Advance Letter Code"); - AdvanceLetterTemplateCZZ.TestField("Advance Letter G/L Account"); - exit(AdvanceLetterTemplateCZZ."Advance Letter G/L Account"); - end; -#endif procedure PostAdvancePaymentVAT(var PurchAdvLetterEntryCZZ: Record "Purch. Adv. Letter Entry CZZ") begin diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/PurchAdvLetterPostCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/PurchAdvLetterPostCZZ.Codeunit.al index 6c3755d598..f6c279848a 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/PurchAdvLetterPostCZZ.Codeunit.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/PurchAdvLetterPostCZZ.Codeunit.al @@ -2230,11 +2230,6 @@ codeunit 31142 "Purch. Adv. Letter-Post CZZ" GenJournalLine."Source Currency Code" := DetailedVendorLedgEntry1."Currency Code"; GenJournalLine."System-Created Entry" := true; OnUnapplyVendLedgEntryOnBeforeUnapplyVendLedgEntry(VendorLedgerEntry, DetailedVendorLedgEntry1, GenJournalLine); -#if not CLEAN25 -#pragma warning disable AL0432 - OnUnapplyVendLedgEntryOnBeforePostUnapplyVendLedgEntry(VendorLedgerEntry, DetailedVendorLedgEntry1, GenJournalLine); -#pragma warning restore AL0432 -#endif GenJnlPostLine.UnapplyVendLedgEntry(GenJournalLine, DetailedVendorLedgEntry1); end else Succes := true; @@ -2857,13 +2852,6 @@ codeunit 31142 "Purch. Adv. Letter-Post CZZ" local procedure OnAfterInitGenJournalLineFromVendorLedgerEntry(var VendorLedgerEntry: Record "Vendor Ledger Entry"; var GenJournalLine: Record "Gen. Journal Line") begin end; -#if not CLEAN25 - [Obsolete('Replaced by OnUnapplyVendLedgEntryOnBeforeUnapplyVendLedgEntry event.', '25.0')] - [IntegrationEvent(false, false)] - local procedure OnUnapplyVendLedgEntryOnBeforePostUnapplyVendLedgEntry(var VendorLedgerEntry: Record "Vendor Ledger Entry"; DetailedVendorLedgEntry1: Record "Detailed Vendor Ledg. Entry"; GenJournalLine: Record "Gen. Journal Line") - begin - end; -#endif [IntegrationEvent(false, false)] local procedure OnUnapplyVendLedgEntryOnBeforeUnapplyVendLedgEntry(var VendorLedgerEntry: Record "Vendor Ledger Entry"; var DetailedVendorLedgEntry: Record "Detailed Vendor Ledg. Entry"; var GenJournalLine: Record "Gen. Journal Line") diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/SalesAdvLetterManagementCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/SalesAdvLetterManagementCZZ.Codeunit.al index 46409c93f8..bcd3e288a1 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/SalesAdvLetterManagementCZZ.Codeunit.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/SalesAdvLetterManagementCZZ.Codeunit.al @@ -310,20 +310,6 @@ codeunit 31002 "SalesAdvLetterManagement CZZ" InsertedEntryNo := SalesAdvLetterPostCZZ.PostAdvancePayment( CustLedgerEntry, PostedGenJournalLine, GenJnlPostLine, AdvancePostingParametersCZZ); end; -#if not CLEAN25 - [Obsolete('Replaced by GetAdvanceGLAccountNoCZZ function in GenJournalLine.', '25.0')] - procedure GetAdvanceGLAccount(var GenJournalLine: Record "Gen. Journal Line"): Code[20] - var - SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; - AdvanceLetterTemplateCZZ: Record "Advance Letter Template CZZ"; - begin - SalesAdvLetterHeaderCZZ.Get(GenJournalLine."Adv. Letter No. (Entry) CZZ"); - SalesAdvLetterHeaderCZZ.TestField("Advance Letter Code"); - AdvanceLetterTemplateCZZ.Get(SalesAdvLetterHeaderCZZ."Advance Letter Code"); - AdvanceLetterTemplateCZZ.TestField("Advance Letter G/L Account"); - exit(AdvanceLetterTemplateCZZ."Advance Letter G/L Account"); - end; -#endif procedure PostAdvancePaymentVAT(var SalesAdvLetterEntryCZZ: Record "Sales Adv. Letter Entry CZZ"; PostingDate: Date) begin diff --git a/Apps/W1/OnPrem Permissions/app/Permissions/smtpsetup.permissionset.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Enums/AltCustVATRegAdvCZZ.Enum.al similarity index 56% rename from Apps/W1/OnPrem Permissions/app/Permissions/smtpsetup.permissionset.al rename to Apps/CZ/AdvancePaymentsLocalization/app/Src/Enums/AltCustVATRegAdvCZZ.Enum.al index 2f22a112b7..f46d70bc49 100644 --- a/Apps/W1/OnPrem Permissions/app/Permissions/smtpsetup.permissionset.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Enums/AltCustVATRegAdvCZZ.Enum.al @@ -2,14 +2,14 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. // ------------------------------------------------------------------------------------------------ -#pragma warning disable AA0247 +namespace Microsoft.Finance.AdvancePayments; -permissionset 2271 "SMTP-SETUP" +enum 11703 "Alt. Cust. VAT Reg. Adv. CZZ" implements "Alt. Cust. VAT Reg. Adv. CZZ" { - Access = Public; - Assignable = true; - Caption = 'SMTP Mail Setup'; - ObsoleteTag = '20.0'; - ObsoleteState = Pending; - ObsoleteReason = '"SMTP Mail - Admin" has been removed.'; -} + Extensible = true; + DefaultImplementation = "Alt. Cust. VAT Reg. Adv. CZZ" = "Alt. Cust. VAT Reg. Impl. CZZ"; + + value(0; Default) + { + } +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Interfaces/AltCustVATRegAdvCZZ.Interface.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Interfaces/AltCustVATRegAdvCZZ.Interface.al new file mode 100644 index 0000000000..3db64fea1c --- /dev/null +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Interfaces/AltCustVATRegAdvCZZ.Interface.al @@ -0,0 +1,34 @@ +// ------------------------------------------------------------------------------------------------ +// 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; + +/// +/// The interfaces provides methods to handle the alternative customer VAT registration in the advance letter. +/// +interface "Alt. Cust. VAT Reg. Adv. CZZ" +{ + Access = Public; + + /// + /// Initializes the VAT registration data taken from the alternative customer registration in the sales advance letter header. + /// + /// The current sales advance letter header record + /// The previous version of the record + procedure Init(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; xSalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ") + + /// + /// Copies the VAT registration data from the customer to the sales advance letter header. + /// + /// The current sales advance letter header record + /// The previous version of the record + procedure CopyFromCustomer(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; xSalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ") + + /// + /// Updates the VAT registration data when the VAT Country/Region Code is changed in the sales advance letter header. + /// + /// The current sales advance letter header record + /// The previous version of the record + procedure UpdateSetupOnVATCountryChangeInSalesAdvLetterHeader(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; xSalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ") +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/PurchaseInvoiceCZZ.PageExt.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/PurchaseInvoiceCZZ.PageExt.al index 856392f74d..026cae9704 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/PurchaseInvoiceCZZ.PageExt.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/PurchaseInvoiceCZZ.PageExt.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. // ------------------------------------------------------------------------------------------------ @@ -13,18 +13,6 @@ pageextension 31039 "Purchase Invoice CZZ" extends "Purchase Invoice" { addlast(factboxes) { -#if not CLEAN25 - part("Purch. Adv. Usage FactBox CZZ"; "Purch. Adv. Usage FactBox CZZ") - { - ApplicationArea = Basic, Suite; - Provider = PurchLines; - SubPageLink = "Document Type" = field("Document Type"), "Document No." = field("Document No."), "Line No." = field("Line No."); - Visible = false; - ObsoleteState = Pending; - ObsoleteReason = 'Replaced by "Advance Usage FactBox CZZ"'; - ObsoleteTag = '25.0'; - } -#endif part(AdvanceUsageFactBoxCZZ; "Advance Usage FactBox CZZ") { ApplicationArea = Basic, Suite; @@ -84,4 +72,4 @@ pageextension 31039 "Purchase Invoice CZZ" extends "Purchase Invoice" if GuiAllowed() then CurrPage.AdvanceUsageFactBoxCZZ.Page.SetDocument(Rec); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/PurchaseOrderCZZ.PageExt.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/PurchaseOrderCZZ.PageExt.al index b5a249f15c..db2f9f1a5d 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/PurchaseOrderCZZ.PageExt.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/PurchaseOrderCZZ.PageExt.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. // ------------------------------------------------------------------------------------------------ @@ -26,18 +26,6 @@ pageextension 31037 "Purchase Order CZZ" extends "Purchase Order" } addlast(factboxes) { -#if not CLEAN25 - part("Purch. Adv. Usage FactBox CZZ"; "Purch. Adv. Usage FactBox CZZ") - { - ApplicationArea = Basic, Suite; - Provider = PurchLines; - SubPageLink = "Document Type" = field("Document Type"), "Document No." = field("Document No."), "Line No." = field("Line No."); - Visible = false; - ObsoleteState = Pending; - ObsoleteReason = 'Replaced by "Advance Usage FactBox CZZ"'; - ObsoleteTag = '25.0'; - } -#endif part(AdvanceUsageFactBoxCZZ; "Advance Usage FactBox CZZ") { ApplicationArea = Basic, Suite; @@ -126,4 +114,4 @@ pageextension 31037 "Purchase Order CZZ" extends "Purchase Order" if GuiAllowed() then CurrPage.AdvanceUsageFactBoxCZZ.Page.SetDocument(Rec); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/SalesInvoiceCZZ.PageExt.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/SalesInvoiceCZZ.PageExt.al index 04719299c1..e43f4df257 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/SalesInvoiceCZZ.PageExt.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/SalesInvoiceCZZ.PageExt.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. // ------------------------------------------------------------------------------------------------ @@ -13,18 +13,6 @@ pageextension 31027 "Sales Invoice CZZ" extends "Sales Invoice" { addlast(factboxes) { -#if not CLEAN25 - part("Sales Adv. Usage FactBox CZZ"; "Sales Adv. Usage FactBox CZZ") - { - ApplicationArea = Basic, Suite; - Provider = SalesLines; - SubPageLink = "Document Type" = field("Document Type"), "Document No." = field("Document No."), "Line No." = field("Line No."); - Visible = false; - ObsoleteState = Pending; - ObsoleteReason = 'Replaced by "Advance Usage FactBox CZZ"'; - ObsoleteTag = '25.0'; - } -#endif part(AdvanceUsageFactBoxCZZ; "Advance Usage FactBox CZZ") { ApplicationArea = Basic, Suite; @@ -83,4 +71,4 @@ pageextension 31027 "Sales Invoice CZZ" extends "Sales Invoice" if GuiAllowed() then CurrPage.AdvanceUsageFactBoxCZZ.Page.SetDocument(Rec); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/SalesOrderCZZ.PageExt.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/SalesOrderCZZ.PageExt.al index b4a9deab85..5273017c71 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/SalesOrderCZZ.PageExt.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/PageExtensions/SalesOrderCZZ.PageExt.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. // ------------------------------------------------------------------------------------------------ @@ -50,18 +50,6 @@ pageextension 31023 "Sales Order CZZ" extends "Sales Order" } addlast(factboxes) { -#if not CLEAN25 - part("Sales Adv. Usage FactBox CZZ"; "Sales Adv. Usage FactBox CZZ") - { - ApplicationArea = Basic, Suite; - Provider = SalesLines; - SubPageLink = "Document Type" = field("Document Type"), "Document No." = field("Document No."), "Line No." = field("Line No."); - Visible = false; - ObsoleteState = Pending; - ObsoleteReason = 'Replaced by "Advance Usage FactBox CZZ"'; - ObsoleteTag = '25.0'; - } -#endif part(AdvanceUsageFactBoxCZZ; "Advance Usage FactBox CZZ") { ApplicationArea = Basic, Suite; @@ -154,4 +142,4 @@ pageextension 31023 "Sales Order CZZ" extends "Sales Order" if GuiAllowed() then CurrPage.AdvanceUsageFactBoxCZZ.Page.SetDocument(Rec); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/PurchAdvUsageFactBoxCZZ.Page.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/PurchAdvUsageFactBoxCZZ.Page.al deleted file mode 100644 index e1e1f05657..0000000000 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/PurchAdvUsageFactBoxCZZ.Page.al +++ /dev/null @@ -1,161 +0,0 @@ -#if not CLEAN25 -// ------------------------------------------------------------------------------------------------ -// 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.VAT.Calculation; -using Microsoft.Purchases.Document; -using Microsoft.Purchases.Posting; - -page 31189 "Purch. Adv. Usage FactBox CZZ" -{ - Caption = 'Purchase Advance Usage'; - PageType = CardPart; - SourceTable = "Purchase Line"; - ObsoleteState = Pending; - ObsoleteReason = 'This page will be removed in a future release. Use the "Advance Usage FactBox CZZ" page instead.'; - ObsoleteTag = '25.0'; - - layout - { - area(Content) - { - field(AdvanceCount; AdvanceCount) - { - ApplicationArea = Basic, Suite; - Caption = 'Advances Count'; - ToolTip = 'Specifies advances count.'; - DrillDown = true; - - trigger OnDrillDown() - var - PurchAdvLetterManagement: Codeunit "PurchAdvLetterManagement CZZ"; - begin - PurchAdvLetterManagement.LinkAdvanceLetter( - PurchaseHeader.GetAdvLetterUsageDocTypeCZZ(), PurchaseHeader."No.", PurchaseHeader."Pay-to Vendor No.", - PurchaseHeader."Posting Date", PurchaseHeader."Currency Code"); - CurrPage.Update(); - end; - } - field(AdvanceAmountToUse; AdvanceAmountToUse) - { - ApplicationArea = Basic, Suite; - Caption = 'Advances Amount to Use'; - ToolTip = 'Specifies advances total amount to use.'; - } - field(AdvanceAmountToUseLCY; AdvanceAmountToUseLCY) - { - ApplicationArea = Basic, Suite; - Caption = 'Advances Amount to Use (LCY)'; - ToolTip = 'Specifies advances total amount (LCY) to use.'; - Visible = false; - } - field(AdvanceAmount; AdvanceAmountAssigned) - { - ApplicationArea = Basic, Suite; - Caption = 'Advances Amount Assigned'; - ToolTip = 'Specifies advances assigned amount.'; - } - field(AdvanceAmountLCY; AdvanceAmountAssignedLCY) - { - ApplicationArea = Basic, Suite; - Caption = 'Advances Amount Assigned (LCY)'; - ToolTip = 'Specifies advances assigned amount (LCY).'; - Visible = false; - } - field(DocumentAmount; TotalAmountInclVAT - AdvanceAmountAssigned) - { - ApplicationArea = Basic, Suite; - Caption = 'Amount with Advance Letters'; - ToolTip = 'Specifies total amount with advance letters.'; - Style = Strong; - } - field(AdvanceVATLineCount; AdvanceVATLineCount) - { - ApplicationArea = Basic, Suite; - Caption = 'Advances VAT Lines Count'; - ToolTip = 'Specifies advances VAT lines count.'; - DrillDown = true; - - trigger OnDrillDown() - begin - Page.RunModal(Page::"Pur. Adv. Letter Ent.Prev. CZZ", TempPurchAdvLetterEntryCZZ); - end; - } - } - } - - var - TempPurchAdvLetterEntryCZZ: Record "Purch. Adv. Letter Entry CZZ" temporary; - PurchaseHeader: Record "Purchase Header"; - PurchAdvLetterManagementCZZ: Codeunit "PurchAdvLetterManagement CZZ"; - AdvanceCount, AdvanceVATLineCount : Integer; - AdvanceAmountAssigned, AdvanceAmountAssignedLCY, AdvanceAmountToUse, AdvanceAmountToUseLCY, TotalAmountInclVAT : Decimal; - - trigger OnAfterGetCurrRecord() - var - AdvanceLetterApplication: Record "Advance Letter Application CZZ"; - TempAdvanceLetterApplication: Record "Advance Letter Application CZZ" temporary; - TempPurchaseLine: Record "Purchase Line" temporary; - TempVATAmountLine: Record "VAT Amount Line" temporary; - PurchPost: Codeunit "Purch.-Post"; - CurrFactor: Decimal; - IsHandled: Boolean; - begin - OnBeforeOnAfterGetCurrRecord(Rec, IsHandled); - if IsHandled then - exit; - - if (not (Rec."Document Type" in [Rec."Document Type"::Order, Rec."Document Type"::Invoice])) or (Rec."Document No." = '') then begin - AdvanceCount := 0; - AdvanceVATLineCount := 0; - AdvanceAmountAssigned := 0; - AdvanceAmountAssignedLCY := 0; - TotalAmountInclVAT := 0; - if not TempPurchAdvLetterEntryCZZ.IsEmpty() then - TempPurchAdvLetterEntryCZZ.DeleteAll(); - Clear(PurchaseHeader); - exit; - end; - - PurchaseHeader.Get(Rec."Document Type", Rec."Document No."); - AdvanceLetterApplication.GetAssignedAdvance( - PurchaseHeader.GetAdvLetterUsageDocTypeCZZ(), PurchaseHeader."No.", TempAdvanceLetterApplication); - - CurrFactor := PurchaseHeader."Currency Factor"; - if CurrFactor = 0 then - CurrFactor := 1; - - PurchPost.GetPurchLines(PurchaseHeader, TempPurchaseLine, 1); - TempPurchaseLine.CalcVATAmountLines(1, PurchaseHeader, TempPurchaseLine, TempVATAmountLine); - TotalAmountInclVAT := TempVATAmountLine.GetTotalAmountInclVAT(); - - AdvanceCount := TempAdvanceLetterApplication.Count(); - TempAdvanceLetterApplication.CalcSums(Amount, "Amount to Use"); - if TempAdvanceLetterApplication.Amount <= TotalAmountInclVAT then - AdvanceAmountAssigned := TempAdvanceLetterApplication.Amount - else - AdvanceAmountAssigned := TotalAmountInclVAT; - if TempAdvanceLetterApplication."Amount to Use" <= TotalAmountInclVAT then - AdvanceAmountToUse := TempAdvanceLetterApplication."Amount to Use" - else - AdvanceAmountToUse := TotalAmountInclVAT; - AdvanceAmountAssignedLCY := Round(AdvanceAmountAssigned / CurrFactor); - AdvanceAmountToUseLCY := Round(AdvanceAmountToUse / CurrFactor); - - PurchAdvLetterManagementCZZ.PostAdvancePaymentUsagePreview(PurchaseHeader, AdvanceAmountAssigned, AdvanceAmountAssignedLCY, TempPurchAdvLetterEntryCZZ); - TempPurchAdvLetterEntryCZZ.SetFilter("Entry Type", '<>%1&<>%2&<>%3', TempPurchAdvLetterEntryCZZ."Entry Type"::"VAT Usage", - TempPurchAdvLetterEntryCZZ."Entry Type"::"VAT Rate", TempPurchAdvLetterEntryCZZ."Entry Type"::"VAT Adjustment"); - TempPurchAdvLetterEntryCZZ.DeleteAll(); - TempPurchAdvLetterEntryCZZ.Reset(); - AdvanceVATLineCount := TempPurchAdvLetterEntryCZZ.Count(); - end; - - [IntegrationEvent(false, false)] - local procedure OnBeforeOnAfterGetCurrRecord(var PurchaseLine: Record "Purchase Line"; var IsHandled: Boolean) - begin - end; -} -#endif \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/PurchAdvanceLetterCZZ.Page.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/PurchAdvanceLetterCZZ.Page.al index 5118c56b29..97f2004fc6 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/PurchAdvanceLetterCZZ.Page.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/PurchAdvanceLetterCZZ.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. // ------------------------------------------------------------------------------------------------ @@ -223,17 +223,6 @@ page 31181 "Purch. Advance Letter CZZ" ApplicationArea = Basic, Suite; ToolTip = 'Specifies if post VAT usage automatically.'; } -#if not CLEAN25 - field("Amount on Iss. Payment Order"; "Amount on Iss. Payment Order") - { - ApplicationArea = Basic, Suite; - ToolTip = 'Specifies amount on issued payment order.'; - Visible = false; - ObsoleteState = Pending; - ObsoleteReason = 'This field is obsolete and will be removed in a future release. The CalcSuggestedAmountToApply function should be used instead.'; - ObsoleteTag = '25.0'; - } -#endif field(SuggestedAmountToApplyCZL; Rec.CalcSuggestedAmountToApply()) { Caption = 'Suggested Amount to Apply (LCY)'; @@ -421,17 +410,6 @@ page 31181 "Purch. Advance Letter CZZ" ApplicationArea = Basic, Suite; SubPageLink = "No." = field("Pay-to Vendor No."); } -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = Basic, Suite; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Purch. Adv. Letter Header CZZ"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = Basic, Suite; @@ -958,4 +936,4 @@ page 31181 "Purch. Advance Letter CZZ" OpenApprovalEntriesExistForCurrUser := ApprovalsMgmt.HasOpenApprovalEntriesForCurrentUser(Rec.RecordId); OpenApprovalEntriesExist := ApprovalsMgmt.HasOpenApprovalEntries(Rec.RecordId); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/PurchAdvanceLettersCZZ.Page.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/PurchAdvanceLettersCZZ.Page.al index 06b96ed175..4299638c8a 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/PurchAdvanceLettersCZZ.Page.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/PurchAdvanceLettersCZZ.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. // ------------------------------------------------------------------------------------------------ @@ -164,17 +164,6 @@ page 31180 "Purch. Advance Letters CZZ" ToolTip = 'Specifies whether VAT document will be posted automatically.'; Visible = false; } -#if not CLEAN25 - field("Amount on Iss. Payment Order"; "Amount on Iss. Payment Order") - { - ApplicationArea = Basic, Suite; - ToolTip = 'Specifies amount on issued payment order.'; - Visible = false; - ObsoleteState = Pending; - ObsoleteReason = 'This field is obsolete and will be removed in a future release. The CalcSuggestedAmountToApply function should be used instead.'; - ObsoleteTag = '25.0'; - } -#endif field(SuggestedAmountToApplyCZL; Rec.CalcSuggestedAmountToApply()) { Caption = 'Suggested Amount to Apply (LCY)'; @@ -220,17 +209,6 @@ page 31180 "Purch. Advance Letters CZZ" ApplicationArea = Basic, Suite; SubPageLink = "No." = field("Pay-to Vendor No."); } -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = Basic, Suite; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Purch. Adv. Letter Header CZZ"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = Basic, Suite; @@ -498,4 +476,4 @@ page 31180 "Purch. Advance Letters CZZ" begin CurrPage.IncomingDocAttachFactBox.Page.LoadDataFromRecord(Rec); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/SalesAdvUsageFactBoxCZZ.Page.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/SalesAdvUsageFactBoxCZZ.Page.al deleted file mode 100644 index 7ca5ea2925..0000000000 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/SalesAdvUsageFactBoxCZZ.Page.al +++ /dev/null @@ -1,161 +0,0 @@ -#if not CLEAN25 -// ------------------------------------------------------------------------------------------------ -// 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.VAT.Calculation; -using Microsoft.Sales.Document; -using Microsoft.Sales.Posting; - -page 31187 "Sales Adv. Usage FactBox CZZ" -{ - Caption = 'Sales Advance Usage'; - PageType = CardPart; - SourceTable = "Sales Line"; - ObsoleteState = Pending; - ObsoleteReason = 'This page will be removed in a future release. Use the "Advance Usage FactBox CZZ" page instead.'; - ObsoleteTag = '25.0'; - - layout - { - area(Content) - { - field(AdvanceCount; AdvanceCount) - { - ApplicationArea = Basic, Suite; - Caption = 'Advances Count'; - ToolTip = 'Specifies advances count.'; - DrillDown = true; - - trigger OnDrillDown() - var - SalesAdvLetterManagement: Codeunit "SalesAdvLetterManagement CZZ"; - begin - SalesAdvLetterManagement.LinkAdvanceLetter( - SalesHeader.GetAdvLetterUsageDocTypeCZZ(), SalesHeader."No.", SalesHeader."Bill-to Customer No.", - SalesHeader."Posting Date", SalesHeader."Currency Code"); - CurrPage.Update(); - end; - } - field(AdvanceAmountToUse; AdvanceAmountToUse) - { - ApplicationArea = Basic, Suite; - Caption = 'Advances Amount to Use'; - ToolTip = 'Specifies advances total amount to use.'; - } - field(AdvanceAmountToUseLCY; AdvanceAmountToUseLCY) - { - ApplicationArea = Basic, Suite; - Caption = 'Advances Amount to Use (LCY)'; - ToolTip = 'Specifies advances total amount (LCY) to use.'; - Visible = false; - } - field(AdvanceAmount; AdvanceAmountAssigned) - { - ApplicationArea = Basic, Suite; - Caption = 'Advances Amount'; - ToolTip = 'Specifies advances assigned amount.'; - } - field(AdvanceAmountLCY; AdvanceAmountAssignedLCY) - { - ApplicationArea = Basic, Suite; - Caption = 'Advances Amount (LCY)'; - ToolTip = 'Specifies advances assigned amount (LCY).'; - Visible = false; - } - field(DocumentAmount; TotalAmountInclVAT - AdvanceAmountAssigned) - { - ApplicationArea = Basic, Suite; - Caption = 'Amount with Advance Letters'; - ToolTip = 'Specifies total amount with advance letters.'; - Style = Strong; - } - field(AdvanceVATLineCount; AdvanceVATLineCount) - { - ApplicationArea = Basic, Suite; - Caption = 'Advances VAT Lines Count'; - ToolTip = 'Specifies advances VAT lines count.'; - DrillDown = true; - - trigger OnDrillDown() - begin - Page.RunModal(Page::"Sal. Adv. Letter Ent.Prev. CZZ", TempSalesAdvLetterEntryCZZ); - end; - } - } - } - - var - TempSalesAdvLetterEntryCZZ: Record "Sales Adv. Letter Entry CZZ" temporary; - SalesHeader: Record "Sales Header"; - SalesAdvLetterManagementCZZ: Codeunit "SalesAdvLetterManagement CZZ"; - AdvanceCount, AdvanceVATLineCount : Integer; - AdvanceAmountAssigned, AdvanceAmountAssignedLCY, AdvanceAmountToUse, AdvanceAmountToUseLCY, TotalAmountInclVAT : Decimal; - - trigger OnAfterGetCurrRecord() - var - AdvanceLetterApplication: Record "Advance Letter Application CZZ"; - TempAdvanceLetterApplication: Record "Advance Letter Application CZZ" temporary; - TempSalesLine: Record "Sales Line" temporary; - TempVATAmountLine: Record "VAT Amount Line" temporary; - SalesPost: Codeunit "Sales-Post"; - CurrFactor: Decimal; - IsHandled: Boolean; - begin - OnBeforeOnAfterGetCurrRecord(Rec, IsHandled); - if IsHandled then - exit; - - if (not (Rec."Document Type" in [Rec."Document Type"::Order, Rec."Document Type"::Invoice])) or (Rec."Document No." = '') then begin - AdvanceCount := 0; - AdvanceVATLineCount := 0; - AdvanceAmountAssigned := 0; - AdvanceAmountAssignedLCY := 0; - TotalAmountInclVAT := 0; - if not TempSalesAdvLetterEntryCZZ.IsEmpty() then - TempSalesAdvLetterEntryCZZ.DeleteAll(); - Clear(SalesHeader); - exit; - end; - - SalesHeader.Get(Rec."Document Type", Rec."Document No."); - AdvanceLetterApplication.GetAssignedAdvance( - SalesHeader.GetAdvLetterUsageDocTypeCZZ(), SalesHeader."No.", TempAdvanceLetterApplication); - - CurrFactor := SalesHeader."Currency Factor"; - if CurrFactor = 0 then - CurrFactor := 1; - - SalesPost.GetSalesLines(SalesHeader, TempSalesLine, 1); - TempSalesLine.CalcVATAmountLines(1, SalesHeader, TempSalesLine, TempVATAmountLine); - TotalAmountInclVAT := TempVATAmountLine.GetTotalAmountInclVAT(); - - AdvanceCount := TempAdvanceLetterApplication.Count(); - TempAdvanceLetterApplication.CalcSums(Amount, "Amount to Use"); - if TempAdvanceLetterApplication.Amount <= TotalAmountInclVAT then - AdvanceAmountAssigned := TempAdvanceLetterApplication.Amount - else - AdvanceAmountAssigned := TotalAmountInclVAT; - if TempAdvanceLetterApplication."Amount to Use" <= TotalAmountInclVAT then - AdvanceAmountToUse := TempAdvanceLetterApplication."Amount to Use" - else - AdvanceAmountToUse := TotalAmountInclVAT; - AdvanceAmountAssignedLCY := Round(AdvanceAmountAssigned / CurrFactor); - AdvanceAmountToUseLCY := Round(AdvanceAmountToUse / CurrFactor); - - SalesAdvLetterManagementCZZ.PostAdvancePaymentUsagePreview(SalesHeader, AdvanceAmountAssigned, AdvanceAmountAssignedLCY, TempSalesAdvLetterEntryCZZ); - TempSalesAdvLetterEntryCZZ.SetFilter("Entry Type", '<>%1&<>%2&<>%3', TempSalesAdvLetterEntryCZZ."Entry Type"::"VAT Usage", - TempSalesAdvLetterEntryCZZ."Entry Type"::"VAT Rate", TempSalesAdvLetterEntryCZZ."Entry Type"::"VAT Adjustment"); - TempSalesAdvLetterEntryCZZ.DeleteAll(); - TempSalesAdvLetterEntryCZZ.Reset(); - AdvanceVATLineCount := TempSalesAdvLetterEntryCZZ.Count(); - end; - - [IntegrationEvent(false, false)] - local procedure OnBeforeOnAfterGetCurrRecord(var SalesLine: Record "Sales Line"; var IsHandled: Boolean) - begin - end; -} -#endif \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/SalesAdvanceLetterCZZ.Page.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/SalesAdvanceLetterCZZ.Page.al index 32daa30d34..716453f6e7 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/SalesAdvanceLetterCZZ.Page.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/SalesAdvanceLetterCZZ.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. // ------------------------------------------------------------------------------------------------ @@ -207,6 +207,7 @@ page 31171 "Sales Advance Letter CZZ" { ApplicationArea = Basic, Suite; ToolTip = 'Specifies the country or region of VAT.'; + Importance = Additional; } field("Automatic Post VAT Document"; Rec."Automatic Post VAT Document") { @@ -382,17 +383,6 @@ page 31171 "Sales Advance Letter CZZ" ApplicationArea = Basic, Suite; SubPageLink = "No." = field("Bill-to Customer No."); } -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = Basic, Suite; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Sales Adv. Letter Header CZZ"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = Basic, Suite; @@ -930,4 +920,4 @@ page 31171 "Sales Advance Letter CZZ" OpenApprovalEntriesExistForCurrUser := ApprovalsMgmt.HasOpenApprovalEntriesForCurrentUser(Rec.RecordId); OpenApprovalEntriesExist := ApprovalsMgmt.HasOpenApprovalEntries(Rec.RecordId); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/SalesAdvanceLettersCZZ.Page.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/SalesAdvanceLettersCZZ.Page.al index 7692355b3c..7c546e83f0 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/SalesAdvanceLettersCZZ.Page.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/SalesAdvanceLettersCZZ.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. // ------------------------------------------------------------------------------------------------ @@ -189,17 +189,6 @@ page 31170 "Sales Advance Letters CZZ" ApplicationArea = Basic, Suite; SubPageLink = "No." = field("Bill-to Customer No."); } -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = Basic, Suite; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Sales Adv. Letter Header CZZ"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = Basic, Suite; @@ -486,4 +475,4 @@ page 31170 "Sales Advance Letters CZZ" begin CurrPage.IncomingDocAttachFactBox.Page.LoadDataFromRecord(Rec); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Permissions/CZAdvancePaymentsObjCZZ.PermissionSet.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Permissions/CZAdvancePaymentsObjCZZ.PermissionSet.al index ba3e113ec5..9d36d4e908 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Permissions/CZAdvancePaymentsObjCZZ.PermissionSet.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Permissions/CZAdvancePaymentsObjCZZ.PermissionSet.al @@ -70,11 +70,6 @@ permissionset 11752 "CZ Advance Payments - Obj. CZZ" Page "Purch. Advance Letters CZZ" = X, Page "Purch. Adv. Letter Entries CZZ" = X, Page "Purch. Adv. Letter FactBox CZZ" = X, -#if not CLEAN25 -#pragma warning disable AL0432 - Page "Purch. Adv. Usage FactBox CZZ" = X, -#pragma warning restore AL0432 -#endif Page "Sal. Adv. Letter Ent.Prev. CZZ" = X, Page "Sales Advance Letter CZZ" = X, Page "Sales Advance Letter Line CZZ" = X, @@ -82,11 +77,6 @@ permissionset 11752 "CZ Advance Payments - Obj. CZZ" Page "Sales Advance Letters CZZ" = X, Page "Sales Adv. Letter Entries CZZ" = X, Page "Sales Adv. Letter FactBox CZZ" = X, -#if not CLEAN25 -#pragma warning disable AL0432 - Page "Sales Adv. Usage FactBox CZZ" = X, -#pragma warning restore AL0432 -#endif Page "Suggested Usage CZZ" = X, Page "VAT Document CZZ" = X, Page "VAT Document Line CZZ" = X, @@ -115,4 +105,4 @@ permissionset 11752 "CZ Advance Payments - Obj. CZZ" Table "Sales Adv. Letter Entry CZZ" = X, Table "Sales Adv. Letter Header CZZ" = X, Table "Sales Adv. Letter Line CZZ" = X; -} +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/TableExtensions/GenJournalLineCZZ.TableExt.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/TableExtensions/GenJournalLineCZZ.TableExt.al index 57f874d243..48cbb57fea 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/TableExtensions/GenJournalLineCZZ.TableExt.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/TableExtensions/GenJournalLineCZZ.TableExt.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. // ------------------------------------------------------------------------------------------------ @@ -163,16 +163,11 @@ tableextension 31004 "Gen. Journal Line CZZ" extends "Gen. Journal Line" begin "Source Currency Code" := SalesAdvLetterHeaderCZZ."Currency Code"; "Bill-to/Pay-to No." := SalesAdvLetterHeaderCZZ."Bill-to Customer No."; - "Country/Region Code" := SalesAdvLetterHeaderCZZ."Bill-to Country/Region Code"; + "Country/Region Code" := SalesAdvLetterHeaderCZZ."VAT Country/Region Code"; "VAT Registration No." := SalesAdvLetterHeaderCZZ."VAT Registration No."; "Registration No. CZL" := SalesAdvLetterHeaderCZZ."Registration No."; "Tax Registration No. CZL" := SalesAdvLetterHeaderCZZ."Tax Registration No."; "System-Created Entry" := true; -#if not CLEAN25 -#pragma warning disable AL0432 - OnAfterCopyGenJnlLineFromSalesAdvLetterHeaderCZZ(SalesAdvLetterHeaderCZZ, Rec); -#pragma warning restore AL0432 -#endif OnAfterCopyGenJournalLineFromSalesAdvLetterHeaderCZZ(SalesAdvLetterHeaderCZZ, Rec); end; @@ -182,11 +177,6 @@ tableextension 31004 "Gen. Journal Line CZZ" extends "Gen. Journal Line" "Shortcut Dimension 2 Code" := SalesAdvLetterEntryCZZ."Global Dimension 2 Code"; "Dimension Set ID" := SalesAdvLetterEntryCZZ."Dimension Set ID"; "Adv. Letter No. (Entry) CZZ" := SalesAdvLetterEntryCZZ."Sales Adv. Letter No."; -#if not CLEAN25 -#pragma warning disable AL0432 - OnAfterCopyGenJnlLineFromSalesAdvLetterEntryCZZ(SalesAdvLetterEntryCZZ, Rec); -#pragma warning restore AL0432 -#endif OnAfterCopyGenJournalLineFromSalesAdvLetterEntryCZZ(SalesAdvLetterEntryCZZ, Rec); end; @@ -194,7 +184,7 @@ tableextension 31004 "Gen. Journal Line CZZ" extends "Gen. Journal Line" begin "Source Currency Code" := PurchAdvLetterHeaderCZZ."Currency Code"; "Bill-to/Pay-to No." := PurchAdvLetterHeaderCZZ."Pay-to Vendor No."; - "Country/Region Code" := PurchAdvLetterHeaderCZZ."Pay-to Country/Region Code"; + "Country/Region Code" := PurchAdvLetterHeaderCZZ."VAT Country/Region Code"; "VAT Registration No." := PurchAdvLetterHeaderCZZ."VAT Registration No."; "Registration No. CZL" := PurchAdvLetterHeaderCZZ."Registration No."; "Tax Registration No. CZL" := PurchAdvLetterHeaderCZZ."Tax Registration No."; @@ -310,19 +300,6 @@ tableextension 31004 "Gen. Journal Line CZZ" extends "Gen. Journal Line" local procedure OnAfterInitNewLineCZZ(var GenJournalLine: Record "Gen. Journal Line") begin end; -#if not CLEAN25 - [Obsolete('Replaced by OnAfterCopyGenJournalLineFromSalesAdvLetterHeaderCZZ event.', '25.0')] - [IntegrationEvent(false, false)] - local procedure OnAfterCopyGenJnlLineFromSalesAdvLetterHeaderCZZ(SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; Rec: Record "Gen. Journal Line") - begin - end; - - [Obsolete('Replaced by OnAfterCopyGenJournalLineFromSalesAdvLetterEntryCZZ event.', '25.0')] - [IntegrationEvent(false, false)] - local procedure OnAfterCopyGenJnlLineFromSalesAdvLetterEntryCZZ(SalesAdvLetterEntryCZZ: Record "Sales Adv. Letter Entry CZZ"; Rec: Record "Gen. Journal Line") - begin - end; -#endif [IntegrationEvent(false, false)] local procedure OnAfterCopyGenJournalLineFromSalesAdvLetterHeaderCZZ(SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; var GenJournalLine: Record "Gen. Journal Line") @@ -363,4 +340,4 @@ tableextension 31004 "Gen. Journal Line CZZ" extends "Gen. Journal Line" local procedure OnAfterCopyFromVendorLedgerEntryCZZ(VendorLedgerEntry: Record "Vendor Ledger Entry"; var GenJournalLine: Record "Gen. Journal Line") begin end; -} +} \ No newline at end of file diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/TableExtensions/VATSetupCZZ.TableExt.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/TableExtensions/VATSetupCZZ.TableExt.al index d5c0ac318e..cfeaa3e1d5 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/TableExtensions/VATSetupCZZ.TableExt.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/TableExtensions/VATSetupCZZ.TableExt.al @@ -16,5 +16,10 @@ tableextension 31059 "VAT Setup CZZ" extends "VAT Setup" DataClassification = CustomerContent; ToolTip = 'Specifies if the non-deductible VAT will be used in purchase advances.'; } + field(31005; "Alt. Cust. VAT Reg. Adv. CZZ"; Enum "Alt. Cust. VAT Reg. Adv. CZZ") + { + Caption = 'Alt. Cust. VAT Reg. Adv.'; + DataClassification = CustomerContent; + } } } diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/PurchAdvLetterHeaderCZZ.Table.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/PurchAdvLetterHeaderCZZ.Table.al index 2b02f86442..d94c3f78fa 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/PurchAdvLetterHeaderCZZ.Table.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/PurchAdvLetterHeaderCZZ.Table.al @@ -5,9 +5,6 @@ namespace Microsoft.Finance.AdvancePayments; using Microsoft.Bank.BankAccount; -#if not CLEAN25 -using Microsoft.Bank.Documents; -#endif using Microsoft.Bank.Setup; using Microsoft.CRM.BusinessRelation; using Microsoft.CRM.Contact; @@ -837,18 +834,6 @@ table 31008 "Purch. Adv. Letter Header CZZ" IncomingDocument.SetPurchaseAdvanceCZZ(Rec); end; } -#if not CLEAN25 - field(31040; "Amount on Iss. Payment Order"; Decimal) - { - Caption = 'Amount on Issued Payment Order'; - FieldClass = FlowField; - CalcFormula = sum("Iss. Payment Order Line CZB".Amount where("Purch. Advance Letter No. CZZ" = field("No."))); - Editable = false; - ObsoleteState = Pending; - ObsoleteReason = 'This field is obsolete and will be removed in a future release. The CalcSuggestedAmountToApply function should be used instead.'; - ObsoleteTag = '25.0'; - } -#endif field(31112; "Original Document VAT Date"; Date) { Caption = 'Original Document VAT Date'; diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/SalesAdvLetterHeaderCZZ.Table.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/SalesAdvLetterHeaderCZZ.Table.al index 5cd740036d..b7c26fc793 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/SalesAdvLetterHeaderCZZ.Table.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/SalesAdvLetterHeaderCZZ.Table.al @@ -89,9 +89,10 @@ table 31004 "Sales Adv. Letter Header CZZ" Confirmed := true else Confirmed := Confirm(ConfirmChangeQst, false, FieldCaption("Bill-to Customer No.")); - if Confirmed then - OnValidateBillToCustomerNoOnAfterConfirmed(Rec) - else + if Confirmed then begin + OnValidateBillToCustomerNoOnAfterConfirmed(Rec); + AltCustVATRegFacadeCZZ.Init(Rec, xRec); + end else "Bill-to Customer No." := xRec."Bill-to Customer No."; end; @@ -510,7 +511,7 @@ table 31004 "Sales Adv. Letter Header CZZ" ApplicableCountryCode := Rec."VAT Country/Region Code"; if ApplicableCountryCode = '' then ApplicableCountryCode := Customer."Country/Region Code"; - if not VATRegistrationNoFormat.Test("VAT Registration No.", Customer."Country/Region Code", Customer."No.", Database::Customer) then + if not VATRegistrationNoFormat.Test("VAT Registration No.", ApplicableCountryCode, Customer."No.", Database::Customer) then exit; ApplicableCountryCode := Customer."Country/Region Code"; @@ -729,6 +730,11 @@ table 31004 "Sales Adv. Letter Header CZZ" Caption = 'VAT Country/Region Code'; DataClassification = CustomerContent; TableRelation = "Country/Region"; + + trigger OnValidate() + begin + AltCustVATRegFacadeCZZ.UpdateSetupOnVATCountryChangeInSalesAdvLetterHeader(Rec, xRec); + end; } field(80; Status; Enum "Advance Letter Doc. Status CZZ") { @@ -747,6 +753,16 @@ table 31004 "Sales Adv. Letter Header CZZ" TableRelation = "Language Selection"."Language Tag"; DataClassification = CustomerContent; } + field(100; "Alt. VAT Registration No."; Boolean) + { + Caption = 'Alternative VAT Registration No.'; + Editable = false; + } + field(101; "Alt. VAT Bus Posting Group"; Boolean) + { + Caption = 'Alternative VAT Bus. Posting Group'; + Editable = false; + } #pragma warning disable AA0232 field(200; "Amount Including VAT"; Decimal) #pragma warning restore AA0232 @@ -901,6 +917,7 @@ table 31004 "Sales Adv. Letter Header CZZ" Customer: Record Customer; SalespersonPurchaser: Record "Salesperson/Purchaser"; ResponsibilityCenter: Record "Responsibility Center"; + AltCustVATRegFacadeCZZ: Codeunit "Alt. Cust. VAT Reg. Facade CZZ"; DimensionManagement: Codeunit DimensionManagement; UserSetupManagement: Codeunit "User Setup Management"; VATReportingDateMgt: Codeunit "VAT Reporting Date Mgt"; @@ -965,6 +982,8 @@ table 31004 "Sales Adv. Letter Header CZZ" "Posting Description" := AdvanceLbl + ' ' + "No."; "Responsibility Center" := UserSetupManagement.GetRespCenter(0, "Responsibility Center"); + AltCustVATRegFacadeCZZ.Init(Rec, xRec); + OnAfterInitRecord(Rec); end; @@ -1097,6 +1116,11 @@ table 31004 "Sales Adv. Letter Header CZZ" HideValidationDialog := NewHideValidationDialog; end; + procedure GetHideValidationDialog(): Boolean + begin + exit(HideValidationDialog); + end; + local procedure UpdateBankInfo(BankAccountCode: Code[20]; BankAccountNo: Text[30]; BankBranchNo: Text[20]; BankName: Text[100]; TransitNo: Text[20]; IBANCode: Code[50]; SWIFTCode: Code[20]) begin "Bank Account Code" := BankAccountCode; @@ -1843,9 +1867,7 @@ table 31004 "Sales Adv. Letter Header CZZ" IsHandled: Boolean; begin OnBeforeUpdateVATRegNoInCust(Rec, Customer, ShouldUpdate, IsHandled); - if IsHandled then - exit(ShouldUpdate); - exit(Customer."VAT Registration No." = ''); + exit(AltCustVATRegFacadeCZZ.UpdateVATRegNoInCustFromSalesAdvLetterHeader(Rec, Customer)); end; [IntegrationEvent(false, false)] diff --git a/Apps/CZ/AdvancedLocalizationPack/app/Src/Codeunits/GLEntryPostApplicationCZA.Codeunit.al b/Apps/CZ/AdvancedLocalizationPack/app/Src/Codeunits/GLEntryPostApplicationCZA.Codeunit.al index 4c4e84a68e..b652e719a9 100644 --- a/Apps/CZ/AdvancedLocalizationPack/app/Src/Codeunits/GLEntryPostApplicationCZA.Codeunit.al +++ b/Apps/CZ/AdvancedLocalizationPack/app/Src/Codeunits/GLEntryPostApplicationCZA.Codeunit.al @@ -104,8 +104,8 @@ codeunit 31370 "G/L Entry Post Application CZA" TempAppliedGLEntry.Ascending(false); if TempAppliedGLEntry.FindSet(true) then repeat - if (ApplyingGLEntry.Amount > 0) and (TempAppliedGLEntry.Amount < 0) or - (ApplyingGLEntry.Amount < 0) and (TempAppliedGLEntry.Amount > 0) + if (ApplyingGLEntry.Amount >= 0) and (TempAppliedGLEntry.Amount < 0) or + (ApplyingGLEntry.Amount <= 0) and (TempAppliedGLEntry.Amount > 0) then begin TempAppliedGLEntry.CalcFields("Applied Amount CZA"); if (ApplyingAmount <> 0) and @@ -121,8 +121,8 @@ codeunit 31370 "G/L Entry Post Application CZA" TempAppliedGLEntry.SetFilter("Amount to Apply CZA", '<>0'); if TempAppliedGLEntry.FindSet(true) then repeat - if (ApplyingGLEntry.Amount > 0) and (TempAppliedGLEntry.Amount < 0) or - (ApplyingGLEntry.Amount < 0) and (TempAppliedGLEntry.Amount > 0) + if (ApplyingGLEntry.Amount >= 0) and (TempAppliedGLEntry.Amount < 0) or + (ApplyingGLEntry.Amount <= 0) and (TempAppliedGLEntry.Amount > 0) then begin SetAmountToApply(TempAppliedGLEntry, ApplyingAmount); TempAppliedGLEntry.Modify(); diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/CrossApplicationHandlerCZB.Codeunit.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/CrossApplicationHandlerCZB.Codeunit.al index 1008a489ad..d5f0defb7b 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/CrossApplicationHandlerCZB.Codeunit.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/CrossApplicationHandlerCZB.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. // ------------------------------------------------------------------------------------------------ @@ -11,13 +11,7 @@ using Microsoft.Sales.Receivables; codeunit 31416 "Cross Application Handler CZB" { -#if not CLEAN25 - ObsoleteState = Pending; - ObsoleteReason = 'The Access property will be changed to Internal.'; - ObsoleteTag = '25.0'; -#else Access = Internal; -#endif [EventSubscriber(ObjectType::Codeunit, Codeunit::"Cross Application Mgt. CZL", 'OnCollectSuggestedApplication', '', false, false)] local procedure AddIssPaymentOrderLineCZBOnCollectSuggestedApplication( @@ -110,4 +104,4 @@ codeunit 31416 "Cross Application Handler CZB" CrossApplicationBufferCZL.RemoveDocument( TableID, IssPaymentOrderLine."Payment Order No.", IssPaymentOrderLine."Line No."); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementCZB.Page.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementCZB.Page.al index 5742e266a7..a5e9f0ef9d 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementCZB.Page.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementCZB.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. // ------------------------------------------------------------------------------------------------ @@ -161,17 +161,6 @@ page 31254 "Bank Statement CZB" } area(FactBoxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Bank Statement Header CZB"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -531,4 +520,4 @@ page 31254 "Bank Statement CZB" CurrPage.SetSelectionFilter(BankStatementHeaderCZB); BankStatementHeaderCZB.TestPrintRecords(true); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementsCZB.Page.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementsCZB.Page.al index 6d1ee7cd67..c5bfe4e817 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementsCZB.Page.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementsCZB.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. // ------------------------------------------------------------------------------------------------ @@ -72,17 +72,6 @@ page 31253 "Bank Statements CZB" } area(FactBoxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Bank Statement Header CZB"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -404,4 +393,4 @@ page 31253 "Bank Statements CZB" CurrPage.SetSelectionFilter(BankStatementHeaderCZB); BankStatementHeaderCZB.TestPrintRecords(true); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssBankStatementCZB.Page.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssBankStatementCZB.Page.al index d38c1bb2a5..c9c9df56ad 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssBankStatementCZB.Page.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssBankStatementCZB.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. // ------------------------------------------------------------------------------------------------ @@ -137,17 +137,6 @@ page 31258 "Iss. Bank Statement CZB" } area(FactBoxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Iss. Bank Statement Header CZB"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -379,4 +368,4 @@ page 31258 "Iss. Bank Statement CZB" IssBankStatementHeaderCZB.SetRecFilter(); exit(IssBankStatementHeaderCZB.IsCreatedJournal(true, InstructionMgt.IsEnabled(InstructionMgtCZB.ShowCreatedJnlIssBankStmtConfirmationMessageCode()))); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssBankStatementsCZB.Page.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssBankStatementsCZB.Page.al index 998ceedb8b..5771c0335b 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssBankStatementsCZB.Page.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssBankStatementsCZB.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. // ------------------------------------------------------------------------------------------------ @@ -78,17 +78,6 @@ page 31257 "Iss. Bank Statements CZB" } area(FactBoxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Iss. Bank Statement Header CZB"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -311,4 +300,4 @@ page 31257 "Iss. Bank Statements CZB" IssBankStatementHeaderCZB.SetRecFilter(); exit(IssBankStatementHeaderCZB.IsCreatedJournal(true, InstructionMgt.IsEnabled(InstructionMgtCZB.ShowCreatedJnlIssBankStmtConfirmationMessageCode()))); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssPaymentOrderCZB.Page.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssPaymentOrderCZB.Page.al index 228a2085ad..5310bafc12 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssPaymentOrderCZB.Page.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssPaymentOrderCZB.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. // ------------------------------------------------------------------------------------------------ @@ -185,17 +185,6 @@ page 31266 "Iss. Payment Order CZB" } area(FactBoxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Iss. Payment Order Header CZB"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -411,4 +400,4 @@ page 31266 "Iss. Payment Order CZB" IssPaymentOrderHeaderCZB.SetRecFilter(); IssPaymentOrderHeaderCZB.PrintRecords(true); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssPaymentOrdersCZB.Page.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssPaymentOrdersCZB.Page.al index 68c6165a73..641203cdfb 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssPaymentOrdersCZB.Page.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/IssPaymentOrdersCZB.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. // ------------------------------------------------------------------------------------------------ @@ -81,17 +81,6 @@ page 31265 "Iss. Payment Orders CZB" } area(FactBoxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Iss. Payment Order Header CZB"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -287,4 +276,4 @@ page 31265 "Iss. Payment Orders CZB" IssPaymentOrderHeaderCZB.SetRecFilter(); IssPaymentOrderHeaderCZB.PrintRecords(true); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrderCZB.Page.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrderCZB.Page.al index e1dd18c842..a374e4e5cd 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrderCZB.Page.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrderCZB.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. // ------------------------------------------------------------------------------------------------ @@ -171,17 +171,6 @@ page 31262 "Payment Order CZB" } area(FactBoxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Payment Order Header CZB"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -718,4 +707,4 @@ page 31262 "Payment Order CZB" OpenApprovalEntriesExistForCurrUser := ApprovalsMgmt.HasOpenApprovalEntriesForCurrentUser(Rec.RecordId); OpenApprovalEntriesExist := ApprovalsMgmt.HasOpenApprovalEntries(Rec.RecordId); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrdersCZB.Page.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrdersCZB.Page.al index e865b1b070..dd285e2239 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrdersCZB.Page.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrdersCZB.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. // ------------------------------------------------------------------------------------------------ @@ -83,17 +83,6 @@ page 31261 "Payment Orders CZB" } area(FactBoxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Payment Order Header CZB"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -566,4 +555,4 @@ page 31261 "Payment Orders CZB" OpenApprovalEntriesExistForCurrUser := ApprovalsMgmt.HasOpenApprovalEntriesForCurrentUser(Rec.RecordId); OpenApprovalEntriesExist := ApprovalsMgmt.HasOpenApprovalEntries(Rec.RecordId); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Reports/SuggestPaymentsCZB.Report.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Reports/SuggestPaymentsCZB.Report.al index 86561f3ee2..a514cf4492 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Reports/SuggestPaymentsCZB.Report.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Reports/SuggestPaymentsCZB.Report.al @@ -267,7 +267,7 @@ report 31280 "Suggest Payments CZB" { ApplicationArea = Basic, Suite; Caption = 'Currency Type'; - OptionCaption = ' ,Payment Order,Bank Account'; + OptionCaption = ' ,Payment Order,Bank Account,All'; ToolTip = 'Specifies used currency code.'; } field(KeepBankCZB; KeepBank) @@ -448,7 +448,7 @@ report 31280 "Suggest Payments CZB" KeepBank, SkipNonWork, UsePaymentDisc, StopPayments, SkipBlocked, IsSkippedBlocked, DialogOpen : Boolean; LineNo: Integer; CustomerNoFilter, VendorNoFilter, EmployeeNoFilter : Text; - CurrencyType: Option " ","Payment Order","Bank Account"; + CurrencyType: Option " ","Payment Order","Bank Account",All; procedure SetPaymentOrder(NewPaymentOrderHeaderCZB: Record "Payment Order Header CZB") begin @@ -458,22 +458,22 @@ report 31280 "Suggest Payments CZB" procedure AddCustLedgEntry(CustLedgerEntry: Record "Cust. Ledger Entry") begin PaymentOrderLineCZB.Init(); - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Payment Order No.", PaymentOrderHeaderCZB."No."); + PaymentOrderLineCZB.Validate("Payment Order No.", PaymentOrderHeaderCZB."No."); PaymentOrderLineCZB."Line No." := LineNo; LineNo += 10000; PaymentOrderLineCZB.Type := PaymentOrderLineCZB.Type::Customer; case CurrencyType of CurrencyType::" ": if PaymentOrderLineCZB."Payment Order Currency Code" <> CustLedgerEntry."Currency Code" then - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Payment Order Currency Code", CustLedgerEntry."Currency Code"); + PaymentOrderLineCZB.Validate("Payment Order Currency Code", CustLedgerEntry."Currency Code"); CurrencyType::"Payment Order": if PaymentOrderLineCZB."Payment Order Currency Code" <> PaymentOrderHeaderCZB."Payment Order Currency Code" then - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Payment Order Currency Code", PaymentOrderHeaderCZB."Payment Order Currency Code"); + PaymentOrderLineCZB.Validate("Payment Order Currency Code", PaymentOrderHeaderCZB."Payment Order Currency Code"); CurrencyType::"Bank Account": if PaymentOrderLineCZB."Payment Order Currency Code" <> PaymentOrderHeaderCZB."Currency Code" then - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Payment Order Currency Code", PaymentOrderHeaderCZB."Currency Code"); + PaymentOrderLineCZB.Validate("Payment Order Currency Code", PaymentOrderHeaderCZB."Currency Code"); end; - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Applies-to C/V/E Entry No.", CustLedgerEntry."Entry No."); + PaymentOrderLineCZB.Validate("Applies-to C/V/E Entry No.", CustLedgerEntry."Entry No."); if not UsePaymentDisc and PaymentOrderLineCZB."Pmt. Discount Possible" and (PaymentOrderHeaderCZB."Document Date" <= CustLedgerEntry."Pmt. Discount Date") then begin @@ -481,7 +481,7 @@ report 31280 "Suggest Payments CZB" PaymentOrderLineCZB."Pmt. Discount Date" := 0D; PaymentOrderLineCZB."Amount (Paym. Order Currency)" += PaymentOrderLineCZB."Remaining Pmt. Disc. Possible"; PaymentOrderLineCZB."Remaining Pmt. Disc. Possible" := 0; - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Amount (Paym. Order Currency)"); + PaymentOrderLineCZB.Validate("Amount (Paym. Order Currency)"); PaymentOrderLineCZB."Original Amount" := PaymentOrderLineCZB.Amount; PaymentOrderLineCZB."Original Amount (LCY)" := PaymentOrderLineCZB."Amount (LCY)"; PaymentOrderLineCZB."Orig. Amount(Pay.Order Curr.)" := PaymentOrderLineCZB."Amount (Paym. Order Currency)"; @@ -492,22 +492,22 @@ report 31280 "Suggest Payments CZB" procedure AddVendLedgEntry(VendorLedgerEntry: Record "Vendor Ledger Entry") begin PaymentOrderLineCZB.Init(); - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Payment Order No.", PaymentOrderHeaderCZB."No."); + PaymentOrderLineCZB.Validate("Payment Order No.", PaymentOrderHeaderCZB."No."); PaymentOrderLineCZB."Line No." := LineNo; LineNo += 10000; PaymentOrderLineCZB.Type := PaymentOrderLineCZB.Type::Vendor; case CurrencyType of CurrencyType::" ": if PaymentOrderLineCZB."Payment Order Currency Code" <> VendorLedgerEntry."Currency Code" then - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Payment Order Currency Code", VendorLedgerEntry."Currency Code"); + PaymentOrderLineCZB.Validate("Payment Order Currency Code", VendorLedgerEntry."Currency Code"); CurrencyType::"Payment Order": if PaymentOrderLineCZB."Payment Order Currency Code" <> PaymentOrderHeaderCZB."Payment Order Currency Code" then - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Payment Order Currency Code", PaymentOrderHeaderCZB."Payment Order Currency Code"); + PaymentOrderLineCZB.Validate("Payment Order Currency Code", PaymentOrderHeaderCZB."Payment Order Currency Code"); CurrencyType::"Bank Account": if PaymentOrderLineCZB."Payment Order Currency Code" <> PaymentOrderHeaderCZB."Currency Code" then - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Payment Order Currency Code", PaymentOrderHeaderCZB."Currency Code"); + PaymentOrderLineCZB.Validate("Payment Order Currency Code", PaymentOrderHeaderCZB."Currency Code"); end; - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Applies-to C/V/E Entry No.", VendorLedgerEntry."Entry No."); + PaymentOrderLineCZB.Validate("Applies-to C/V/E Entry No.", VendorLedgerEntry."Entry No."); if not UsePaymentDisc and PaymentOrderLineCZB."Pmt. Discount Possible" and (PaymentOrderHeaderCZB."Document Date" <= VendorLedgerEntry."Pmt. Discount Date") then begin @@ -515,7 +515,7 @@ report 31280 "Suggest Payments CZB" PaymentOrderLineCZB."Pmt. Discount Date" := 0D; PaymentOrderLineCZB."Amount (Paym. Order Currency)" -= PaymentOrderLineCZB."Remaining Pmt. Disc. Possible"; PaymentOrderLineCZB."Remaining Pmt. Disc. Possible" := 0; - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Amount (Paym. Order Currency)"); + PaymentOrderLineCZB.Validate("Amount (Paym. Order Currency)"); PaymentOrderLineCZB."Original Amount" := PaymentOrderLineCZB.Amount; PaymentOrderLineCZB."Original Amount (LCY)" := PaymentOrderLineCZB."Amount (LCY)"; PaymentOrderLineCZB."Orig. Amount(Pay.Order Curr.)" := PaymentOrderLineCZB."Amount (Paym. Order Currency)"; @@ -527,13 +527,13 @@ report 31280 "Suggest Payments CZB" procedure AddEmplLedgEntry(EmployeeLedgerEntry: Record "Employee Ledger Entry") begin PaymentOrderLineCZB.Init(); - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Payment Order No.", PaymentOrderHeaderCZB."No."); + PaymentOrderLineCZB.Validate("Payment Order No.", PaymentOrderHeaderCZB."No."); PaymentOrderLineCZB."Line No." := LineNo; LineNo += 10000; PaymentOrderLineCZB.Type := PaymentOrderLineCZB.Type::Employee; if PaymentOrderLineCZB."Payment Order Currency Code" <> EmployeeLedgerEntry."Currency Code" then - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Payment Order Currency Code", EmployeeLedgerEntry."Currency Code"); - PaymentOrderLineCZB.Validate(PaymentOrderLineCZB."Applies-to C/V/E Entry No.", EmployeeLedgerEntry."Entry No."); + PaymentOrderLineCZB.Validate("Payment Order Currency Code", EmployeeLedgerEntry."Currency Code"); + PaymentOrderLineCZB.Validate("Applies-to C/V/E Entry No.", EmployeeLedgerEntry."Entry No."); AddPaymentLine(); end; diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Tables/PaymentOrderLineCZB.Table.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Tables/PaymentOrderLineCZB.Table.al index 9787a702f5..5c23880b6b 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Tables/PaymentOrderLineCZB.Table.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Tables/PaymentOrderLineCZB.Table.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. // ------------------------------------------------------------------------------------------------ @@ -872,13 +872,6 @@ table 31257 "Payment Order Line CZB" PaymentOrderCurrency.Testfield("Amount Rounding Precision"); end; end; -#if not CLEAN25 - [Obsolete('Replaced by CreateDescription function with PlaceholderValues parameter.', '25.0')] - procedure CreateDescription(DocType: Text[30]; DocNo: Text[20]; PartnerNo: Text[20]; PartnerName: Text[100]; ExtNo: Text[35]): Text[50] - begin - exit(CopyStr(StrSubstNo(BankAccount."Payment Order Line Descr. CZB", DocType, DocNo, PartnerNo, PartnerName, ExtNo), 1, 50)); - end; -#endif procedure CreateDescription(PlaceholderValues: List of [Text[100]]) Description: Text[100] var @@ -1278,10 +1271,6 @@ table 31257 "Payment Order Line CZB" CustLedgerEntry: Record "Cust. Ledger Entry"; VendorLedgerEntry: Record "Vendor Ledger Entry"; EmployeeLedgerEntry: Record "Employee Ledger Entry"; -#if not CLEAN25 - CrossApplicationMgtCZL: Codeunit "Cross Application Mgt. CZL"; - AppliesToAdvanceLetterNo: Code[20]; -#endif begin if "No." = '' then exit; @@ -1298,17 +1287,6 @@ table 31257 "Payment Order Line CZB" if EmployeeLedgerEntry.Get("Applies-to C/V/E Entry No.") then EmployeeLedgerEntry.CollectSuggestedApplicationCZL(Rec, CrossApplicationBufferCZL); end; -#if not CLEAN25 -#pragma warning disable AL0432 - if Type = Type::Vendor then begin - OnBeforeFindRelatedAmoutToApply(Rec, AppliesToAdvanceLetterNo); - if AppliesToAdvanceLetterNo <> '' then - CrossApplicationMgtCZL.OnGetSuggestedAmountForPurchAdvLetterHeader( - AppliesToAdvanceLetterNo, CrossApplicationBufferCZL, - Database::"Iss. Payment Order Line CZB", Rec."Payment Order No.", Rec."Line No."); - end; -#pragma warning restore AL0432 -#endif OnAfterCollectSuggestedApplication(Rec, CrossApplicationBufferCZL); end; @@ -1342,14 +1320,6 @@ table 31257 "Payment Order Line CZB" local procedure OnAfterAppliesToEmplLedgEntryNo(var PaymentOrderLineCZB: Record "Payment Order Line CZB"; EmployeeLedgerEntry: Record "Employee Ledger Entry"); begin end; -#if not CLEAN25 - - [Obsolete('The event is obsolete and will be removed in the future version. Use OnAfterCollectSuggestedApplication instead.', '25.0')] - [IntegrationEvent(false, false)] - local procedure OnBeforeFindRelatedAmoutToApply(PaymentOrderLineCZB: Record "Payment Order Line CZB"; var AppliesToAdvanceLetterNo: Code[20]); - begin - end; -#endif [IntegrationEvent(false, false)] local procedure OnAfterCollectSuggestedApplication(PaymentOrderLineCZB: Record "Payment Order Line CZB"; var CrossApplicationBufferCZL: Record "Cross Application Buffer CZL") @@ -1400,4 +1370,4 @@ table 31257 "Payment Order Line CZB" local procedure OnAppliesToCVEEntryNoLookupOnAfterSetEmployeeLedgerEntryFilters(var EmployeeLedgerEntry: Record "Employee Ledger Entry") begin end; -} +} \ No newline at end of file diff --git a/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/CashDeskManagementCZP.Codeunit.al b/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/CashDeskManagementCZP.Codeunit.al index d43510ac5f..fad2ce5a74 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/CashDeskManagementCZP.Codeunit.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/CashDeskManagementCZP.Codeunit.al @@ -85,6 +85,9 @@ codeunit 11724 "Cash Desk Management CZP" CheckCashDesks(); SetCashDeskFilter(CashDeskCZP); + CashDeskCZP.FilterGroup(2); + CashDeskCZP.SetRange(Blocked, false); + CashDeskCZP.FilterGroup(0); case CashDeskCZP.Count() of 0: diff --git a/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/CrossApplicationHandlerCZP.Codeunit.al b/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/CrossApplicationHandlerCZP.Codeunit.al index 26d23a35e4..fefaa58995 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/CrossApplicationHandlerCZP.Codeunit.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/CrossApplicationHandlerCZP.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. // ------------------------------------------------------------------------------------------------ @@ -12,13 +12,7 @@ using Microsoft.Sales.Receivables; codeunit 31417 "Cross Application Handler CZP" { -#if not CLEAN25 - ObsoleteState = Pending; - ObsoleteReason = 'The Access property will be changed to Internal.'; - ObsoleteTag = '25.0'; -#else Access = Internal; -#endif [EventSubscriber(ObjectType::Codeunit, Codeunit::"Cross Application Mgt. CZL", 'OnCollectSuggestedApplication', '', false, false)] local procedure AddCashDocumentLineCZPOnCollectSuggestedApplication( @@ -124,4 +118,4 @@ codeunit 31417 "Cross Application Handler CZP" CrossApplicationBufferCZL.RemoveDocument( TableID, CashDocumentLineCZL."Cash Document No.", CashDocumentLineCZL."Line No."); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/CashDeskLocalization/app/Src/PageExtensions/HumanResourcesSetupCZP.PageExt.al b/Apps/CZ/CashDeskLocalization/app/Src/PageExtensions/HumanResourcesSetupCZP.PageExt.al new file mode 100644 index 0000000000..67dd9ddf3c --- /dev/null +++ b/Apps/CZ/CashDeskLocalization/app/Src/PageExtensions/HumanResourcesSetupCZP.PageExt.al @@ -0,0 +1,18 @@ +// ------------------------------------------------------------------------------------------------ +// 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; + +using Microsoft.HumanResources.Setup; + +pageextension 31278 "Human Resources Setup CZP" extends "Human Resources Setup" +{ + layout + { + modify("Allow Multiple Posting Groups") + { + ToolTip = 'Specifies if to enable checking on assignment an alternative posting group from employee posting group setup for the employee assigned in the general journal and cash document.'; + } + } +} \ No newline at end of file diff --git a/Apps/CZ/CashDeskLocalization/app/Src/PageExtensions/ReconciliationCZP.PageExt.al b/Apps/CZ/CashDeskLocalization/app/Src/PageExtensions/ReconciliationCZP.PageExt.al index 18c53fd194..7b7f7bf069 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/PageExtensions/ReconciliationCZP.PageExt.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/PageExtensions/ReconciliationCZP.PageExt.al @@ -30,15 +30,13 @@ pageextension 31269 "Reconciliation CZP" extends Reconciliation TotalCashDocumentLineCZP: Record "Cash Document Line CZP"; begin TotalCashDocumentLineCZP.SetRange("Cash Document No.", CashDocumentHeaderCZP."No."); - TotalCashDocumentLineCZP.CalcSums(Amount, "VAT Amount", "Amount (LCY)", "VAT Amount (LCY)"); + TotalCashDocumentLineCZP.CalcSums("Amount Including VAT", "Amount Including VAT (LCY)"); GenJournalLine."Account Type" := Enum::"Net Change Account Type CZL"::"Cash Desk CZP"; GenJournalLine."Account No." := CashDocumentHeaderCZP."Cash Desk No."; GenJournalLine."Currency Code" := CashDocumentHeaderCZP."Currency Code"; - GenJournalLine."Amount" := -CashDocumentHeaderCZP.SignAmount() * TotalCashDocumentLineCZP."Amount"; - GenJournalLine."VAT Amount" := -CashDocumentHeaderCZP.SignAmount() * TotalCashDocumentLineCZP."VAT Amount"; - GenJournalLine."Amount (LCY)" := -CashDocumentHeaderCZP.SignAmount() * TotalCashDocumentLineCZP."Amount (LCY)"; - GenJournalLine."VAT Amount (LCY)" := -CashDocumentHeaderCZP.SignAmount() * TotalCashDocumentLineCZP."VAT Amount (LCY)"; + GenJournalLine."Amount" := -CashDocumentHeaderCZP.SignAmount() * TotalCashDocumentLineCZP."Amount Including VAT"; + GenJournalLine."Amount (LCY)" := -CashDocumentHeaderCZP.SignAmount() * TotalCashDocumentLineCZP."Amount Including VAT (LCY)"; end; local procedure PopulateGenJournalLineFrom(CashDocumentHeaderCZP: Record "Cash Document Header CZP"; CashDocumentLineCZP: Record "Cash Document Line CZP") GenJournalLine: Record "Gen. Journal Line" @@ -46,9 +44,9 @@ pageextension 31269 "Reconciliation CZP" extends Reconciliation GenJournalLine."Account Type" := CashDocumentLineCZP.AccountTypeToNetChangeAccountType(); GenJournalLine."Account No." := CashDocumentLineCZP."Account No."; GenJournalLine."Currency Code" := CashDocumentLineCZP."Currency Code"; - GenJournalLine."Amount" := CashDocumentHeaderCZP.SignAmount() * CashDocumentLineCZP."Amount"; + GenJournalLine."Amount" := CashDocumentHeaderCZP.SignAmount() * CashDocumentLineCZP."Amount Including VAT"; GenJournalLine."VAT Amount" := CashDocumentHeaderCZP.SignAmount() * CashDocumentLineCZP."VAT Amount"; - GenJournalLine."Amount (LCY)" := CashDocumentHeaderCZP.SignAmount() * CashDocumentLineCZP."Amount (LCY)"; + GenJournalLine."Amount (LCY)" := CashDocumentHeaderCZP.SignAmount() * CashDocumentLineCZP."Amount Including VAT (LCY)"; GenJournalLine."VAT Amount (LCY)" := CashDocumentHeaderCZP.SignAmount() * CashDocumentLineCZP."VAT Amount (LCY)"; end; } diff --git a/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDeskUsersCZP.Page.al b/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDeskUsersCZP.Page.al index a578c18a7f..66f7650ed2 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDeskUsersCZP.Page.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDeskUsersCZP.Page.al @@ -13,7 +13,8 @@ page 31156 "Cash Desk Users CZP" DelayedInsert = true; PageType = List; SourceTable = "Cash Desk User CZP"; - UsageCategory = None; + UsageCategory = Lists; + ApplicationArea = Basic, Suite; layout { diff --git a/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDocumentCZP.Page.al b/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDocumentCZP.Page.al index eee627af8c..72668af3e4 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDocumentCZP.Page.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDocumentCZP.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. // ------------------------------------------------------------------------------------------------ @@ -268,17 +268,6 @@ page 31160 "Cash Document CZP" } area(factboxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(database::"Cash Document Header CZP"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -969,4 +958,4 @@ page 31160 "Cash Document CZP" local procedure OnAfterUpdateEditable(CashDocumentHeaderCZP: Record "Cash Document Header CZP") begin end; -} +} \ No newline at end of file diff --git a/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDocumentListCZP.Page.al b/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDocumentListCZP.Page.al index 862876cbcf..4533fcf226 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDocumentListCZP.Page.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDocumentListCZP.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. // ------------------------------------------------------------------------------------------------ @@ -91,17 +91,6 @@ page 31162 "Cash Document List CZP" } area(FactBoxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(database::"Cash Document Header CZP"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -461,4 +450,4 @@ page 31162 "Cash Document List CZP" begin CashDocumentPostYesNoCZP.Preview(Rec); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/CashDeskLocalization/app/Src/Pages/PostedCashDocumentCZP.Page.al b/Apps/CZ/CashDeskLocalization/app/Src/Pages/PostedCashDocumentCZP.Page.al index f854767d08..f9eb02e93d 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/Pages/PostedCashDocumentCZP.Page.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/Pages/PostedCashDocumentCZP.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. // ------------------------------------------------------------------------------------------------ @@ -204,17 +204,6 @@ page 31165 "Posted Cash Document CZP" } area(FactBoxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(database::"Posted Cash Document Hdr. CZP"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -365,4 +354,4 @@ page 31165 "Posted Cash Document CZP" } } } -} +} \ No newline at end of file diff --git a/Apps/CZ/CashDeskLocalization/app/Src/Pages/PostedCashDocumentListCZP.Page.al b/Apps/CZ/CashDeskLocalization/app/Src/Pages/PostedCashDocumentListCZP.Page.al index a68576ace8..0a18388dd2 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/Pages/PostedCashDocumentListCZP.Page.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/Pages/PostedCashDocumentListCZP.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. // ------------------------------------------------------------------------------------------------ @@ -80,17 +80,6 @@ page 31167 "Posted Cash Document List CZP" } area(FactBoxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Posted Cash Document Hdr. CZP"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -258,4 +247,4 @@ page 31167 "Posted Cash Document List CZP" var CashDeskManagementCZP: Codeunit "Cash Desk Management CZP"; -} +} \ No newline at end of file diff --git a/Apps/CZ/CashDeskLocalization/app/Src/Tables/CashDocumentLineCZP.Table.al b/Apps/CZ/CashDeskLocalization/app/Src/Tables/CashDocumentLineCZP.Table.al index 620f651de7..1b21aa0719 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/Tables/CashDocumentLineCZP.Table.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/Tables/CashDocumentLineCZP.Table.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. // ------------------------------------------------------------------------------------------------ @@ -828,13 +828,8 @@ table 11733 "Cash Document Line CZP" Caption = 'VAT Difference (LCY)'; DataClassification = CustomerContent; ObsoleteReason = 'Moved to Core Localization Pack for Czech.'; -#if CLEAN25 ObsoleteState = Removed; ObsoleteTag = '28.0'; -#else - ObsoleteState = Pending; - ObsoleteTag = '18.0'; -#endif } #endif field(63; "System-Created Entry"; Boolean) @@ -1972,10 +1967,6 @@ table 11733 "Cash Document Line CZP" CustLedgerEntry: Record "Cust. Ledger Entry"; VendorLedgerEntry: Record "Vendor Ledger Entry"; EmployeeLedgerEntry: Record "Employee Ledger Entry"; -#if not CLEAN25 - CrossApplicationMgtCZL: Codeunit "Cross Application Mgt. CZL"; - AppliesToAdvanceLetterNo: Code[20]; -#endif begin if "Account No." = '' then exit; @@ -2010,17 +2001,6 @@ table 11733 "Cash Document Line CZP" EmployeeLedgerEntry.CollectSuggestedApplicationCZL(Rec, CrossApplicationBufferCZL); end; end; -#if not CLEAN25 -#pragma warning disable AL0432 - if "Account Type" = "Account Type"::Vendor then begin - OnBeforeFindRelatedAmoutToApply(Rec, AppliesToAdvanceLetterNo); - if AppliesToAdvanceLetterNo <> '' then - CrossApplicationMgtCZL.OnGetSuggestedAmountForPurchAdvLetterHeader( - AppliesToAdvanceLetterNo, CrossApplicationBufferCZL, - Database::"Cash Document Line CZP", "Cash Document No.", "Line No."); - end; -#pragma warning restore AL0432 -#endif OnAfterCollectSuggestedApplication(Rec, CrossApplicationBufferCZL); end; @@ -2198,13 +2178,6 @@ table 11733 "Cash Document Line CZP" local procedure OnAfterIsEETCashRegister(CashDocumentLineCZP: Record "Cash Document Line CZP"; var EETCashRegister: Boolean) begin end; -#if not CLEAN25 - [Obsolete('The event is obsolete and will be removed in the future version. Use OnAfterCollectSuggestedApplication instead.', '25.0')] - [IntegrationEvent(false, false)] - local procedure OnBeforeFindRelatedAmoutToApply(CashDocumentLineCZP: Record "Cash Document Line CZP"; var AppliesToAdvanceLetterNo: Code[20]); - begin - end; -#endif [IntegrationEvent(false, false)] local procedure OnBeforeCreateDim(var CashDocumentLineCZP: Record "Cash Document Line CZP"; var IsHandled: Boolean) diff --git a/Apps/CZ/CompensationLocalization/app/Src/Codeunits/CrossApplicationHandlerCZC.Codeunit.al b/Apps/CZ/CompensationLocalization/app/Src/Codeunits/CrossApplicationHandlerCZC.Codeunit.al index 1b4d881248..49c8c62ec3 100644 --- a/Apps/CZ/CompensationLocalization/app/Src/Codeunits/CrossApplicationHandlerCZC.Codeunit.al +++ b/Apps/CZ/CompensationLocalization/app/Src/Codeunits/CrossApplicationHandlerCZC.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. // ------------------------------------------------------------------------------------------------ @@ -10,13 +10,7 @@ using Microsoft.Sales.Receivables; codeunit 31415 "Cross Application Handler CZC" { -#if not CLEAN25 - ObsoleteState = Pending; - ObsoleteReason = 'The Access property will be changed to Internal.'; - ObsoleteTag = '25.0'; -#else Access = Internal; -#endif [EventSubscriber(ObjectType::Codeunit, Codeunit::"Cross Application Mgt. CZL", 'OnCollectSuggestedApplication', '', false, false)] local procedure AddCompensationLineCZCOnCollectSuggestedApplication( @@ -103,4 +97,4 @@ codeunit 31415 "Cross Application Handler CZC" CrossApplicationBufferCZL.RemoveDocument( TableID, CompensationLineCZC."Compensation No.", CompensationLineCZC."Line No."); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/CompensationLocalization/app/Src/Pages/CompensationCardCZC.Page.al b/Apps/CZ/CompensationLocalization/app/Src/Pages/CompensationCardCZC.Page.al index 873c178a63..ca6fac9b4d 100644 --- a/Apps/CZ/CompensationLocalization/app/Src/Pages/CompensationCardCZC.Page.al +++ b/Apps/CZ/CompensationLocalization/app/Src/Pages/CompensationCardCZC.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. // ------------------------------------------------------------------------------------------------ @@ -162,17 +162,6 @@ page 31272 "Compensation Card CZC" } area(factboxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Compensation Header CZC"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -754,4 +743,4 @@ page 31272 "Compensation Card CZC" CompensationHeaderCZC.Insert(true); Page.Run(Page::"Compensation Card CZC", CompensationHeaderCZC); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/CompensationLocalization/app/Src/Pages/CompensationListCZC.Page.al b/Apps/CZ/CompensationLocalization/app/Src/Pages/CompensationListCZC.Page.al index 7893516f03..a657293bbf 100644 --- a/Apps/CZ/CompensationLocalization/app/Src/Pages/CompensationListCZC.Page.al +++ b/Apps/CZ/CompensationLocalization/app/Src/Pages/CompensationListCZC.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. // ------------------------------------------------------------------------------------------------ @@ -86,17 +86,6 @@ page 31274 "Compensation List CZC" } area(factboxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Compensation Header CZC"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -457,4 +446,4 @@ page 31274 "Compensation List CZC" begin OpenApprovalEntriesExist := ApprovalsMgmt.HasOpenApprovalEntries(Rec.RecordId); end; -} +} \ No newline at end of file diff --git a/Apps/CZ/CompensationLocalization/app/Src/Pages/PostedCompensationCardCZC.Page.al b/Apps/CZ/CompensationLocalization/app/Src/Pages/PostedCompensationCardCZC.Page.al index 77c883fe88..9346498825 100644 --- a/Apps/CZ/CompensationLocalization/app/Src/Pages/PostedCompensationCardCZC.Page.al +++ b/Apps/CZ/CompensationLocalization/app/Src/Pages/PostedCompensationCardCZC.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. // ------------------------------------------------------------------------------------------------ @@ -141,17 +141,6 @@ page 31277 "Posted Compensation Card CZC" } area(factboxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Posted Compensation Header CZC"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -370,4 +359,4 @@ page 31277 "Posted Compensation Card CZC" var HasIncomingDocument: Boolean; -} +} \ No newline at end of file diff --git a/Apps/CZ/CompensationLocalization/app/Src/Pages/PostedCompensationListCZC.Page.al b/Apps/CZ/CompensationLocalization/app/Src/Pages/PostedCompensationListCZC.Page.al index b1d0a5524c..4f4dc2958b 100644 --- a/Apps/CZ/CompensationLocalization/app/Src/Pages/PostedCompensationListCZC.Page.al +++ b/Apps/CZ/CompensationLocalization/app/Src/Pages/PostedCompensationListCZC.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. // ------------------------------------------------------------------------------------------------ @@ -80,17 +80,6 @@ page 31279 "Posted Compensation List CZC" } area(factboxes) { -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(Database::"Posted Compensation Header CZC"), "No." = field("No."); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -309,4 +298,4 @@ page 31279 "Posted Compensation List CZC" var HasIncomingDocument: Boolean; -} +} \ No newline at end of file diff --git a/Apps/CZ/CompensationLocalization/app/Src/Reports/Compensation.rdl b/Apps/CZ/CompensationLocalization/app/Src/Reports/Compensation.rdl index 42d8405cec..2d568c0f92 100644 --- a/Apps/CZ/CompensationLocalization/app/Src/Reports/Compensation.rdl +++ b/Apps/CZ/CompensationLocalization/app/Src/Reports/Compensation.rdl @@ -92,13 +92,13 @@ Cstr(Fields!RegistrationNoLbl.Value) - 1.44165cm + 1.5cm 1.55641cm - 2.5cm + 2.25102cm 1.89146cm @@ -107,7 +107,7 @@ Cstr(Fields!RegistrationNoLbl.Value) 1.12415cm - 1.30937cm + 1.5cm 2.02374cm @@ -891,13 +891,13 @@ Cstr(Fields!RegistrationNoLbl.Value) - 1.44165cm + 1.5cm 1.55641cm - 2.5cm + 2.25102cm 1.89146cm @@ -906,7 +906,7 @@ Cstr(Fields!RegistrationNoLbl.Value) 1.12415cm - 1.30937cm + 1.5cm 2.02374cm diff --git a/Apps/CZ/CompensationLocalization/app/Src/Reports/PostedCompensation.rdl b/Apps/CZ/CompensationLocalization/app/Src/Reports/PostedCompensation.rdl index 930d6b84ec..5ec48f8e99 100644 --- a/Apps/CZ/CompensationLocalization/app/Src/Reports/PostedCompensation.rdl +++ b/Apps/CZ/CompensationLocalization/app/Src/Reports/PostedCompensation.rdl @@ -92,13 +92,13 @@ Cstr(Fields!RegistrationNoLbl.Value) - 1.44165cm + 1.5cm 1.55641cm - 2.5cm + 2.28102cm 1.89146cm @@ -107,7 +107,7 @@ Cstr(Fields!RegistrationNoLbl.Value) 1.12415cm - 1.30937cm + 1.5cm 2.02374cm @@ -879,7 +879,7 @@ Cstr(Fields!RegistrationNoLbl.Value) 0.69533cm 1.39311cm - 17.97cm + 18cm 1 + + 3333333333333333333333333333333333333 + + + + 3 + + @@ -111,7 +111,7 @@ - =Fields!greVendor_Name.Value + =Fields!greVendor_Name.Value @@ -149,7 +149,7 @@ - + @@ -183,7 +183,7 @@ - + @@ -217,7 +217,7 @@ - + @@ -251,7 +251,7 @@ - + @@ -285,7 +285,7 @@ - + @@ -324,7 +324,7 @@ - =Fields!Vendor_Ledger_Entry__Posting_Date_.Value + =Fields!Vendor_Ledger_Entry__Posting_Date_.Value @@ -356,7 +356,7 @@ - =Fields!Vendor_Ledger_Entry__Document_Type_.Value + =Fields!Vendor_Ledger_Entry__Document_Type_.Value @@ -387,7 +387,7 @@ - =Fields!Vendor_Ledger_Entry__Document_No__.Value + =Fields!Vendor_Ledger_Entry__Document_No__.Value @@ -418,7 +418,7 @@ - =Fields!Vendor_Ledger_Entry_External_Document_No.Value + =Fields!Vendor_Ledger_Entry_External_Document_No.Value @@ -450,7 +450,7 @@ - =Fields!Vendor_Ledger_Entry_Description.Value + =Fields!Vendor_Ledger_Entry_Description.Value @@ -481,7 +481,7 @@ - =Fields!Vendor_Ledger_Entry__Due_Date_.Value + =Fields!Vendor_Ledger_Entry__Due_Date_.Value @@ -512,7 +512,7 @@ - =Fields!ginDaysAfterDue.Value + =Fields!ginDaysAfterDue.Value @@ -544,7 +544,7 @@ - =Fields!greGLSetup__LCY_Code_.Value + =Fields!greGLSetup__LCY_Code_.Value @@ -576,7 +576,7 @@ - =Fields!Vendor_Ledger_Entry__Original_Amt___LCY__.Value + =Fields!Vendor_Ledger_Entry__Original_Amt___LCY__.Value @@ -677,7 +677,7 @@ - + @@ -709,7 +709,7 @@ - + @@ -741,7 +741,7 @@ - + @@ -773,7 +773,7 @@ - + @@ -805,7 +805,7 @@ - + @@ -837,7 +837,7 @@ - + @@ -869,7 +869,7 @@ - =Fields!gcoCurrency.Value + =Fields!gcoCurrency.Value @@ -901,7 +901,7 @@ - =Fields!Vendor_Ledger_Entry__Original_Amount_.Value + =Fields!Vendor_Ledger_Entry__Original_Amount_.Value @@ -1002,7 +1002,7 @@ - + @@ -1034,7 +1034,7 @@ - + @@ -1066,7 +1066,7 @@ - + @@ -1098,7 +1098,7 @@ - + @@ -1130,7 +1130,7 @@ - =Fields!TotalCaption.Value + =Fields!TotalCaption.Value @@ -1166,7 +1166,7 @@ - =Fields!greGLSetup__LCY_Code_.Value + =Fields!greGLSetup__LCY_Code_.Value @@ -1198,7 +1198,7 @@ - =Sum(Fields!Vendor_Ledger_Entry__Original_Amt___LCY__.Value) + =Sum(Fields!Vendor_Ledger_Entry__Original_Amt___LCY__.Value) @@ -1300,7 +1300,7 @@ - =Fields!greVendor_Name.Value + =Fields!greVendor_Name.Value @@ -1335,7 +1335,7 @@ - + @@ -1367,7 +1367,7 @@ - + @@ -1399,7 +1399,7 @@ - =Fields!greGLSetup__LCY_Code_.Value + =Fields!greGLSetup__LCY_Code_.Value @@ -1431,7 +1431,7 @@ - =Sum(Fields!Vendor_Ledger_Entry__Original_Amt___LCY__.Value) + =Sum(Fields!Vendor_Ledger_Entry__Original_Amt___LCY__.Value) @@ -1633,7 +1633,7 @@ - =Fields!greTCurrencyBuffer__No__.Value + =Fields!greTCurrencyBuffer__No__.Value @@ -1665,7 +1665,7 @@ - =Fields!greTCurrencyBuffer__Balance_after_Posting_.Value + =Fields!greTCurrencyBuffer__Balance_after_Posting_.Value @@ -1836,7 +1836,7 @@ - =Fields!BalanceCaption1.Value + =Fields!BalanceCaption1.Value @@ -1870,7 +1870,7 @@ - =Fields!BalanceCaption2.Value + =Fields!BalanceCaption2.Value @@ -1904,7 +1904,7 @@ - =Fields!BalanceCaption3.Value + =Fields!BalanceCaption3.Value @@ -1938,7 +1938,7 @@ - =Fields!BalanceCaption4.Value + =Fields!BalanceCaption4.Value @@ -1972,7 +1972,7 @@ - =Fields!BalanceCaption5.Value + =Fields!BalanceCaption5.Value @@ -2006,7 +2006,7 @@ - =Fields!BalanceCaption6.Value + =Fields!BalanceCaption6.Value @@ -2040,7 +2040,7 @@ - =Fields!BalanceCaption7.Value + =Fields!BalanceCaption7.Value @@ -2079,7 +2079,7 @@ - =Fields!greGLSetup__LCY_Code_.Value + =Fields!greGLSetup__LCY_Code_.Value @@ -2113,7 +2113,7 @@ - =LAST(Fields!gdeBalance_1_.Value) + =LAST(Fields!gdeBalance_1_.Value) @@ -2537,7 +2537,7 @@ - =Fields!greGLSetup__LCY_Code__Control72.Value + =Fields!greGLSetup__LCY_Code__Control72.Value @@ -2569,7 +2569,7 @@ - =Fields!greTTotalCurrencyBuffer__Balance_after_Posting_.Value + =Fields!greTTotalCurrencyBuffer__Balance_after_Posting_.Value @@ -2674,7 +2674,7 @@ - =Fields!greTTotalCurrencyBuffer__No__.Value + =Fields!greTTotalCurrencyBuffer__No__.Value @@ -2706,7 +2706,7 @@ - =Fields!greTTotalCurrencyBuffer__Balance_after_Posting__Control1104000009.Value + =Fields!greTTotalCurrencyBuffer__Balance_after_Posting__Control1104000009.Value @@ -2907,7 +2907,7 @@ - =Fields!BalanceTCaption1.Value + =Fields!BalanceTCaption1.Value @@ -2941,7 +2941,7 @@ - =Fields!BalanceTCaption2.Value + =Fields!BalanceTCaption2.Value @@ -2975,7 +2975,7 @@ - =Fields!BalanceTCaption3.Value + =Fields!BalanceTCaption3.Value @@ -3009,7 +3009,7 @@ - =Fields!BalanceTCaption4.Value + =Fields!BalanceTCaption4.Value @@ -3043,7 +3043,7 @@ - =Fields!BalanceTCaption5.Value + =Fields!BalanceTCaption5.Value @@ -3077,7 +3077,7 @@ - =Fields!BalanceTCaption6.Value + =Fields!BalanceTCaption6.Value @@ -3111,7 +3111,7 @@ - =Fields!BalanceTCaption7.Value + =Fields!BalanceTCaption7.Value @@ -3150,7 +3150,7 @@ - =Fields!greGLSetup__LCY_Code__Control72.Value + =Fields!greGLSetup__LCY_Code__Control72.Value @@ -3184,7 +3184,7 @@ - =Fields!gdeBalanceT_1_.Value + =Fields!gdeBalanceT_1_.Value @@ -3579,7 +3579,7 @@ - + @@ -3611,7 +3611,7 @@ - + @@ -3648,7 +3648,7 @@ - =Fields!greGLAcc_FIELDCAPTION__No___.Value + =Fields!greGLAcc_FIELDCAPTION__No___.Value @@ -3681,7 +3681,7 @@ - =Fields!greGLAcc_FIELDCAPTION_Name_.Value + =Fields!greGLAcc_FIELDCAPTION_Name_.Value @@ -3713,7 +3713,7 @@ - =Fields!greGLAcc_FIELDCAPTION__Balance_at_Date__.Value + =Fields!greGLAcc_FIELDCAPTION__Balance_at_Date__.Value @@ -3747,7 +3747,7 @@ - =Fields!greGLAcc__Net_Change_Caption.Value + =Fields!greGLAcc__Net_Change_Caption.Value @@ -3781,7 +3781,7 @@ - =Fields!greTGLAccBuffer__Balance_after_Posting____greGLAcc__Net_Change_Caption.Value + =Fields!greTGLAccBuffer__Balance_after_Posting____greGLAcc__Net_Change_Caption.Value @@ -3820,7 +3820,7 @@ - =Fields!greTGLAccBuffer__No__.Value + =Fields!greTGLAccBuffer__No__.Value @@ -3853,7 +3853,7 @@ - =Fields!greGLAcc_Name.Value + =Fields!greGLAcc_Name.Value @@ -3885,7 +3885,7 @@ - =Fields!greTGLAccBuffer__Balance_after_Posting_.Value + =Fields!greTGLAccBuffer__Balance_after_Posting_.Value @@ -4022,7 +4022,7 @@ - + @@ -4054,7 +4054,7 @@ - =Sum(Fields!greTGLAccBuffer__Balance_after_Posting_.Value) + =Sum(Fields!greTGLAccBuffer__Balance_after_Posting_.Value) @@ -4285,7 +4285,7 @@ - =User!UserID + =User!UserID @@ -4311,7 +4311,7 @@ - =Globals!ExecutionTime + =Globals!ExecutionTime @@ -4360,7 +4360,7 @@ - =First(Fields!STRSUBSTNO_gtcText000_gteVendDateFilter_.Value, "DataSet_Result") + =First(Fields!STRSUBSTNO_gtcText000_gteVendDateFilter_.Value, "DataSet_Result") @@ -4384,7 +4384,7 @@ - =First(Fields!CurrReport_PAGENOCaption.Value, "DataSet_Result") + =First(Fields!CurrReport_PAGENOCaption.Value, "DataSet_Result") @@ -4408,7 +4408,7 @@ - =First(Fields!Open_Vendor_Entries_at_DateCaption.Value, "DataSet_Result") + =First(Fields!Open_Vendor_Entries_at_DateCaption.Value, "DataSet_Result") @@ -4488,7 +4488,7 @@ - =First(Fields!Vendor_Ledger_Entry__TABLECAPTION__________gteLedgEntryFilter.Value, "DataSet_Result") + =First(Fields!Vendor_Ledger_Entry__TABLECAPTION__________gteLedgEntryFilter.Value, "DataSet_Result") @@ -4519,7 +4519,7 @@ - =First(Fields!VendorNoCaption.Value, "DataSet_Result") + =First(Fields!VendorNoCaption.Value, "DataSet_Result") @@ -4552,7 +4552,7 @@ - =FIRST(Fields!VendorNameCaption.Value, "DataSet_Result") + =FIRST(Fields!VendorNameCaption.Value, "DataSet_Result") @@ -4587,7 +4587,7 @@ - =first(Fields!CurrencyCodeCaption.Value, "DataSet_Result") + =first(Fields!CurrencyCodeCaption.Value, "DataSet_Result") @@ -4622,7 +4622,7 @@ - =first(Fields!OriginalAmountCaption.Value, "DataSet_Result") + =first(Fields!OriginalAmountCaption.Value, "DataSet_Result") @@ -4659,7 +4659,7 @@ - =first(Fields!RemainingAmountCaption.Value, "DataSet_Result") + =first(Fields!RemainingAmountCaption.Value, "DataSet_Result") @@ -4714,7 +4714,7 @@ - =First(Fields!PostingDateCaption.Value, "DataSet_Result") + =First(Fields!PostingDateCaption.Value, "DataSet_Result") @@ -4741,7 +4741,7 @@ - =first(Fields!DocumentTypeCaption.Value, "DataSet_Result") + =first(Fields!DocumentTypeCaption.Value, "DataSet_Result") @@ -4770,7 +4770,7 @@ - =first(Fields!DocumentNoCaption.Value, "DataSet_Result") + =first(Fields!DocumentNoCaption.Value, "DataSet_Result") @@ -4799,7 +4799,7 @@ - =first(Fields!ExternalDocumentNoCaption.Value, "DataSet_Result") + =first(Fields!ExternalDocumentNoCaption.Value, "DataSet_Result") @@ -4828,7 +4828,7 @@ - =first(Fields!DescriptionCaption.Value, "DataSet_Result") + =first(Fields!DescriptionCaption.Value, "DataSet_Result") @@ -4857,7 +4857,7 @@ - =first(Fields!DueDateCaption.Value, "DataSet_Result") + =first(Fields!DueDateCaption.Value, "DataSet_Result") @@ -4886,7 +4886,7 @@ - =first(Fields!ginDaysAfterDueCaption.Value, "DataSet_Result") + =first(Fields!ginDaysAfterDueCaption.Value, "DataSet_Result") @@ -4917,7 +4917,7 @@ - =first(Fields!CurrencyCodeCaption.Value, "DataSet_Result") + =first(Fields!CurrencyCodeCaption.Value, "DataSet_Result") @@ -4946,7 +4946,7 @@ - =first(Fields!OriginalAmountCaption.Value, "DataSet_Result") + =first(Fields!OriginalAmountCaption.Value, "DataSet_Result") @@ -4977,7 +4977,7 @@ - =first(Fields!RemainingAmountCaption.Value, "DataSet_Result") + =first(Fields!RemainingAmountCaption.Value, "DataSet_Result") diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/HumanResourcesSetupCZL.TableExt.al b/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/HumanResourcesSetupCZL.TableExt.al new file mode 100644 index 0000000000..5554297acc --- /dev/null +++ b/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/HumanResourcesSetupCZL.TableExt.al @@ -0,0 +1,35 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.HumanResources.Setup; + +using Microsoft.HumanResources.Employee; +using System.Utilities; + +tableextension 31075 "Human Resources Setup CZL" extends "Human Resources Setup" +{ + fields + { + modify("Allow Multiple Posting Groups") + { + trigger OnAfterValidate() + var + Employee: Record Employee; + ConfirmManagement: Codeunit "Confirm Management"; + IsConfirmed: Boolean; + begin + if "Allow Multiple Posting Groups" and ("Allow Multiple Posting Groups" <> xRec."Allow Multiple Posting Groups") then begin + Employee.SetRange("Allow Multiple Posting Groups", false); + if not Employee.IsEmpty() then + IsConfirmed := ConfirmManagement.GetResponse(EmployeeUpdateQst, false); + if IsConfirmed then + Employee.ModifyAll("Allow Multiple Posting Groups", true); + end; + end; + } + } + + var + EmployeeUpdateQst: Label 'There are employees that do not allow multiple posting groups. Do you want to update these employees to allow multiple posting groups?'; +} \ No newline at end of file diff --git a/Apps/CZ/CoreLocalizationPack/test/Src/TestInitializeHandlerCZL.Codeunit.al b/Apps/CZ/CoreLocalizationPack/test/Src/TestInitializeHandlerCZL.Codeunit.al index 187a6f04aa..53d3ec0ca3 100644 --- a/Apps/CZ/CoreLocalizationPack/test/Src/TestInitializeHandlerCZL.Codeunit.al +++ b/Apps/CZ/CoreLocalizationPack/test/Src/TestInitializeHandlerCZL.Codeunit.al @@ -24,11 +24,13 @@ codeunit 148104 "Test Initialize Handler CZL" UpdateReportSelections(); 134475, // "ERM Dimension Sales" 137460, // "Phys. Invt. Item Tracking", + 137007, // "SCM Inventory Costing", 137153, // "SCM Warehouse - Journal", + 137275, // "SCM Inventory Journals" 137294, // "SCM Inventory Miscellaneous II", 137295, // "SCM Inventory Misc. III", 137400, // "SCM Inventory - Orders", - 137007, // "SCM Inventory Costing", + 137408, // "SCM Warehouse VI" 137611: // "SCM Costing Rollup Sev 1": UpdateInventorySetup(); 134008, // ERM VAT Settlement with Apply diff --git a/Apps/CZ/FixedAssetLocalization/app/Src/Codeunits/SubstituteReportHandlerCZF.Codeunit.al b/Apps/CZ/FixedAssetLocalization/app/Src/Codeunits/SubstituteReportHandlerCZF.Codeunit.al index bdefaf8f0f..381d32cf09 100644 --- a/Apps/CZ/FixedAssetLocalization/app/Src/Codeunits/SubstituteReportHandlerCZF.Codeunit.al +++ b/Apps/CZ/FixedAssetLocalization/app/Src/Codeunits/SubstituteReportHandlerCZF.Codeunit.al @@ -33,16 +33,20 @@ codeunit 31245 "Substitute Report Handler CZF" case ReportId of Report::"Calculate Depreciation CZF": NewReportId := Report::"Calculate Depreciation"; +#if not CLEAN28 Report::"Fixed Asset - Analysis CZF": NewReportId := Report::"Fixed Asset - Analysis"; +#endif Report::"Fixed Asset - Book Value 1 CZF": NewReportId := Report::"Fixed Asset - Book Value 01"; Report::"Fixed Asset - Book Value 2 CZF": NewReportId := Report::"Fixed Asset - Book Value 02"; Report::"Fixed Asset Card CZF": NewReportId := Report::"Fixed Asset - G/L Analysis"; +#if not CLEAN28 Report::"Fixed Asset - Proj. Value CZF": NewReportId := Report::"Fixed Asset - Projected Value"; +#endif Report::"Maintenance - Analysis CZF": NewReportId := Report::"Maintenance - Analysis"; end; @@ -53,16 +57,20 @@ codeunit 31245 "Substitute Report Handler CZF" case ReportId of Report::"Calculate Depreciation": NewReportId := Report::"Calculate Depreciation CZF"; +#if not CLEAN28 Report::"Fixed Asset - Analysis": NewReportId := Report::"Fixed Asset - Analysis CZF"; +#endif Report::"Fixed Asset - Book Value 01": NewReportId := Report::"Fixed Asset - Book Value 1 CZF"; Report::"Fixed Asset - Book Value 02": NewReportId := Report::"Fixed Asset - Book Value 2 CZF"; Report::"Fixed Asset - G/L Analysis": NewReportId := Report::"Fixed Asset - G/L Analysis CZF"; +#if not CLEAN28 Report::"Fixed Asset - Projected Value": NewReportId := Report::"Fixed Asset - Proj. Value CZF"; +#endif Report::"Maintenance - Analysis": NewReportId := Report::"Maintenance - Analysis CZF"; end; diff --git a/Apps/DE/EDocumentDE/app/src/ZUGFeRD/ExportZUGFeRDDocument.Codeunit.al b/Apps/DE/EDocumentDE/app/src/ZUGFeRD/ExportZUGFeRDDocument.Codeunit.al index d4446d71f7..ff59cb3320 100644 --- a/Apps/DE/EDocumentDE/app/src/ZUGFeRD/ExportZUGFeRDDocument.Codeunit.al +++ b/Apps/DE/EDocumentDE/app/src/ZUGFeRD/ExportZUGFeRDDocument.Codeunit.al @@ -1121,16 +1121,4 @@ codeunit 13917 "Export ZUGFeRD Document" local procedure OnBeforeAddCrMemoLineElement(var CrMemoLineElement: XmlElement; var SalesCrMemoLine: Record "Sales Cr.Memo Line"; Currency: Record Currency; CurrencyCode: Code[10]; PricesIncVAT: Boolean) begin end; - - [EventSubscriber(ObjectType::Report, Report::"Standard Sales - Invoice", 'OnPreReportOnBeforeInitializePDF', '', false, false)] - local procedure OnBeforeInitializePDFSalesInvoice(SalesInvHeader: Record "Sales Invoice Header"; var CreateZUGFeRDXML: Boolean) - begin - CreateZUGFeRDXML := true; - end; - - [EventSubscriber(ObjectType::Report, Report::"Standard Sales - Credit Memo", 'OnPreReportOnBeforeInitializePDF', '', false, false)] - local procedure OnBeforeInitializePDFSalesCrMemo(SalesCrMemoHeader: Record "Sales Cr.Memo Header"; var CreateZUGFeRDXML: Boolean) - begin - CreateZUGFeRDXML := true; - end; } diff --git a/Apps/DE/EDocumentDE/app/src/ZUGFeRD/PostedSalesCrMemo.ReportExt.al b/Apps/DE/EDocumentDE/app/src/ZUGFeRD/PostedSalesCrMemo.ReportExt.al index bd96689854..abae143ea2 100644 --- a/Apps/DE/EDocumentDE/app/src/ZUGFeRD/PostedSalesCrMemo.ReportExt.al +++ b/Apps/DE/EDocumentDE/app/src/ZUGFeRD/PostedSalesCrMemo.ReportExt.al @@ -30,7 +30,6 @@ reportextension 13919 "Posted Sales Cr.Memo" extends "Standard Sales - Credit Me XmlInStream: InStream; UserCode: SecretText; AdminCode: SecretText; - FileName: Text; Name: Text; MimeType: Text; Description: Text; @@ -64,13 +63,15 @@ reportextension 13919 "Posted Sales Cr.Memo" extends "Standard Sales - Credit Me ExportZUGFeRDDocument.CreateXML(Header, OutStream); end; -#if not CLEAN28 +#pragma warning disable AS0072 +#if not CLEAN27 [Obsolete('Event not used anymore. If you need to know whether the report is being called for ZUGFeRD Export then use IsZUGFeRDPrintProcess in Codeunit "Export ZUGFeRD Document"', '27.2')] [IntegrationEvent(false, false)] local procedure OnPreReportOnBeforeInitializePDF(SalesCrMemoHeader: Record "Sales Cr.Memo Header"; var CreateZUGFeRDXML: Boolean) begin end; #endif +#pragma warning restore AS0072 var PDFDocument: Codeunit "PDF Document"; diff --git a/Apps/DE/EDocumentDE/app/src/ZUGFeRD/PostedSalesInvoice.ReportExt.al b/Apps/DE/EDocumentDE/app/src/ZUGFeRD/PostedSalesInvoice.ReportExt.al index 6da9d81661..a1f0ba6ed2 100644 --- a/Apps/DE/EDocumentDE/app/src/ZUGFeRD/PostedSalesInvoice.ReportExt.al +++ b/Apps/DE/EDocumentDE/app/src/ZUGFeRD/PostedSalesInvoice.ReportExt.al @@ -61,14 +61,15 @@ reportextension 13918 "Posted Sales Invoice" extends "Standard Sales - Invoice" ExportZUGFeRDDocument.CreateXML(Header, OutStream); end; -#if not CLEAN28 +#pragma warning disable AS0072 +#if not CLEAN27 [Obsolete('Event not used anymore. If you need to know whether the report is being called for ZUGFeRD Export then use IsZUGFeRDPrintProcess in Codeunit "Export ZUGFeRD Document"', '27.2')] - [IntegrationEvent(false, false)] local procedure OnPreReportOnBeforeInitializePDF(SalesInvHeader: Record "Sales Invoice Header"; var CreateZUGFeRDXML: Boolean) begin end; #endif +#pragma warning restore AS0072 var PDFDocument: Codeunit "PDF Document"; diff --git a/Apps/DE/EDocumentDE/app/src/ZUGFeRD/ZUGFeRDReportIntegration.al b/Apps/DE/EDocumentDE/app/src/ZUGFeRD/ZUGFeRDReportIntegration.Codeunit.al similarity index 97% rename from Apps/DE/EDocumentDE/app/src/ZUGFeRD/ZUGFeRDReportIntegration.al rename to Apps/DE/EDocumentDE/app/src/ZUGFeRD/ZUGFeRDReportIntegration.Codeunit.al index 07501957db..52827820af 100644 --- a/Apps/DE/EDocumentDE/app/src/ZUGFeRD/ZUGFeRDReportIntegration.al +++ b/Apps/DE/EDocumentDE/app/src/ZUGFeRD/ZUGFeRDReportIntegration.Codeunit.al @@ -1,21 +1,21 @@ -// ------------------------------------------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// ------------------------------------------------------------------------------------------------ -namespace Microsoft.eServices.EDocument.Formats; - -codeunit 11036 "ZUGFeRD Report Integration" -{ - Access = Internal; - EventSubscriberInstance = Manual; - InherentPermissions = X; - InherentEntitlements = X; - - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"Export ZUGFeRD Document", OnIsZUGFeRDPrintProcess, '', false, false)] - local procedure EnableOnIsZUGFeRDPrintProcess(var Result: Boolean) - begin - Result := true; - end; - +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.eServices.EDocument.Formats; + +codeunit 11036 "ZUGFeRD Report Integration" +{ + Access = Internal; + EventSubscriberInstance = Manual; + InherentPermissions = X; + InherentEntitlements = X; + + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Export ZUGFeRD Document", OnIsZUGFeRDPrintProcess, '', false, false)] + local procedure EnableOnIsZUGFeRDPrintProcess(var Result: Boolean) + begin + Result := true; + end; + } \ No newline at end of file diff --git a/Apps/DE/EDocumentDE/test/src/XRechnungXMLDocumentTests.Codeunit.al b/Apps/DE/EDocumentDE/test/src/XRechnungXMLDocumentTests.Codeunit.al index ae0f9d213b..00bce42a3c 100644 --- a/Apps/DE/EDocumentDE/test/src/XRechnungXMLDocumentTests.Codeunit.al +++ b/Apps/DE/EDocumentDE/test/src/XRechnungXMLDocumentTests.Codeunit.al @@ -1367,5 +1367,4 @@ codeunit 13918 "XRechnung XML Document Tests" LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"XRechnung XML Document Tests"); end; -} - +} \ No newline at end of file diff --git a/Apps/DE/EDocumentDE/test/src/ZUGFeRDXMLDocumentTests.Codeunit.al b/Apps/DE/EDocumentDE/test/src/ZUGFeRDXMLDocumentTests.Codeunit.al index b88d56caa7..0b010d877b 100644 --- a/Apps/DE/EDocumentDE/test/src/ZUGFeRDXMLDocumentTests.Codeunit.al +++ b/Apps/DE/EDocumentDE/test/src/ZUGFeRDXMLDocumentTests.Codeunit.al @@ -377,7 +377,6 @@ codeunit 13922 "ZUGFeRD XML Document Tests" procedure PrintPostedSalesInvoiceWithCustomReportLayout(); var SalesInvoiceHeader: Record "Sales Invoice Header"; - TempXMLBuffer: Record "XML Buffer" temporary; ExportZUGFeRDDocument: Codeunit "Export ZUGFeRD Document"; PDFDocument: Codeunit "PDF Document"; PDFTempBlob: Codeunit "Temp Blob"; diff --git a/Apps/DK/C52012DataMigration/app/src/items/C5ItemMigrator.Codeunit.al b/Apps/DK/C52012DataMigration/app/src/items/C5ItemMigrator.Codeunit.al index b2bf390899..3d22598d1b 100644 --- a/Apps/DK/C52012DataMigration/app/src/items/C5ItemMigrator.Codeunit.al +++ b/Apps/DK/C52012DataMigration/app/src/items/C5ItemMigrator.Codeunit.al @@ -566,25 +566,6 @@ codeunit 1867 "C5 Item Migrator" UninitializedItemDataMigrationFacade.CreateItemDiscGroupIfNeeded(C5DiscountGroupCode, GroupDescription); end; -#if not CLEAN25 - local procedure CreateNavSalesPriceIfNeeded(C5InvenPrice: Record "C5 InvenPrice") - var - SalesType: Option Customer,"Customer Price Group","All Customers",Campaign; - begin - CreateCustomerPriceGroupIfNeeded(C5InvenPrice.PriceGroup); - - UninitializedItemDataMigrationFacade.CreateSalesPriceIfNeeded( - SalesType::"Customer Price Group", - C5InvenPrice.PriceGroup, - C5InvenPrice.ItemNumber, - C5InvenPrice.Price, - C5InvenPrice.Currency, - 0D, - '', - 0, - ''); - end; -#else local procedure CreateNavSalesPriceIfNeeded(C5InvenPrice: Record "C5 InvenPrice") var SalesType: Enum "Price Source Type"; @@ -600,7 +581,6 @@ codeunit 1867 "C5 Item Migrator" '', '', 0, C5InvenPrice.Price); end; -#endif local procedure CreateCustomerPriceGroupIfNeeded(C5InvenPriceGroupTxt: Code[10]): Code[10] var diff --git a/Apps/DK/C52012DataMigration/test/src/C5ItemMigratorTest.Codeunit.al b/Apps/DK/C52012DataMigration/test/src/C5ItemMigratorTest.Codeunit.al index 54cbe5bc21..f7d3dc5914 100644 --- a/Apps/DK/C52012DataMigration/test/src/C5ItemMigratorTest.Codeunit.al +++ b/Apps/DK/C52012DataMigration/test/src/C5ItemMigratorTest.Codeunit.al @@ -239,8 +239,6 @@ codeunit 148005 "C5 Item Migrator Test" DefaultDimension: Record "Default Dimension"; DimensionValue: Record "Dimension Value"; CustomerDiscountGroup: Record "Customer Discount Group"; - SalesLineDiscount: Record "Sales Line Discount"; - SalesPrice: Record "Sales Price"; PriceListLine: Record "Price List Line"; CustomerPriceGroup: Record "Customer Price Group"; GenJournalLine: Record "Gen. Journal Line"; @@ -255,11 +253,9 @@ codeunit 148005 "C5 Item Migrator Test" CustomerDiscountGroup.DeleteAll(); Vendor.DeleteAll(); TariffNumber.DeleteAll(); - SalesLineDiscount.DeleteAll(); ItemTrackingCode.DeleteAll(); DefaultDimension.DeleteAll(); DimensionValue.DeleteAll(); - SalesPrice.DeleteAll(); PriceListLine.DeleteAll(); CustomerPriceGroup.DeleteAll(); GenJournalLine.DeleteAll(); @@ -485,12 +481,7 @@ codeunit 148005 "C5 Item Migrator Test" ItemTrackingCode: Record "Item Tracking Code"; DefaultDimension: Record "Default Dimension"; CustomerDiscountGroup: Record "Customer Discount Group"; -#if not CLEAN25 - SalesLineDiscount: Record "Sales Line Discount"; - SalesPrice: Record "Sales Price"; -#else PriceListLine: Record "Price List Line"; -#endif CustomerPriceGroup: Record "Customer Price Group"; GenProductPostingSetup: Record "General Posting Setup"; InventoryPostingSetup: Record "Inventory Posting Setup"; @@ -521,21 +512,12 @@ codeunit 148005 "C5 Item Migrator Test" Assert.AreEqual('Super amazing discount cust', CustomerDiscountGroup.Description, 'CustomerDiscountGroup.Description'); // check inven cust disc -#if not CLEAN25 - SalesLineDiscount.SetRange(Type, SalesLineDiscount.Type::Item); - SalesLineDiscount.SetRange(Code, ItemNumTxt); - SalesLineDiscount.SetRange("Sales Type", SalesLineDiscount."Sales Type"::"Customer Disc. Group"); - SalesLineDiscount.SetRange("Sales Code", 'SuperC'); - SalesLineDiscount.SetRange("Line Discount %", 12.1); - Assert.IsFalse(SalesLineDiscount.IsEmpty(), 'The discount was not created.'); -#else PriceListLine.SetRange("Asset Type", "Price Asset Type"::Item); PriceListLine.SetRange("Asset No.", ItemNumTxt); PriceListLine.SetRange("Source Type", "Price Source Type"::"Customer Disc. Group"); PriceListLine.SetRange("Source No.", 'SuperC'); PriceListLine.SetRange("Line Discount %", 12.1); Assert.IsFalse(PriceListLine.IsEmpty(), 'The discount was not created.'); -#endif Assert.AreEqual(Item."Costing Method"::FIFO, Item."Costing Method", 'Costing Method incorrect'); Assert.AreEqual(111.11, Item."Unit Cost", 'Unit Cost incorrect'); @@ -577,14 +559,6 @@ codeunit 148005 "C5 Item Migrator Test" Assert.IsTrue(Item.PreventNegativeInventory(), 'PreventNegativeInventory incorrect'); // check price is created -#if not CLEAN25 - SalesPrice.SetRange("Sales Code", 'PREMIUM'); - SalesPrice.SetRange("Sales Type", SalesPrice."Sales Type"::"Customer Price Group"); - SalesPrice.SetRange("Item No.", ItemNumTxt); - SalesPrice.SetRange("Unit Price", 1600.80); - SalesPrice.SetRange("Currency Code", 'EUR'); - Assert.IsFalse(SalesPrice.IsEmpty(), 'The price was not created.'); -#else PriceListLine.SetRange("Source No.", 'PREMIUM'); PriceListLine.SetRange("Source Type", "Price Source Type"::"Customer Price Group"); PriceListLine.SetRange("Asset Type", "Price Asset Type"::Item); @@ -592,7 +566,6 @@ codeunit 148005 "C5 Item Migrator Test" PriceListLine.SetRange("Unit Price", 1600.80); PriceListLine.SetRange("Currency Code", 'EUR'); Assert.IsFalse(PriceListLine.IsEmpty(), 'The discount was not created.'); -#endif // check customer price group is created CustomerPriceGroup.Get('Premium'); @@ -814,4 +787,4 @@ codeunit 148005 "C5 Item Migrator Test" C5InvenTable.CostPrice := 999.99; C5InvenTable.Insert(); end; -} +} \ No newline at end of file diff --git a/Apps/DK/OIOUBL/app/src/Management/OIOUBLSubscribers.Codeunit.al b/Apps/DK/OIOUBL/app/src/Management/OIOUBLSubscribers.Codeunit.al index 4ef46e2173..3e4715f147 100644 --- a/Apps/DK/OIOUBL/app/src/Management/OIOUBLSubscribers.Codeunit.al +++ b/Apps/DK/OIOUBL/app/src/Management/OIOUBLSubscribers.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. // ------------------------------------------------------------------------------------------------ @@ -20,13 +20,6 @@ codeunit 13622 "OIOUBL-Subscribers" OIOUBLSetupShortTitleTxt: Label 'Electronic Invoicing'; OIOUBLSetupDescriptionTxt: Label 'Get ready for submitting invoices, credit memos, finance charge memos, and reminders for sales and services.'; -#if not CLEAN25 - [Obsolete('Replaced by subscriber ExportCustomerDocumentsOnBeforeSendToDisk.', '15.4')] - [EventSubscriber(ObjectType::Table, Database::"Document Sending Profile", 'OnBeforeSend', '', false, false)] - procedure ExportCustomerDocumentOnBeforeSend(VAR Sender: Record "Document Sending Profile"; ReportUsage: Integer; RecordVariant: Variant; DocNo: Code[20]; ToCust: Code[20]; DocName: Text[150]; CustomerFieldNo: Integer; DocumentNoFieldNo: Integer; VAR IsHandled: Boolean) - begin - end; -#endif [EventSubscriber(ObjectType::Table, Database::"Document Sending Profile", 'OnBeforeSendToDisk', '', false, false)] local procedure ExportCustomerDocumentsOnBeforeSendToDisk(var Sender: Record "Document Sending Profile"; ReportUsage: Integer; RecordVariant: Variant; DocNo: Code[20]; DocName: Text; ToCust: Code[20]; var IsHandled: Boolean) @@ -202,4 +195,4 @@ codeunit 13622 "OIOUBL-Subscribers" begin end; -} +} \ No newline at end of file diff --git a/Apps/FR/FECAuditFile/app/src/ExportEngine/GenerateFileFEC.Codeunit.al b/Apps/FR/FECAuditFile/app/src/ExportEngine/GenerateFileFEC.Codeunit.al index 9e3cfb78ac..b666da8fdd 100644 --- a/Apps/FR/FECAuditFile/app/src/ExportEngine/GenerateFileFEC.Codeunit.al +++ b/Apps/FR/FECAuditFile/app/src/ExportEngine/GenerateFileFEC.Codeunit.al @@ -6,19 +6,19 @@ namespace Microsoft.Finance.AuditFileExport; using Microsoft.Bank.BankAccount; using Microsoft.Bank.Ledger; +using Microsoft.Finance.Currency; using Microsoft.Finance.GeneralLedger.Account; using Microsoft.Finance.GeneralLedger.Journal; using Microsoft.Finance.GeneralLedger.Ledger; using Microsoft.Foundation.AuditCodes; using Microsoft.Purchases.Payables; -using Microsoft.Sales.Setup; using Microsoft.Purchases.Vendor; using Microsoft.Sales.Customer; using Microsoft.Sales.Receivables; +using Microsoft.Sales.Setup; using System.Reflection; using System.Telemetry; using System.Utilities; -using Microsoft.Finance.Currency; codeunit 10826 "Generate File FEC" { @@ -630,11 +630,10 @@ codeunit 10826 "Generate File FEC" var DetailedVendorLedgEntry: Record "Detailed Vendor Ledg. Entry"; begin - if GetDetailedVendorLedgEntry(DetailedVendorLedgEntry, VendorLedgEntryApplied."Entry No.") then begin - if DetailedVendorLedgEntry."Posting Date" > AppliedDate then - AppliedDate := DetailedVendorLedgEntry."Posting Date"; - end else - AppliedDate := VendorLedgEntryApplied."Posting Date"; + if GetDetailedVendorLedgEntry(DetailedVendorLedgEntry, VendorLedgEntryApplied."Entry No.") then + AppliedDate := DT2Date(DetailedVendorLedgEntry.SystemCreatedAt) + else + AppliedDate := DT2Date(VendorLedgEntryApplied.SystemCreatedAt); end; local procedure GetDetailedVendorLedgEntry(var DetailedVendorLedgEntryApplied: Record "Detailed Vendor Ledg. Entry"; AppliedVendorLedgerEntryNo: Integer): Boolean diff --git a/Apps/FR/FECAuditFile/test/src/FECAuditFileExportTests.Codeunit.al b/Apps/FR/FECAuditFile/test/src/FECAuditFileExportTests.Codeunit.al index 23f4599f83..e92a0ff2eb 100644 --- a/Apps/FR/FECAuditFile/test/src/FECAuditFileExportTests.Codeunit.al +++ b/Apps/FR/FECAuditFile/test/src/FECAuditFileExportTests.Codeunit.al @@ -2279,6 +2279,48 @@ codeunit 148017 "FEC Audit File Export Tests" VerifyExportGLEntriesReport(GLRegister, AuditFile, '', Customer."No.", Customer.Name); end; + [Test] + [HandlerFunctions('ConfirmHandlerYes')] + procedure DateletFieldShowsLetteringDateForVendor() + var + AuditFile: Record "Audit File"; + GenJournalLine: Record "Gen. Journal Line"; + GLRegister: Record "G/L Register"; + Vendor: Record Vendor; + VendorPostingGroup: Record "Vendor Posting Group"; + InvoiceDate: Date; + PaymentDate: Date; + InvoiceDocNo: Code[20]; + begin + // [SCENARIO 603700] Datelet field in FEC export should show the lettering date (SystemCreatedAt) instead of posting date for vendor entries. + Initialize(); + + // [GIVEN] Create Vendor with posting group. + LibraryPurchase.CreateVendor(Vendor); + VendorPostingGroup.Get(Vendor."Vendor Posting Group"); + InvoiceDate := GetStartingDate(); + PaymentDate := InvoiceDate + 14; // Payment 14 days after invoice + + // [GIVEN] Invoice posted on InvoiceDate. + LibraryJournals.CreateGenJournalLineWithBatch( + GenJournalLine, "Gen. Journal Document Type"::Invoice, + "Gen. Journal Account Type"::Vendor, Vendor."No.", -LibraryRandom.RandDecInRange(1000, 2000, 2)); + GenJournalLine.Validate("Posting Date", InvoiceDate); + GenJournalLine.Modify(true); + InvoiceDocNo := GenJournalLine."Document No."; + LibraryERM.PostGeneralJnlLine(GenJournalLine); + + // [GIVEN] Payment posted on PaymentDate and applied to Invoice. + CreateApplyVendorPayment(Vendor."No.", PaymentDate, 1); + + // [WHEN] Export FEC file + RunFECExport(AuditFile, VendorPostingGroup."Payables Account", InvoiceDate, PaymentDate, false); + + // [THEN] Datelet field (field 15) for payment entry shows the application date (Today), not the payment posting date. + GLRegister.FindLast(); + VerifyDateLetFieldReport(GLRegister, AuditFile, VendorPostingGroup."Payables Account", InvoiceDocNo, "Gen. Journal Document Type"::Payment, Today); + end; + local procedure Initialize() begin LibrarySetupStorage.Restore(); @@ -3572,6 +3614,28 @@ codeunit 148017 "FEC Audit File Export Tests" exit(false); end; + local procedure VerifyDateLetFieldReport(GLRegister: Record "G/L Register"; AuditFile: Record "Audit File"; GLAccountNo: Code[250]; AppliedEntries: Text; DocumentType: Enum "Gen. Journal Document Type"; AppliedDate: Date) + var + GLEntry: Record "G/L Entry"; + IStream: InStream; + LineToRead: Text; + FieldsValueArray: array[18] of Text[50]; + begin + CreateReadStream(IStream, AuditFile); + IStream.ReadText(LineToRead); // headers + IStream.ReadText(LineToRead); + + GLEntry.SetFilter("Entry No.", '%1..%2', GLRegister."From Entry No.", GLRegister."To Entry No."); + GLEntry.SetRange("G/L Account No.", GLAccountNo); + GLEntry.SetRange("Document Type", DocumentType); + if GLEntry.FindSet() then + repeat + PopulateFieldsArray(iStream, FieldsValueArray); + Assert.AreEqual(AppliedEntries, FieldsValueArray[14], GetErrorTextForAssertStmnt(14)); + Assert.AreEqual(GetFormattedDate(AppliedDate), FieldsValueArray[15], GetErrorTextForAssertStmnt(15)); + until GLEntry.Next() = 0; + end; + [ConfirmHandler] procedure ConfirmHandlerYes(Question: Text[1024]; var Reply: Boolean) begin diff --git a/Apps/GB/GovTalk/app/src/Codeunits/GovTalkSubscribers.Codeunit.al b/Apps/GB/GovTalk/app/src/Codeunits/GovTalkSubscribers.Codeunit.al index 0b4f5727c4..bc777934d6 100644 --- a/Apps/GB/GovTalk/app/src/Codeunits/GovTalkSubscribers.Codeunit.al +++ b/Apps/GB/GovTalk/app/src/Codeunits/GovTalkSubscribers.Codeunit.al @@ -366,7 +366,7 @@ codeunit 10503 "GovTalk Subscribers" #endif [EventSubscriber(ObjectType::Report, Report::"VAT Report Request Page", 'OnBeforeVATStatementLineFindSet', '', false, false)] - local procedure OnBeforeVATStatementLineFindSet(VATStatementLine: Record "VAT Statement Line"; VATReportHeader: Record "VAT Report Header") + local procedure OnBeforeVATStatementLineFindSet(var VATStatementLine: Record "VAT Statement Line"; VATReportHeader: Record "VAT Report Header") #if not CLEAN27 var GovTalk: Codeunit GovTalk; @@ -384,7 +384,7 @@ codeunit 10503 "GovTalk Subscribers" #pragma warning disable AL0432 [Obsolete('Event will be removed in a future release', '27.0')] [EventSubscriber(ObjectType::Report, Report::"VAT Report Request Page", 'OnBeforeVATStatementLineFindSet2', '', false, false)] - local procedure OnBeforeVATStatementLineFindSet2(VATStatementLine: Record "VAT Statement Line"; VATReportHeader: Record "VAT Report Header"; var IsHandled: Boolean) + local procedure OnBeforeVATStatementLineFindSet2(var VATStatementLine: Record "VAT Statement Line"; VATReportHeader: Record "VAT Report Header"; var IsHandled: Boolean) var GovTalk: Codeunit GovTalk; begin diff --git a/Apps/GB/GovTalk/test/app.json b/Apps/GB/GovTalk/test/app.json index 9695de6a06..62632e8a86 100644 --- a/Apps/GB/GovTalk/test/app.json +++ b/Apps/GB/GovTalk/test/app.json @@ -44,6 +44,10 @@ { "from": 144029, "to": 144036 + }, + { + "from": 148001, + "to": 148001 } ], "target": "OnPrem", diff --git a/Apps/GB/GovTalk/test/src/RegularTests/GovTalkVATRequestPageTests.Codeunit.al b/Apps/GB/GovTalk/test/src/RegularTests/GovTalkVATRequestPageTests.Codeunit.al new file mode 100644 index 0000000000..66ad61e3fe --- /dev/null +++ b/Apps/GB/GovTalk/test/src/RegularTests/GovTalkVATRequestPageTests.Codeunit.al @@ -0,0 +1,295 @@ +// ------------------------------------------------------------------------------------------------ +// 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.VAT.GovTalk; + +using Microsoft.Finance.VAT.Reporting; +using System.TestLibraries.Utilities; + +codeunit 148001 "GovTalk VAT Request Page Tests" +{ + Subtype = Test; + TestType = IntegrationTest; + TestPermissions = Disabled; +#if not CLEAN27 + EventSubscriberInstance = Manual; +#endif + + var + LibraryERM: Codeunit "Library - ERM"; + LibraryVariableStorage: Codeunit "Library - Variable Storage"; + LibraryVATReport: Codeunit "Library - VAT Report"; + Assert: Codeunit Assert; + Selection: Enum "VAT Statement Report Selection"; + PeriodSelection: Enum "VAT Statement Report Period Selection"; + IsInitialized: Boolean; + WrongVATStatementSetupErr: Label 'VAT statement template %1 name %2 has a wrong setup. There must be nine rows, each with a value between 1 and 9 for the Box No. field.', Comment = '%1 = statement template name, %2 = statement name'; + + [Test] + [HandlerFunctions('SuggestLinesRPH')] + procedure VATStatementLineCountEqualsNine() + var + VATReportHeader: Record "VAT Report Header"; + VATStatementName: Record "VAT Statement Name"; + VATStatementReportLine: Record "VAT Statement Report Line"; + begin + // [SCENARIO 614191] VAT Report Request Page successfully processes VAT statement with exactly 9 lines + Initialize(); + +#if not CLEAN27 + Bindsubscription(this); +#endif + // [GIVEN] VAT statement template "T" and name "N" with 9 VAT statement lines with Box No. 1-9 and 5 VAT statement lines without Box No. + CreateVATStatementWithLines(VATStatementName, 9); + CreateVATReturn(VATReportHeader); + EnqueueVATStatementValues(VATStatementName); + + // [WHEN] VAT Report Request Page is run for VAT return "R" + SuggestLines(VATReportHeader); + + // [THEN] VAT return "R" is generated without errors + VATStatementReportLine.SetRange("VAT Report No.", VATReportHeader."No."); + VATStatementReportLine.SetRange("VAT Report Config. Code", VATReportHeader."VAT Report Config. Code"); + Assert.RecordCount(VATStatementReportLine, 9); + +#if not CLEAN27 + Unbindsubscription(this); +#endif + LibraryVariableStorage.AssertEmpty(); + end; + + [Test] + [HandlerFunctions('SuggestLinesRPH')] + procedure VATStatementLineCountLessThanNine() + var + VATReportHeader: Record "VAT Report Header"; + VATStatementName: Record "VAT Statement Name"; + begin + // [SCENARIO 614191] VAT Report Request Page fails when VAT statement has less than 9 lines and 5 VAT statement lines without Box No. + Initialize(); +#if not CLEAN27 + Bindsubscription(this); +#endif + // [GIVEN] VAT statement template "T" and name "N" with 8 VAT statement lines with Box No. 1-8 + CreateVATStatementWithLines(VATStatementName, 8); + CreateVATReturn(VATReportHeader); + EnqueueVATStatementValues(VATStatementName); + + // [WHEN] VAT Report Request Page is run for VAT return "R" + asserterror SuggestLines(VATReportHeader); + + // [THEN] Error is thrown indicating wrong VAT statement setup + Assert.ExpectedError(StrSubstNo(WrongVATStatementSetupErr, VATStatementName."Statement Template Name", VATStatementName.Name)); + +#if not CLEAN27 + Unbindsubscription(this); +#endif + LibraryVariableStorage.AssertEmpty(); + end; + + [Test] + [HandlerFunctions('SuggestLinesRPH')] + procedure VATStatementLineCountMoreThanNine() + var + VATReportHeader: Record "VAT Report Header"; + VATStatementName: Record "VAT Statement Name"; + begin + // [SCENARIO 614191] VAT Report Request Page fails when VAT statement has more than 9 lines and 5 VAT statement lines without Box No. + Initialize(); +#if not CLEAN27 + Bindsubscription(this); +#endif + // [GIVEN] VAT statement template "T" and name "N" with 10 VAT statement lines with Box No. 1-10 + CreateVATStatementWithLines(VATStatementName, 10); + CreateVATReturn(VATReportHeader); + EnqueueVATStatementValues(VATStatementName); + + // [WHEN] VAT Report Request Page is run for VAT return "R" + asserterror SuggestLines(VATReportHeader); + + // [THEN] Error is thrown indicating wrong VAT statement setup + Assert.ExpectedError(StrSubstNo(WrongVATStatementSetupErr, VATStatementName."Statement Template Name", VATStatementName.Name)); + +#if not CLEAN27 + Unbindsubscription(this); +#endif + LibraryVariableStorage.AssertEmpty(); + end; + +#if not CLEAN27 +#pragma warning disable AS0018 + [Test] + [HandlerFunctions('SuggestLinesRPH')] + [Obsolete('These tests are not required anymore', '27.0')] + procedure VATStatementLineCountEqualsNineViaObsoleteEvent() + var + VATReportHeader: Record "VAT Report Header"; + VATStatementName: Record "VAT Statement Name"; + VATStatementReportLine: Record "VAT Statement Report Line"; + begin + // [SCENARIO 614191] VAT Report Request Page successfully processes VAT statement with exactly 9 lines via obsolete event + Initialize(); + + // [GIVEN] VAT statement template "T" and name "N" with 9 VAT statement lines with Box No. 1-9 and 5 VAT statement lines without Box No., GovTalk feature is disabled + CreateVATStatementWithLines(VATStatementName, 9); + CreateVATReturn(VATReportHeader); + EnqueueVATStatementValues(VATStatementName); + + // [WHEN] VAT Report Request Page is run for VAT return "R" + SuggestLines(VATReportHeader); + + // [THEN] VAT return "R" is generated without errors + VATStatementReportLine.SetRange("VAT Report No.", VATReportHeader."No."); + VATStatementReportLine.SetRange("VAT Report Config. Code", VATReportHeader."VAT Report Config. Code"); + Assert.RecordCount(VATStatementReportLine, 9); + + LibraryVariableStorage.AssertEmpty(); + end; + + [Test] + [HandlerFunctions('SuggestLinesRPH')] + [Obsolete('These tests are not required anymore', '27.0')] + procedure VATStatementLineCountLessThanNineViaObsoleteEvent() + var + VATReportHeader: Record "VAT Report Header"; + VATStatementName: Record "VAT Statement Name"; + begin + // [SCENARIO 614191] VAT Report Request Page fails when VAT statement has less than 9 lines via obsolete event + Initialize(); + + // [GIVEN] VAT statement template "T" and name "N" with 8 VAT statement lines with Box No. 1-8 and 5 VAT statement lines without Box No., GovTalk feature is disabled + CreateVATStatementWithLines(VATStatementName, 8); + CreateVATReturn(VATReportHeader); + EnqueueVATStatementValues(VATStatementName); + + // [WHEN] VAT Report Request Page is run for VAT return "R" + asserterror SuggestLines(VATReportHeader); + + // [THEN] Error is thrown indicating wrong VAT statement setup + Assert.ExpectedError(StrSubstNo(WrongVATStatementSetupErr, VATStatementName."Statement Template Name", VATStatementName.Name)); + + LibraryVariableStorage.AssertEmpty(); + end; + + [Test] + [HandlerFunctions('SuggestLinesRPH')] + [Obsolete('These tests are not required anymore', '27.0')] + procedure VATStatementLineCountMoreThanNineViaObsoleteEvent() + var + VATReportHeader: Record "VAT Report Header"; + VATStatementName: Record "VAT Statement Name"; + begin + // [SCENARIO 614191] VAT Report Request Page fails when VAT statement has more than 9 lines via obsolete event + Initialize(); + + // [GIVEN] VAT statement template "T" and name "N" with 10 VAT statement lines with Box No. 1-10 and 5 VAT statement lines without Box No., GovTalk feature is disabled + CreateVATStatementWithLines(VATStatementName, 10); + CreateVATReturn(VATReportHeader); + EnqueueVATStatementValues(VATStatementName); + + // [WHEN] VAT Report Request Page is run for VAT return "R" + asserterror SuggestLines(VATReportHeader); + + // [THEN] Error is thrown indicating wrong VAT statement setup + Assert.ExpectedError(StrSubstNo(WrongVATStatementSetupErr, VATStatementName."Statement Template Name", VATStatementName.Name)); + + LibraryVariableStorage.AssertEmpty(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::GovTalk, OnAfterCheckFeatureEnabled, '', false, false)] + local procedure OnAfterCheckFeatureEnabled(var IsEnabled: Boolean) + begin + IsEnabled := true; + end; +#pragma warning restore AS0018 +#endif + + local procedure Initialize() + var + VATStatementTemplate: Record "VAT Statement Template"; + VATStatementLine: Record "VAT Statement Line"; + begin + VATStatementTemplate.DeleteAll(); + VATStatementLine.DeleteAll(); + if IsInitialized then + exit; + + SetupVATReportsConfiguration(); + IsInitialized := true; + Commit(); + end; + + local procedure SetupVATReportsConfiguration() + var + VATReportsConfiguration: Record "VAT Reports Configuration"; + begin + VATReportsConfiguration.SetRange("VAT Report Type", VATReportsConfiguration."VAT Report Type"::"VAT Return"); + VATReportsConfiguration.DeleteAll(); + LibraryVATReport.CreateVATReportConfigurationNo(Codeunit::"VAT Report Suggest Lines", 0, 0, 0, 0); + end; + + local procedure CreateVATReturn(var VATReportHeader: Record "VAT Report Header") + begin + LibraryVATReport.CreateVATReturn(VATReportHeader, Date2DMY(WorkDate(), 3)); + end; + + local procedure CreateVATStatementWithLines(var VATStatementName: Record "VAT Statement Name"; LineCount: Integer) + var + VATStatementTemplate: Record "VAT Statement Template"; + VATStatementLine: Record "VAT Statement Line"; + i: Integer; + begin + LibraryERM.CreateVATStatementTemplate(VATStatementTemplate); + LibraryERM.CreateVATStatementName(VATStatementName, VATStatementTemplate.Name); + + for i := 1 to LineCount do begin + LibraryERM.CreateVATStatementLine(VATStatementLine, VATStatementName."Statement Template Name", VATStatementName.Name); + VATStatementLine.Validate("Row No.", Format(i)); + VATStatementLine.Validate("Box No.", Format(i)); + VATStatementLine.Modify(true); + end; + LineCount += 1; + for i := LineCount to (LineCount + 5) do begin + LibraryERM.CreateVATStatementLine(VATStatementLine, VATStatementName."Statement Template Name", VATStatementName.Name); + VATStatementLine.Validate("Row No.", Format(i)); + VATStatementLine.Validate("Box No.", ''); + VATStatementLine.Modify(true); + end; + end; + + local procedure EnqueueVATStatementValues(VATStatementName: Record "VAT Statement Name") + begin + LibraryVariableStorage.Enqueue(VATStatementName."Statement Template Name"); + LibraryVariableStorage.Enqueue(VATStatementName.Name); + LibraryVariableStorage.Enqueue(Selection::Open); + LibraryVariableStorage.Enqueue(PeriodSelection::"Within Period"); + LibraryVariableStorage.Enqueue(Date2DMY(WorkDate(), 3)); + LibraryVariableStorage.Enqueue(false); + end; + + local procedure SuggestLines(VATReportHeader: Record "VAT Report Header") + var + VATReportMediator: Codeunit "VAT Report Mediator"; + begin + Commit(); + VATReportMediator.GetLines(VATReportHeader); + end; + + [RequestPageHandler] + procedure SuggestLinesRPH(var VATReportRequestPage: TestRequestPage "VAT Report Request Page") + begin + VATReportRequestPage.VATStatementTemplate.SetValue(LibraryVariableStorage.DequeueText()); + VATReportRequestPage.VATStatementName.SetValue(LibraryVariableStorage.DequeueText()); + + Selection := "VAT Statement Report Selection".FromInteger(LibraryVariableStorage.DequeueInteger()); + VATReportRequestPage.Selection.SetValue(Format(Selection)); + + PeriodSelection := "VAT Statement Report Period Selection".FromInteger(LibraryVariableStorage.DequeueInteger()); + VATReportRequestPage.PeriodSelection.SetValue(Format(PeriodSelection)); + + VATReportRequestPage."Period Year".SetValue(LibraryVariableStorage.DequeueInteger()); + VATReportRequestPage."Amounts in ACY".SetValue(LibraryVariableStorage.DequeueBoolean()); + VATReportRequestPage.OK().Invoke(); + end; +} diff --git a/Apps/GB/ReportsGB/app/src/Codeunits/FeatureReportsGB.Codeunit.al b/Apps/GB/ReportsGB/app/src/Codeunits/FeatureReportsGB.Codeunit.al index 96448e5817..a5b666e662 100644 --- a/Apps/GB/ReportsGB/app/src/Codeunits/FeatureReportsGB.Codeunit.al +++ b/Apps/GB/ReportsGB/app/src/Codeunits/FeatureReportsGB.Codeunit.al @@ -98,7 +98,9 @@ codeunit 10580 "Feature - Reports GB" implements "Feature Data Update" SetDefaultReportLayout(Report::"Bank Account - List"); SetDefaultReportLayout(Report::"Cash Flow Dimensions - Detail"); SetDefaultReportLayout(Report::"Finance Charge Memo"); +#if not CLEAN28 SetDefaultReportLayout(Report::"Fixed Asset - Projected Value"); +#endif SetDefaultReportLayout(Report::"Purchase - Quote"); SetDefaultReportLayout(Report::"Purchase - Receipt"); SetDefaultReportLayout(Report::"Sales - Shipment"); diff --git a/Apps/GB/ReportsGB/app/src/Codeunits/ReportsSubscribers.Codeunit.al b/Apps/GB/ReportsGB/app/src/Codeunits/ReportsSubscribers.Codeunit.al index d0e80c061d..eeeb196adb 100644 --- a/Apps/GB/ReportsGB/app/src/Codeunits/ReportsSubscribers.Codeunit.al +++ b/Apps/GB/ReportsGB/app/src/Codeunits/ReportsSubscribers.Codeunit.al @@ -6,17 +6,23 @@ namespace Microsoft.Finance.VAT.Setup; using Microsoft.Sales.Document; +#if not CLEAN28 using Microsoft.FixedAssets.Reports; +#endif using Microsoft.Purchases.Setup; using Microsoft.Sales.Reports; using Microsoft.Purchases.Document; using Microsoft.CashFlow.Forecast; using Microsoft.Sales.Reminder; +#if not CLEAN28 using Microsoft.FixedAssets.Depreciation; using Microsoft.FixedAssets.FixedAsset; +#endif using Microsoft.CashFlow.Reports; using Microsoft.Purchases.History; +#if not CLEAN28 using Microsoft.Foundation.Period; +#endif using Microsoft.Inventory.Item; using Microsoft.Purchases.Reports; @@ -72,7 +78,10 @@ codeunit 10581 "Reports Subscribers" AddError(StrSubstNo(Text10500Err, Round(0)), ErrorCounter, ErrorText); end; +#if not CLEAN28 +#pragma warning disable AL0432 [EventSubscriber(ObjectType::Report, Report::"Fixed Asset - Projected Value", OnAfterAccountingPeriodSetFilter, '', false, false)] +#pragma warning restore AL0432 local procedure OnAfterAccountingPeriodSetFilter(var AccountingPeriod: Record "Accounting Period"; var PeriodEndingDate: Date; UseAccountingPeriod: Boolean; Year365Days: Boolean) begin if Year365Days then @@ -86,6 +95,7 @@ codeunit 10581 "Reports Subscribers" AccountingPeriod.SetFilter( "Starting Date", '>=%1', PeriodEndingDate + 1); end; +#endif [EventSubscriber(ObjectType::Report, Report::"Purchase - Receipt", OnAfterInitializeRequest, '', false, false)] local procedure OnAfterInitializeRequest(var NoOfCopies: Integer; var ShowInternalInfo: Boolean; var LogInteraction: Boolean; var ShowCorrectionLines: Boolean; var sender: Report "Purchase - Receipt") @@ -100,11 +110,15 @@ codeunit 10581 "Reports Subscribers" sender.SetPrintEmptyLines(PrintEmptyLines); end; +#if not CLEAN28 +#pragma warning disable AL0432 [EventSubscriber(ObjectType::Report, Report::"Fixed Asset - Projected Value", OnBeforeCalculateFirstDeprAmount, '', false, false)] local procedure OnBeforeCalculateFirstDeprAmount(sender: Report "Fixed Asset - Projected Value"; var CalculateDepr: Codeunit "Calculate Depreciation"; var Custom1Amount: Decimal; var Custom1NumberOfDays: Integer; var DaysInFirstPeriod: Integer; var DeprAmount: Decimal; var DeprBookCode: Code[10]; var DepreciationCalculation: Codeunit "Depreciation Calculation"; var Done: Boolean; var EndingDate: Date; var EntryAmounts: array[4] of Decimal; var FirstTime: Boolean; var FixedAsset: Record "Fixed Asset"; var IsHandled: Boolean; var NumberOfDays: Integer; var StartingDate: Date; var UntilDate: Date) +#pragma warning restore AL0432 begin sender.SetUntilDate(UntilDate); end; +#endif [EventSubscriber(ObjectType::Report, Report::Reminder, OnAfterResetAmounts, '', false, false)] local procedure OnAfterResetAmounts(var VATInterest: Decimal; var AddFeeInclVAT: Decimal; var AddFeePerLineInclVAT: Decimal; var sender: Report Reminder) @@ -131,8 +145,11 @@ codeunit 10581 "Reports Subscribers" sender.SetDim_Code_ValCode_ValName(DimCode, DimValCode, DimValName, Level); end; +#if not CLEAN28 +#pragma warning disable AL0432 [EventSubscriber(ObjectType::Report, Report::"Fixed Asset - Projected Value", OnAfterTransferValues, '', false, false)] local procedure OnAfterTransferValues(GroupAmounts: array[4] of Decimal; TotalBookValue: array[2] of Decimal; var sender: Report "Fixed Asset - Projected Value") +#pragma warning restore AL0432 begin sender.SetGroupAmounts(GroupAmounts); sender.SetTotalBookValue(TotalBookValue); @@ -145,6 +162,7 @@ codeunit 10581 "Reports Subscribers" ThisDate := ThisDate + 1; exit(ThisDate); end; +#endif local procedure AddError(Text: Text; var ErrorCounter: Integer; var ErrorText: Text[250]) begin diff --git a/Apps/GB/ReportsGB/app/src/ReportExtensions/FixedAssetProjectedValue.ReportExt.al b/Apps/GB/ReportsGB/app/src/ReportExtensions/FixedAssetProjectedValue.ReportExt.al index d31dcf87e1..aebdb3568f 100644 --- a/Apps/GB/ReportsGB/app/src/ReportExtensions/FixedAssetProjectedValue.ReportExt.al +++ b/Apps/GB/ReportsGB/app/src/ReportExtensions/FixedAssetProjectedValue.ReportExt.al @@ -1,3 +1,4 @@ +#if not CLEAN28 // ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. @@ -7,7 +8,9 @@ namespace Microsoft.FixedAssets.Reports; using Microsoft.FixedAssets.Ledger; using Microsoft.FixedAssets.Depreciation; +#pragma warning disable AL0432 reportextension 10583 "Fixed Asset - Projected Value" extends "Fixed Asset - Projected Value" +#pragma warning restore AL0432 { #if CLEAN27 RDLCLayout = './src/ReportExtensions/FixedAssetProjectedValue.rdlc'; @@ -190,3 +193,4 @@ reportextension 10583 "Fixed Asset - Projected Value" extends "Fixed Asset - Pro TotalBookValue[1] := Total_BookValue[1]; end; } +#endif \ No newline at end of file diff --git a/Apps/GB/ReportsGB/app/src/Reports/BlanketOrderSalesGB.Report.al b/Apps/GB/ReportsGB/app/src/Reports/BlanketOrderSalesGB.Report.al index 09d621c6f2..398298187a 100644 --- a/Apps/GB/ReportsGB/app/src/Reports/BlanketOrderSalesGB.Report.al +++ b/Apps/GB/ReportsGB/app/src/Reports/BlanketOrderSalesGB.Report.al @@ -839,13 +839,7 @@ report 10602 "Blanket Order Sales GB" CompanyInfo2: Record "Company Information"; CompanyInfo3: Record "Company Information"; Salessetup: Record "Sales & Receivables Setup"; -#if not CLEAN25 -#pragma warning disable AL0432 -#endif TempVATAmountLine: Record "VAT Amount Line" temporary; -#if not CLEAN25 -#pragma warning restore AL0432 -#endif TempSalesLine: Record "Sales Line" temporary; DimSetEntry1: Record "Dimension Set Entry"; DimSetEntry2: Record "Dimension Set Entry"; @@ -922,4 +916,3 @@ report 10602 "Blanket Order Sales GB" FeatureNameTok: Label 'Blanket Sales Order GB', Locked = true; EventNameTok: Label 'Blanket Sales Order GB report has been used', Locked = true; } - diff --git a/Apps/GB/ReportsGB/app/src/Reports/OrderConfirmation.Report.al b/Apps/GB/ReportsGB/app/src/Reports/OrderConfirmation.Report.al index ca14262f03..2ea3b29dc2 100644 --- a/Apps/GB/ReportsGB/app/src/Reports/OrderConfirmation.Report.al +++ b/Apps/GB/ReportsGB/app/src/Reports/OrderConfirmation.Report.al @@ -865,13 +865,7 @@ report 10603 "Order Confirmation" CompanyInfo3: Record "Company Information"; CompanyInfo2: Record "Company Information"; SalesSetup: Record "Sales & Receivables Setup"; -#if not CLEAN25 -#pragma warning disable AL0432 -#endif TempVATAmountLine: Record "VAT Amount Line" temporary; -#if not CLEAN25 -#pragma warning restore AL0432 -#endif TempSalesLine: Record "Sales Line" temporary; DimSetEntry1: Record "Dimension Set Entry"; DimSetEntry2: Record "Dimension Set Entry"; @@ -951,4 +945,3 @@ report 10603 "Order Confirmation" FeatureNameTok: Label 'Order Confirmation GB', Locked = true; EventNameTok: Label 'Order ConfirmationGB report has been used', Locked = true; } - diff --git a/Apps/GB/ReportsGB/app/src/Reports/OrderGB.Report.al b/Apps/GB/ReportsGB/app/src/Reports/OrderGB.Report.al index 2f7eb47861..db8acdecb4 100644 --- a/Apps/GB/ReportsGB/app/src/Reports/OrderGB.Report.al +++ b/Apps/GB/ReportsGB/app/src/Reports/OrderGB.Report.al @@ -868,13 +868,7 @@ report 10600 "OrderGB" ShipmentMethod: Record "Shipment Method"; PaymentTerms: Record "Payment Terms"; SalesPurchPerson: Record "Salesperson/Purchaser"; -#if not CLEAN25 -#pragma warning disable AL0432 -#endif TempVATAmountLine: Record "VAT Amount Line" temporary; -#if not CLEAN25 -#pragma warning restore AL0432 -#endif TempPurchLine: Record "Purchase Line" temporary; DimSetEntry1: Record "Dimension Set Entry"; DimSetEntry2: Record "Dimension Set Entry"; @@ -961,4 +955,3 @@ report 10600 "OrderGB" } - diff --git a/Apps/GB/ReportsGB/app/src/Reports/PurchaseCreditMemo.Report.al b/Apps/GB/ReportsGB/app/src/Reports/PurchaseCreditMemo.Report.al index dc07369410..245440d15e 100644 --- a/Apps/GB/ReportsGB/app/src/Reports/PurchaseCreditMemo.Report.al +++ b/Apps/GB/ReportsGB/app/src/Reports/PurchaseCreditMemo.Report.al @@ -836,13 +836,7 @@ report 10580 "Purchase Credit Memo" GLSetup: Record "General Ledger Setup"; CompanyInfo: Record "Company Information"; SalesPurchPerson: Record "Salesperson/Purchaser"; -#if not CLEAN25 -#pragma warning disable AL0432 -#endif TempVATAmountLine: Record "VAT Amount Line" temporary; -#if not CLEAN25 -#pragma warning restore AL0432 -#endif DimSetEntry1: Record "Dimension Set Entry"; DimSetEntry2: Record "Dimension Set Entry"; RespCenter: Record "Responsibility Center"; @@ -932,4 +926,3 @@ report 10580 "Purchase Credit Memo" InteractionLogging := SegManagement.FindInteractionTemplateCode("Interaction Log Entry Document Type"::"Purch. Cr. Memo") <> ''; end; } - diff --git a/Apps/GB/ReportsGB/app/src/Reports/PurchaseInvoice.Report.al b/Apps/GB/ReportsGB/app/src/Reports/PurchaseInvoice.Report.al index 4926eb06af..10289c6458 100644 --- a/Apps/GB/ReportsGB/app/src/Reports/PurchaseInvoice.Report.al +++ b/Apps/GB/ReportsGB/app/src/Reports/PurchaseInvoice.Report.al @@ -846,13 +846,7 @@ report 10581 "Purchase Invoice" ShipmentMethod: Record "Shipment Method"; PaymentTerms: Record "Payment Terms"; SalesPurchPerson: Record "Salesperson/Purchaser"; -#if not CLEAN25 -#pragma warning disable AL0432 -#endif TempVATAmountLine: Record "VAT Amount Line" temporary; -#if not CLEAN25 -#pragma warning restore AL0432 -#endif DimSetEntry1: Record "Dimension Set Entry"; DimSetEntry2: Record "Dimension Set Entry"; RespCenter: Record "Responsibility Center"; @@ -935,4 +929,3 @@ report 10581 "Purchase Invoice" FeatureNameTok: Label 'Purchase Invoice GB', Locked = true; EventNameTok: Label 'Purchase Invoice GB report has been used', Locked = true; } - diff --git a/Apps/GB/ReportsGB/app/src/Reports/SalesCreditMemo.Report.al b/Apps/GB/ReportsGB/app/src/Reports/SalesCreditMemo.Report.al index bbd92796cd..e56b4e177e 100644 --- a/Apps/GB/ReportsGB/app/src/Reports/SalesCreditMemo.Report.al +++ b/Apps/GB/ReportsGB/app/src/Reports/SalesCreditMemo.Report.al @@ -894,13 +894,7 @@ report 10582 "Sales - Credit Memo" SalesPurchPerson: Record "Salesperson/Purchaser"; CompanyBankAccount: Record "Bank Account"; CompanyInfo: Record "Company Information"; -#if not CLEAN25 -#pragma warning disable AL0432 -#endif TempVATAmountLine: Record "VAT Amount Line" temporary; -#if not CLEAN25 -#pragma warning restore AL0432 -#endif DimSetEntry1: Record "Dimension Set Entry"; DimSetEntry2: Record "Dimension Set Entry"; TempSalesShipmentBuffer: Record "Sales Shipment Buffer" temporary; @@ -1122,4 +1116,3 @@ report 10582 "Sales - Credit Memo" NextEntryNo := NextEntryNo + 1 end; } - diff --git a/Apps/GB/ReportsGB/app/src/Reports/SalesInvoice.Report.al b/Apps/GB/ReportsGB/app/src/Reports/SalesInvoice.Report.al index 28c6a77b7f..d0abf89b1d 100644 --- a/Apps/GB/ReportsGB/app/src/Reports/SalesInvoice.Report.al +++ b/Apps/GB/ReportsGB/app/src/Reports/SalesInvoice.Report.al @@ -950,13 +950,7 @@ report 10583 "Sales - Invoice" CompanyInfo2: Record "Company Information"; SalesSetup: Record "Sales & Receivables Setup"; Cust: Record Customer; -#if not CLEAN25 -#pragma warning disable AL0432 -#endif TempVATAmountLine: Record "VAT Amount Line" temporary; -#if not CLEAN25 -#pragma warning restore AL0432 -#endif DimSetEntry1: Record "Dimension Set Entry"; DimSetEntry2: Record "Dimension Set Entry"; RespCenter: Record "Responsibility Center"; @@ -1176,4 +1170,3 @@ report 10583 "Sales - Invoice" NextEntryNo := NextEntryNo + 1 end; } - diff --git a/Apps/GB/ReportsGB/app/src/Reports/SalesQuoteGB.Report.al b/Apps/GB/ReportsGB/app/src/Reports/SalesQuoteGB.Report.al index 0d4eb7f900..bcc44f4385 100644 --- a/Apps/GB/ReportsGB/app/src/Reports/SalesQuoteGB.Report.al +++ b/Apps/GB/ReportsGB/app/src/Reports/SalesQuoteGB.Report.al @@ -906,13 +906,7 @@ report 10604 "Sales Quote GB" CompanyInfo2: Record "Company Information"; CompanyInfo3: Record "Company Information"; SalesSetup: Record "Sales & Receivables Setup"; -#if not CLEAN25 -#pragma warning disable AL0432 -#endif TempVATAmountLine: Record "VAT Amount Line" temporary; -#if not CLEAN25 -#pragma warning restore AL0432 -#endif TempSalesLine: Record "Sales Line" temporary; DimSetEntry1: Record "Dimension Set Entry"; DimSetEntry2: Record "Dimension Set Entry"; @@ -998,4 +992,3 @@ report 10604 "Sales Quote GB" FeatureNameTok: Label 'Sales Quote GB', Locked = true; EventNameTok: Label 'Sales Quote GB report has been used', Locked = true; } - diff --git a/Apps/GB/ReverseChargeVAT/app/src/Codeunits/ReverseChargeVATSubscribers.Codeunit.al b/Apps/GB/ReverseChargeVAT/app/src/Codeunits/ReverseChargeVATSubscribers.Codeunit.al index 8c148f30d6..b9346d6097 100644 --- a/Apps/GB/ReverseChargeVAT/app/src/Codeunits/ReverseChargeVATSubscribers.Codeunit.al +++ b/Apps/GB/ReverseChargeVAT/app/src/Codeunits/ReverseChargeVATSubscribers.Codeunit.al @@ -166,21 +166,9 @@ codeunit 10552 "Reverse Charge VAT Subscribers" end; [EventSubscriber(ObjectType::Table, Database::"Sales Line", OnInsertVATAmountOnBeforeInsert, '', false, false)] -#if not CLEAN25 -#pragma warning disable AL0432 -#endif local procedure OnInsertVATAmountOnBeforeInsert(var SalesLine: Record "Sales Line"; var VATAmountLine: Record "VAT Amount Line") -#if not CLEAN25 -#pragma warning restore AL0432 -#endif begin -#if not CLEAN25 -#pragma warning disable AL0432 -#endif VATAmountLine."Reverse Charge GB" := SalesLine."Reverse Charge GB"; -#if not CLEAN25 -#pragma warning restore AL0432 -#endif end; local procedure DomesticCustomerWarning(SalesLine: Record "Sales Line"; CurrFieldNo: Integer) @@ -229,13 +217,7 @@ codeunit 10552 "Reverse Charge VAT Subscribers" end; [EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales-Post", OnRunOnBeforeCalcVATAmountLines, '', false, false)] -#if not CLEAN25 -#pragma warning disable AL0432 -#endif local procedure OnRunOnBeforeCalcVATAmountLines(var TempSalesLineGlobal: Record "Sales Line" temporary; var SalesHeader: Record "Sales Header"; var TempVATAmountLine: Record "VAT Amount Line" temporary; var IsHandled: Boolean) -#if not CLEAN25 -#pragma warning restore AL0432 -#endif begin if SalesHeader.GetReverseChargeApplies() then TempSalesLineGlobal.SetReverseChargeAppliesGB(); diff --git a/Apps/GB/ReverseChargeVAT/app/src/TableExtensions/VATAmountLine.TableExt.al b/Apps/GB/ReverseChargeVAT/app/src/TableExtensions/VATAmountLine.TableExt.al index be51da6068..c5f21279fd 100644 --- a/Apps/GB/ReverseChargeVAT/app/src/TableExtensions/VATAmountLine.TableExt.al +++ b/Apps/GB/ReverseChargeVAT/app/src/TableExtensions/VATAmountLine.TableExt.al @@ -6,13 +6,7 @@ namespace Microsoft.Finance.VAT.Setup; using Microsoft.Finance.VAT.Calculation; -#if not CLEAN25 -#pragma warning disable AL0432 -#endif tableextension 10552 "VAT Amount Line" extends "VAT Amount Line" -#if not CLEAN25 -#pragma warning restore AL0432 -#endif { fields { diff --git a/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeConfigurationPageGB.Page.al b/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeConfigurationPageGB.Page.al index ed55f74fe4..4c8c3840f3 100644 --- a/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeConfigurationPageGB.Page.al +++ b/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeConfigurationPageGB.Page.al @@ -28,7 +28,7 @@ page 10503 "Postcode Configuration Page GB" ShowCaption = false; field(SelectedService; ServiceKeyText) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Caption = 'Address Provider'; Editable = false; @@ -106,4 +106,3 @@ page 10503 "Postcode Configuration Page GB" DisabledTok: Label 'Disabled'; ServiceKeyText: Text; } - diff --git a/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeSearchGB.Page.al b/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeSearchGB.Page.al index 5f88647613..c6bfa1d8aa 100644 --- a/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeSearchGB.Page.al +++ b/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeSearchGB.Page.al @@ -18,14 +18,14 @@ page 10505 "Postcode Search GB" { field(PostcodeField; Rec.Postcode) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Caption = 'Postcode'; Lookup = true; ShowMandatory = true; } field(DeliveryPoint; Rec.Address) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Caption = 'Delivery Point'; } } @@ -71,4 +71,3 @@ page 10505 "Postcode Search GB" ResultDeliveryPoint := Rec.Address; end; } - diff --git a/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeServiceLookupGB.Page.al b/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeServiceLookupGB.Page.al index 975403a732..dcec910cac 100644 --- a/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeServiceLookupGB.Page.al +++ b/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeServiceLookupGB.Page.al @@ -26,7 +26,7 @@ page 10506 "Postcode Service Lookup GB" { field(Name; Rec.Name) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; ToolTip = 'Specifies the name of the service to automatically insert post codes, such as GetAdress.io.'; } } @@ -70,4 +70,3 @@ page 10506 "Postcode Service Lookup GB" PostcodeServiceManager: Codeunit "Postcode Service Manager"; DisabledLbl: Label 'Disabled'; } - diff --git a/Apps/IN/INDataMigration/src/FinalizeIndiaMigration.Page.al b/Apps/IN/INDataMigration/src/FinalizeIndiaMigration.Page.al index 92ab4c9e05..d31269de6c 100644 --- a/Apps/IN/INDataMigration/src/FinalizeIndiaMigration.Page.al +++ b/Apps/IN/INDataMigration/src/FinalizeIndiaMigration.Page.al @@ -72,7 +72,7 @@ page 19010 "Finalize India Migration" { action(ActionBack) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Caption = 'Back'; Enabled = BackActionEnabled; Image = PreviousRecord; @@ -85,7 +85,7 @@ page 19010 "Finalize India Migration" } action(ActionNext) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Caption = 'Next'; Enabled = NextActionEnabled; Image = NextRecord; @@ -98,7 +98,7 @@ page 19010 "Finalize India Migration" } action(ActionFinish) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Caption = 'Finish'; Enabled = FinishActionEnabled; Image = Approve; diff --git a/Apps/IN/INGST/app/.resources/GSTUseCases/21957e13-9751-40a2-b591-67ade93573e7.json b/Apps/IN/INGST/app/.resources/GSTUseCases/21957e13-9751-40a2-b591-67ade93573e7.json index 5bc9a924bb..3269a2d0da 100644 --- a/Apps/IN/INGST/app/.resources/GSTUseCases/21957e13-9751-40a2-b591-67ade93573e7.json +++ b/Apps/IN/INGST/app/.resources/GSTUseCases/21957e13-9751-40a2-b591-67ade93573e7.json @@ -2,7 +2,7 @@ { "CaseID": "{21957E13-9751-40A2-B591-67ADE93573E7}", "Description": "Inter-State Purchase of Charge Item from Registered Vendor where Input Tax Credit is available", - "Version": 5, + "Version": 6, "MinorVersion": 0, "TaxType": "GST", "ChangedBy": "Microsoft", @@ -10,7 +10,7 @@ "TaxEntity": "Purchase Line", "ParentUseCase": "Purchase of Goods from Registered/Unregistered Vendor.", "ParentCaseId": "{5DA99FBE-AAAE-4DE9-8E7F-C4E15FC778B0}", - "PresentationOrder": 706, + "PresentationOrder": 710, "Indent": 1, "PostingTableName": "General Posting Setup", "PostingTableFilters": [ @@ -498,14 +498,14 @@ ], "Components": [ { - "ComponentName": "IGST", - "Sequence": 1, + "ComponentName": "GST Base Amount", + "Sequence": 2, "Formula": { - "VariableName": "IGST", - "Expression": "{Amount}*{IGST}/100", + "VariableName": "GST Base Amount", + "Expression": "{GST Base Amoumt}", "Tokens": [ { - "TokenName": "{Amount}", + "TokenName": "{GST Base Amoumt}", "TokenValue": { "Type": "Lookup", "Lookup": { @@ -514,29 +514,19 @@ "FieldName": "Amount" } } - }, - { - "TokenName": "{IGST}", - "TokenValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Component Percent", - "ComponentName": "IGST" - } - } } ] } }, { - "ComponentName": "GST Base Amount", - "Sequence": 2, + "ComponentName": "IGST", + "Sequence": 1, "Formula": { - "VariableName": "GST Base Amount", - "Expression": "{GST Base Amoumt}", + "VariableName": "IGST", + "Expression": "{Amount}*{IGST}/100", "Tokens": [ { - "TokenName": "{GST Base Amoumt}", + "TokenName": "{Amount}", "TokenValue": { "Type": "Lookup", "Lookup": { @@ -545,6 +535,16 @@ "FieldName": "Amount" } } + }, + { + "TokenName": "{IGST}", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Component Percent", + "ComponentName": "IGST" + } + } } ] } @@ -968,41 +968,66 @@ "When": [ { "ValueType": "Insert Record", - "Sequence": 0, + "Sequence": 1, "InsertRecord": { - "TableName": "GST Ledger Entry", + "TableName": "Detailed GST Ledger Entry", "RunTrigger": true, - "SubLedgerGrpBy": "Component", + "SubLedgerGrpBy": "Line / Component", "InsertRecordFields": [ { - "FieldName": "Gen. Bus. Posting Group", - "Sequence": 1, + "FieldName": "Entry No.", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Gen. Bus. Posting Group" + "SourceType": "Posting Field", + "PostingVariableName": "G/L Entry No." } } }, { - "FieldName": "Gen. Prod. Posting Group", - "Sequence": 2, + "FieldName": "Entry Type", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Initial Entry" + } + }, + { + "FieldName": "Transaction Type", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Purchase" + } + }, + { + "FieldName": "Document Type", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Invoice" + } + }, + { + "FieldName": "Document No.", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Gen. Prod. Posting Group" + "SourceType": "Posting Field", + "PostingVariableName": "Posted Document No." } } }, { "FieldName": "Posting Date", - "Sequence": 3, + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", @@ -1041,175 +1066,147 @@ } }, { - "FieldName": "Document No.", - "Sequence": 4, + "FieldName": "Type", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Posted Document No." + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Type" } } }, { - "FieldName": "Document Type", - "Sequence": 5, + "FieldName": "No.", + "Sequence": 0, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "Invoice" + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "No." + } } }, { - "FieldName": "Transaction Type", - "Sequence": 6, + "FieldName": "Product Type", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Constant", - "Value": "Purchase" + "Value": "Item" } }, { - "FieldName": "GST Base Amount", - "Sequence": 7, + "FieldName": "Source Type", + "Sequence": 0, "ReverseSign": false, "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Component", - "ComponentName": "GST Base Amount" - } + "Type": "Constant", + "Value": "Vendor" } }, { - "FieldName": "GST Base Amount", - "Sequence": 26, + "FieldName": "Source No.", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Component", - "ComponentName": "GST Base Amount" + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Buy-from Vendor No." } } }, { - "FieldName": "Source Type", - "Sequence": 8, + "FieldName": "HSN/SAC Code", + "Sequence": 0, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "Vendor" + "Type": "Lookup", + "Lookup": { + "SourceType": "Tax Attributes", + "AttributeName": "HSN/SAC" + } } }, { - "FieldName": "Source No.", - "Sequence": 10, + "FieldName": "GST Component Code", + "Sequence": 0, "ReverseSign": false, "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Pay-to Vendor No." - } + "Type": "Constant", + "Value": "IGST" } }, { - "FieldName": "User ID", - "Sequence": 11, + "FieldName": "GST Group Code", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Database", - "DatabaseVariableName": "UserId" + "SourceType": "Tax Attributes", + "AttributeName": "GST Group Code" } } }, { - "FieldName": "Source Code", - "Sequence": 12, + "FieldName": "GST Jurisdiction Type", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Table", - "TableName": "Source Code Setup", - "TableFieldName": "Purchases", - "Method": "First", - "TableFilters": [] + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "GST Jurisdiction Type" } } }, { - "FieldName": "Reason Code", - "Sequence": 13, + "FieldName": "GST Base Amount", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Table", - "TableName": "Purchase Header", - "TableFieldName": "Reason Code", - "Method": "First", - "TableFilters": [ - { - "FiterFieldName": "Document Type", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Document Type" - } - } - }, - { - "FiterFieldName": "No.", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Document No." - } - } - } - ] + "SourceType": "Component", + "ComponentName": "GST Base Amount" } } }, { - "FieldName": "Purchase Group Type", - "Sequence": 14, + "FieldName": "GST %", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Tax Attributes", - "AttributeName": "GST Group Type" + "SourceType": "Component Percent", + "ComponentName": "IGST" } } }, { - "FieldName": "Transaction No.", - "Sequence": 25, + "FieldName": "GST Amount", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "G/L Entry Transaction No." + "SourceType": "Component", + "ComponentName": "IGST" } } }, { "FieldName": "External Document No.", - "Sequence": 15, + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", @@ -1248,85 +1245,149 @@ } }, { - "FieldName": "GST Component Code", - "Sequence": 16, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "IGST" - } - }, - { - "FieldName": "Reverse Charge", - "Sequence": 17, + "FieldName": "Quantity", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Purchase Line", - "FieldName": "GST Reverse Charge" + "FieldName": "Qty. to Invoice" } } }, { - "FieldName": "GST Amount", - "Sequence": 18, + "FieldName": "G/L Account No.", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Component", - "ComponentName": "IGST" + "SourceType": "Table", + "TableName": "GST Posting Setup", + "TableFieldName": "Receivable Account (Interim)", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "State Code", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Purchase Header", + "TableFieldName": "Location State Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FiterFieldName": "Component ID", + "FilterType": "Equals", + "FilterValue": { + "Type": "Constant", + "Value": "3" + } + } + ] } } }, { - "FieldName": "Currency Code", - "Sequence": 19, + "FieldName": "Document Line No.", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Posted Document Line No." + } + } + }, + { + "FieldName": "Item Charge Entry", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "true" + } + }, + { + "FieldName": "Reverse Charge", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Purchase Line", - "FieldName": "Currency Code" + "FieldName": "GST Reverse Charge" } } }, { - "FieldName": "Currency Factor", - "Sequence": 20, + "FieldName": "GST Exempted Goods", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Exempted" + } + } + }, + { + "FieldName": "Location Reg. No.", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Table", - "TableName": "Purchase Header", - "TableFieldName": "Currency Factor", + "TableName": "Location", + "TableFieldName": "GST Registration No.", "Method": "First", "TableFilters": [ { - "FiterFieldName": "Document Type", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Document Type" - } - } - }, - { - "FiterFieldName": "No.", + "FiterFieldName": "Code", "FilterType": "Equals", "FilterValue": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Purchase Line", - "FieldName": "Document No." + "FieldName": "Location Code" } } } @@ -1335,24 +1396,65 @@ } }, { - "FieldName": "Entry Type", - "Sequence": 21, + "FieldName": "Buyer/Seller Reg. No.", + "Sequence": 0, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "Initial Entry" + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "BuyerSellerRegNo" + } } }, { - "FieldName": "Input Service Distribution", - "Sequence": 22, + "FieldName": "GST Group Type", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Tax Attributes", + "AttributeName": "GST Group Type" + } + } + }, + { + "FieldName": "GST Credit", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "GST Credit" + } + } + }, + { + "FieldName": "Currency Code", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Currency Code" + } + } + }, + { + "FieldName": "Currency Factor", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Table", "TableName": "Purchase Header", - "TableFieldName": "GST Input Service Distribution", + "TableFieldName": "Currency Factor", "Method": "First", "TableFilters": [ { @@ -1384,15 +1486,28 @@ } }, { - "FieldName": "POS Out Of India", - "Sequence": 23, + "FieldName": "Location Code", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Location Code" + } + } + }, + { + "FieldName": "GST Vendor Type", + "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Table", "TableName": "Purchase Header", - "TableFieldName": "POS Out Of India", + "TableFieldName": "GST Vendor Type", "Method": "First", "TableFilters": [ { @@ -1424,15 +1539,12 @@ } }, { - "FieldName": "G/L Entry No.", - "Sequence": 24, + "FieldName": "Eligibility for ITC", + "Sequence": 0, "ReverseSign": false, "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "G/L Entry No." - } + "Type": "Constant", + "Value": "Input Services" } } ] @@ -1440,66 +1552,41 @@ }, { "ValueType": "Insert Record", - "Sequence": 1, + "Sequence": 0, "InsertRecord": { - "TableName": "Detailed GST Ledger Entry", + "TableName": "GST Ledger Entry", "RunTrigger": true, - "SubLedgerGrpBy": "Line / Component", + "SubLedgerGrpBy": "Component", "InsertRecordFields": [ { - "FieldName": "Entry No.", - "Sequence": 0, + "FieldName": "Gen. Bus. Posting Group", + "Sequence": 1, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "G/L Entry No." + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Gen. Bus. Posting Group" } } }, { - "FieldName": "Entry Type", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "Initial Entry" - } - }, - { - "FieldName": "Transaction Type", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "Purchase" - } - }, - { - "FieldName": "Document Type", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "Invoice" - } - }, - { - "FieldName": "Document No.", - "Sequence": 0, + "FieldName": "Gen. Prod. Posting Group", + "Sequence": 2, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Posted Document No." + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Gen. Prod. Posting Group" } } }, { "FieldName": "Posting Date", - "Sequence": 0, + "Sequence": 3, "ReverseSign": false, "Lookup": { "Type": "Lookup", @@ -1538,154 +1625,118 @@ } }, { - "FieldName": "Type", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Type" - } - } - }, - { - "FieldName": "No.", - "Sequence": 0, + "FieldName": "Document No.", + "Sequence": 4, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "No." + "SourceType": "Posting Field", + "PostingVariableName": "Posted Document No." } } }, { - "FieldName": "Product Type", - "Sequence": 0, + "FieldName": "Document Type", + "Sequence": 5, "ReverseSign": false, "Lookup": { "Type": "Constant", - "Value": "Item" + "Value": "Invoice" } }, { - "FieldName": "Source Type", - "Sequence": 0, + "FieldName": "Transaction Type", + "Sequence": 6, "ReverseSign": false, "Lookup": { "Type": "Constant", - "Value": "Vendor" + "Value": "Purchase" } }, { - "FieldName": "Source No.", - "Sequence": 0, + "FieldName": "GST Base Amount", + "Sequence": 7, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Buy-from Vendor No." + "SourceType": "Component", + "ComponentName": "GST Base Amount" } } }, { - "FieldName": "HSN/SAC Code", - "Sequence": 0, + "FieldName": "GST Base Amount", + "Sequence": 26, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Tax Attributes", - "AttributeName": "HSN/SAC" + "SourceType": "Component", + "ComponentName": "GST Base Amount" } } }, { - "FieldName": "GST Component Code", - "Sequence": 0, + "FieldName": "Source Type", + "Sequence": 8, "ReverseSign": false, "Lookup": { "Type": "Constant", - "Value": "IGST" - } - }, - { - "FieldName": "GST Group Code", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Tax Attributes", - "AttributeName": "GST Group Code" - } + "Value": "Vendor" } }, { - "FieldName": "GST Jurisdiction Type", - "Sequence": 0, + "FieldName": "Source No.", + "Sequence": 10, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Purchase Line", - "FieldName": "GST Jurisdiction Type" - } - } - }, - { - "FieldName": "GST Base Amount", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Component", - "ComponentName": "GST Base Amount" + "FieldName": "Pay-to Vendor No." } } }, { - "FieldName": "GST %", - "Sequence": 0, + "FieldName": "User ID", + "Sequence": 11, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Component Percent", - "ComponentName": "IGST" + "SourceType": "Database", + "DatabaseVariableName": "UserId" } } }, { - "FieldName": "GST Amount", - "Sequence": 0, + "FieldName": "Source Code", + "Sequence": 12, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Component", - "ComponentName": "IGST" + "SourceType": "Table", + "TableName": "Source Code Setup", + "TableFieldName": "Purchases", + "Method": "First", + "TableFilters": [] } } }, - { - "FieldName": "External Document No.", - "Sequence": 0, + { + "FieldName": "Reason Code", + "Sequence": 13, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Table", "TableName": "Purchase Header", - "TableFieldName": "Vendor Invoice No.", + "TableFieldName": "Reason Code", "Method": "First", "TableFilters": [ { @@ -1717,75 +1768,63 @@ } }, { - "FieldName": "Quantity", - "Sequence": 0, + "FieldName": "Purchase Group Type", + "Sequence": 14, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Qty. to Invoice" + "SourceType": "Tax Attributes", + "AttributeName": "GST Group Type" } } }, { - "FieldName": "G/L Account No.", - "Sequence": 0, + "FieldName": "Transaction No.", + "Sequence": 25, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "G/L Entry Transaction No." + } + } + }, + { + "FieldName": "External Document No.", + "Sequence": 15, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Table", - "TableName": "GST Posting Setup", - "TableFieldName": "Receivable Account (Interim)", + "TableName": "Purchase Header", + "TableFieldName": "Vendor Invoice No.", "Method": "First", "TableFilters": [ { - "FiterFieldName": "State Code", + "FiterFieldName": "Document Type", "FilterType": "Equals", "FilterValue": { "Type": "Lookup", "Lookup": { - "SourceType": "Table", - "TableName": "Purchase Header", - "TableFieldName": "Location State Code", - "Method": "First", - "TableFilters": [ - { - "FiterFieldName": "Document Type", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Document Type" - } - } - }, - { - "FiterFieldName": "No.", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Document No." - } - } - } - ] + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" } } }, { - "FiterFieldName": "Component ID", + "FiterFieldName": "No.", "FilterType": "Equals", "FilterValue": { - "Type": "Constant", - "Value": "3" + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } } } ] @@ -1793,73 +1832,98 @@ } }, { - "FieldName": "Document Line No.", - "Sequence": 0, + "FieldName": "GST Component Code", + "Sequence": 16, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "IGST" + } + }, + { + "FieldName": "Reverse Charge", + "Sequence": 17, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Posted Document Line No." + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "GST Reverse Charge" } } }, { - "FieldName": "Item Charge Entry", - "Sequence": 0, + "FieldName": "GST Amount", + "Sequence": 18, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "true" + "Type": "Lookup", + "Lookup": { + "SourceType": "Component", + "ComponentName": "IGST" + } } }, { - "FieldName": "Reverse Charge", - "Sequence": 0, + "FieldName": "Currency Code", + "Sequence": 19, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Purchase Line", - "FieldName": "GST Reverse Charge" + "FieldName": "Currency Code" } } }, { - "FieldName": "GST Exempted Goods", - "Sequence": 0, + "FieldName": "Currency Code", + "Sequence": 27, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Purchase Line", - "FieldName": "Exempted" + "FieldName": "Currency Code" } } }, { - "FieldName": "Location Reg. No.", - "Sequence": 0, + "FieldName": "Currency Factor", + "Sequence": 20, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Table", - "TableName": "Location", - "TableFieldName": "GST Registration No.", + "TableName": "Purchase Header", + "TableFieldName": "Currency Factor", "Method": "First", "TableFilters": [ { - "FiterFieldName": "Code", + "FiterFieldName": "Document Type", "FilterType": "Equals", "FilterValue": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Purchase Line", - "FieldName": "Location Code" + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." } } } @@ -1868,65 +1932,104 @@ } }, { - "FieldName": "Buyer/Seller Reg. No.", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "BuyerSellerRegNo" - } - } - }, - { - "FieldName": "GST Group Type", - "Sequence": 0, + "FieldName": "Currency Factor", + "Sequence": 28, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Tax Attributes", - "AttributeName": "GST Group Type" + "SourceType": "Table", + "TableName": "Purchase Header", + "TableFieldName": "Currency Factor", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } + } + } + ] } } }, { - "FieldName": "GST Credit", - "Sequence": 0, + "FieldName": "Entry Type", + "Sequence": 21, "ReverseSign": false, "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "GST Credit" - } + "Type": "Constant", + "Value": "Initial Entry" } }, { - "FieldName": "Location Code", - "Sequence": 0, + "FieldName": "Input Service Distribution", + "Sequence": 22, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Location Code" + "SourceType": "Table", + "TableName": "Purchase Header", + "TableFieldName": "GST Input Service Distribution", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } + } + } + ] } } }, { - "FieldName": "GST Vendor Type", - "Sequence": 0, + "FieldName": "POS Out Of India", + "Sequence": 23, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Table", "TableName": "Purchase Header", - "TableFieldName": "GST Vendor Type", + "TableFieldName": "POS Out Of India", "Method": "First", "TableFilters": [ { @@ -1958,12 +2061,15 @@ } }, { - "FieldName": "Eligibility for ITC", - "Sequence": 0, + "FieldName": "G/L Entry No.", + "Sequence": 24, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "Input Services" + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "G/L Entry No." + } } } ] diff --git a/Apps/IN/INGST/app/.resources/GSTUseCases/4e1d5479-c527-4295-a0c1-7d82d94860f6.json b/Apps/IN/INGST/app/.resources/GSTUseCases/4e1d5479-c527-4295-a0c1-7d82d94860f6.json index ba85559a47..e4c42d1878 100644 --- a/Apps/IN/INGST/app/.resources/GSTUseCases/4e1d5479-c527-4295-a0c1-7d82d94860f6.json +++ b/Apps/IN/INGST/app/.resources/GSTUseCases/4e1d5479-c527-4295-a0c1-7d82d94860f6.json @@ -2,7 +2,7 @@ { "CaseID": "{4E1D5479-C527-4295-A0C1-7D82D94860F6}", "Description": "Inter-State Sales Return of Service to Registered Customer through Sales Journal/Journal/General Journal.", - "Version": 1, + "Version": 2, "MinorVersion": 0, "TaxType": "GST", "ChangedBy": "Microsoft", @@ -10,7 +10,7 @@ "TaxEntity": "Gen. Journal Line", "ParentUseCase": "Sales of Goods from Registered/Unregistered Customer through Sales Journal/General Journal.", "ParentCaseId": "{DBFAD9E1-15D2-44E9-9305-E453D15DE128}", - "PresentationOrder": 960, + "PresentationOrder": 963, "Indent": 1, "PostingTableName": "GST Posting Setup", "PostingTableFilters": [ @@ -44,14 +44,14 @@ "PostingScript": [], "Components": [ { - "ComponentName": "GST Base Amount", + "ComponentName": "IGST", "Sequence": 0, "Formula": { - "VariableName": "GST Base Amount", - "Expression": "Amount", + "VariableName": "IGST", + "Expression": "{Amount}*{iGST}/100", "Tokens": [ { - "TokenName": "Amount", + "TokenName": "{Amount}", "TokenValue": { "Type": "Lookup", "Lookup": { @@ -60,19 +60,29 @@ "FieldName": "Amount" } } + }, + { + "TokenName": "{iGST}", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Component Percent", + "ComponentName": "IGST" + } + } } ] } }, { - "ComponentName": "IGST", + "ComponentName": "GST Base Amount", "Sequence": 0, "Formula": { - "VariableName": "IGST", - "Expression": "{Amount}*{iGST}/100", + "VariableName": "GST Base Amount", + "Expression": "Amount", "Tokens": [ { - "TokenName": "{Amount}", + "TokenName": "Amount", "TokenValue": { "Type": "Lookup", "Lookup": { @@ -81,16 +91,6 @@ "FieldName": "Amount" } } - }, - { - "TokenName": "{iGST}", - "TokenValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Component Percent", - "ComponentName": "IGST" - } - } } ] } @@ -260,213 +260,6 @@ } ], "When": [ - { - "ValueType": "Insert Record", - "Sequence": 2, - "InsertRecord": { - "TableName": "Detailed GST Ledger Entry Info", - "RunTrigger": true, - "SubLedgerGrpBy": "Line / Component", - "InsertRecordFields": [ - { - "FieldName": "User ID", - "Sequence": 40, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Database", - "DatabaseVariableName": "UserId" - } - } - }, - { - "FieldName": "Nature of Supply", - "Sequence": 19, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Nature of Supply" - } - } - }, - { - "FieldName": "Location State Code", - "Sequence": 20, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Location State Code" - } - } - }, - { - "FieldName": "Buyer/Seller State Code", - "Sequence": 21, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Table", - "TableName": "Customer", - "TableFieldName": "State Code", - "Method": "First", - "TableFilters": [ - { - "FiterFieldName": "No.", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Account No." - } - } - } - ] - } - } - }, - { - "FieldName": "Shipping Address State Code", - "Sequence": 22, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "GST Ship-to State Code" - } - } - }, - { - "FieldName": "Bill Of Export No.", - "Sequence": 29, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Bill Of Export No." - } - } - }, - { - "FieldName": "Bill Of Export Date", - "Sequence": 30, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Bill Of Export Date" - } - } - }, - { - "FieldName": "e-Comm. Merchant Id", - "Sequence": 31, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "e-Commerce Merchant Id" - } - } - }, - { - "FieldName": "Sales Invoice Type", - "Sequence": 43, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Sales Invoice Type" - } - } - }, - { - "FieldName": "Gen. Bus. Posting Group", - "Sequence": 33, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Gen. Bus. Posting Group" - } - } - }, - { - "FieldName": "Gen. Prod. Posting Group", - "Sequence": 34, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Gen. Prod. Posting Group" - } - } - }, - { - "FieldName": "Ship-to Code", - "Sequence": 37, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Ship-to Code" - } - } - }, - { - "FieldName": "Location ARN No.", - "Sequence": 38, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Table", - "TableName": "Location", - "TableFieldName": "Location ARN No.", - "Method": "First", - "TableFilters": [ - { - "FiterFieldName": "Code", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Location Code" - } - } - } - ] - } - } - } - ] - } - }, { "ValueType": "Insert Record", "Sequence": 1, @@ -475,15 +268,6 @@ "RunTrigger": true, "SubLedgerGrpBy": "Line / Component", "InsertRecordFields": [ - { - "FieldName": "", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "" - } - }, { "FieldName": "Transaction Type", "Sequence": 7, @@ -980,6 +764,213 @@ ] } }, + { + "ValueType": "Insert Record", + "Sequence": 2, + "InsertRecord": { + "TableName": "Detailed GST Ledger Entry Info", + "RunTrigger": true, + "SubLedgerGrpBy": "Line / Component", + "InsertRecordFields": [ + { + "FieldName": "User ID", + "Sequence": 40, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Database", + "DatabaseVariableName": "UserId" + } + } + }, + { + "FieldName": "Nature of Supply", + "Sequence": 19, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Nature of Supply" + } + } + }, + { + "FieldName": "Location State Code", + "Sequence": 20, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Location State Code" + } + } + }, + { + "FieldName": "Buyer/Seller State Code", + "Sequence": 21, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Customer", + "TableFieldName": "State Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Account No." + } + } + } + ] + } + } + }, + { + "FieldName": "Shipping Address State Code", + "Sequence": 22, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "GST Ship-to State Code" + } + } + }, + { + "FieldName": "Bill Of Export No.", + "Sequence": 29, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Bill Of Export No." + } + } + }, + { + "FieldName": "Bill Of Export Date", + "Sequence": 30, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Bill Of Export Date" + } + } + }, + { + "FieldName": "e-Comm. Merchant Id", + "Sequence": 31, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "E-Comm. Merchant Id" + } + } + }, + { + "FieldName": "Sales Invoice Type", + "Sequence": 43, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Sales Invoice Type" + } + } + }, + { + "FieldName": "Gen. Bus. Posting Group", + "Sequence": 33, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Bus. Posting Group" + } + } + }, + { + "FieldName": "Gen. Prod. Posting Group", + "Sequence": 34, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Prod. Posting Group" + } + } + }, + { + "FieldName": "Ship-to Code", + "Sequence": 37, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Ship-to Code" + } + } + }, + { + "FieldName": "Location ARN No.", + "Sequence": 38, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Location", + "TableFieldName": "Location ARN No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Code", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Location Code" + } + } + } + ] + } + } + } + ] + } + }, { "ValueType": "Insert Record", "Sequence": 0, diff --git a/Apps/IN/INGST/app/.resources/GSTUseCases/4f234b8b-1b95-4938-b3df-3d96784eac77.json b/Apps/IN/INGST/app/.resources/GSTUseCases/4f234b8b-1b95-4938-b3df-3d96784eac77.json index d9a90befbf..25a9e9c3a5 100644 --- a/Apps/IN/INGST/app/.resources/GSTUseCases/4f234b8b-1b95-4938-b3df-3d96784eac77.json +++ b/Apps/IN/INGST/app/.resources/GSTUseCases/4f234b8b-1b95-4938-b3df-3d96784eac77.json @@ -2,7 +2,7 @@ { "CaseID": "{4F234B8B-1B95-4938-B3DF-3D96784EAC77}", "Description": "Intra-State Purchase of Charge Item from Registered Vendor when Input Tax Credit is Available Through Purchase Invoice/Order/Quote", - "Version": 4, + "Version": 5, "MinorVersion": 0, "TaxType": "GST", "ChangedBy": "Microsoft", @@ -10,7 +10,7 @@ "TaxEntity": "Purchase Line", "ParentUseCase": "Purchase of Goods from Registered/Unregistered Vendor.", "ParentCaseId": "{5DA99FBE-AAAE-4DE9-8E7F-C4E15FC778B0}", - "PresentationOrder": 665, + "PresentationOrder": 669, "Indent": 1, "PostingTableName": "GST Posting Setup", "PostingTableFilters": [ @@ -410,27 +410,6 @@ } ], "Components": [ - { - "ComponentName": "GST Base Amount", - "Sequence": 0, - "Formula": { - "VariableName": "GST Base Amount", - "Expression": "{LineAmuont}", - "Tokens": [ - { - "TokenName": "{LineAmuont}", - "TokenValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Amount" - } - } - } - ] - } - }, { "ComponentName": "SGST", "Sequence": 0, @@ -492,6 +471,27 @@ } ] } + }, + { + "ComponentName": "GST Base Amount", + "Sequence": 0, + "Formula": { + "VariableName": "GST Base Amount", + "Expression": "{LineAmuont}", + "Tokens": [ + { + "TokenName": "{LineAmuont}", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Amount" + } + } + } + ] + } } ], "Condition": { @@ -792,7 +792,7 @@ }, "TaxPostingSetup": [ { - "ComponentName": "CGST", + "ComponentName": "SGST", "TableName": "GST Posting Setup", "AccountSourceType": "Field", "FieldName": "Receivable Account", @@ -806,37 +806,115 @@ "FilterType": "Equals", "FilterValue": { "Type": "Constant", - "Value": "2" + "Value": "6" } } ], "When": [ { "ValueType": "Insert Record", - "Sequence": 1, + "Sequence": 2, "InsertRecord": { - "TableName": "Detailed GST Ledger Entry", + "TableName": "Detailed GST Ledger Entry Info", "RunTrigger": true, "SubLedgerGrpBy": "Line / Component", "InsertRecordFields": [ { - "FieldName": "Entry Type", + "FieldName": "User ID", "Sequence": 0, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "Initial Entry" + "Type": "Lookup", + "Lookup": { + "SourceType": "Database", + "DatabaseVariableName": "UserId" + } } }, { - "FieldName": "Transaction Type", + "FieldName": "Positive", "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Constant", - "Value": "Purchase" + "Value": "Yes" + } + }, + { + "FieldName": "Location State Code", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Purchase Header", + "TableFieldName": "Location State Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Buyer/Seller State Code", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "BuyerSellerStateCode" + } } }, + { + "FieldName": "Order Address Code", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "OrderAddressCode" + } + } + } + ] + } + }, + { + "ValueType": "Insert Record", + "Sequence": 1, + "InsertRecord": { + "TableName": "Detailed GST Ledger Entry", + "RunTrigger": true, + "SubLedgerGrpBy": "Line / Component", + "InsertRecordFields": [ { "FieldName": "Document Type", "Sequence": 0, @@ -973,7 +1051,7 @@ "ReverseSign": false, "Lookup": { "Type": "Constant", - "Value": "CGST" + "Value": "SGST" } }, { @@ -1022,7 +1100,7 @@ "Type": "Lookup", "Lookup": { "SourceType": "Component Percent", - "ComponentName": "CGST" + "ComponentName": "SGST" } } }, @@ -1034,7 +1112,7 @@ "Type": "Lookup", "Lookup": { "SourceType": "Component", - "ComponentName": "CGST" + "ComponentName": "SGST" } } }, @@ -1135,7 +1213,7 @@ "FilterType": "Equals", "FilterValue": { "Type": "Constant", - "Value": "2" + "Value": "6" } } ] @@ -1149,9 +1227,8 @@ "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Line No." + "SourceType": "Posting Field", + "PostingVariableName": "Posted Document Line No." } } }, @@ -1164,19 +1241,6 @@ "Value": "true" } }, - { - "FieldName": "Reverse Charge", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "GST Reverse Charge" - } - } - }, { "FieldName": "Location Reg. No.", "Sequence": 0, @@ -1235,6 +1299,59 @@ "Value": "Availment" } }, + { + "FieldName": "Currency Code", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Currency Code" + } + } + }, + { + "FieldName": "Currency Factor", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Purchase Header", + "TableFieldName": "Currency Factor", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, { "FieldName": "GST Vendor Type", "Sequence": 0, @@ -1338,35 +1455,40 @@ }, { "ValueType": "Insert Record", - "Sequence": 2, + "Sequence": 0, "InsertRecord": { - "TableName": "Detailed GST Ledger Entry Info", + "TableName": "GST Ledger Entry", "RunTrigger": true, - "SubLedgerGrpBy": "Line / Component", + "SubLedgerGrpBy": "Component", "InsertRecordFields": [ { - "FieldName": "User ID", + "FieldName": "Gen. Bus. Posting Group", "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Database", - "DatabaseVariableName": "UserId" + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Gen. Bus. Posting Group" } } }, { - "FieldName": "Positive", + "FieldName": "Gen. Prod. Posting Group", "Sequence": 0, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "Yes" + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Gen. Prod. Posting Group" + } } }, { - "FieldName": "Location State Code", + "FieldName": "Posting Date", "Sequence": 0, "ReverseSign": false, "Lookup": { @@ -1374,7 +1496,7 @@ "Lookup": { "SourceType": "Table", "TableName": "Purchase Header", - "TableFieldName": "Location State Code", + "TableFieldName": "Posting Date", "Method": "First", "TableFilters": [ { @@ -1406,123 +1528,24 @@ } }, { - "FieldName": "Buyer/Seller State Code", + "FieldName": "Document No.", "Sequence": 0, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Variable", - "VariableName": "BuyerSellerStateCode" + "SourceType": "Posting Field", + "PostingVariableName": "Posted Document No." } } }, { - "FieldName": "Order Address Code", + "FieldName": "Document Type", "Sequence": 0, "ReverseSign": false, "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "OrderAddressCode" - } - } - } - ] - } - }, - { - "ValueType": "Insert Record", - "Sequence": 0, - "InsertRecord": { - "TableName": "GST Ledger Entry", - "RunTrigger": true, - "SubLedgerGrpBy": "Component", - "InsertRecordFields": [ - { - "FieldName": "Gen. Bus. Posting Group", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Gen. Bus. Posting Group" - } - } - }, - { - "FieldName": "Gen. Prod. Posting Group", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Gen. Prod. Posting Group" - } - } - }, - { - "FieldName": "Posting Date", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Table", - "TableName": "Purchase Header", - "TableFieldName": "Posting Date", - "Method": "First", - "TableFilters": [ - { - "FiterFieldName": "Document Type", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Document Type" - } - } - }, - { - "FiterFieldName": "No.", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Document No." - } - } - } - ] - } - } - }, - { - "FieldName": "Document No.", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Posted Document No." - } - } - }, - { - "FieldName": "Document Type", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "Invoice" + "Type": "Constant", + "Value": "Invoice" } }, { @@ -1693,7 +1716,7 @@ "ReverseSign": false, "Lookup": { "Type": "Constant", - "Value": "CGST" + "Value": "SGST" } }, { @@ -1717,7 +1740,60 @@ "Type": "Lookup", "Lookup": { "SourceType": "Component", - "ComponentName": "CGST" + "ComponentName": "SGST" + } + } + }, + { + "FieldName": "Currency Code", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Currency Code" + } + } + }, + { + "FieldName": "Currency Factor", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Purchase Header", + "TableFieldName": "Currency Factor", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } + } + } + ] } } }, @@ -1793,7 +1869,7 @@ "Lookup": { "SourceType": "Current Record", "TableName": "Purchase Line", - "FieldName": "Document No." + "FieldName": "Buy-from Vendor No." } } } @@ -1819,7 +1895,7 @@ ] }, { - "ComponentName": "SGST", + "ComponentName": "CGST", "TableName": "GST Posting Setup", "AccountSourceType": "Field", "FieldName": "Receivable Account", @@ -1833,11 +1909,107 @@ "FilterType": "Equals", "FilterValue": { "Type": "Constant", - "Value": "6" + "Value": "2" } } ], "When": [ + { + "ValueType": "Insert Record", + "Sequence": 2, + "InsertRecord": { + "TableName": "Detailed GST Ledger Entry Info", + "RunTrigger": true, + "SubLedgerGrpBy": "Line / Component", + "InsertRecordFields": [ + { + "FieldName": "User ID", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Database", + "DatabaseVariableName": "UserId" + } + } + }, + { + "FieldName": "Positive", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Yes" + } + }, + { + "FieldName": "Location State Code", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Purchase Header", + "TableFieldName": "Location State Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Buyer/Seller State Code", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "BuyerSellerStateCode" + } + } + }, + { + "FieldName": "Order Address Code", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "OrderAddressCode" + } + } + } + ] + } + }, { "ValueType": "Insert Record", "Sequence": 1, @@ -1846,6 +2018,24 @@ "RunTrigger": true, "SubLedgerGrpBy": "Line / Component", "InsertRecordFields": [ + { + "FieldName": "Entry Type", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Initial Entry" + } + }, + { + "FieldName": "Transaction Type", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Purchase" + } + }, { "FieldName": "Document Type", "Sequence": 0, @@ -1982,7 +2172,7 @@ "ReverseSign": false, "Lookup": { "Type": "Constant", - "Value": "SGST" + "Value": "CGST" } }, { @@ -2031,7 +2221,7 @@ "Type": "Lookup", "Lookup": { "SourceType": "Component Percent", - "ComponentName": "SGST" + "ComponentName": "CGST" } } }, @@ -2043,7 +2233,7 @@ "Type": "Lookup", "Lookup": { "SourceType": "Component", - "ComponentName": "SGST" + "ComponentName": "CGST" } } }, @@ -2144,7 +2334,7 @@ "FilterType": "Equals", "FilterValue": { "Type": "Constant", - "Value": "6" + "Value": "2" } } ] @@ -2158,8 +2348,9 @@ "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Posted Document Line No." + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Line No." } } }, @@ -2172,6 +2363,19 @@ "Value": "true" } }, + { + "FieldName": "Reverse Charge", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "GST Reverse Charge" + } + } + }, { "FieldName": "Location Reg. No.", "Sequence": 0, @@ -2231,7 +2435,20 @@ } }, { - "FieldName": "GST Vendor Type", + "FieldName": "Currency Code", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Currency Code" + } + } + }, + { + "FieldName": "Currency Factor", "Sequence": 0, "ReverseSign": false, "Lookup": { @@ -2239,7 +2456,7 @@ "Lookup": { "SourceType": "Table", "TableName": "Purchase Header", - "TableFieldName": "GST Vendor Type", + "TableFieldName": "Currency Factor", "Method": "First", "TableFilters": [ { @@ -2271,16 +2488,7 @@ } }, { - "FieldName": "Credit Availed", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "Yes" - } - }, - { - "FieldName": "Input Service Distribution", + "FieldName": "GST Vendor Type", "Sequence": 0, "ReverseSign": false, "Lookup": { @@ -2288,7 +2496,7 @@ "Lookup": { "SourceType": "Table", "TableName": "Purchase Header", - "TableFieldName": "GST Input Service Distribution", + "TableFieldName": "GST Vendor Type", "Method": "First", "TableFilters": [ { @@ -2320,39 +2528,7 @@ } }, { - "FieldName": "Eligibility for ITC", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "Input Services" - } - } - ] - } - }, - { - "ValueType": "Insert Record", - "Sequence": 2, - "InsertRecord": { - "TableName": "Detailed GST Ledger Entry Info", - "RunTrigger": true, - "SubLedgerGrpBy": "Line / Component", - "InsertRecordFields": [ - { - "FieldName": "User ID", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Database", - "DatabaseVariableName": "UserId" - } - } - }, - { - "FieldName": "Positive", + "FieldName": "Credit Availed", "Sequence": 0, "ReverseSign": false, "Lookup": { @@ -2361,7 +2537,7 @@ } }, { - "FieldName": "Location State Code", + "FieldName": "Input Service Distribution", "Sequence": 0, "ReverseSign": false, "Lookup": { @@ -2369,7 +2545,7 @@ "Lookup": { "SourceType": "Table", "TableName": "Purchase Header", - "TableFieldName": "Location State Code", + "TableFieldName": "GST Input Service Distribution", "Method": "First", "TableFilters": [ { @@ -2401,27 +2577,12 @@ } }, { - "FieldName": "Buyer/Seller State Code", - "Sequence": 0, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "BuyerSellerStateCode" - } - } - }, - { - "FieldName": "Order Address Code", + "FieldName": "Eligibility for ITC", "Sequence": 0, "ReverseSign": false, "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "OrderAddressCode" - } + "Type": "Constant", + "Value": "Input Services" } } ] @@ -2442,9 +2603,8 @@ "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Gen. Bus. Posting Group" + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Bus. Posting Group" } } }, @@ -2455,9 +2615,8 @@ "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Gen. Prod. Posting Group" + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Prod. Posting Group" } } }, @@ -2690,7 +2849,7 @@ "ReverseSign": false, "Lookup": { "Type": "Constant", - "Value": "SGST" + "Value": "CGST" } }, { @@ -2714,7 +2873,60 @@ "Type": "Lookup", "Lookup": { "SourceType": "Component", - "ComponentName": "SGST" + "ComponentName": "CGST" + } + } + }, + { + "FieldName": "Currency Code", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Currency Code" + } + } + }, + { + "FieldName": "Currency Factor", + "Sequence": 0, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Purchase Header", + "TableFieldName": "Currency Factor", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } + } + } + ] } } }, @@ -2790,7 +3002,7 @@ "Lookup": { "SourceType": "Current Record", "TableName": "Purchase Line", - "FieldName": "Buy-from Vendor No." + "FieldName": "Document No." } } } diff --git a/Apps/IN/INGST/app/.resources/GSTUseCases/A744EF89-44A8-4CE0-81F8-3D8094623CD1.json b/Apps/IN/INGST/app/.resources/GSTUseCases/A744EF89-44A8-4CE0-81F8-3D8094623CD1.json new file mode 100644 index 0000000000..c455ff3cd5 --- /dev/null +++ b/Apps/IN/INGST/app/.resources/GSTUseCases/A744EF89-44A8-4CE0-81F8-3D8094623CD1.json @@ -0,0 +1,1925 @@ +[ + { + "CaseID": "{A744EF89-44A8-4CE0-81F8-3D8094623CD1}", + "Description": "Export Return of Goods to SEZ Development With Payment of Duty through Sales Return Order/Credit Memo.", + "Version": 4, + "MinorVersion": 0, + "TaxType": "GST", + "ChangedBy": "Microsoft", + "Code": "GST SEZ", + "TaxEntity": "Sales Line", + "ParentUseCase": "Export and Goods/Services to Foreign Customer.", + "ParentCaseId": "{B6045C50-0B69-4DCE-B55D-20613A893341}", + "PresentationOrder": 84, + "Indent": 1, + "PostingTableName": "GST Posting Setup", + "PostingTableFilters": [ + { + "FiterFieldName": "State Code", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Location", + "TableFieldName": "State Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Code", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Location Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + } + ] + } + } + } + ], + "Attributes": [], + "RateColumns": [], + "ComputationVariables": [], + "ComputationScript": [], + "PostingVariables": [], + "PostingScript": [], + "Components": [ + { + "ComponentName": "GST Base Amount", + "Sequence": 2, + "Formula": { + "VariableName": "GST Base Amount", + "Expression": "{GST BAse Amount}", + "Tokens": [ + { + "TokenName": "{GST BAse Amount}", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Amount" + } + } + } + ] + } + }, + { + "ComponentName": "IGST", + "Sequence": 1, + "Formula": { + "VariableName": "IGST", + "Expression": "{Amount}*{IGSTPer}/100", + "Tokens": [ + { + "TokenName": "{Amount}", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Amount" + } + } + }, + { + "TokenName": "{IGSTPer}", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Component Percent", + "ComponentName": "IGST" + } + } + } + ] + } + } + ], + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + }, + "RHS": { + "Type": "Constant", + "Value": "Return Order" + } + }, + { + "Operator": "or", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + }, + "RHS": { + "Type": "Constant", + "Value": "Credit Memo" + } + }, + { + "Operator": "and", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "GST-Ship to Customer Type", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + }, + "RHS": { + "Type": "Constant", + "Value": "SEZ Development" + } + }, + { + "Operator": "and", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "GST Without Payment of Duty", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + }, + "RHS": { + "Type": "Constant", + "Value": "No" + } + }, + { + "Operator": "and", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Exempted" + } + }, + "RHS": { + "Type": "Constant", + "Value": "No" + } + }, + { + "Operator": "and", + "ConditionType": "Not Equals", + "LHS": { + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "GST Group Code" + } + }, + "RHS": { + "Type": "Constant", + "Value": "" + } + }, + { + "Operator": "and", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Type" + } + }, + "RHS": { + "Type": "Constant", + "Value": "Item" + } + }, + { + "Operator": "and", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Post GST to Customer", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + }, + "RHS": { + "Type": "Constant", + "Value": "" + } + }, + { + "Operator": "and", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "FOC" + } + }, + "RHS": { + "Type": "Constant", + "Value": "" + } + } + ] + }, + "TaxPostingSetup": [ + { + "ComponentName": "IGST", + "TableName": "GST Posting Setup", + "AccountSourceType": "Field", + "FieldName": "Refund Account", + "AccountingImpact": "Credit", + "ReverseCharge": true, + "ReverseAccountSourceType": "Field", + "ReverseChargeFieldName": "Payable Account", + "TableFilters": [ + { + "FiterFieldName": "Component ID", + "FilterType": "Equals", + "FilterValue": { + "Type": "Constant", + "Value": "3" + } + } + ], + "When": [ + { + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Not Equals", + "LHS": { + "Lookup": { + "SourceType": "Component", + "ComponentName": "IGST" + } + }, + "RHS": { + "Type": "Constant", + "Value": "0" + } + } + ] + }, + "ValueType": "Insert Record", + "Sequence": 1, + "InsertRecord": { + "TableName": "Detailed GST Ledger Entry", + "RunTrigger": true, + "SubLedgerGrpBy": "Line / Component", + "InsertRecordFields": [ + { + "FieldName": "Entry Type", + "Sequence": 42, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Initial Entry" + } + }, + { + "FieldName": "Transaction Type", + "Sequence": 7, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Sales" + } + }, + { + "FieldName": "Document Type", + "Sequence": 51, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Credit Memo" + } + }, + { + "FieldName": "Document No.", + "Sequence": 1, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Posted Document No." + } + } + }, + { + "FieldName": "Posting Date", + "Sequence": 2, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Posting Date" + } + } + }, + { + "FieldName": "Type", + "Sequence": 3, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Type" + } + } + }, + { + "FieldName": "No.", + "Sequence": 4, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "No." + } + } + }, + { + "FieldName": "Product Type", + "Sequence": 5, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Item" + } + }, + { + "FieldName": "Source Type", + "Sequence": 6, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Customer" + } + }, + { + "FieldName": "Source No.", + "Sequence": 8, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Bill-to Customer No." + } + } + }, + { + "FieldName": "HSN/SAC Code", + "Sequence": 9, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "HSN/SAC Code" + } + } + }, + { + "FieldName": "GST Component Code", + "Sequence": 10, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "IGST" + } + }, + { + "FieldName": "GST Group Code", + "Sequence": 11, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "GST Group Code" + } + } + }, + { + "FieldName": "GST Jurisdiction Type", + "Sequence": 12, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "GST Jurisdiction Type" + } + } + }, + { + "FieldName": "GST Jurisdiction Type", + "Sequence": 44, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "GST Jurisdiction Type" + } + } + }, + { + "FieldName": "GST Base Amount", + "Sequence": 13, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Component", + "ComponentName": "GST Base Amount" + } + } + }, + { + "FieldName": "GST %", + "Sequence": 14, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Component Percent", + "ComponentName": "IGST" + } + } + }, + { + "FieldName": "GST Amount", + "Sequence": 15, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Component", + "ComponentName": "IGST" + } + } + }, + { + "FieldName": "External Document No.", + "Sequence": 43, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "External Document No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Quantity", + "Sequence": 16, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Qty. to Invoice" + } + } + }, + { + "FieldName": "GST Without Payment of Duty", + "Sequence": 17, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "GST Without Payment of Duty", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "G/L Account No.", + "Sequence": 49, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "GST Posting Setup", + "TableFieldName": "Payable Account", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "State Code", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Location State Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FiterFieldName": "Component ID", + "FilterType": "Equals", + "FilterValue": { + "Type": "Constant", + "Value": "3" + } + } + ] + } + } + }, + { + "FieldName": "Document Line No.", + "Sequence": 18, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Line No." + } + } + }, + { + "FieldName": "Location Reg. No.", + "Sequence": 23, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Location", + "TableFieldName": "GST Registration No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Code", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Location Code" + } + } + } + ] + } + } + }, + { + "FieldName": "Buyer/Seller Reg. No.", + "Sequence": 50, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Customer", + "TableFieldName": "GST Registration No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Sell-to Customer No." + } + } + } + ] + } + } + }, + { + "FieldName": "GST Group Type", + "Sequence": 24, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "GST Group Type" + } + } + }, + { + "FieldName": "Currency Code", + "Sequence": 26, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Currency Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Currency Factor", + "Sequence": 27, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Currency Factor", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Location Code", + "Sequence": 28, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Location Code" + } + } + }, + { + "FieldName": "GST Customer Type", + "Sequence": 29, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "GST Customer Type", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + } + ] + } + } + }, + { + "FieldName": "GST Customer Type", + "Sequence": 46, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "GST Customer Type", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "GST Place of Supply", + "Sequence": 33, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "GST Place Of Supply" + } + } + }, + { + "FieldName": "Liable to Pay", + "Sequence": 48, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "true" + } + }, + { + "FieldName": "ARN No.", + "Sequence": 37, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Customer", + "TableFieldName": "ARN No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Bill-to Customer No." + } + } + } + ] + } + } + } + ] + } + }, + { + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Not Equals", + "LHS": { + "Lookup": { + "SourceType": "Component", + "ComponentName": "IGST" + } + }, + "RHS": { + "Type": "Constant", + "Value": "0" + } + } + ] + }, + "ValueType": "Insert Record", + "Sequence": 0, + "InsertRecord": { + "TableName": "GST Ledger Entry", + "RunTrigger": true, + "SubLedgerGrpBy": "Component", + "InsertRecordFields": [ + { + "FieldName": "Gen. Bus. Posting Group", + "Sequence": 2, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Bus. Posting Group" + } + } + }, + { + "FieldName": "Gen. Prod. Posting Group", + "Sequence": 3, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Prod. Posting Group" + } + } + }, + { + "FieldName": "Posting Date", + "Sequence": 4, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Posting Date", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Document No.", + "Sequence": 5, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Posted Document No." + } + } + }, + { + "FieldName": "Document Type", + "Sequence": 6, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Credit Memo" + } + }, + { + "FieldName": "Transaction Type", + "Sequence": 16, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Sales" + } + }, + { + "FieldName": "GST Base Amount", + "Sequence": 7, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Component", + "ComponentName": "GST Base Amount" + } + } + }, + { + "FieldName": "Source Type", + "Sequence": 8, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Customer" + } + }, + { + "FieldName": "Source No.", + "Sequence": 9, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Bill-to Customer No." + } + } + }, + { + "FieldName": "User ID", + "Sequence": 17, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Database", + "DatabaseVariableName": "UserId" + } + } + }, + { + "FieldName": "Source Code", + "Sequence": 15, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Source Code Setup", + "TableFieldName": "Sales", + "Method": "First", + "TableFilters": [] + } + } + }, + { + "FieldName": "Transaction No.", + "Sequence": 18, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "G/L Entry Transaction No." + } + } + }, + { + "FieldName": "External Document No.", + "Sequence": 10, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "External Document No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "GST Component Code", + "Sequence": 11, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "IGST" + } + }, + { + "FieldName": "GST Amount", + "Sequence": 12, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Component", + "ComponentName": "IGST" + } + } + }, + { + "FieldName": "Currency Code", + "Sequence": 13, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Currency Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Currency Factor", + "Sequence": 14, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Currency Factor", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "G/L Entry No.", + "Sequence": 1, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "G/L Entry No." + } + } + } + ] + } + }, + { + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Not Equals", + "LHS": { + "Lookup": { + "SourceType": "Component", + "ComponentName": "IGST" + } + }, + "RHS": { + "Type": "Constant", + "Value": "0" + } + } + ] + }, + "ValueType": "Insert Record", + "Sequence": 2, + "InsertRecord": { + "TableName": "Detailed GST Ledger Entry Info", + "RunTrigger": true, + "SubLedgerGrpBy": "Line / Component", + "InsertRecordFields": [ + { + "FieldName": "User ID", + "Sequence": 45, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Database", + "DatabaseVariableName": "UserId" + } + } + }, + { + "FieldName": "Nature of Supply", + "Sequence": 19, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Nature of Supply", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Location State Code", + "Sequence": 20, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Location", + "TableFieldName": "State Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Code", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Location Code" + } + } + } + ] + } + } + }, + { + "FieldName": "Buyer/Seller State Code", + "Sequence": 21, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Customer", + "TableFieldName": "State Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Bill-to Customer No." + } + } + } + ] + } + } + }, + { + "FieldName": "Shipping Address State Code", + "Sequence": 22, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "GST Ship-to State Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Original Doc. Type", + "Sequence": 40, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "Credit Memo" + } + }, + { + "FieldName": "Original Doc. No.", + "Sequence": 41, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Posted Document No." + } + } + }, + { + "FieldName": "Bill Of Export No.", + "Sequence": 30, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Bill Of Export No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Bill Of Export Date", + "Sequence": 31, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Bill Of Export Date", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "e-Comm. Merchant Id", + "Sequence": 32, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "E-Comm. Merchant Id", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Sales Invoice Type", + "Sequence": 47, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Invoice Type", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Gen. Bus. Posting Group", + "Sequence": 34, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Bus. Posting Group" + } + } + }, + { + "FieldName": "Gen. Prod. Posting Group", + "Sequence": 35, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Prod. Posting Group" + } + } + }, + { + "FieldName": "UOM", + "Sequence": 36, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Unit of Measure Code" + } + } + }, + { + "FieldName": "Ship-to Code", + "Sequence": 38, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Ship-to Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + }, + { + "FieldName": "Location ARN No.", + "Sequence": 39, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Location", + "TableFieldName": "Location ARN No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Code", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Location Code" + } + } + } + ] + } + } + }, + { + "FieldName": "Ship-to GST Customer Type", + "Sequence": 48, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Sales Header", + "TableFieldName": "Ship-to GST Customer Type", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Sales Line", + "FieldName": "Document No." + } + } + } + ] + } + } + } + ] + } + } + ] + } + ] + } +] \ No newline at end of file diff --git a/Apps/IN/INGST/app/.resources/GSTUseCases/ccf41113-dc62-47e2-b45b-87af0248af65.json b/Apps/IN/INGST/app/.resources/GSTUseCases/ccf41113-dc62-47e2-b45b-87af0248af65.json index a2310d734d..d74818a826 100644 --- a/Apps/IN/INGST/app/.resources/GSTUseCases/ccf41113-dc62-47e2-b45b-87af0248af65.json +++ b/Apps/IN/INGST/app/.resources/GSTUseCases/ccf41113-dc62-47e2-b45b-87af0248af65.json @@ -2,7 +2,7 @@ { "CaseID": "{CCF41113-DC62-47E2-B45B-87AF0248AF65}", "Description": "Inter-State Sales Return of Service to UnRegistered Customer through Sales Journal/Journal/General Journal.", - "Version": 4, + "Version": 5, "MinorVersion": 0, "TaxType": "GST", "ChangedBy": "Microsoft", @@ -10,7 +10,7 @@ "TaxEntity": "Gen. Journal Line", "ParentUseCase": "Sales of Goods from Registered/Unregistered Customer through Sales Journal/General Journal.", "ParentCaseId": "{DBFAD9E1-15D2-44E9-9305-E453D15DE128}", - "PresentationOrder": 962, + "PresentationOrder": 965, "Indent": 1, "PostingTableName": "GST Posting Setup", "PostingTableFilters": [ @@ -262,42 +262,52 @@ "When": [ { "ValueType": "Insert Record", - "Sequence": 1, + "Sequence": 0, "InsertRecord": { - "TableName": "Detailed GST Ledger Entry", + "TableName": "GST Ledger Entry", "RunTrigger": true, - "SubLedgerGrpBy": "Line / Component", + "SubLedgerGrpBy": "Component", "InsertRecordFields": [ { - "FieldName": "", - "Sequence": 0, + "FieldName": "Gen. Bus. Posting Group", + "Sequence": 2, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "" + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Bus. Posting Group" + } } }, { - "FieldName": "Transaction Type", - "Sequence": 7, + "FieldName": "Gen. Prod. Posting Group", + "Sequence": 3, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "Sales" + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Prod. Posting Group" + } } }, { - "FieldName": "Document Type", - "Sequence": 45, + "FieldName": "Posting Date", + "Sequence": 4, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "Credit Memo" + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Posting Date" + } } }, { "FieldName": "Document No.", - "Sequence": 1, + "Sequence": 5, "ReverseSign": false, "Lookup": { "Type": "Lookup", @@ -308,56 +318,56 @@ } }, { - "FieldName": "Posting Date", - "Sequence": 2, + "FieldName": "Document Type", + "Sequence": 6, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Posting Date" + "FieldName": "Document Type" } } }, { - "FieldName": "Type", - "Sequence": 3, + "FieldName": "Transaction Type", + "Sequence": 16, "ReverseSign": false, "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Bal. Account Type" - } + "Type": "Constant", + "Value": "Sales" } }, { - "FieldName": "Type", - "Sequence": 46, + "FieldName": "GST Base Amount", + "Sequence": 7, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "G/L Account" + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Amount" + } } }, { - "FieldName": "No.", - "Sequence": 4, + "FieldName": "Source Type", + "Sequence": 8, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Bal. Account No." + "FieldName": "Account Type" } } }, { "FieldName": "Source Type", - "Sequence": 6, + "Sequence": 18, "ReverseSign": false, "Lookup": { "Type": "Constant", @@ -366,7 +376,7 @@ }, { "FieldName": "Source No.", - "Sequence": 8, + "Sequence": 9, "ReverseSign": false, "Lookup": { "Type": "Lookup", @@ -378,64 +388,80 @@ } }, { - "FieldName": "HSN/SAC Code", - "Sequence": 9, + "FieldName": "User ID", + "Sequence": 15, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "HSN/SAC Code" + "SourceType": "Database", + "DatabaseVariableName": "UserId" } } }, { - "FieldName": "GST Component Code", - "Sequence": 10, + "FieldName": "Source Code", + "Sequence": 19, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "IGST" + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Source Code Setup", + "TableFieldName": "Sales Journal", + "Method": "First", + "TableFilters": [] + } } }, { - "FieldName": "GST Group Code", - "Sequence": 11, + "FieldName": "Transaction No.", + "Sequence": 17, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "GST Group Code" + "SourceType": "Posting Field", + "PostingVariableName": "G/L Entry Transaction No." } } }, { - "FieldName": "GST Jurisdiction Type", - "Sequence": 12, + "FieldName": "External Document No.", + "Sequence": 10, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "GST Jurisdiction Type" + "FieldName": "External Document No." } } }, { - "FieldName": "GST Jurisdiction Type", - "Sequence": 48, + "FieldName": "GST Component Code", + "Sequence": 11, "ReverseSign": false, "Lookup": { "Type": "Constant", - "Value": "InterState" + "Value": "IGST" } }, { - "FieldName": "GST Base Amount", + "FieldName": "GST Amount", + "Sequence": 12, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Component", + "ComponentName": "IGST" + } + } + }, + { + "FieldName": "Currency Code", "Sequence": 13, "ReverseSign": false, "Lookup": { @@ -443,326 +469,235 @@ "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Amount" + "FieldName": "Currency Code" } } }, { - "FieldName": "GST %", + "FieldName": "Currency Factor", "Sequence": 14, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Component Percent", - "ComponentName": "IGST" + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Currency Factor" } } }, { - "FieldName": "GST Amount", - "Sequence": 15, + "FieldName": "G/L Entry No.", + "Sequence": 1, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Component", - "ComponentName": "IGST" + "SourceType": "Posting Field", + "PostingVariableName": "G/L Entry No." } } - }, + } + ] + } + }, + { + "ValueType": "Insert Record", + "Sequence": 2, + "InsertRecord": { + "TableName": "Detailed GST Ledger Entry Info", + "RunTrigger": true, + "SubLedgerGrpBy": "Line / Component", + "InsertRecordFields": [ { - "FieldName": "External Document No.", - "Sequence": 49, + "FieldName": "User ID", + "Sequence": 40, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "External Document No." + "SourceType": "Database", + "DatabaseVariableName": "UserId" } } }, { - "FieldName": "Quantity", - "Sequence": 16, + "FieldName": "Nature of Supply", + "Sequence": 19, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Quantity" + "FieldName": "Nature of Supply" } } }, { - "FieldName": "Quantity", - "Sequence": 50, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "1" - } - }, - { - "FieldName": "GST Without Payment of Duty", - "Sequence": 17, + "FieldName": "Location State Code", + "Sequence": 20, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "GST Without Payment of Duty" + "FieldName": "Location State Code" } } }, { - "FieldName": "G/L Account No.", - "Sequence": 44, + "FieldName": "Buyer/Seller State Code", + "Sequence": 21, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Table", - "TableName": "GST Posting Setup", - "TableFieldName": "Payable Account", + "TableName": "Customer", + "TableFieldName": "State Code", "Method": "First", "TableFilters": [ { - "FiterFieldName": "State Code", + "FiterFieldName": "No.", "FilterType": "Equals", "FilterValue": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Location State Code" + "FieldName": "Account No." } } - }, - { - "FiterFieldName": "Component ID", - "FilterType": "Equals", - "FilterValue": { - "Type": "Constant", - "Value": "3" - } } ] } } }, { - "FieldName": "Document Line No.", - "Sequence": 18, + "FieldName": "Shipping Address State Code", + "Sequence": 22, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Line No." + "FieldName": "GST Ship-to State Code" } } }, { - "FieldName": "Location Reg. No.", - "Sequence": 39, + "FieldName": "Bill Of Export No.", + "Sequence": 29, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Table", - "TableName": "Location", - "TableFieldName": "GST Registration No.", - "Method": "First", - "TableFilters": [ - { - "FiterFieldName": "Code", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Location Code" - } - } - } - ] + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Bill Of Export No." } } }, { - "FieldName": "Buyer/Seller Reg. No.", - "Sequence": 47, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Table", - "TableName": "Customer", - "TableFieldName": "GST Registration No.", - "Method": "First", - "TableFilters": [ - { - "FiterFieldName": "No.", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Account No." - } - } - } - ] - } - } - }, - { - "FieldName": "GST Group Type", - "Sequence": 23, + "FieldName": "Bill Of Export Date", + "Sequence": 30, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "GST Group Type" - } - } - }, - { - "FieldName": "GST Credit", - "Sequence": 24, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "GST Credit" + "FieldName": "Bill Of Export Date" } } }, { - "FieldName": "Currency Code", - "Sequence": 25, + "FieldName": "e-Comm. Merchant Id", + "Sequence": 31, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Currency Code" + "FieldName": "E-Comm. Merchant Id" } } }, { - "FieldName": "Currency Factor", - "Sequence": 26, + "FieldName": "Sales Invoice Type", + "Sequence": 43, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Currency Factor" + "FieldName": "Sales Invoice Type" } } }, { - "FieldName": "Location Code", - "Sequence": 27, + "FieldName": "Gen. Bus. Posting Group", + "Sequence": 33, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Location Code" + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Bus. Posting Group" } } }, { - "FieldName": "GST Customer Type", - "Sequence": 28, + "FieldName": "Gen. Prod. Posting Group", + "Sequence": 34, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "GST Customer Type" + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Prod. Posting Group" } } }, { - "FieldName": "GST Place of Supply", - "Sequence": 32, + "FieldName": "Ship-to Code", + "Sequence": 37, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "GST Place of Supply" + "FieldName": "Ship-to Code" } } }, { - "FieldName": "GST Place of Supply", - "Sequence": 42, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "Bill-to Address" - } - }, - { - "FieldName": "Liable to Pay", - "Sequence": 41, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "true" - } - }, - { - "FieldName": "Journal Entry", - "Sequence": 51, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "true" - } - }, - { - "FieldName": "ARN No.", - "Sequence": 36, + "FieldName": "Location ARN No.", + "Sequence": 38, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Table", - "TableName": "Customer", - "TableFieldName": "ARN No.", + "TableName": "Location", + "TableFieldName": "Location ARN No.", "Method": "First", "TableFilters": [ { - "FiterFieldName": "No.", + "FiterFieldName": "Code", "FilterType": "Equals", "FilterValue": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Account No." + "FieldName": "Location Code" } } } @@ -775,52 +710,42 @@ }, { "ValueType": "Insert Record", - "Sequence": 0, + "Sequence": 1, "InsertRecord": { - "TableName": "GST Ledger Entry", + "TableName": "Detailed GST Ledger Entry", "RunTrigger": true, - "SubLedgerGrpBy": "Component", + "SubLedgerGrpBy": "Line / Component", "InsertRecordFields": [ { - "FieldName": "Gen. Bus. Posting Group", - "Sequence": 2, + "FieldName": "", + "Sequence": 0, "ReverseSign": false, "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Gen. Bus. Posting Group" - } + "Type": "Constant", + "Value": "" } }, { - "FieldName": "Gen. Prod. Posting Group", - "Sequence": 3, + "FieldName": "Transaction Type", + "Sequence": 7, "ReverseSign": false, "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Gen. Prod. Posting Group" - } + "Type": "Constant", + "Value": "Sales" } }, { - "FieldName": "Posting Date", - "Sequence": 4, + "FieldName": "Document Type", + "Sequence": 45, "ReverseSign": false, "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Posting Date" - } + "Type": "Constant", + "Value": "Credit Memo" } }, { "FieldName": "Document No.", - "Sequence": 5, + "Sequence": 1, "ReverseSign": false, "Lookup": { "Type": "Lookup", @@ -831,56 +756,56 @@ } }, { - "FieldName": "Document Type", - "Sequence": 6, + "FieldName": "Posting Date", + "Sequence": 2, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Document Type" + "FieldName": "Posting Date" } } }, { - "FieldName": "Transaction Type", - "Sequence": 16, - "ReverseSign": false, - "Lookup": { - "Type": "Constant", - "Value": "Sales" - } - }, - { - "FieldName": "GST Base Amount", - "Sequence": 7, + "FieldName": "Type", + "Sequence": 3, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Amount" + "FieldName": "Bal. Account Type" } } }, { - "FieldName": "Source Type", - "Sequence": 8, + "FieldName": "Type", + "Sequence": 46, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "G/L Account" + } + }, + { + "FieldName": "No.", + "Sequence": 4, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Account Type" + "FieldName": "Bal. Account No." } } }, { "FieldName": "Source Type", - "Sequence": 18, + "Sequence": 6, "ReverseSign": false, "Lookup": { "Type": "Constant", @@ -889,7 +814,7 @@ }, { "FieldName": "Source No.", - "Sequence": 9, + "Sequence": 8, "ReverseSign": false, "Lookup": { "Type": "Lookup", @@ -901,69 +826,90 @@ } }, { - "FieldName": "User ID", - "Sequence": 15, + "FieldName": "HSN/SAC Code", + "Sequence": 9, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Database", - "DatabaseVariableName": "UserId" + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "HSN/SAC Code" } } }, { - "FieldName": "Source Code", - "Sequence": 19, + "FieldName": "GST Component Code", + "Sequence": 10, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "IGST" + } + }, + { + "FieldName": "GST Group Code", + "Sequence": 11, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Table", - "TableName": "Source Code Setup", - "TableFieldName": "Sales Journal", - "Method": "First", - "TableFilters": [] + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "GST Group Code" } } }, { - "FieldName": "Transaction No.", - "Sequence": 17, + "FieldName": "GST Jurisdiction Type", + "Sequence": 12, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "G/L Entry Transaction No." + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "GST Jurisdiction Type" } } }, { - "FieldName": "External Document No.", - "Sequence": 10, + "FieldName": "GST Jurisdiction Type", + "Sequence": 48, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "InterState" + } + }, + { + "FieldName": "GST Base Amount", + "Sequence": 13, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "External Document No." + "FieldName": "Amount" } } }, { - "FieldName": "GST Component Code", - "Sequence": 11, + "FieldName": "GST %", + "Sequence": 14, "ReverseSign": false, "Lookup": { - "Type": "Constant", - "Value": "IGST" + "Type": "Lookup", + "Lookup": { + "SourceType": "Component Percent", + "ComponentName": "IGST" + } } }, { "FieldName": "GST Amount", - "Sequence": 12, + "Sequence": 15, "ReverseSign": false, "Lookup": { "Type": "Lookup", @@ -974,102 +920,140 @@ } }, { - "FieldName": "Currency Code", - "Sequence": 13, + "FieldName": "External Document No.", + "Sequence": 49, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Currency Code" + "FieldName": "External Document No." } } }, { - "FieldName": "Currency Factor", - "Sequence": 14, + "FieldName": "Quantity", + "Sequence": 16, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Currency Factor" + "FieldName": "Quantity" } } }, { - "FieldName": "G/L Entry No.", - "Sequence": 1, + "FieldName": "Quantity", + "Sequence": 50, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "1" + } + }, + { + "FieldName": "GST Without Payment of Duty", + "Sequence": 17, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "G/L Entry No." + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "GST Without Payment of Duty" } } - } - ] - } - }, - { - "ValueType": "Insert Record", - "Sequence": 2, - "InsertRecord": { - "TableName": "Detailed GST Ledger Entry Info", - "RunTrigger": true, - "SubLedgerGrpBy": "Line / Component", - "InsertRecordFields": [ + }, { - "FieldName": "User ID", - "Sequence": 40, + "FieldName": "G/L Account No.", + "Sequence": 44, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Database", - "DatabaseVariableName": "UserId" + "SourceType": "Table", + "TableName": "GST Posting Setup", + "TableFieldName": "Payable Account", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "State Code", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Location State Code" + } + } + }, + { + "FiterFieldName": "Component ID", + "FilterType": "Equals", + "FilterValue": { + "Type": "Constant", + "Value": "3" + } + } + ] } } }, { - "FieldName": "Nature of Supply", - "Sequence": 19, + "FieldName": "Document Line No.", + "Sequence": 18, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Nature of Supply" + "FieldName": "Line No." } } }, { - "FieldName": "Location State Code", - "Sequence": 20, + "FieldName": "Location Reg. No.", + "Sequence": 39, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Location State Code" + "SourceType": "Table", + "TableName": "Location", + "TableFieldName": "GST Registration No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Code", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Location Code" + } + } + } + ] } } }, { - "FieldName": "Buyer/Seller State Code", - "Sequence": 21, + "FieldName": "Buyer/Seller Reg. No.", + "Sequence": 47, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Table", "TableName": "Customer", - "TableFieldName": "State Code", + "TableFieldName": "GST Registration No.", "Method": "First", "TableFilters": [ { @@ -1089,128 +1073,144 @@ } }, { - "FieldName": "Shipping Address State Code", - "Sequence": 22, + "FieldName": "GST Group Type", + "Sequence": 23, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "GST Ship-to State Code" + "FieldName": "GST Group Type" } } }, { - "FieldName": "Bill Of Export No.", - "Sequence": 29, + "FieldName": "GST Credit", + "Sequence": 24, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Bill Of Export No." + "FieldName": "GST Credit" } } }, { - "FieldName": "Bill Of Export Date", - "Sequence": 30, + "FieldName": "Currency Code", + "Sequence": 25, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Bill Of Export Date" + "FieldName": "Currency Code" } } }, { - "FieldName": "e-Comm. Merchant Id", - "Sequence": 31, + "FieldName": "Currency Factor", + "Sequence": 26, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "e-Commerce Merchant Id" + "FieldName": "Currency Factor" } } }, { - "FieldName": "Sales Invoice Type", - "Sequence": 43, + "FieldName": "Location Code", + "Sequence": 27, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Sales Invoice Type" + "FieldName": "Location Code" } } }, { - "FieldName": "Gen. Bus. Posting Group", - "Sequence": 33, + "FieldName": "GST Customer Type", + "Sequence": 28, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Gen. Bus. Posting Group" + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "GST Customer Type" } } }, { - "FieldName": "Gen. Prod. Posting Group", - "Sequence": 34, + "FieldName": "GST Place of Supply", + "Sequence": 32, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Gen. Prod. Posting Group" + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "GST Place of Supply" } } }, { - "FieldName": "Ship-to Code", - "Sequence": 37, + "FieldName": "GST Place of Supply", + "Sequence": 42, "ReverseSign": false, "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Ship-to Code" - } + "Type": "Constant", + "Value": "Bill-to Address" } }, { - "FieldName": "Location ARN No.", - "Sequence": 38, + "FieldName": "Liable to Pay", + "Sequence": 41, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "true" + } + }, + { + "FieldName": "Journal Entry", + "Sequence": 51, + "ReverseSign": false, + "Lookup": { + "Type": "Constant", + "Value": "true" + } + }, + { + "FieldName": "ARN No.", + "Sequence": 36, "ReverseSign": false, "Lookup": { "Type": "Lookup", "Lookup": { "SourceType": "Table", - "TableName": "Location", - "TableFieldName": "Location ARN No.", + "TableName": "Customer", + "TableFieldName": "ARN No.", "Method": "First", "TableFilters": [ { - "FiterFieldName": "Code", + "FiterFieldName": "No.", "FilterType": "Equals", "FilterValue": { "Type": "Lookup", "Lookup": { "SourceType": "Current Record", "TableName": "Gen. Journal Line", - "FieldName": "Location Code" + "FieldName": "Account No." } } } diff --git a/Apps/IN/INGST/app/.resources/GSTUseCases/cf221dcd-487c-4b3c-bbc4-fe16b6667e76.json b/Apps/IN/INGST/app/.resources/GSTUseCases/cf221dcd-487c-4b3c-bbc4-fe16b6667e76.json index a4b8d64d2f..b84625edd3 100644 --- a/Apps/IN/INGST/app/.resources/GSTUseCases/cf221dcd-487c-4b3c-bbc4-fe16b6667e76.json +++ b/Apps/IN/INGST/app/.resources/GSTUseCases/cf221dcd-487c-4b3c-bbc4-fe16b6667e76.json @@ -2,7 +2,7 @@ { "CaseID": "{CF221DCD-487C-4B3C-BBC4-FE16B6667E76}", "Description": "Inter-State Sales of Services to Registered or Unregistered Customer through Sales Journal/Journal/General Journal.", - "Version": 4, + "Version": 5, "MinorVersion": 0, "TaxType": "GST", "ChangedBy": "Microsoft", @@ -10,7 +10,7 @@ "TaxEntity": "Gen. Journal Line", "ParentUseCase": "Sales of Goods from Registered/Unregistered Customer through Sales Journal/General Journal.", "ParentCaseId": "{DBFAD9E1-15D2-44E9-9305-E453D15DE128}", - "PresentationOrder": 974, + "PresentationOrder": 977, "Indent": 1, "PostingTableName": "GST Posting Setup", "PostingTableFilters": [ @@ -245,213 +245,6 @@ } ], "When": [ - { - "ValueType": "Insert Record", - "Sequence": 2, - "InsertRecord": { - "TableName": "Detailed GST Ledger Entry Info", - "RunTrigger": true, - "SubLedgerGrpBy": "Line / Component", - "InsertRecordFields": [ - { - "FieldName": "User ID", - "Sequence": 40, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Database", - "DatabaseVariableName": "UserId" - } - } - }, - { - "FieldName": "Nature of Supply", - "Sequence": 19, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Nature of Supply" - } - } - }, - { - "FieldName": "Location State Code", - "Sequence": 20, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Location State Code" - } - } - }, - { - "FieldName": "Buyer/Seller State Code", - "Sequence": 21, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Table", - "TableName": "Customer", - "TableFieldName": "State Code", - "Method": "First", - "TableFilters": [ - { - "FiterFieldName": "No.", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Account No." - } - } - } - ] - } - } - }, - { - "FieldName": "Shipping Address State Code", - "Sequence": 22, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "GST Ship-to State Code" - } - } - }, - { - "FieldName": "Bill Of Export No.", - "Sequence": 29, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Bill Of Export No." - } - } - }, - { - "FieldName": "Bill Of Export Date", - "Sequence": 30, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Bill Of Export Date" - } - } - }, - { - "FieldName": "e-Comm. Merchant Id", - "Sequence": 31, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "e-Commerce Merchant Id" - } - } - }, - { - "FieldName": "Sales Invoice Type", - "Sequence": 47, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Sales Invoice Type" - } - } - }, - { - "FieldName": "Gen. Bus. Posting Group", - "Sequence": 33, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Gen. Bus. Posting Group" - } - } - }, - { - "FieldName": "Gen. Prod. Posting Group", - "Sequence": 34, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Posting Field", - "PostingVariableName": "Gen. Prod. Posting Group" - } - } - }, - { - "FieldName": "Ship-to Code", - "Sequence": 37, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Ship-to Code" - } - } - }, - { - "FieldName": "Location ARN No.", - "Sequence": 38, - "ReverseSign": false, - "Lookup": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Table", - "TableName": "Location", - "TableFieldName": "Location ARN No.", - "Method": "First", - "TableFilters": [ - { - "FiterFieldName": "Code", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Gen. Journal Line", - "FieldName": "Location Code" - } - } - } - ] - } - } - } - ] - } - }, { "ValueType": "Insert Record", "Sequence": 1, @@ -1164,6 +957,213 @@ } ] } + }, + { + "ValueType": "Insert Record", + "Sequence": 2, + "InsertRecord": { + "TableName": "Detailed GST Ledger Entry Info", + "RunTrigger": true, + "SubLedgerGrpBy": "Line / Component", + "InsertRecordFields": [ + { + "FieldName": "User ID", + "Sequence": 40, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Database", + "DatabaseVariableName": "UserId" + } + } + }, + { + "FieldName": "Nature of Supply", + "Sequence": 19, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Nature of Supply" + } + } + }, + { + "FieldName": "Location State Code", + "Sequence": 20, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Location State Code" + } + } + }, + { + "FieldName": "Buyer/Seller State Code", + "Sequence": 21, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Customer", + "TableFieldName": "State Code", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Account No." + } + } + } + ] + } + } + }, + { + "FieldName": "Shipping Address State Code", + "Sequence": 22, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "GST Ship-to State Code" + } + } + }, + { + "FieldName": "Bill Of Export No.", + "Sequence": 29, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Bill Of Export No." + } + } + }, + { + "FieldName": "Bill Of Export Date", + "Sequence": 30, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Bill Of Export Date" + } + } + }, + { + "FieldName": "e-Comm. Merchant Id", + "Sequence": 31, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "E-Comm. Merchant Id" + } + } + }, + { + "FieldName": "Sales Invoice Type", + "Sequence": 47, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Sales Invoice Type" + } + } + }, + { + "FieldName": "Gen. Bus. Posting Group", + "Sequence": 33, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Bus. Posting Group" + } + } + }, + { + "FieldName": "Gen. Prod. Posting Group", + "Sequence": 34, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Posting Field", + "PostingVariableName": "Gen. Prod. Posting Group" + } + } + }, + { + "FieldName": "Ship-to Code", + "Sequence": 37, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Ship-to Code" + } + } + }, + { + "FieldName": "Location ARN No.", + "Sequence": 38, + "ReverseSign": false, + "Lookup": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Table", + "TableName": "Location", + "TableFieldName": "Location ARN No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Code", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Gen. Journal Line", + "FieldName": "Location Code" + } + } + } + ] + } + } + } + ] + } } ] } diff --git a/Apps/IN/INGST/app/GSTApplication/src/Codeunit/GSTApplicationLibrary.Codeunit.al b/Apps/IN/INGST/app/GSTApplication/src/Codeunit/GSTApplicationLibrary.Codeunit.al index ca36718754..c24f7e69c9 100644 --- a/Apps/IN/INGST/app/GSTApplication/src/Codeunit/GSTApplicationLibrary.Codeunit.al +++ b/Apps/IN/INGST/app/GSTApplication/src/Codeunit/GSTApplicationLibrary.Codeunit.al @@ -836,6 +836,7 @@ codeunit 18433 "GST Application Library" var GSTApplicationBuffer: Record "GST Application Buffer"; VendorLedgerEntry: Record "Vendor Ledger Entry"; + DetailedVendorLedgEntry: Record "Detailed Vendor Ledg. Entry"; ChargeAmount: Decimal; TDSTCSAmount: Decimal; TotalInvoiceAmount: Decimal; @@ -936,8 +937,12 @@ codeunit 18433 "GST Application Library" VendorLedgerEntry.SetRange("Document Type", VendorLedgerEntry."Document Type"::Payment); VendorLedgerEntry.SetRange("Document No.", GSTApplicationBuffer."Original Document No."); if VendorLedgerEntry.FindFirst() then begin + DetailedVendorLedgEntry.SetCurrentKey("Vendor Ledger Entry No.", "Entry Type"); + DetailedVendorLedgEntry.SetRange("Vendor Ledger Entry No.", VendorLedgerEntry."Entry No."); + DetailedVendorLedgEntry.SetRange("Entry Type", DetailedVendorLedgEntry."Entry Type"::Application); + DetailedVendorLedgEntry.CalcSums(Amount); VendorLedgerEntry.CalcFields("Remaining Amount"); - if VendorLedgerEntry."Remaining Amount" <> Round(GSTApplicationBuffer."GST Base Amount", 0.01) then + if (VendorLedgerEntry."Remaining Amount" + Abs(DetailedVendorLedgEntry.Amount)) <> Round(GSTApplicationBuffer."GST Base Amount", 0.01) then GSTApplicationBuffer."Applied Base Amount" := VendorLedgerEntry."Remaining Amount"; end; diff --git a/Apps/IN/INGST/app/GSTBase/src/Codeunit/GSTBaseValidation.Codeunit.al b/Apps/IN/INGST/app/GSTBase/src/Codeunit/GSTBaseValidation.Codeunit.al index 58c10dad5c..e9c6b3a599 100644 --- a/Apps/IN/INGST/app/GSTBase/src/Codeunit/GSTBaseValidation.Codeunit.al +++ b/Apps/IN/INGST/app/GSTBase/src/Codeunit/GSTBaseValidation.Codeunit.al @@ -302,7 +302,7 @@ codeunit 18001 "GST Base Validation" Rec."GST Base Amount" := (Rec."GST Base Amount") * SignFactor; Rec."GST Amount" := (Rec."GST Amount") * SignFactor; end else - if Rec."GST Base Amount" > 0 then begin + if (Rec."GST Base Amount" > 0) or (Rec."Journal Entry") then begin Rec."GST Base Amount" := Abs(Rec."GST Base Amount") * SignFactor; Rec."GST Amount" := Abs(Rec."GST Amount") * SignFactor; end @@ -353,8 +353,9 @@ codeunit 18001 "GST Base Validation" Rec."Executed Use Case ID" := GSTPostingManagement.GetUseCaseID(); if Rec."Source Type" = Rec."Source Type"::Vendor then - if GSTPostingManagement.GetPaytoVendorNo() <> '' then - Rec."Source No." := GSTPostingManagement.GetPaytoVendorNo(); + if Rec."Source No." = '' then + if GSTPostingManagement.GetPaytoVendorNo() <> '' then + Rec."Source No." := GSTPostingManagement.GetPaytoVendorNo(); if GSTPostingManagement.GetBuyerSellerRegNo() <> '' then Rec."Buyer/Seller Reg. No." := GSTPostingManagement.GetBuyerSellerRegNo(); diff --git a/Apps/IN/INGST/app/GSTBase/src/Codeunit/GSTDataSenstivityMgmt.Codeunit.al b/Apps/IN/INGST/app/GSTBase/src/Codeunit/GSTDataSenstivityMgmt.Codeunit.al index 21a512f538..4e20ea5f77 100644 --- a/Apps/IN/INGST/app/GSTBase/src/Codeunit/GSTDataSenstivityMgmt.Codeunit.al +++ b/Apps/IN/INGST/app/GSTBase/src/Codeunit/GSTDataSenstivityMgmt.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. // ------------------------------------------------------------------------------------------------ @@ -37,9 +37,6 @@ using Microsoft.Sales.Archive; using Microsoft.Sales.Customer; using Microsoft.Sales.Document; using Microsoft.Sales.History; -#if not CLEAN25 -using Microsoft.Sales.Pricing; -#endif using Microsoft.Sales.Receivables; using Microsoft.Sales.Setup; using Microsoft.Service.Contract; @@ -143,9 +140,6 @@ codeunit 18020 "GST Data Senstivity Mgmt." SetTableFieldsToNormal(Database::"Sales Header"); SetTableFieldsToNormal(Database::"Sales Invoice Line"); SetTableFieldsToNormal(Database::"Sales Line"); -#if not CLEAN25 - SetTableFieldsToNormal(Database::"Sales Price"); -#endif SetTableFieldsToNormal(Database::"Sales Shipment Header"); SetTableFieldsToNormal(Database::"Sales Shipment Line"); SetTableFieldsToNormal(Database::"Shipping Agent"); @@ -207,4 +201,4 @@ codeunit 18020 "GST Data Senstivity Mgmt." begin DataClassificationMgt.SetTableFieldsToNormal(TableNo); end; -} +} \ No newline at end of file diff --git a/Apps/IN/INGST/app/GSTBase/src/TaxEngineSetup/GSTTaxConfiguration.Codeunit.al b/Apps/IN/INGST/app/GSTBase/src/TaxEngineSetup/GSTTaxConfiguration.Codeunit.al index f95ce262e5..57c82db01e 100644 --- a/Apps/IN/INGST/app/GSTBase/src/TaxEngineSetup/GSTTaxConfiguration.Codeunit.al +++ b/Apps/IN/INGST/app/GSTBase/src/TaxEngineSetup/GSTTaxConfiguration.Codeunit.al @@ -217,7 +217,7 @@ codeunit 18017 "GST Tax Configuration" UseCases.Add('{24F69259-FD27-49A7-B5E8-3CBF5351132F}', 6); UseCases.Add('{97CF7642-AB0E-4686-A5CE-3D7C7C641E7E}', 3); UseCases.Add('{7627B9EF-CB23-4EAB-88D9-3D894B6F6607}', 5); - UseCases.Add('{4F234B8B-1B95-4938-B3DF-3D96784EAC77}', 4); + UseCases.Add('{4F234B8B-1B95-4938-B3DF-3D96784EAC77}', 5); UseCases.Add('{F8D35423-18AA-4916-A10C-3DC5A6F80CB0}', 3); UseCases.Add('{C8AEE991-4EDD-4562-BCE7-3DFA3502C8D2}', 4); UseCases.Add('{272FFE9F-A7C9-4AF8-87DD-3EA53BA18511}', 1); @@ -324,7 +324,7 @@ codeunit 18017 "GST Tax Configuration" UseCases.Add('{04F944A1-EF9C-440F-A89B-654782D13EAA}', 2); UseCases.Add('{2AB850AD-528A-498A-9E23-65E396AC61A8}', 2); UseCases.Add('{F7C5C8B6-2EB3-478E-AE6B-66BEEB6A3861}', 8); - UseCases.Add('{21957E13-9751-40A2-B591-67ADE93573E7}', 5); + UseCases.Add('{21957E13-9751-40A2-B591-67ADE93573E7}', 6); UseCases.Add('{1988B611-ABD4-44C4-9CB5-67BB88E0002C}', 1); UseCases.Add('{E5053EEB-44D1-4552-8084-67D72A90CECB}', 1); UseCases.Add('{5430A349-B6AE-4CA1-A7D9-6884D93DA5EF}', 1); @@ -397,7 +397,7 @@ codeunit 18017 "GST Tax Configuration" UseCases.Add('{3DC33AD0-69AB-4B36-B58D-7C409957507C}', 4); UseCases.Add('{9F7A9C0A-BC4A-45C2-B79B-7D22EDB6ABBB}', 5); UseCases.Add('{A622E949-C161-4AE2-B6DB-7D3C16E5D899}', 1); - UseCases.Add('{4E1D5479-C527-4295-A0C1-7D82D94860F6}', 1); + UseCases.Add('{4E1D5479-C527-4295-A0C1-7D82D94860F6}', 2); UseCases.Add('{18F45902-76C4-4B57-AF7F-7D9B3A76D51F}', 5); UseCases.Add('{6ADC0F4A-6D69-4BAE-A94F-7DC0889758DC}', 1); UseCases.Add('{AE6444ED-20D1-4E69-A69C-7DCAEC9C4738}', 1); @@ -428,7 +428,7 @@ codeunit 18017 "GST Tax Configuration" UseCases.Add('{B83A838B-C0A8-4E69-B735-86D011229B1C}', 3); UseCases.Add('{23B7CD0D-EA02-4835-9AE8-875813B138F0}', 3); UseCases.Add('{9DFF9CBE-B1A5-4D28-A855-8783315A87D0}', 4); - UseCases.Add('{CCF41113-DC62-47E2-B45B-87AF0248AF65}', 4); + UseCases.Add('{CCF41113-DC62-47E2-B45B-87AF0248AF65}', 5); UseCases.Add('{2CEB6A3E-11E4-420F-A3C6-886B920BEC29}', 3); UseCases.Add('{36017702-208F-4E8C-A75E-8872EA7D1205}', 4); UseCases.Add('{A8BF5AD2-5132-40E7-9DF1-893B3940F6EE}', 6); @@ -783,7 +783,7 @@ codeunit 18017 "GST Tax Configuration" UseCases.Add('{46CB3503-286F-43C3-9B04-FBBD5F2CBAF0}', 7); UseCases.Add('{0B9DBB2B-8F9C-496E-B373-FC5A4BD43F96}', 3); UseCases.Add('{78A245B3-3BAB-4347-B09A-FDE73A600BB2}', 3); - UseCases.Add('{CF221DCD-487C-4B3C-BBC4-FE16B6667E76}', 4); + UseCases.Add('{CF221DCD-487C-4B3C-BBC4-FE16B6667E76}', 5); UseCases.Add('{1B728E5D-4A32-4E32-A2AA-FE3673AFC2CD}', 4); UseCases.Add('{F3E7CEF3-5437-42EC-9DED-FE81F994FFCB}', 3); UseCases.Add('{041E1938-9B6A-4173-937C-FF0FDC0E7309}', 2); diff --git a/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTBlankPurchOrdArchExt.PageExt.al b/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTBlankPurchOrdArchExt.PageExt.al index c837e79731..62acd5c2d4 100644 --- a/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTBlankPurchOrdArchExt.PageExt.al +++ b/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTBlankPurchOrdArchExt.PageExt.al @@ -23,19 +23,6 @@ pageextension 18016 "GST Blank. Purch Ord Arch Ext" extends "Blanket Purchase Or SubPageLink = "Table ID Filter" = const(5110), "Document Type Filter" = field("Document Type"), "Document No. Filter" = field("Document No."), "Line No. Filter" = field("Line No."), "Version No. Filter" = field("Version No."); ApplicationArea = Basic, Suite; } -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(38), - "No." = field("No."), - "Document Type" = field("Document Type"); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; diff --git a/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTPurchOrdArchiveExt.PageExt.al b/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTPurchOrdArchiveExt.PageExt.al index ad09b54f3e..e630a09ba8 100644 --- a/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTPurchOrdArchiveExt.PageExt.al +++ b/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTPurchOrdArchiveExt.PageExt.al @@ -22,19 +22,6 @@ pageextension 18100 "GST Purch Ord Archive Ext" extends "Purchase Order Archive" SubPageLink = "Table ID Filter" = const(5110), "Document Type Filter" = field("Document Type"), "Document No. Filter" = field("Document No."), "Line No. Filter" = field("Line No."), "Version No. Filter" = field("Version No."); ApplicationArea = Basic, Suite; } -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(38), - "No." = field("No."), - "Document Type" = field("Document Type"); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; diff --git a/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTPurchQuoteArchiveExt.PageExt.al b/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTPurchQuoteArchiveExt.PageExt.al index 3c7a2b5ae2..b38be1ba4a 100644 --- a/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTPurchQuoteArchiveExt.PageExt.al +++ b/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTPurchQuoteArchiveExt.PageExt.al @@ -22,19 +22,6 @@ pageextension 18105 "GST Purch Quote Archive Ext" extends "Purchase Quote Archiv SubPageLink = "Table ID Filter" = const(5110), "Document Type Filter" = field("Document Type"), "Document No. Filter" = field("Document No."), "Line No. Filter" = field("Line No."), "Version No. Filter" = field("Version No."); ApplicationArea = Basic, Suite; } -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(38), - "No." = field("No."), - "Document Type" = field("Document Type"); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; diff --git a/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTPurchReturnOrdArchExt.PageExt.al b/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTPurchReturnOrdArchExt.PageExt.al index 10c86716cd..525373670b 100644 --- a/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTPurchReturnOrdArchExt.PageExt.al +++ b/Apps/IN/INGST/app/GSTPurchase/src/PageExtension/GSTPurchReturnOrdArchExt.PageExt.al @@ -23,19 +23,6 @@ pageextension 18106 "GST Purch Return Ord Arch Ext" extends "Purchase Return Ord SubPageLink = "Table ID Filter" = const(5110), "Document Type Filter" = field("Document Type"), "Document No. Filter" = field("Document No."), "Line No. Filter" = field("Line No."), "Version No. Filter" = field("Version No."); ApplicationArea = Basic, Suite; } -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(38), - "No." = field("No."), - "Document Type" = field("Document Type"); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; diff --git a/Apps/IN/INGST/app/GSTSales/src/Codeunit/GSTSalesValidation.Codeunit.al b/Apps/IN/INGST/app/GSTSales/src/Codeunit/GSTSalesValidation.Codeunit.al index 212ef5608f..4a23dd5a6e 100644 --- a/Apps/IN/INGST/app/GSTSales/src/Codeunit/GSTSalesValidation.Codeunit.al +++ b/Apps/IN/INGST/app/GSTSales/src/Codeunit/GSTSalesValidation.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. // ------------------------------------------------------------------------------------------------ @@ -20,9 +20,6 @@ using Microsoft.Sales.Customer; using Microsoft.Sales.Document; using Microsoft.Sales.History; using Microsoft.Sales.Posting; -#if not CLEAN25 -using Microsoft.Sales.Pricing; -#endif using Microsoft.Sales.Receivables; using Microsoft.Sales.Setup; using Microsoft.Utilities; @@ -148,26 +145,6 @@ codeunit 18143 "GST Sales Validation" SalesLine."Total UPIT Amount" := SalesLine."Unit Price Incl. of Tax" * SalesLine.Quantity - SalesLine."Line Discount Amount"; end; -#if not CLEAN25 - //AssignPrice Inclusice of Tax -#pragma warning disable AS0072 - [Obsolete('Replaced by the new implementation (V16) of price calculation.', '19.0')] -#pragma warning restore AS0072 - [EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales Price Calc. Mgt.", 'OnAfterFindSalesLineItemPrice', '', false, false)] - local procedure AssignPriceInclusiveTax(var SalesLine: Record "Sales Line"; var TempSalesPrice: Record "Sales Price") - begin - if TempSalesPrice.IsEmpty() then - exit; - - SalesLine."Price Inclusive of Tax" := TempSalesPrice."Price Inclusive of Tax"; - SalesLine."Unit Price Incl. of Tax" := 0; - SalesLine."Total UPIT Amount" := 0; - if SalesLine."Price Inclusive of Tax" then begin - SalesLine."Unit Price Incl. of Tax" := TempSalesPrice."Unit Price"; - SalesLine."Total UPIT Amount" := SalesLine."Unit Price Incl. of Tax" * SalesLine.Quantity - SalesLine."Line Discount Amount"; - end; - end; -#endif //Check Accounting Period [EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales-Post (Yes/No)", 'OnAfterConfirmPost', '', false, false)] @@ -2116,4 +2093,4 @@ codeunit 18143 "GST Sales Validation" local procedure OnAfterShipToAddrfields(var SalesHeader: Record "Sales Header"; ShipToAddress: Record "Ship-to Address") begin end; -} +} \ No newline at end of file diff --git a/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTBlankSalesOrdArchExt.PageExt.al b/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTBlankSalesOrdArchExt.PageExt.al index 53313034c7..0fbbb24259 100644 --- a/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTBlankSalesOrdArchExt.PageExt.al +++ b/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTBlankSalesOrdArchExt.PageExt.al @@ -22,19 +22,6 @@ pageextension 18019 "GST Blank Sales Ord Arch Ext" extends "Blanket Sales Order SubPageLink = "Table ID Filter" = const(5108), "Document Type Filter" = field("Document Type"), "Document No. Filter" = field("Document No."), "Line No. Filter" = field("Line No."), "Version No. Filter" = field("Version No."); ApplicationArea = Basic, Suite; } -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(36), - "No." = field("No."), - "Document Type" = field("Document Type"); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -71,4 +58,4 @@ pageextension 18019 "GST Blank Sales Ord Arch Ext" extends "Blanket Sales Order } } } -} +} \ No newline at end of file diff --git a/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesOrdArchiveExt.PageExt.al b/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesOrdArchiveExt.PageExt.al index 7fec0faffe..72737c8b07 100644 --- a/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesOrdArchiveExt.PageExt.al +++ b/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesOrdArchiveExt.PageExt.al @@ -21,19 +21,6 @@ pageextension 18107 "GST Sales Ord Archive Ext" extends "Sales Order Archive" SubPageLink = "Table ID Filter" = const(5108), "Document Type Filter" = field("Document Type"), "Document No. Filter" = field("Document No."), "Line No. Filter" = field("Line No."), "Version No. Filter" = field("Version No."); ApplicationArea = Basic, Suite; } -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(36), - "No." = field("No."), - "Document Type" = field("Document Type"); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -65,4 +52,4 @@ pageextension 18107 "GST Sales Ord Archive Ext" extends "Sales Order Archive" } } } -} +} \ No newline at end of file diff --git a/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesPricesExt.PageExt.al b/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesPricesExt.PageExt.al index 0845af0559..10e2b29769 100644 --- a/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesPricesExt.PageExt.al +++ b/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesPricesExt.PageExt.al @@ -1,33 +1,4 @@ -// ------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -// ------------------------------------------------------------------------------------------------ -#if not CLEAN25 -namespace Microsoft.Sales.Pricing; - -pageextension 18152 "GST Sales Prices Ext" extends "Sales Prices" -{ - ObsoleteState = Pending; - ObsoleteReason = 'Replaced by the new implementation (V16) of price calculation.'; -#pragma warning disable AS0072 - ObsoleteTag = '19.0'; -#pragma warning restore AS0072 - - layout - { - addafter("Price Includes VAT") - { - field("Price Inclusive of Tax"; Rec."Price Inclusive of Tax") - { - ApplicationArea = Basic, Suite; - ToolTip = 'Specifies if prices are Inclusive of tax on the line.'; - ObsoleteState = Pending; - ObsoleteReason = 'Replaced by the new implementation (V16) of price calculation.'; -#pragma warning disable AS0072 - ObsoleteTag = '19.0'; -#pragma warning restore AS0072 - } - } - } -} -#endif +// ------------------------------------------------------------------------------------------------ \ No newline at end of file diff --git a/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesQuoteArchiveExt.PageExt.al b/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesQuoteArchiveExt.PageExt.al index a0e7acf8d8..99b1fd1ae5 100644 --- a/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesQuoteArchiveExt.PageExt.al +++ b/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesQuoteArchiveExt.PageExt.al @@ -21,19 +21,6 @@ pageextension 18108 "GST Sales Quote Archive Ext" extends "Sales Quote Archive" SubPageLink = "Table ID Filter" = const(5108), "Document Type Filter" = field("Document Type"), "Document No. Filter" = field("Document No."), "Line No. Filter" = field("Line No."), "Version No. Filter" = field("Version No."); ApplicationArea = Basic, Suite; } -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(36), - "No." = field("No."), - "Document Type" = field("Document Type"); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -65,4 +52,4 @@ pageextension 18108 "GST Sales Quote Archive Ext" extends "Sales Quote Archive" } } } -} +} \ No newline at end of file diff --git a/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesReturnOrdArchExt.PageExt.al b/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesReturnOrdArchExt.PageExt.al index 14fa6bae4f..91ca1288a4 100644 --- a/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesReturnOrdArchExt.PageExt.al +++ b/Apps/IN/INGST/app/GSTSales/src/PageExtension/GSTSalesReturnOrdArchExt.PageExt.al @@ -22,19 +22,6 @@ pageextension 18109 "GST Sales Return Ord Arch Ext" extends "Sales Return Order SubPageLink = "Table ID Filter" = const(5108), "Document Type Filter" = field("Document Type"), "Document No. Filter" = field("Document No."), "Line No. Filter" = field("Line No."), "Version No. Filter" = field("Version No."); ApplicationArea = Basic, Suite; } -#if not CLEAN25 - part("Attached Documents"; "Document Attachment Factbox") - { - ObsoleteTag = '25.0'; - ObsoleteState = Pending; - ObsoleteReason = 'The "Document Attachment FactBox" has been replaced by "Doc. Attachment List Factbox", which supports multiple files upload.'; - ApplicationArea = All; - Caption = 'Attachments'; - SubPageLink = "Table ID" = const(36), - "No." = field("No."), - "Document Type" = field("Document Type"); - } -#endif part("Attached Documents List"; "Doc. Attachment List Factbox") { ApplicationArea = All; @@ -71,4 +58,4 @@ pageextension 18109 "GST Sales Return Ord Arch Ext" extends "Sales Return Order } } } -} +} \ No newline at end of file diff --git a/Apps/IN/INGST/app/GSTSubcontracting/src/Page/SubcontractingOrderSubform.Page.al b/Apps/IN/INGST/app/GSTSubcontracting/src/Page/SubcontractingOrderSubform.Page.al index b636a20cfc..64fd867abb 100644 --- a/Apps/IN/INGST/app/GSTSubcontracting/src/Page/SubcontractingOrderSubform.Page.al +++ b/Apps/IN/INGST/app/GSTSubcontracting/src/Page/SubcontractingOrderSubform.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. // ------------------------------------------------------------------------------------------------ @@ -10,9 +10,6 @@ using Microsoft.Foundation.ExtendedText; using Microsoft.Foundation.Navigate; using Microsoft.Inventory.Item.Catalog; using Microsoft.Purchases.Document; -#if not CLEAN25 -using Microsoft.Purchases.Pricing; -#endif using Microsoft.Sales.Document; page 18493 "Subcontracting Order Subform" @@ -870,10 +867,6 @@ page 18493 "Subcontracting Order Subform" end; var -#if not CLEAN25 - PurchHeader: Record "Purchase Header"; - PurchPriceCalcMgt: Codeunit "Purch. Price Calc. Mgt."; -#endif TransferExtendedText: Codeunit "Transfer Extended Text"; ShortcutDimCode: array[8] of Code[20]; UpdateAllowedVar: Boolean; @@ -984,27 +977,6 @@ page 18493 "Subcontracting Order Subform" exit(true); end; -#if not CLEAN25 -#pragma warning disable AS0072 - [Obsolete('Replaced by the new implementation (V16) of price calculation.', '19.0')] -#pragma warning restore AS0072 - procedure ShowPrices() - begin - PurchHeader.Get(Rec."Document Type", Rec."Document No."); - Clear(PurchPriceCalcMgt); - PurchPriceCalcMgt.GetPurchLinePrice(PurchHeader, Rec); - end; - -#pragma warning disable AS0072 - [Obsolete('Replaced by the new implementation (V16) of price calculation.', '19.0')] -#pragma warning restore AS0072 - procedure ShowLineDisc() - begin - PurchHeader.Get(Rec."Document Type", Rec."Document No."); - Clear(PurchPriceCalcMgt); - PurchPriceCalcMgt.GetPurchLineLineDisc(PurchHeader, Rec); - end; -#endif procedure ShowLineComment() begin @@ -1071,4 +1043,4 @@ page 18493 "Subcontracting Order Subform" var IsHSNSACEditable: Boolean; -} +} \ No newline at end of file diff --git a/Apps/IN/INTDS/app/.resources/TDSUseCases/33bfbe99-9140-4112-a55b-35ec0d9b61b9.json b/Apps/IN/INTDS/app/.resources/TDSUseCases/33bfbe99-9140-4112-a55b-35ec0d9b61b9.json index 40f674d544..d6fef472e4 100644 --- a/Apps/IN/INTDS/app/.resources/TDSUseCases/33bfbe99-9140-4112-a55b-35ec0d9b61b9.json +++ b/Apps/IN/INTDS/app/.resources/TDSUseCases/33bfbe99-9140-4112-a55b-35ec0d9b61b9.json @@ -2,7 +2,7 @@ { "CaseID": "{33BFBE99-9140-4112-A55B-35EC0D9B61B9}", "Description": "Calculation of Tax Deduction at Source through General Journal for Vendor where PAN No. is specified without Concessional Codes.\n", - "Version": 3, + "Version": 4, "MinorVersion": 0, "TaxType": "TDS", "ChangedBy": "Microsoft", @@ -10,7 +10,7 @@ "TaxEntity": "Gen. Journal Line", "ParentUseCase": "Calculation of Tax Deduction at Source through General Journal for Vendors.\n", "ParentCaseId": "{D0CED206-BE26-47A3-A370-D064D8AFCE44}", - "PresentationOrder": 934, + "PresentationOrder": 937, "Indent": 1, "PostingTableName": "TDS Posting Setup", "PostingTableFilters": [ @@ -1031,6 +1031,14 @@ "Type": "Constant", "Value": "Payment" } + }, + { + "FiterFieldName": "Applied", + "FilterType": "Equals", + "FilterValue": { + "Type": "Constant", + "Value": "false" + } } ] } @@ -2657,6 +2665,52 @@ ] } }, + { + "ActivityType": "IFSTATEMENT", + "Activity": { + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Not Equals", + "LHS": { + "Lookup": { + "SourceType": "Variable", + "VariableName": "AppliedAmount" + } + }, + "RHS": { + "Type": "Constant", + "Value": "" + } + } + ] + }, + "Body": [ + { + "ActivityType": "NUMBERCALCULATION", + "Activity": { + "OutputVariableName": "TotalInvAmountLCY", + "Operator": "Minus", + "LHS": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "TotalInvAmountLCY" + } + }, + "RHS": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "AppliedAmount" + } + } + } + } + ] + } + }, { "ActivityType": "COMMENT", "Activity": { @@ -4917,19 +4971,19 @@ } }, { - "ComponentName": "eCESS", - "Sequence": 3, + "ComponentName": "SHE Cess ", + "Sequence": 4, "Formula": { - "VariableName": "eCESS", - "Expression": "(TDSAmount+SurchargeAmount)*EcessPercent/100", + "VariableName": "SHE Cess ", + "Expression": "(TDSAmount+SurchargeAmount)*SHECessPercent/100", "Tokens": [ { - "TokenName": "EcessPercent", + "TokenName": "SHECessPercent", "TokenValue": { "Type": "Lookup", "Lookup": { "SourceType": "Component Percent", - "ComponentName": "eCESS" + "ComponentName": "SHE Cess " } } }, @@ -4957,39 +5011,29 @@ } }, { - "ComponentName": "SHE Cess ", - "Sequence": 4, + "ComponentName": "TDS", + "Sequence": 1, "Formula": { - "VariableName": "SHE Cess ", - "Expression": "(TDSAmount+SurchargeAmount)*SHECessPercent/100", + "VariableName": "TDS", + "Expression": "TDSTaxableAmount*TDSPercent/100", "Tokens": [ { - "TokenName": "SHECessPercent", + "TokenName": "TDSPercent", "TokenValue": { "Type": "Lookup", "Lookup": { "SourceType": "Component Percent", - "ComponentName": "SHE Cess " - } - } - }, - { - "TokenName": "SurchargeAmount", - "TokenValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Component", - "ComponentName": "Surcharge" + "ComponentName": "TDS" } } }, { - "TokenName": "TDSAmount", + "TokenName": "TDSTaxableAmount", "TokenValue": { "Type": "Lookup", "Lookup": { - "SourceType": "Component", - "ComponentName": "TDS" + "SourceType": "Variable", + "VariableName": "TDSTaxableAmount" } } } @@ -4997,29 +5041,39 @@ } }, { - "ComponentName": "TDS", - "Sequence": 1, + "ComponentName": "eCESS", + "Sequence": 3, "Formula": { - "VariableName": "TDS", - "Expression": "TDSTaxableAmount*TDSPercent/100", + "VariableName": "eCESS", + "Expression": "(TDSAmount+SurchargeAmount)*EcessPercent/100", "Tokens": [ { - "TokenName": "TDSPercent", + "TokenName": "EcessPercent", "TokenValue": { "Type": "Lookup", "Lookup": { "SourceType": "Component Percent", - "ComponentName": "TDS" + "ComponentName": "eCESS" } } }, { - "TokenName": "TDSTaxableAmount", + "TokenName": "SurchargeAmount", "TokenValue": { "Type": "Lookup", "Lookup": { - "SourceType": "Variable", - "VariableName": "TDSTaxableAmount" + "SourceType": "Component", + "ComponentName": "Surcharge" + } + } + }, + { + "TokenName": "TDSAmount", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Component", + "ComponentName": "TDS" } } } diff --git a/Apps/IN/INTDS/app/.resources/TDSUseCases/a8e114bf-f8cd-44db-a2b3-614bc18f4442.json b/Apps/IN/INTDS/app/.resources/TDSUseCases/a8e114bf-f8cd-44db-a2b3-614bc18f4442.json index c304f37289..af01b067ae 100644 --- a/Apps/IN/INTDS/app/.resources/TDSUseCases/a8e114bf-f8cd-44db-a2b3-614bc18f4442.json +++ b/Apps/IN/INTDS/app/.resources/TDSUseCases/a8e114bf-f8cd-44db-a2b3-614bc18f4442.json @@ -2,7 +2,7 @@ { "CaseID": "{A8E114BF-F8CD-44DB-A2B3-614BC18F4442}", "Description": "Calculation of Tax Deduction at Source on Vendor Invoice where PAN No. is specified without Concessional Codes.\n", - "Version": 29, + "Version": 30, "MinorVersion": 0, "TaxType": "TDS", "ChangedBy": "Microsoft", @@ -5420,6 +5420,72 @@ } ] } + }, + { + "ActivityType": "IFSTATEMENT", + "Activity": { + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Not Equals", + "LHS": { + "Lookup": { + "SourceType": "Table", + "TableName": "Purchase Header", + "TableFieldName": "Applies-to Doc. No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } + } + } + ] + } + }, + "RHS": { + "Type": "Constant", + "Value": "" + } + } + ] + }, + "Body": [ + { + "ActivityType": "SETVARIABLE", + "Activity": { + "OutputVariableName": "TDSTaxableAmount", + "OutputValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "TaxableAmountExclApplied" + } + } + } + } + ] + } } ] } @@ -7761,7 +7827,50 @@ ], "ElseIf": { "Condition": { - "Body": [] + "Body": [ + { + "Operator": " ", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Table", + "TableName": "Purchase Header", + "TableFieldName": "Applies-to Doc. No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } + } + } + ] + } + }, + "RHS": { + "Type": "Constant", + "Value": "" + } + } + ] }, "Body": [ { @@ -8786,13 +8895,41 @@ "ConditionType": "Equals", "LHS": { "Lookup": { - "SourceType": "Column", - "RateColumnName": "Per Contract Value" + "SourceType": "Table", + "TableName": "Allowed Sections", + "TableFieldName": "Threshold Overlook", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Vendor No", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Pay-to Vendor No." + } + } + }, + { + "FiterFieldName": "TDS Section", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "TDS Section Code" + } + } + } + ] } }, "RHS": { "Type": "Constant", - "Value": "" + "Value": "false" } } ] @@ -8808,78 +8945,8 @@ "ConditionType": "Equals", "LHS": { "Lookup": { - "SourceType": "Table", - "TableName": "Purchase Header", - "TableFieldName": "Applies-to Doc. Type", - "Method": "First", - "TableFilters": [ - { - "FiterFieldName": "Document Type", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Document Type" - } - } - }, - { - "FiterFieldName": "No.", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Document No." - } - } - } - ] - } - }, - "RHS": { - "Type": "Constant", - "Value": "Payment" - } - }, - { - "Operator": "and", - "ConditionType": "Not Equals", - "LHS": { - "Lookup": { - "SourceType": "Table", - "TableName": "Purchase Header", - "TableFieldName": "Applies-to Doc. No.", - "Method": "First", - "TableFilters": [ - { - "FiterFieldName": "Document Type", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Document Type" - } - } - }, - { - "FiterFieldName": "No.", - "FilterType": "Equals", - "FilterValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Document No." - } - } - } - ] + "SourceType": "Column", + "RateColumnName": "Per Contract Value" } }, "RHS": { @@ -8897,106 +8964,144 @@ "Body": [ { "Operator": " ", - "ConditionType": "Is Less Than Or Equals To", + "ConditionType": "Equals", "LHS": { "Lookup": { - "SourceType": "Variable", - "VariableName": "PositiveAmountTillThisLine" + "SourceType": "Table", + "TableName": "Purchase Header", + "TableFieldName": "Applies-to Doc. Type", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } + } + } + ] } }, "RHS": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "AppliedAmount" - } + "Type": "Constant", + "Value": "Payment" + } + }, + { + "Operator": "and", + "ConditionType": "Not Equals", + "LHS": { + "Lookup": { + "SourceType": "Table", + "TableName": "Purchase Header", + "TableFieldName": "Applies-to Doc. No.", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Document Type", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document Type" + } + } + }, + { + "FiterFieldName": "No.", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Document No." + } + } + } + ] + } + }, + "RHS": { + "Type": "Constant", + "Value": "" } } ] }, "Body": [ { - "ActivityType": "SETVARIABLE", + "ActivityType": "IFSTATEMENT", "Activity": { - "OutputVariableName": "TDSBaseAmt", - "OutputValue": { - "Type": "Constant", - "Value": "" - } - } - } - ], - "ElseIf": { - "Condition": { - "Body": [ - { - "Operator": " ", - "ConditionType": "Is Greater Than", - "LHS": { - "Lookup": { - "SourceType": "Variable", - "VariableName": "PositiveAmountTillThisLine" - } - }, - "RHS": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "AppliedAmount" - } - } - } - ] - }, - "Body": [ - { - "ActivityType": "NUMERICEXPRESSION", - "Activity": { - "VariableName": "TDSBaseAmt", - "Expression": "CurrentLineAmt-AppliedAmount", - "Tokens": [ + "Condition": { + "Body": [ { - "TokenName": "AppliedAmount", - "TokenValue": { - "Type": "Lookup", + "Operator": " ", + "ConditionType": "Is Less Than Or Equals To", + "LHS": { "Lookup": { "SourceType": "Variable", - "VariableName": "AppliedAmount" + "VariableName": "PositiveAmountTillThisLine" } - } - }, - { - "TokenName": "CurrentLineAmt", - "TokenValue": { + }, + "RHS": { "Type": "Lookup", "Lookup": { "SourceType": "Variable", - "VariableName": "PositiveAmountTillThisLine" + "VariableName": "AppliedAmount" } } } ] - } - }, - { - "ActivityType": "IFSTATEMENT", - "Activity": { + }, + "Body": [ + { + "ActivityType": "SETVARIABLE", + "Activity": { + "OutputVariableName": "TDSBaseAmt", + "OutputValue": { + "Type": "Constant", + "Value": "" + } + } + } + ], + "ElseIf": { "Condition": { "Body": [ { "Operator": " ", - "ConditionType": "Is Less Than", + "ConditionType": "Is Greater Than", "LHS": { "Lookup": { "SourceType": "Variable", - "VariableName": "PrevInvAmountLCY" + "VariableName": "PositiveAmountTillThisLine" } }, "RHS": { "Type": "Lookup", "Lookup": { - "SourceType": "Column", - "RateColumnName": "TDS Threshold Amount" + "SourceType": "Variable", + "VariableName": "AppliedAmount" } } } @@ -9004,145 +9109,34 @@ }, "Body": [ { - "ActivityType": "SETVARIABLE", + "ActivityType": "NUMERICEXPRESSION", "Activity": { - "OutputVariableName": "TDSTaxableAmount", - "OutputValue": { - "Type": "Constant", - "Value": "" - } - } - } - ], - "ElseIf": { - "Condition": { - "Body": [ - { - "Operator": " ", - "ConditionType": "Is Greater Than", - "LHS": { - "Lookup": { - "SourceType": "Variable", - "VariableName": "PrevInvAmountLCY" - } - }, - "RHS": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Column", - "RateColumnName": "TDS Threshold Amount" - } - } - } - ] - }, - "Body": [ - { - "ActivityType": "SETVARIABLE", - "Activity": { - "OutputVariableName": "TDSTaxableAmount", - "OutputValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "TDSBaseAmt" - } - } - } - }, - { - "ActivityType": "IFSTATEMENT", - "Activity": { - "Condition": { - "Body": [ - { - "Operator": " ", - "ConditionType": "Equals", - "LHS": { - "Lookup": { - "SourceType": "Column", - "RateColumnName": "Calc. Over & Above Threshold" - } - }, - "RHS": { - "Type": "Constant", - "Value": "1" - } + "VariableName": "TDSBaseAmt", + "Expression": "CurrentLineAmt-AppliedAmount", + "Tokens": [ + { + "TokenName": "AppliedAmount", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "AppliedAmount" } - ] + } }, - "Body": [ - { - "ActivityType": "NUMERICEXPRESSION", - "Activity": { - "VariableName": "TDSTaxableAmount", - "Expression": "(PrevInvAmtLcy+TdsBaseAmt) - ThresholdAmount", - "Tokens": [ - { - "TokenName": "PrevInvAmtLcy", - "TokenValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "PrevInvAmountLCY" - } - } - }, - { - "TokenName": "TdsBaseAmt", - "TokenValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "TDSBaseAmt" - } - } - }, - { - "TokenName": "ThresholdAmount", - "TokenValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Column", - "RateColumnName": "TDS Threshold Amount" - } - } - } - ] + { + "TokenName": "CurrentLineAmt", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "PositiveAmountTillThisLine" } } - ] - } - } - ] - } - } - }, - { - "ActivityType": "IFSTATEMENT", - "Activity": { - "Condition": { - "Body": [ - { - "Operator": " ", - "ConditionType": "Is Greater Than", - "LHS": { - "Lookup": { - "SourceType": "Variable", - "VariableName": "PositiveAmountTillThisLine" } - }, - "RHS": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Column", - "RateColumnName": "TDS Threshold Amount" - } - } + ] } - ] - }, - "Body": [ + }, { "ActivityType": "IFSTATEMENT", "Activity": { @@ -9150,39 +9144,31 @@ "Body": [ { "Operator": " ", - "ConditionType": "Equals", + "ConditionType": "Is Less Than", "LHS": { "Lookup": { - "SourceType": "Column", - "RateColumnName": "Calc. Over & Above Threshold" + "SourceType": "Variable", + "VariableName": "PrevInvAmountLCY" } }, "RHS": { - "Type": "Constant", - "Value": "1" + "Type": "Lookup", + "Lookup": { + "SourceType": "Column", + "RateColumnName": "TDS Threshold Amount" + } } } ] }, "Body": [ { - "ActivityType": "NUMBERCALCULATION", + "ActivityType": "SETVARIABLE", "Activity": { "OutputVariableName": "TDSTaxableAmount", - "Operator": "Minus", - "LHS": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "PositiveAmountTillThisLine" - } - }, - "RHS": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Column", - "RateColumnName": "TDS Threshold Amount" - } + "OutputValue": { + "Type": "Constant", + "Value": "" } } } @@ -9192,16 +9178,19 @@ "Body": [ { "Operator": " ", - "ConditionType": "Equals", + "ConditionType": "Is Greater Than", "LHS": { "Lookup": { - "SourceType": "Column", - "RateColumnName": "Calc. Over & Above Threshold" + "SourceType": "Variable", + "VariableName": "PrevInvAmountLCY" } }, "RHS": { - "Type": "Constant", - "Value": "" + "Type": "Lookup", + "Lookup": { + "SourceType": "Column", + "RateColumnName": "TDS Threshold Amount" + } } } ] @@ -9215,54 +9204,186 @@ "Type": "Lookup", "Lookup": { "SourceType": "Variable", - "VariableName": "PositiveAmountTillThisLine" + "VariableName": "TDSBaseAmt" } } } + }, + { + "ActivityType": "IFSTATEMENT", + "Activity": { + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Column", + "RateColumnName": "Calc. Over & Above Threshold" + } + }, + "RHS": { + "Type": "Constant", + "Value": "1" + } + } + ] + }, + "Body": [ + { + "ActivityType": "NUMERICEXPRESSION", + "Activity": { + "VariableName": "TDSTaxableAmount", + "Expression": "(PrevInvAmtLcy+TdsBaseAmt) - ThresholdAmount", + "Tokens": [ + { + "TokenName": "PrevInvAmtLcy", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "PrevInvAmountLCY" + } + } + }, + { + "TokenName": "TdsBaseAmt", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "TDSBaseAmt" + } + } + }, + { + "TokenName": "ThresholdAmount", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Column", + "RateColumnName": "TDS Threshold Amount" + } + } + } + ] + } + } + ] + } } ] } } - } - ] - } - }, - { - "ActivityType": "IFSTATEMENT", - "Activity": { - "Condition": { - "Body": [ - { - "Operator": " ", - "ConditionType": "Is Greater Than", - "LHS": { - "Lookup": { - "SourceType": "Variable", - "VariableName": "PositiveAmountTillThisLine" - } - }, - "RHS": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "AppliedAmount" - } - } - } - ] - }, - "Body": [ + }, { - "ActivityType": "SETVARIABLE", + "ActivityType": "IFSTATEMENT", "Activity": { - "OutputVariableName": "TDSTaxableAmount", - "OutputValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "TDSBaseAmt" + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Is Greater Than", + "LHS": { + "Lookup": { + "SourceType": "Variable", + "VariableName": "PositiveAmountTillThisLine" + } + }, + "RHS": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Column", + "RateColumnName": "TDS Threshold Amount" + } + } + } + ] + }, + "Body": [ + { + "ActivityType": "IFSTATEMENT", + "Activity": { + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Column", + "RateColumnName": "Calc. Over & Above Threshold" + } + }, + "RHS": { + "Type": "Constant", + "Value": "1" + } + } + ] + }, + "Body": [ + { + "ActivityType": "NUMBERCALCULATION", + "Activity": { + "OutputVariableName": "TDSTaxableAmount", + "Operator": "Minus", + "LHS": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "PositiveAmountTillThisLine" + } + }, + "RHS": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Column", + "RateColumnName": "TDS Threshold Amount" + } + } + } + } + ], + "ElseIf": { + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Column", + "RateColumnName": "Calc. Over & Above Threshold" + } + }, + "RHS": { + "Type": "Constant", + "Value": "" + } + } + ] + }, + "Body": [ + { + "ActivityType": "SETVARIABLE", + "Activity": { + "OutputVariableName": "TDSTaxableAmount", + "OutputValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "PositiveAmountTillThisLine" + } + } + } + } + ] + } + } } - } + ] } }, { @@ -9272,18 +9393,18 @@ "Body": [ { "Operator": " ", - "ConditionType": "Is Less Than", + "ConditionType": "Is Greater Than", "LHS": { "Lookup": { "SourceType": "Variable", - "VariableName": "TotalPrevAndCurrentInvAmt" + "VariableName": "PositiveAmountTillThisLine" } }, "RHS": { "Type": "Lookup", "Lookup": { - "SourceType": "Column", - "RateColumnName": "TDS Threshold Amount" + "SourceType": "Variable", + "VariableName": "AppliedAmount" } } } @@ -9295,19 +9416,60 @@ "Activity": { "OutputVariableName": "TDSTaxableAmount", "OutputValue": { - "Type": "Constant", - "Value": "" + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "TDSBaseAmt" + } } } }, { - "ActivityType": "SETVARIABLE", + "ActivityType": "IFSTATEMENT", "Activity": { - "OutputVariableName": "TDSBaseAmt", - "OutputValue": { - "Type": "Constant", - "Value": "" - } + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Is Less Than", + "LHS": { + "Lookup": { + "SourceType": "Variable", + "VariableName": "TotalPrevAndCurrentInvAmt" + } + }, + "RHS": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Column", + "RateColumnName": "TDS Threshold Amount" + } + } + } + ] + }, + "Body": [ + { + "ActivityType": "SETVARIABLE", + "Activity": { + "OutputVariableName": "TDSTaxableAmount", + "OutputValue": { + "Type": "Constant", + "Value": "" + } + } + }, + { + "ActivityType": "SETVARIABLE", + "Activity": { + "OutputVariableName": "TDSBaseAmt", + "OutputValue": { + "Type": "Constant", + "Value": "" + } + } + } + ] } } ] @@ -9316,38 +9478,10 @@ ] } } - ] - } - } - } - ] - } - }, - { - "ActivityType": "IFSTATEMENT", - "Activity": { - "Condition": { - "Body": [ - { - "Operator": " ", - "ConditionType": "Is Greater Than Or Equals To", - "LHS": { - "Lookup": { - "SourceType": "Variable", - "VariableName": "TotalPrevAndCurrentInvAmt" - } - }, - "RHS": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Column", - "RateColumnName": "TDS Threshold Amount" } - } + ] } - ] - }, - "Body": [ + }, { "ActivityType": "IFSTATEMENT", "Activity": { @@ -9355,28 +9489,8 @@ "Body": [ { "Operator": " ", - "ConditionType": "Equals", - "LHS": { - "Lookup": { - "SourceType": "Column", - "RateColumnName": "Calc. Over & Above Threshold" - } - }, - "RHS": { - "Type": "Constant", - "Value": "1" - } - } - ] - }, - "Body": [ - { - "ActivityType": "NUMBERCALCULATION", - "Activity": { - "OutputVariableName": "TDSBaseAmt", - "Operator": "Minus", + "ConditionType": "Is Greater Than Or Equals To", "LHS": { - "Type": "Lookup", "Lookup": { "SourceType": "Variable", "VariableName": "TotalPrevAndCurrentInvAmt" @@ -9390,76 +9504,124 @@ } } } - }, + ] + }, + "Body": [ { - "ActivityType": "SETVARIABLE", + "ActivityType": "IFSTATEMENT", "Activity": { - "OutputVariableName": "TDSTaxableAmount", - "OutputValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "TDSBaseAmt" + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Column", + "RateColumnName": "Calc. Over & Above Threshold" + } + }, + "RHS": { + "Type": "Constant", + "Value": "1" + } + } + ] + }, + "Body": [ + { + "ActivityType": "NUMBERCALCULATION", + "Activity": { + "OutputVariableName": "TDSBaseAmt", + "Operator": "Minus", + "LHS": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "TotalPrevAndCurrentInvAmt" + } + }, + "RHS": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Column", + "RateColumnName": "TDS Threshold Amount" + } + } + } + }, + { + "ActivityType": "SETVARIABLE", + "Activity": { + "OutputVariableName": "TDSTaxableAmount", + "OutputValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "TDSBaseAmt" + } + } + } } - } - } - } - ], - "ElseIf": { - "Condition": { - "Body": [] - }, - "Body": [ - { - "ActivityType": "SETVARIABLE", - "Activity": { - "OutputVariableName": "TDSBaseAmt", - "OutputValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "TotalPrevAndCurrentInvAmt" + ], + "ElseIf": { + "Condition": { + "Body": [] + }, + "Body": [ + { + "ActivityType": "SETVARIABLE", + "Activity": { + "OutputVariableName": "TDSBaseAmt", + "OutputValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "TotalPrevAndCurrentInvAmt" + } + } + } + }, + { + "ActivityType": "SETVARIABLE", + "Activity": { + "OutputVariableName": "TDSTaxableAmount", + "OutputValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "TDSBaseAmt" + } + } + } } - } + ] } - }, - { - "ActivityType": "SETVARIABLE", - "Activity": { - "OutputVariableName": "TDSTaxableAmount", - "OutputValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "TDSBaseAmt" - } + } + }, + { + "ActivityType": "NUMBERCALCULATION", + "Activity": { + "OutputVariableName": "TotalPrevAndCurrentInvAmt", + "Operator": "Minus", + "LHS": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "TotalPrevAndCurrentInvAmt" + } + }, + "RHS": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Amount" } } } - ] - } - } - }, - { - "ActivityType": "NUMBERCALCULATION", - "Activity": { - "OutputVariableName": "TotalPrevAndCurrentInvAmt", - "Operator": "Minus", - "LHS": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "TotalPrevAndCurrentInvAmt" } - }, - "RHS": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Amount" - } - } + ] } } ] @@ -9580,63 +9742,116 @@ "Body": [ { "Operator": " ", - "ConditionType": "Is Greater Than Or Equals To", - "LHS": { - "Lookup": { - "SourceType": "Variable", - "VariableName": "TotalPrevAndCurrentInvAmt" - } - }, - "RHS": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Column", - "RateColumnName": "TDS Threshold Amount" - } - } - }, - { - "Operator": "and", "ConditionType": "Equals", "LHS": { "Lookup": { - "SourceType": "Column", - "RateColumnName": "Per Contract Value" + "SourceType": "Table", + "TableName": "Allowed Sections", + "TableFieldName": "Threshold Overlook", + "Method": "First", + "TableFilters": [ + { + "FiterFieldName": "Vendor No", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Pay-to Vendor No." + } + } + }, + { + "FiterFieldName": "TDS Section", + "FilterType": "Equals", + "FilterValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "TDS Section Code" + } + } + } + ] } }, "RHS": { "Type": "Constant", - "Value": "" + "Value": "false" } } ] }, "Body": [ { - "ActivityType": "SETVARIABLE", - "Activity": { - "OutputVariableName": "TDSBaseAmt", - "OutputValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Current Record", - "TableName": "Purchase Line", - "FieldName": "Amount" - } - } - } - }, - { - "ActivityType": "SETVARIABLE", + "ActivityType": "IFSTATEMENT", "Activity": { - "OutputVariableName": "TDSTaxableAmount", - "OutputValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "TDSBaseAmt" + "Condition": { + "Body": [ + { + "Operator": " ", + "ConditionType": "Is Greater Than Or Equals To", + "LHS": { + "Lookup": { + "SourceType": "Variable", + "VariableName": "TotalPrevAndCurrentInvAmt" + } + }, + "RHS": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Column", + "RateColumnName": "TDS Threshold Amount" + } + } + }, + { + "Operator": "and", + "ConditionType": "Equals", + "LHS": { + "Lookup": { + "SourceType": "Column", + "RateColumnName": "Per Contract Value" + } + }, + "RHS": { + "Type": "Constant", + "Value": "" + } + } + ] + }, + "Body": [ + { + "ActivityType": "SETVARIABLE", + "Activity": { + "OutputVariableName": "TDSBaseAmt", + "OutputValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Current Record", + "TableName": "Purchase Line", + "FieldName": "Amount" + } + } + } + }, + { + "ActivityType": "SETVARIABLE", + "Activity": { + "OutputVariableName": "TDSTaxableAmount", + "OutputValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "TDSBaseAmt" + } + } + } } - } + ] } } ] @@ -12467,19 +12682,19 @@ ], "Components": [ { - "ComponentName": "SHE Cess ", - "Sequence": 4, + "ComponentName": "eCESS", + "Sequence": 3, "Formula": { - "VariableName": "SHE Cess ", - "Expression": "(TDSAmount+SurchargeAmount)*SHECessPercent/100", + "VariableName": "eCESS", + "Expression": "(TDSAmount+SurchargeAmount)*EcessPercent/100", "Tokens": [ { - "TokenName": "SHECessPercent", + "TokenName": "EcessPercent", "TokenValue": { "Type": "Lookup", "Lookup": { "SourceType": "Component Percent", - "ComponentName": "SHE Cess " + "ComponentName": "eCESS" } } }, @@ -12507,39 +12722,19 @@ } }, { - "ComponentName": "TDS Base Amount", - "Sequence": 6, - "Formula": { - "VariableName": "TDS Base Amount", - "Expression": "TDSBaseAmount", - "Tokens": [ - { - "TokenName": "TDSBaseAmount", - "TokenValue": { - "Type": "Lookup", - "Lookup": { - "SourceType": "Variable", - "VariableName": "TDSBaseAmt" - } - } - } - ] - } - }, - { - "ComponentName": "eCESS", - "Sequence": 3, + "ComponentName": "SHE Cess ", + "Sequence": 4, "Formula": { - "VariableName": "eCESS", - "Expression": "(TDSAmount+SurchargeAmount)*EcessPercent/100", + "VariableName": "SHE Cess ", + "Expression": "(TDSAmount+SurchargeAmount)*SHECessPercent/100", "Tokens": [ { - "TokenName": "EcessPercent", + "TokenName": "SHECessPercent", "TokenValue": { "Type": "Lookup", "Lookup": { "SourceType": "Component Percent", - "ComponentName": "eCESS" + "ComponentName": "SHE Cess " } } }, @@ -12596,6 +12791,26 @@ ] } }, + { + "ComponentName": "TDS Base Amount", + "Sequence": 6, + "Formula": { + "VariableName": "TDS Base Amount", + "Expression": "TDSBaseAmount", + "Tokens": [ + { + "TokenName": "TDSBaseAmount", + "TokenValue": { + "Type": "Lookup", + "Lookup": { + "SourceType": "Variable", + "VariableName": "TDSBaseAmt" + } + } + } + ] + } + }, { "ComponentName": "Surcharge", "Sequence": 2, diff --git a/Apps/IN/INTDS/app/TDSBase/src/TaxEngineSetup/TDSTaxConfiguration.Codeunit.al b/Apps/IN/INTDS/app/TDSBase/src/TaxEngineSetup/TDSTaxConfiguration.Codeunit.al index c8e27fbc46..01c451036d 100644 --- a/Apps/IN/INTDS/app/TDSBase/src/TaxEngineSetup/TDSTaxConfiguration.Codeunit.al +++ b/Apps/IN/INTDS/app/TDSBase/src/TaxEngineSetup/TDSTaxConfiguration.Codeunit.al @@ -61,9 +61,9 @@ codeunit 18694 "TDS Tax Configuration" UseCases.Add('{5D4C69D3-E776-4E9D-B397-09336BFDC884}', 1); UseCases.Add('{FED919F2-CBDB-45F9-9383-0E1607897400}', 2); UseCases.Add('{B0C259BC-64CC-4818-887A-3337D357CDFF}', 2); - UseCases.Add('{33BFBE99-9140-4112-A55B-35EC0D9B61B9}', 3); + UseCases.Add('{33BFBE99-9140-4112-A55B-35EC0D9B61B9}', 4); UseCases.Add('{271D5BC6-17E8-424E-9E34-3BEE548F938F}', 1); - UseCases.Add('{A8E114BF-F8CD-44DB-A2B3-614BC18F4442}', 29); + UseCases.Add('{A8E114BF-F8CD-44DB-A2B3-614BC18F4442}', 30); UseCases.Add('{6FBA1A5C-41A0-4430-976E-6B54E4884164}', 1); UseCases.Add('{FEE5DFFF-0BC1-4246-AD90-6CB3DC44A451}', 1); UseCases.Add('{FA0E357D-1AC0-42AA-94DE-6DACA521D38E}', 2); diff --git a/Apps/IN/INTaxBase/app/src/pageextension/PurchaseInvoiceSubform.PageExt.al b/Apps/IN/INTaxBase/app/src/pageextension/PurchaseInvoiceSubform.PageExt.al deleted file mode 100644 index abca58cda8..0000000000 --- a/Apps/IN/INTaxBase/app/src/pageextension/PurchaseInvoiceSubform.PageExt.al +++ /dev/null @@ -1,16 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// ------------------------------------------------------------------------------------------------ -namespace Microsoft.Purchases.Document; - -pageextension 18550 "Purchase Invoice Subform" extends "Purch. Invoice Subform" -{ - ObsoleteState = Pending; - ObsoleteTag = '22.0'; - ObsoleteReason = 'The functionality will be removed and this page extension should not be used.'; - - layout - { - } -} diff --git a/Apps/IN/INTaxBase/app/src/pageextension/PurchaseOrderSubform.PageExt.al b/Apps/IN/INTaxBase/app/src/pageextension/PurchaseOrderSubform.PageExt.al deleted file mode 100644 index d1a889fadd..0000000000 --- a/Apps/IN/INTaxBase/app/src/pageextension/PurchaseOrderSubform.PageExt.al +++ /dev/null @@ -1,16 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// ------------------------------------------------------------------------------------------------ -namespace Microsoft.Purchases.Document; - -pageextension 18552 "Purchase Order Subform" extends "Purchase Order Subform" -{ - ObsoleteState = Pending; - ObsoleteTag = '22.0'; - ObsoleteReason = 'The functionality will be removed and this page extension should not be used.'; - - layout - { - } -} diff --git a/Apps/IS/ISCore/app/src/Codeunits/EnableISCoreApp.Codeunit.al b/Apps/IS/ISCore/app/src/Codeunits/EnableISCoreApp.Codeunit.al index 62d75980d2..1365611415 100644 --- a/Apps/IS/ISCore/app/src/Codeunits/EnableISCoreApp.Codeunit.al +++ b/Apps/IS/ISCore/app/src/Codeunits/EnableISCoreApp.Codeunit.al @@ -64,7 +64,7 @@ codeunit 14611 "Enable IS Core App" TargetFieldRef := TargetRecRef.Field(SourceFieldRefNo); TargetFieldRef.VALUE := SourceFieldRef.VALUE; until SourceField.Next() = 0; - TargetRecRef.Insert(); + if TargetRecRef.Insert() then; until SourceRecRef.Next() = 0; SourceRecRef.Close(); TargetRecRef.Close(); diff --git a/Apps/NA/Ceridian/ExtensionLogo.png b/Apps/NA/Ceridian/app/ExtensionLogo.png similarity index 100% rename from Apps/NA/Ceridian/ExtensionLogo.png rename to Apps/NA/Ceridian/app/ExtensionLogo.png diff --git a/Apps/NA/Ceridian/app.json b/Apps/NA/Ceridian/app/app.json similarity index 100% rename from Apps/NA/Ceridian/app.json rename to Apps/NA/Ceridian/app/app.json diff --git a/Apps/NA/Ceridian/src/CeridianInstall.Codeunit.al b/Apps/NA/Ceridian/app/src/CeridianInstall.Codeunit.al similarity index 100% rename from Apps/NA/Ceridian/src/CeridianInstall.Codeunit.al rename to Apps/NA/Ceridian/app/src/CeridianInstall.Codeunit.al diff --git a/Apps/NA/Ceridian/src/ImportCeridianPayroll.XmlPort.al b/Apps/NA/Ceridian/app/src/ImportCeridianPayroll.XmlPort.al similarity index 100% rename from Apps/NA/Ceridian/src/ImportCeridianPayroll.XmlPort.al rename to Apps/NA/Ceridian/app/src/ImportCeridianPayroll.XmlPort.al diff --git a/Apps/NA/Ceridian/src/MSCeridianPayrollMgt.Codeunit.al b/Apps/NA/Ceridian/app/src/MSCeridianPayrollMgt.Codeunit.al similarity index 100% rename from Apps/NA/Ceridian/src/MSCeridianPayrollMgt.Codeunit.al rename to Apps/NA/Ceridian/app/src/MSCeridianPayrollMgt.Codeunit.al diff --git a/Apps/NA/Ceridian/src/MSCeridianPayrollSetup.Page.al b/Apps/NA/Ceridian/app/src/MSCeridianPayrollSetup.Page.al similarity index 100% rename from Apps/NA/Ceridian/src/MSCeridianPayrollSetup.Page.al rename to Apps/NA/Ceridian/app/src/MSCeridianPayrollSetup.Page.al diff --git a/Apps/NA/Ceridian/src/MSCeridianPayrollSetup.Table.al b/Apps/NA/Ceridian/app/src/MSCeridianPayrollSetup.Table.al similarity index 100% rename from Apps/NA/Ceridian/src/MSCeridianPayrollSetup.Table.al rename to Apps/NA/Ceridian/app/src/MSCeridianPayrollSetup.Table.al diff --git a/Apps/NA/Ceridian/src/MSCeridianPayrollimport.Codeunit.al b/Apps/NA/Ceridian/app/src/MSCeridianPayrollimport.Codeunit.al similarity index 100% rename from Apps/NA/Ceridian/src/MSCeridianPayrollimport.Codeunit.al rename to Apps/NA/Ceridian/app/src/MSCeridianPayrollimport.Codeunit.al diff --git a/Apps/NA/Ceridian/src/MSCeridianPayrollupgrade.Codeunit.al b/Apps/NA/Ceridian/app/src/MSCeridianPayrollupgrade.Codeunit.al similarity index 100% rename from Apps/NA/Ceridian/src/MSCeridianPayrollupgrade.Codeunit.al rename to Apps/NA/Ceridian/app/src/MSCeridianPayrollupgrade.Codeunit.al diff --git a/Apps/NA/Ceridian/src/Permissions/d365basicceridianpayroll.permissionsetext.al b/Apps/NA/Ceridian/app/src/Permissions/d365basicceridianpayroll.permissionsetext.al similarity index 100% rename from Apps/NA/Ceridian/src/Permissions/d365basicceridianpayroll.permissionsetext.al rename to Apps/NA/Ceridian/app/src/Permissions/d365basicceridianpayroll.permissionsetext.al diff --git a/Apps/NA/Ceridian/src/Permissions/d365basicisvceridianpayroll.permissionsetext.al b/Apps/NA/Ceridian/app/src/Permissions/d365basicisvceridianpayroll.permissionsetext.al similarity index 100% rename from Apps/NA/Ceridian/src/Permissions/d365basicisvceridianpayroll.permissionsetext.al rename to Apps/NA/Ceridian/app/src/Permissions/d365basicisvceridianpayroll.permissionsetext.al diff --git a/Apps/NA/Ceridian/src/Permissions/d365busfullaccessceridianpayroll.permissionsetext.al b/Apps/NA/Ceridian/app/src/Permissions/d365busfullaccessceridianpayroll.permissionsetext.al similarity index 100% rename from Apps/NA/Ceridian/src/Permissions/d365busfullaccessceridianpayroll.permissionsetext.al rename to Apps/NA/Ceridian/app/src/Permissions/d365busfullaccessceridianpayroll.permissionsetext.al diff --git a/Apps/NA/Ceridian/src/Permissions/d365buspremiumceridianpayroll.permissionsetext.al b/Apps/NA/Ceridian/app/src/Permissions/d365buspremiumceridianpayroll.permissionsetext.al similarity index 100% rename from Apps/NA/Ceridian/src/Permissions/d365buspremiumceridianpayroll.permissionsetext.al rename to Apps/NA/Ceridian/app/src/Permissions/d365buspremiumceridianpayroll.permissionsetext.al diff --git a/Apps/NA/Ceridian/src/Permissions/d365fullaccessceridianpayroll.permissionsetext.al b/Apps/NA/Ceridian/app/src/Permissions/d365fullaccessceridianpayroll.permissionsetext.al similarity index 100% rename from Apps/NA/Ceridian/src/Permissions/d365fullaccessceridianpayroll.permissionsetext.al rename to Apps/NA/Ceridian/app/src/Permissions/d365fullaccessceridianpayroll.permissionsetext.al diff --git a/Apps/NA/Ceridian/src/Permissions/d365readceridianpayroll.permissionsetext.al b/Apps/NA/Ceridian/app/src/Permissions/d365readceridianpayroll.permissionsetext.al similarity index 100% rename from Apps/NA/Ceridian/src/Permissions/d365readceridianpayroll.permissionsetext.al rename to Apps/NA/Ceridian/app/src/Permissions/d365readceridianpayroll.permissionsetext.al diff --git a/Apps/NA/Ceridian/src/Permissions/d365teammemberceridianpayroll.permissionsetext.al b/Apps/NA/Ceridian/app/src/Permissions/d365teammemberceridianpayroll.permissionsetext.al similarity index 100% rename from Apps/NA/Ceridian/src/Permissions/d365teammemberceridianpayroll.permissionsetext.al rename to Apps/NA/Ceridian/app/src/Permissions/d365teammemberceridianpayroll.permissionsetext.al diff --git a/Apps/NA/Ceridian/src/Permissions/intelligentcloudceridianpayroll.permissionsetext.al b/Apps/NA/Ceridian/app/src/Permissions/intelligentcloudceridianpayroll.permissionsetext.al similarity index 100% rename from Apps/NA/Ceridian/src/Permissions/intelligentcloudceridianpayroll.permissionsetext.al rename to Apps/NA/Ceridian/app/src/Permissions/intelligentcloudceridianpayroll.permissionsetext.al diff --git a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeBankServiceSetup.Table.al b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeBankServiceSetup.Table.al index e0c281729c..eb74c0f148 100644 --- a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeBankServiceSetup.Table.al +++ b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeBankServiceSetup.Table.al @@ -569,12 +569,9 @@ table 1450 "MS - Yodlee Bank Service Setup" [NonDebuggable] [Scope('OnPrem')] - procedure SaveConsumerPassword(var ConsumerPasswordKey: Guid; ConsumerPassword: SecretText); + procedure SaveConsumerPassword(var ConsumerPasswordKey: Guid; ConsumerPasswordValue: Text); var - ConsumerPasswordValue: Text; begin - ConsumerPasswordValue := ConsumerPassword.Unwrap(); - ConsumerPasswordValue := DELCHR(ConsumerPasswordValue, '=', ' '); if ISNULLGUID(ConsumerPasswordKey) or not IsolatedStorage.Contains(ConsumerPasswordKey, DataScope::Company) then diff --git a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeServiceMgt.Codeunit.al b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeServiceMgt.Codeunit.al index 8de04d9257..204b14d45e 100644 --- a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeServiceMgt.Codeunit.al +++ b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeServiceMgt.Codeunit.al @@ -88,6 +88,8 @@ codeunit 1450 "MS - Yodlee Service Mgt." BankAccountRefreshBankInBetaMaintenanceTxt: Label 'Yodlee was unable to update your account because it has started providing data updates for this online bank, and it may take a few days to be successful. Please try again later.'; BankAccountRefreshTimedOutTxt: Label 'Your request timed out due to technical reasons. Open the corresponding bank account card and choose action Edit Online Bank Account Information. Provide the credentials for the online bank account, close the page and then choose action Refresh Online Bank Account.'; BankAccountRefreshAdditionalAuthInfoNeededTxt: Label 'Additional authentication information is required. Open the corresponding bank account card and choose action Edit Online Bank Account Information.'; + BankAccountConsentRequiredTxt: Label 'Access consent update is required for this online bank account. Open the corresponding bank account card, choose action ''Manage Access Consent for Online Bank Account'' and provide consent. If that doesn''t help, choose action ''Edit Online Bank Account Information'' and provide credentials and consent.'; + UserActionNeededAtSiteTxt: Label 'Your financial institution requires additional action at their site. Sign in to your financial institution''s website to complete the necessary steps.'; YodleeFastlinkUrlTxt: Label 'YODLEE_FASTLINKURL', Locked = true; GLBDisableRethrowException: Boolean; ErrorsIgnoredTxt: Label 'This failure has been ignored.'; @@ -615,12 +617,13 @@ codeunit 1450 "MS - Yodlee Service Mgt." exit(true); end; + + [NonDebuggable] procedure RegisterConsumer(var Username: Text[250]; var Password: SecretText; var ErrorText: Text; CobrandToken: Text): Boolean; var MSYodleeBankServiceSetup: Record "MS - Yodlee Bank Service Setup"; GeneralLedgerSetup: Record "General Ledger Setup"; PasswordHelper: Codeunit "Password Helper"; - Body: SecretText; Response: Text; LcyCode: Text; Email: Text; @@ -644,13 +647,14 @@ codeunit 1450 "MS - Yodlee Service Mgt." false: begin AuthorizationHeaderValue := YodleeAPIStrings.GetAuthorizationHeaderValue(CobrandToken, ''); - Password := PasswordHelper.GenerateSecretPassword(50); + Password := COPYSTR(PasswordHelper.GenerateSecretPassword(50).Unwrap(), 1, 50); end; end; Session.LogMessage('0000DL9', StrSubstNo(StartingToRegisterUserTxt, UserName, LcyCode), Verbosity::Normal, DataClassification::CustomerContent, TelemetryScope::ExtensionPublisher, 'Category', YodleeTelemetryCategoryTok); - Body := YodleeAPIStrings.GetRegisterConsumerBodySecret(CobrandToken, Username, Password, LcyCode, Email); - ExecuteWebServiceRequest(YodleeAPIStrings.GetRegisterConsumerURL(), 'POST', Body, AuthorizationHeaderValue, ErrorText, ''); + ExecuteWebServiceRequest(YodleeAPIStrings.GetRegisterConsumerURL(), 'POST', + YodleeAPIStrings.GetRegisterConsumerBody(CobrandToken, UserName, Password, Email, LcyCode), AuthorizationHeaderValue, + ErrorText, ''); if not GetResponseValue('/', Response, ErrorText) then begin ErrorText := GetAdjustedErrorText(ErrorText, FailedRegisterConsumerTxt); @@ -671,7 +675,7 @@ codeunit 1450 "MS - Yodlee Service Mgt." LogActivitySucceed(RegisterConsumerTxt, SuccessRegisterConsumerTxt, StrSubstNo(TelemetryActivitySuccessTxt, RegisterConsumerTxt, SuccessRegisterConsumerTxt)); MSYodleeBankServiceSetup.VALIDATE("Consumer Name", COPYSTR(Username, 1, MAXSTRLEN(MSYodleeBankServiceSetup."Consumer Name"))); - MSYodleeBankServiceSetup.SaveConsumerPassword(MSYodleeBankServiceSetup."Consumer Password", Password); + MSYodleeBankServiceSetup.SaveConsumerPassword(MSYodleeBankServiceSetup."Consumer Password", Password.Unwrap()); MSYodleeBankServiceSetup.MODIFY(true); StoreConsumerName(MSYodleeBankServiceSetup."Consumer Name"); exit(true); @@ -783,7 +787,6 @@ codeunit 1450 "MS - Yodlee Service Mgt." ErrorText: Text; AuthorizationHeaderValue: Text; LoginName: Text; - EmptyText: Text; begin CheckServiceEnabled(); Authenticate(CobrandToken, ConsumerToken); @@ -797,7 +800,7 @@ codeunit 1450 "MS - Yodlee Service Mgt." AuthorizationHeaderValue := YodleeAPIStrings.GetAuthorizationHeaderValue(CobrandToken, ConsumerToken); end; - ExecuteWebServiceRequest(YodleeAPIStrings.GetLinkedBankAccountURL(AccountId), 'GET', EmptyText, AuthorizationHeaderValue, ErrorText, LoginName); + ExecuteWebServiceRequest(YodleeAPIStrings.GetLinkedBankAccountURL(AccountId), 'GET', '', AuthorizationHeaderValue, ErrorText, LoginName); if ErrorText <> '' then begin LogActivityFailed( @@ -949,13 +952,13 @@ codeunit 1450 "MS - Yodlee Service Mgt." local procedure UserFriendlyRefreshErrorMessage(RefreshCode: Text): Text; begin case RefreshCode of - '402', 'CREDENTIALS_UPDATE_NEEDED', 'INCORRECT_CREDENTIALS': + '402', 'CREDENTIALS_UPDATE_NEEDED', 'INCORRECT_CREDENTIALS', 'INCORRECT_OAUTH_TOKEN': exit(BankAccountRefreshInvalidCredentialsTxt); '404', 'TECH_ERROR': exit(BankAccountRefreshUnknownErrorTxt); '407', 'ACCOUNT_LOCKED': exit(BankAccountRefreshAccountLockedTxt); - '409', 'UNEXPECTED_SITE_ERROR', 'SITE_UNAVAILABLE': + '409', 'UNEXPECTED_SITE_ERROR', 'SITE_UNAVAILABLE', 'DATA_NOT_AVAILABLE', 'NOT_AVAILABLE', 'SITE_BLOCKING_ERROR': exit(BankAccountRefreshBankDownTxt); '424': exit(BankAccountRefreshBankDownForMaintenanceTxt); @@ -965,6 +968,10 @@ codeunit 1450 "MS - Yodlee Service Mgt." exit(BankAccountRefreshTimedOutTxt); '518', '519', '520', '522', '523', '524', '526', 'ADDL_AUTHENTICATION_REQUIRED', 'INVALID_ADDL_INFO_PROVIDED', 'NEW_AUTHENTICATION_REQUIRED': exit(BankAccountRefreshAdditionalAuthInfoNeededTxt); + 'CONSENT_EXPIRED', 'CONSENT_REVOKED', 'CONSENT_REQUIRED': + exit(BankAccountConsentRequiredTxt); + 'USER_ACTION_NEEDED_AT_SITE': + exit(UserActionNeededAtSiteTxt); end; exit(''); end; @@ -1593,7 +1600,8 @@ codeunit 1450 "MS - Yodlee Service Mgt." exit(URL.ToLower().Contains('transactions')); end; - local procedure ExecuteWebServiceRequest(URL: Text; Method: Text[6]; BodyText: SecretText; AuthorizationHeaderValue: Text; var ErrorText: Text; LoginName: Text) PaginationLink: Text + [NonDebuggable] + local procedure ExecuteWebServiceRequest(URL: Text; Method: Text[6]; BodyText: Text; AuthorizationHeaderValue: Text; var ErrorText: Text; LoginName: Text) PaginationLink: Text var MSYodleeBankServiceSetup: Record "MS - Yodlee Bank Service Setup"; ActivityLog: Record "Activity Log"; @@ -1637,7 +1645,7 @@ codeunit 1450 "MS - Yodlee Service Mgt." RequestHeaders.TryAddWithoutValidation('Authorization', AuthorizationHeaderValue); HttpRequestMessage.SetRequestUri(URL); HttpRequestMessage.Method(Method); - if BodyText.IsEmpty() then begin + if BodyText <> '' then begin ReqHttpContent.GetHeaders(ContentHeaders); ReqHttpContent.WriteFrom(BodyText); ContentHeaders.Remove('Content-Type'); diff --git a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/YodleeAPIStrings.Codeunit.al b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/YodleeAPIStrings.Codeunit.al index 8b063f8c04..eb6dde4ea6 100644 --- a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/YodleeAPIStrings.Codeunit.al +++ b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/YodleeAPIStrings.Codeunit.al @@ -120,10 +120,9 @@ codeunit 1458 "Yodlee API Strings" exit(GetFullURL('/user/register')); end; -#if not CLEAN28 + [Scope('OnPrem')] [NonDebuggable] - [Obsolete('Use GetRegisterConsumerBodySecret instead', '28.0')] procedure GetRegisterConsumerBody(CobrandToken: Text; UserName: Text; UserPassword: SecretText; UserEmail: Text; UserCurrency: Text): Text; var GetRegisterConsumerRequestBodyJsonObject: JsonObject; @@ -141,9 +140,10 @@ codeunit 1458 "Yodlee API Strings" GetRegisterConsumerRequestBodyJsonObject.WriteTo(GetRegisterConsumerRequestBodyText); exit(GetRegisterConsumerRequestBodyText); end; -#endif +#if not CLEAN28 [Scope('OnPrem')] + [Obsolete('Use GetRegisterConsumerBody instead', '28.0')] procedure GetRegisterConsumerBodySecret(CobrandToken: Text; UserName: Text; UserPassword: SecretText; UserEmail: Text; UserCurrency: Text): SecretText; var RegisterConsumerRequestBodyJsonObject: JsonObject; @@ -172,6 +172,7 @@ codeunit 1458 "Yodlee API Strings" exit(RegisterConsumerRequestBodySecretText); end; +#endif [Scope('OnPrem')] procedure GetRemoveConsumerURL(): Text; diff --git a/Apps/NA/Onprem Permissions NA/app/Permissions/bankrecpost.permissionset.al b/Apps/NA/Onprem Permissions NA/app/Permissions/bankrecpost.permissionset.al index 55f9e7efd5..b0c0d87016 100644 --- a/Apps/NA/Onprem Permissions NA/app/Permissions/bankrecpost.permissionset.al +++ b/Apps/NA/Onprem Permissions NA/app/Permissions/bankrecpost.permissionset.al @@ -37,10 +37,6 @@ permissionset 27004 "BANKREC-POST" tabledata "Gen. Journal Template" = RI, tabledata "General Ledger Setup" = r, tabledata "General Posting Setup" = r, -#if not CLEAN25 - tabledata "IRS 1099 Adjustment" = RIMD, - tabledata "IRS 1099 Form-Box" = RIMD, -#endif tabledata "Reversal Entry" = RIMD, tabledata "Tax Area" = R, tabledata "Tax Area Line" = R, @@ -50,4 +46,4 @@ permissionset 27004 "BANKREC-POST" tabledata "User Setup" = r, tabledata "VAT Entry" = Ri, tabledata "VAT Posting Setup" = R; -} +} \ No newline at end of file diff --git a/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/Finance/1.Setup Data/CreateIRS1099FormBoxUS.Codeunit.al b/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/Finance/1.Setup Data/CreateIRS1099FormBoxUS.Codeunit.al deleted file mode 100644 index b0fff3c917..0000000000 --- a/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/Finance/1.Setup Data/CreateIRS1099FormBoxUS.Codeunit.al +++ /dev/null @@ -1,571 +0,0 @@ -#if not CLEAN27 -// ------------------------------------------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// ------------------------------------------------------------------------------------------------ - -namespace Microsoft.DemoData.Finance; - -using Microsoft.DemoTool.Helpers; - -codeunit 11451 "Create IRS 1099 Form-Box US" -{ - InherentEntitlements = X; - InherentPermissions = X; - ObsoleteReason = 'Moved to IRS Forms App.'; - ObsoleteState = Pending; - ObsoleteTag = '27.0'; - - trigger OnRun() - var - ContosoIRS1099US: Codeunit "Contoso IRS 1099 US"; - begin - ContosoIRS1099US.InsertIRS1099FormBox(BTok, ProceedsFromBrokerBarterExchangeTransactionsLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(B02Tok, StocksbondsetcLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(B03Tok, BarteringLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(B04Tok, FederalincometaxwithheldLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(B06Tok, ProfitlossrealizedthisyearLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(B07Tok, UnrealprofitlossonopencontractslastyearLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(B08Tok, UnrealprofitlossonopencontractsthisyearLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(B09Tok, AggregateprofitlossLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(DIVTok, DividendsandDistributionsLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(DIV01ATok, TotalordinarydividendsLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(DIV01BTok, QualifieddividendsLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(DIV02ATok, TotalcapitalgaindistrLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(DIV02BTok, UnrecapSec1250gainLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(DIV02CTok, Section1202gainLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(DIV02DTok, Collectibles28gainLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(DIV02ETok, Section897ordinarydividendsLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(DIV02FTok, Section897capitalgainLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(DIV03Tok, NondividenddistributionsLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(DIV04Tok, FederalincometaxwithheldLbl, -1); - ContosoIRS1099US.InsertIRS1099FormBox(DIV05Tok, Section199AdividendsLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(DIV06Tok, InvestmentexpensesLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(DIV07Tok, ForeigntaxpaidLbl, -1); - ContosoIRS1099US.InsertIRS1099FormBox(DIV09Tok, CashliquidationdistributionsLbl, 600); - ContosoIRS1099US.InsertIRS1099FormBox(DIV10Tok, NoncashliquidationdistributionsLbl, 600); - ContosoIRS1099US.InsertIRS1099FormBox(DIV12Tok, ExemptinterestdividendsLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(DIV13Tok, SpecifiedprivateactivitybondinterestdividendsLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(INTTok, InterestIncomeLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(INT01Tok, InterestincomeLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(INT02Tok, EarlywithdrawalpenaltyLbl, -1); - ContosoIRS1099US.InsertIRS1099FormBox(INT03Tok, InterestonUSSavingsBondsandTreasobligationsLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(INT04Tok, FederalincometaxwithheldLbl, -1); - ContosoIRS1099US.InsertIRS1099FormBox(INT05Tok, InvestmentexpensesLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(INT06Tok, ForeigntaxpaidLbl, -1); - ContosoIRS1099US.InsertIRS1099FormBox(INT08Tok, TaxexemptinterestLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(INT09Tok, SpecifiedprivateactivitybondinterestLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(INT10Tok, MarketdiscountLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(INT11Tok, BondpremiumLbl, 0.01); - ContosoIRS1099US.InsertIRS1099FormBox(INT12Tok, BondPremiumonTreasuryObligationLbl, 0.01); - ContosoIRS1099US.InsertIRS1099FormBox(INT13Tok, BondpremiumontaxexemptbondLbl, 0.01); - ContosoIRS1099US.InsertIRS1099FormBox(MISCTok, MiscellaneousIncomeLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(MISC01Tok, RentsLbl, 600); - ContosoIRS1099US.InsertIRS1099FormBox(MISC02Tok, RoyaltiesLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(MISC03Tok, OtherIncomeLbl, 600); - ContosoIRS1099US.InsertIRS1099FormBox(MISC04Tok, FederalincometaxwithheldLbl, -1); - ContosoIRS1099US.InsertIRS1099FormBox(MISC05Tok, FishingboatproceedsLbl, 1); - ContosoIRS1099US.InsertIRS1099FormBox(MISC06Tok, MedicalandhealthcarepaymentsLbl, 600); - ContosoIRS1099US.InsertIRS1099FormBox(MISC07Tok, Payermadedirectsalesof5000ormoreofconsumerproductsLbl, 5000); - ContosoIRS1099US.InsertIRS1099FormBox(MISC08Tok, SubstitutepaymentsinlieuofdividendsorinterestLbl, 10); - ContosoIRS1099US.InsertIRS1099FormBox(MISC09Tok, CropinsuranceproceedsLbl, 1); - ContosoIRS1099US.InsertIRS1099FormBox(MISC10Tok, GrossproceedspaidtoanattorneyLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(MISC11Tok, FishpurchasedforresaleLbl, 600); - ContosoIRS1099US.InsertIRS1099FormBox(MISC12Tok, Section409AdeferralsLbl, 600); - ContosoIRS1099US.InsertIRS1099FormBox(MISC14Tok, ExcessgoldenparachutepaymentsLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(MISC15Tok, NonqualifieddeferredcompensationLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(MISC16Tok, StatetaxwithheldLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(NEC01Tok, NonemployeecompensationLbl, 600); - ContosoIRS1099US.InsertIRS1099FormBox(NEC02Tok, Payermadedirectsalestotaling5000ormoreofconsumerproductstorecipientforresaleLbl, 5000); - ContosoIRS1099US.InsertIRS1099FormBox(NEC04Tok, FederalincometaxwithheldLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(RTok, PensionsAnnRetirementProfitSharPlansIRAsLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(R01Tok, GrossdistributionLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(R02ATok, TaxableAmountLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(R03Tok, AmountinBox2eligibleforcapitalgainelectionLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(R04Tok, FederalincometaxwithheldLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(R05Tok, EmployeecontributionsinsurancepremiumsLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(R06Tok, NetunrealappreciationinemployerssecuritiesLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(R10Tok, StateincometaxwithheldLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(R12Tok, LocalincometaxwithheldLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(STok, ProceedsFromRealEstateTransactionsLbl, 0); - ContosoIRS1099US.InsertIRS1099FormBox(S02Tok, GrossproceedsLbl, 0); - end; - - procedure B(): Code[10] - begin - exit(BTok); - end; - - procedure B02(): Code[10] - begin - exit(B02Tok); - end; - - procedure B03(): Code[10] - begin - exit(B03Tok); - end; - - procedure B04(): Code[10] - begin - exit(B04Tok); - end; - - procedure B06(): Code[10] - begin - exit(B06Tok); - end; - - procedure B07(): Code[10] - begin - exit(B07Tok); - end; - - procedure B08(): Code[10] - begin - exit(B08Tok); - end; - - procedure B09(): Code[10] - begin - exit(B09Tok); - end; - - procedure DIV(): Code[10] - begin - exit(DIVTok); - end; - - procedure DIV01A(): Code[10] - begin - exit(DIV01ATok); - end; - - procedure DIV01B(): Code[10] - begin - exit(DIV01BTok); - end; - - procedure DIV02A(): Code[10] - begin - exit(DIV02ATok); - end; - - procedure DIV02B(): Code[10] - begin - exit(DIV02BTok); - end; - - procedure DIV02C(): Code[10] - begin - exit(DIV02CTok); - end; - - procedure DIV02D(): Code[10] - begin - exit(DIV02DTok); - end; - - procedure DIV02E(): Code[10] - begin - exit(DIV02ETok); - end; - - procedure DIV02F(): Code[10] - begin - exit(DIV02FTok); - end; - - procedure DIV03(): Code[10] - begin - exit(DIV03Tok); - end; - - procedure DIV04(): Code[10] - begin - exit(DIV04Tok); - end; - - procedure DIV05(): Code[10] - begin - exit(DIV05Tok); - end; - - procedure DIV06(): Code[10] - begin - exit(DIV06Tok); - end; - - procedure DIV07(): Code[10] - begin - exit(DIV07Tok); - end; - - procedure DIV09(): Code[10] - begin - exit(DIV09Tok); - end; - - procedure DIV10(): Code[10] - begin - exit(DIV10Tok); - end; - - procedure DIV12(): Code[10] - begin - exit(DIV12Tok); - end; - - procedure DIV13(): Code[10] - begin - exit(DIV13Tok); - end; - - procedure INT(): Code[10] - begin - exit(INTTok); - end; - - procedure INT01(): Code[10] - begin - exit(INT01Tok); - end; - - procedure INT02(): Code[10] - begin - exit(INT02Tok); - end; - - procedure INT03(): Code[10] - begin - exit(INT03Tok); - end; - - procedure INT04(): Code[10] - begin - exit(INT04Tok); - end; - - procedure INT05(): Code[10] - begin - exit(INT05Tok); - end; - - procedure INT06(): Code[10] - begin - exit(INT06Tok); - end; - - procedure INT08(): Code[10] - begin - exit(INT08Tok); - end; - - procedure INT09(): Code[10] - begin - exit(INT09Tok); - end; - - procedure INT10(): Code[10] - begin - exit(INT10Tok); - end; - - procedure INT11(): Code[10] - begin - exit(INT11Tok); - end; - - procedure INT12(): Code[10] - begin - exit(INT12Tok); - end; - - procedure INT13(): Code[10] - begin - exit(INT13Tok); - end; - - procedure MISC(): Code[10] - begin - exit(MISCTok); - end; - - procedure MISC01(): Code[10] - begin - exit(MISC01Tok); - end; - - procedure MISC02(): Code[10] - begin - exit(MISC02Tok); - end; - - procedure MISC03(): Code[10] - begin - exit(MISC03Tok); - end; - - procedure MISC04(): Code[10] - begin - exit(MISC04Tok); - end; - - procedure MISC05(): Code[10] - begin - exit(MISC05Tok); - end; - - procedure MISC06(): Code[10] - begin - exit(MISC06Tok); - end; - - procedure MISC07(): Code[10] - begin - exit(MISC07Tok); - end; - - procedure MISC08(): Code[10] - begin - exit(MISC08Tok); - end; - - procedure MISC09(): Code[10] - begin - exit(MISC09Tok); - end; - - procedure MISC10(): Code[10] - begin - exit(MISC10Tok); - end; - - procedure MISC11(): Code[10] - begin - exit(MISC11Tok); - end; - - procedure MISC12(): Code[10] - begin - exit(MISC12Tok); - end; - - procedure MISC14(): Code[10] - begin - exit(MISC14Tok); - end; - - procedure MISC15(): Code[10] - begin - exit(MISC15Tok); - end; - - procedure MISC16(): Code[10] - begin - exit(MISC16Tok); - end; - - procedure NEC01(): Code[10] - begin - exit(NEC01Tok); - end; - - procedure NEC02(): Code[10] - begin - exit(NEC02Tok); - end; - - procedure NEC04(): Code[10] - begin - exit(NEC04Tok); - end; - - procedure R(): Code[10] - begin - exit(RTok); - end; - - procedure R01(): Code[10] - begin - exit(R01Tok); - end; - - procedure R02A(): Code[10] - begin - exit(R02ATok); - end; - - procedure R03(): Code[10] - begin - exit(R03Tok); - end; - - procedure R04(): Code[10] - begin - exit(R04Tok); - end; - - procedure R05(): Code[10] - begin - exit(R05Tok); - end; - - procedure R06(): Code[10] - begin - exit(R06Tok); - end; - - procedure R10(): Code[10] - begin - exit(R10Tok); - end; - - procedure R12(): Code[10] - begin - exit(R12Tok); - end; - - procedure S(): Code[10] - begin - exit(STok); - end; - - procedure S02(): Code[10] - begin - exit(S02Tok); - end; - - var - BTok: Label 'B', MaxLength = 10, Locked = true; - B02Tok: Label 'B-02', MaxLength = 10, Locked = true; - B03Tok: Label 'B-03', MaxLength = 10, Locked = true; - B04Tok: Label 'B-04', MaxLength = 10, Locked = true; - B06Tok: Label 'B-06', MaxLength = 10, Locked = true; - B07Tok: Label 'B-07', MaxLength = 10, Locked = true; - B08Tok: Label 'B-08', MaxLength = 10, Locked = true; - B09Tok: Label 'B-09', MaxLength = 10, Locked = true; - DIVTok: Label 'DIV', MaxLength = 10, Locked = true; - DIV01ATok: Label 'DIV-01-A', MaxLength = 10, Locked = true; - DIV01BTok: Label 'DIV-01-B', MaxLength = 10, Locked = true; - DIV02ATok: Label 'DIV-02-A', MaxLength = 10, Locked = true; - DIV02BTok: Label 'DIV-02-B', MaxLength = 10, Locked = true; - DIV02CTok: Label 'DIV-02-C', MaxLength = 10, Locked = true; - DIV02DTok: Label 'DIV-02-D', MaxLength = 10, Locked = true; - DIV02ETok: Label 'DIV-02-E', MaxLength = 10, Locked = true; - DIV02FTok: Label 'DIV-02-F', MaxLength = 10, Locked = true; - DIV03Tok: Label 'DIV-03', MaxLength = 10, Locked = true; - DIV04Tok: Label 'DIV-04', MaxLength = 10, Locked = true; - DIV05Tok: Label 'DIV-05', MaxLength = 10, Locked = true; - DIV06Tok: Label 'DIV-06', MaxLength = 10, Locked = true; - DIV07Tok: Label 'DIV-07', MaxLength = 10, Locked = true; - DIV09Tok: Label 'DIV-09', MaxLength = 10, Locked = true; - DIV10Tok: Label 'DIV-10', MaxLength = 10, Locked = true; - DIV12Tok: Label 'DIV-12', MaxLength = 10, Locked = true; - DIV13Tok: Label 'DIV-13', MaxLength = 10, Locked = true; - INTTok: Label 'INT', MaxLength = 10, Locked = true; - INT01Tok: Label 'INT-01', MaxLength = 10, Locked = true; - INT02Tok: Label 'INT-02', MaxLength = 10, Locked = true; - INT03Tok: Label 'INT-03', MaxLength = 10, Locked = true; - INT04Tok: Label 'INT-04', MaxLength = 10, Locked = true; - INT05Tok: Label 'INT-05', MaxLength = 10, Locked = true; - INT06Tok: Label 'INT-06', MaxLength = 10, Locked = true; - INT08Tok: Label 'INT-08', MaxLength = 10, Locked = true; - INT09Tok: Label 'INT-09', MaxLength = 10, Locked = true; - INT10Tok: Label 'INT-10', MaxLength = 10, Locked = true; - INT11Tok: Label 'INT-11', MaxLength = 10, Locked = true; - INT12Tok: Label 'INT-12', MaxLength = 10, Locked = true; - INT13Tok: Label 'INT-13', MaxLength = 10, Locked = true; - MISCTok: Label 'MISC', MaxLength = 10, Locked = true; - MISC01Tok: Label 'MISC-01', MaxLength = 10, Locked = true; - MISC02Tok: Label 'MISC-02', MaxLength = 10, Locked = true; - MISC03Tok: Label 'MISC-03', MaxLength = 10, Locked = true; - MISC04Tok: Label 'MISC-04', MaxLength = 10, Locked = true; - MISC05Tok: Label 'MISC-05', MaxLength = 10, Locked = true; - MISC06Tok: Label 'MISC-06', MaxLength = 10, Locked = true; - MISC07Tok: Label 'MISC-07', MaxLength = 10, Locked = true; - MISC08Tok: Label 'MISC-08', MaxLength = 10, Locked = true; - MISC09Tok: Label 'MISC-09', MaxLength = 10, Locked = true; - MISC10Tok: Label 'MISC-10', MaxLength = 10, Locked = true; - MISC11Tok: Label 'MISC-11', MaxLength = 10, Locked = true; - MISC12Tok: Label 'MISC-12', MaxLength = 10, Locked = true; - MISC14Tok: Label 'MISC-14', MaxLength = 10, Locked = true; - MISC15Tok: Label 'MISC-15', MaxLength = 10, Locked = true; - MISC16Tok: Label 'MISC-16', MaxLength = 10, Locked = true; - NEC01Tok: Label 'NEC-01', MaxLength = 10, Locked = true; - NEC02Tok: Label 'NEC-02', MaxLength = 10, Locked = true; - NEC04Tok: Label 'NEC-04', MaxLength = 10, Locked = true; - RTok: Label 'R', MaxLength = 10, Locked = true; - R01Tok: Label 'R-01', MaxLength = 10, Locked = true; - R02ATok: Label 'R-02A', MaxLength = 10, Locked = true; - R03Tok: Label 'R-03', MaxLength = 10, Locked = true; - R04Tok: Label 'R-04', MaxLength = 10, Locked = true; - R05Tok: Label 'R-05', MaxLength = 10, Locked = true; - R06Tok: Label 'R-06', MaxLength = 10, Locked = true; - R10Tok: Label 'R-10', MaxLength = 10, Locked = true; - R12Tok: Label 'R-12', MaxLength = 10, Locked = true; - STok: Label 'S', MaxLength = 10, Locked = true; - S02Tok: Label 'S-02', MaxLength = 10, Locked = true; - ProceedsFromBrokerBarterExchangeTransactionsLbl: Label 'Proceeds From Broker+Barter Exchange Transactions', MaxLength = 100; - StocksbondsetcLbl: Label 'Stocks, bonds, etc.', MaxLength = 100; - BarteringLbl: Label 'Bartering', MaxLength = 100; - ProfitlossrealizedthisyearLbl: Label 'Profit/loss realized - this year', MaxLength = 100; - UnrealprofitlossonopencontractslastyearLbl: Label 'Unreal. profit/loss on open contracts - last year', MaxLength = 100; - UnrealprofitlossonopencontractsthisyearLbl: Label 'Unreal. profit/loss on open contracts - this year', MaxLength = 100; - AggregateprofitlossLbl: Label 'Aggregate profit/loss', MaxLength = 100; - DividendsandDistributionsLbl: Label 'Dividends and Distributions', MaxLength = 100; - TotalordinarydividendsLbl: Label 'Total ordinary dividends', MaxLength = 100; - QualifieddividendsLbl: Label 'Qualified dividends', MaxLength = 100; - TotalcapitalgaindistrLbl: Label 'Total capital gain distr.', MaxLength = 100; - UnrecapSec1250gainLbl: Label 'Unrecap. Sec. 1250 gain', MaxLength = 100; - Section1202gainLbl: Label 'Section 1202 gain', MaxLength = 100; - Collectibles28gainLbl: Label 'Collectibles (28%) gain', MaxLength = 100; - Section897ordinarydividendsLbl: Label 'Section 897 ordinary dividends', MaxLength = 100; - Section897capitalgainLbl: Label 'Section 897 capital gain', MaxLength = 100; - NondividenddistributionsLbl: Label 'Nondividend distributions', MaxLength = 100; - Section199AdividendsLbl: Label 'Section 199A dividends', MaxLength = 100; - InvestmentexpensesLbl: Label 'Investment expenses', MaxLength = 100; - ForeigntaxpaidLbl: Label 'Foreign tax paid', MaxLength = 100; - CashliquidationdistributionsLbl: Label 'Cash liquidation distributions', MaxLength = 100; - NoncashliquidationdistributionsLbl: Label 'Noncash liquidation distributions', MaxLength = 100; - ExemptinterestdividendsLbl: Label 'Exempt-interest dividends', MaxLength = 100; - SpecifiedprivateactivitybondinterestdividendsLbl: Label 'Specified private activity bond interest dividends', MaxLength = 100; - InterestIncomeLbl: Label 'Interest Income', MaxLength = 100; - EarlywithdrawalpenaltyLbl: Label 'Early withdrawal penalty', MaxLength = 100; - InterestonUSSavingsBondsandTreasobligationsLbl: Label 'Interest on US Savings Bonds and Treas. obligations', MaxLength = 100; - TaxexemptinterestLbl: Label 'Tax-exempt interest', MaxLength = 100; - SpecifiedprivateactivitybondinterestLbl: Label 'Specified private activity bond interest', MaxLength = 100; - MarketdiscountLbl: Label 'Market discount', MaxLength = 100; - BondpremiumLbl: Label 'Bond premium', MaxLength = 100; - BondPremiumonTreasuryObligationLbl: Label 'Bond Premium on Treasury Obligation', MaxLength = 100; - BondpremiumontaxexemptbondLbl: Label 'Bond premium on tax-exempt bond', MaxLength = 100; - MiscellaneousIncomeLbl: Label 'Miscellaneous Income', MaxLength = 100; - RentsLbl: Label 'Rents', MaxLength = 100; - RoyaltiesLbl: Label 'Royalties', MaxLength = 100; - OtherIncomeLbl: Label 'Other Income', MaxLength = 100; - FederalincometaxwithheldLbl: Label 'Federal income tax withheld', MaxLength = 100; - FishingboatproceedsLbl: Label 'Fishing boat proceeds', MaxLength = 100; - MedicalandhealthcarepaymentsLbl: Label 'Medical and health care payments', MaxLength = 100; - Payermadedirectsalesof5000ormoreofconsumerproductsLbl: Label 'Payer made direct sales of $5000 or more of consumer products', MaxLength = 100; - SubstitutepaymentsinlieuofdividendsorinterestLbl: Label 'Substitute payments in lieu of dividends or interest', MaxLength = 100; - CropinsuranceproceedsLbl: Label 'Crop insurance proceeds', MaxLength = 100; - GrossproceedspaidtoanattorneyLbl: Label 'Gross proceeds paid to an attorney', MaxLength = 100; - FishpurchasedforresaleLbl: Label 'Fish purchased for resale', MaxLength = 100; - Section409AdeferralsLbl: Label 'Section 409A deferrals', MaxLength = 100; - ExcessgoldenparachutepaymentsLbl: Label 'Excess golden parachute payments', MaxLength = 100; - NonqualifieddeferredcompensationLbl: Label 'Nonqualified deferred compensation', MaxLength = 100; - StatetaxwithheldLbl: Label 'State tax withheld', MaxLength = 100; - NonemployeecompensationLbl: Label 'Nonemployee compensation', MaxLength = 100; - Payermadedirectsalestotaling5000ormoreofconsumerproductstorecipientforresaleLbl: Label 'Payer made direct sales totaling $5,000 or more of consumer products to recipient for resale', MaxLength = 100; - PensionsAnnRetirementProfitSharPlansIRAsLbl: Label 'Pensions/Ann./Retirement/Profit-Shar.Plans/IRAs...', MaxLength = 100; - GrossdistributionLbl: Label 'Gross distribution', MaxLength = 100; - TaxableAmountLbl: Label 'Taxable Amount', MaxLength = 100; - AmountinBox2eligibleforcapitalgainelectionLbl: Label 'Amount in Box 2 eligible for capital gain election', MaxLength = 100; - EmployeecontributionsinsurancepremiumsLbl: Label 'Employee contributions/insurance premiums', MaxLength = 100; - NetunrealappreciationinemployerssecuritiesLbl: Label 'Net unreal. appreciation in employers securities', MaxLength = 100; - StateincometaxwithheldLbl: Label 'State income tax withheld', MaxLength = 100; - LocalincometaxwithheldLbl: Label 'Local income tax withheld', MaxLength = 100; - ProceedsFromRealEstateTransactionsLbl: Label 'Proceeds From Real Estate Transactions', MaxLength = 100; - GrossproceedsLbl: Label 'Gross proceeds', MaxLength = 100; -} -#endif \ No newline at end of file diff --git a/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/Finance/1.Setup Data/CreateUSGLAccounts.Codeunit.al b/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/Finance/1.Setup Data/CreateUSGLAccounts.Codeunit.al index 279a5a111e..1b35bdcc60 100644 --- a/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/Finance/1.Setup Data/CreateUSGLAccounts.Codeunit.al +++ b/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/Finance/1.Setup Data/CreateUSGLAccounts.Codeunit.al @@ -635,6 +635,7 @@ codeunit 10499 "Create US GL Accounts" ContosoGLAccount.AddAccountForLocalization(WIPAccruedCostsName(), '14240'); ContosoGLAccount.AddAccountForLocalization(WIPInvoicedSalesName(), '14250'); ContosoGLAccount.AddAccountForLocalization(TotalWorkinProgressName(), '14299'); + ContosoGLAccount.AddAccountForLocalization(TotalInventoriesProductsandWorkinProgressName(), '14999'); ContosoGLAccount.AddAccountForLocalization(ReceivablesName(), '15000'); ContosoGLAccount.AddAccountForLocalization(AccountsReceivablesName(), '15100'); ContosoGLAccount.AddAccountForLocalization(AccountReceivableDomesticName(), '15110'); @@ -814,6 +815,7 @@ codeunit 10499 "Create US GL Accounts" ContosoGLAccount.InsertGLAccount(WIPAccruedCosts(), WIPAccruedCostsName(), Enum::"G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); ContosoGLAccount.InsertGLAccount(WIPInvoicedSales(), WIPInvoicedSalesName(), Enum::"G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); ContosoGLAccount.InsertGLAccount(TotalWorkinProgress(), TotalWorkinProgressName(), Enum::"G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::"End-Total", '', '', 0, WorkinProgress() + '..' + TotalWorkinProgress(), Enum::"General Posting Type"::" ", '', '', false, false, false); + ContosoGLAccount.InsertGLAccount(TotalInventoriesProductsandWorkinProgress(), TotalInventoriesProductsandWorkinProgressName(), Enum::"G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::"End-Total", '', '', 0, InventoriesProductsandWorkinProgress() + '..' + TotalInventoriesProductsandWorkinProgress(), Enum::"General Posting Type"::" ", '', '', false, false, false); ContosoGLAccount.InsertGLAccount(CreateGlAccount.FinishedGoods(), CreateGlAccount.FinishedGoodsName(), Enum::"G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); ContosoGLAccount.InsertGLAccount(CreateGlAccount.WIPJobSales(), CreateGlAccount.WIPJobSalesName(), Enum::"G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); ContosoGLAccount.InsertGLAccount(CreateGlAccount.WIPJobCosts(), CreateGlAccount.WIPJobCostsName(), Enum::"G/L Account Income/Balance"::"Balance Sheet", Enum::"G/L Account Category"::Assets, SubCategory, Enum::"G/L Account Type"::Posting, '', '', 0, '', Enum::"General Posting Type"::" ", '', '', true, false, false); @@ -3430,6 +3432,16 @@ codeunit 10499 "Create US GL Accounts" exit(InventoriesProductsandWorkinProgressTok); end; + procedure TotalInventoriesProductsandWorkinProgress(): Code[20] + begin + exit(ContosoGLAccount.GetAccountNo(TotalInventoriesProductsandWorkinProgressName())); + end; + + procedure TotalInventoriesProductsandWorkinProgressName(): Text[100] + begin + exit(TotalInventoriesProductsandWorkinProgressTok); + end; + procedure SuppliesandConsumables(): Code[20] begin exit(ContosoGLAccount.GetAccountNo(SuppliesandConsumablesName())); @@ -4655,6 +4667,7 @@ codeunit 10499 "Create US GL Accounts" OtherLongTermReceivablesTok: Label 'Other Long-term Receivables', MaxLength = 100; TotalFinancialandFixedAssetsTok: Label 'Total, Financial and Fixed Assets', MaxLength = 100; InventoriesProductsandWorkinProgressTok: Label 'Inventories, Products and work in Progress', MaxLength = 100; + TotalInventoriesProductsandWorkinProgressTok: Label 'Total, Inventories, Products and work in Progress', MaxLength = 100; SuppliesandConsumablesTok: Label 'Supplies and Consumables', MaxLength = 100; ProductsinProgressTok: Label 'Products in Progress', MaxLength = 100; FinishedGoodsTok: Label 'Finished Goods', MaxLength = 100; diff --git a/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/USContosoLocalization.Codeunit.al b/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/USContosoLocalization.Codeunit.al index 30eb6e6be1..fc74dd77bd 100644 --- a/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/USContosoLocalization.Codeunit.al +++ b/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/USContosoLocalization.Codeunit.al @@ -70,9 +70,6 @@ codeunit 11465 "US Contoso Localization" Codeunit.Run(Codeunit::"Create Currency US"); Codeunit.Run(Codeunit::"Create Tax Group US"); Codeunit.Run(Codeunit::"Create Tax Setup US"); -#if not CLEAN27 - Codeunit.Run(Codeunit::"Create IRS 1099 Form-Box US"); -#endif end; Enum::"Contoso Demo Data Level"::"Master Data": begin diff --git a/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoTool/Contoso Helpers/ContosoIRS1099US.Codeunit.al b/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoTool/Contoso Helpers/ContosoIRS1099US.Codeunit.al deleted file mode 100644 index 031556afb0..0000000000 --- a/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoTool/Contoso Helpers/ContosoIRS1099US.Codeunit.al +++ /dev/null @@ -1,50 +0,0 @@ -#if not CLEAN27 -// ------------------------------------------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// ------------------------------------------------------------------------------------------------ - -namespace Microsoft.DemoTool.Helpers; - -using Microsoft.Finance.VAT.Reporting; - -codeunit 11450 "Contoso IRS 1099 US" -{ - InherentEntitlements = X; - InherentPermissions = X; - ObsoleteReason = 'Moved to IRS Forms App.'; - ObsoleteState = Pending; - ObsoleteTag = '27.0'; - Permissions = tabledata "IRS 1099 Form-Box" = rim; - - procedure SetOverwriteData(Overwrite: Boolean) - begin - OverwriteData := Overwrite; - end; - - procedure InsertIRS1099FormBox(Code: Code[10]; Description: Text[100]; MinimumReportable: Decimal) - var - IRS1099FormBox: Record "IRS 1099 Form-Box"; - Exists: Boolean; - begin - if IRS1099FormBox.Get(Code) then begin - Exists := true; - - if not OverwriteData then - exit; - end; - - IRS1099FormBox.Validate(Code, Code); - IRS1099FormBox.Validate(Description, Description); - IRS1099FormBox.Validate("Minimum Reportable", MinimumReportable); - - if Exists then - IRS1099FormBox.Modify(true) - else - IRS1099FormBox.Insert(true); - end; - - var - OverwriteData: Boolean; -} -#endif \ No newline at end of file diff --git a/Apps/US/HybridGP_US/test/src/MigrationVendor1099Tests.Codeunit.al b/Apps/US/HybridGP_US/test/src/MigrationVendor1099Tests.Codeunit.al index 65397f76a1..3cb930cdff 100644 --- a/Apps/US/HybridGP_US/test/src/MigrationVendor1099Tests.Codeunit.al +++ b/Apps/US/HybridGP_US/test/src/MigrationVendor1099Tests.Codeunit.al @@ -11,9 +11,6 @@ codeunit 139684 "Migration Vendor 1099 Tests" TestVendorNoLbl: Label 'TESTVENDOR01', Locked = true; PayablesAccountNoLbl: Label '2100', Locked = true; PostingGroupCodeTxt: Label 'GP', Locked = true; -#if not CLEAN25 - IRSFormFeatureKeyIdTok: Label 'IRSForm', Locked = true; -#endif [Test] procedure TestMappingsCreated() @@ -309,9 +306,6 @@ codeunit 139684 "Migration Vendor 1099 Tests" GPCompanyAdditionalSettings: Record "GP Company Additional Settings"; IRS1099VendorFormBoxSetup: Record "IRS 1099 Vendor Form Box Setup"; begin -#if not CLEAN25 - ManuallyEnabledIRSFormFeatureIfRequired(); -#endif Vendor.SetRange("No.", TestVendorNoLbl); if not Vendor.IsEmpty() then @@ -506,23 +500,4 @@ codeunit 139684 "Migration Vendor 1099 Tests" end; end; -#if not CLEAN25 - local procedure ManuallyEnabledIRSFormFeatureIfRequired() - var - FeatureKey: Record "Feature Key"; - FeatureDataUpdateStatus: Record "Feature Data Update Status"; - begin - if FeatureKey.Get(IRSFormFeatureKeyIdTok) then - if FeatureKey.Enabled <> FeatureKey.Enabled::"All Users" then begin - FeatureKey.Enabled := FeatureKey.Enabled::"All Users"; - FeatureKey.Modify(); - end; - - if FeatureDataUpdateStatus.Get(IRSFormFeatureKeyIdTok, CompanyName()) then - if FeatureDataUpdateStatus."Feature Status" <> FeatureDataUpdateStatus."Feature Status"::Enabled then begin - FeatureDataUpdateStatus."Feature Status" := FeatureDataUpdateStatus."Feature Status"::Enabled; - FeatureDataUpdateStatus.Modify(); - end; - end; -#endif } \ No newline at end of file diff --git a/Apps/US/IRS1096/app/src/Processing/IRS1096FormLine.Table.al b/Apps/US/IRS1096/app/src/Processing/IRS1096FormLine.Table.al index 9645f2713e..d66ec0cf61 100644 --- a/Apps/US/IRS1096/app/src/Processing/IRS1096FormLine.Table.al +++ b/Apps/US/IRS1096/app/src/Processing/IRS1096FormLine.Table.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. // ------------------------------------------------------------------------------------------------ @@ -23,9 +23,6 @@ table 10019 "IRS 1096 Form Line" field(3; "IRS Code"; Code[20]) { Caption = 'IRS Code'; -#if not CLEAN25 - TableRelation = "IRS 1099 Form-Box"; -#endif } field(4; "Vendor No."; Code[20]) { @@ -88,21 +85,7 @@ table 10019 "IRS 1096 Form Line" procedure ShowAdjustments() var -#if not CLEAN25 - IRS1096FormHeader: Record "IRS 1096 Form Header"; - IRS1099Adjustment: Record "IRS 1099 Adjustment"; - IRS1099Adjustments: Page "IRS 1099 Adjustments"; -#endif begin -#if not CLEAN25 - IRS1096FormHeader.Get("Form No."); - IRS1099Adjustment.SetRange(Year, Date2DMY(IRS1096FormHeader."Starting Date", 3), Date2DMY(IRS1096FormHeader."Ending Date", 3)); - IRS1099Adjustment.SetRange("Vendor No.", "Vendor No."); - IRS1099Adjustment.SetRange("IRS 1099 Code", "IRS Code"); - IRS1099Adjustments.Editable := false; - IRS1099Adjustments.SetTableView(IRS1099Adjustment); - IRS1099Adjustments.Run(); -#endif end; @@ -118,4 +101,4 @@ table 10019 "IRS 1096 Form Line" IRS1096FormHeader."Total Amount To Report" := IRS1096FormLine."Total Amount" + "Total Amount"; IRS1096FormHeader.Modify(true); end; -} +} \ No newline at end of file diff --git a/Apps/US/IRS1096/app/src/Processing/IRS1096FormMgt.Codeunit.al b/Apps/US/IRS1096/app/src/Processing/IRS1096FormMgt.Codeunit.al index e647b2b893..cb643a450a 100644 --- a/Apps/US/IRS1096/app/src/Processing/IRS1096FormMgt.Codeunit.al +++ b/Apps/US/IRS1096/app/src/Processing/IRS1096FormMgt.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. // ------------------------------------------------------------------------------------------------ @@ -9,9 +9,6 @@ using Microsoft.Utilities; using System.Environment.Configuration; using System.Media; using System.Telemetry; -#if not CLEAN25 -using System.Utilities; -#endif codeunit 10016 "IRS 1096 Form Mgt." { @@ -24,9 +21,6 @@ codeunit 10016 "IRS 1096 Form Mgt." InstallIRS1096NotificationNameTxt: Label 'IRS 1096 Form - Install feature'; InstallIRS1096NotificationDescriptionTxt: Label 'This notification is used to let users know about the new IRS 1096 feature . It can be used to open the Feature Management and install the 1096 feature.'; NoEntriesToCreateFormsMsg: Label 'No entries have been found by filters specified.'; -#if not CLEAN25 - FormPerPeriodAlreadyExistsQst: Label 'The form %1 for the period from %2 to %3 already exist. If you want to replace it, use the Replace parameter on the request page. Do you want to stop the creation of forms?', Comment = '%1 - code of the form, %2,%3 - starting and ending dates of the period'; -#endif FormsCreatedMsg: Label 'IRS 1096 forms have been created'; AssistedSetupTxt: Label 'Set up an IRS 1096 feature'; AssistedSetupDescriptionTxt: Label 'This feature provides functionality that enables an easy overview and reporting of the 1096 form to IRS.'; @@ -62,16 +56,10 @@ codeunit 10016 "IRS 1096 Form Mgt." TempVendorLedgerEntry: Record "Vendor Ledger Entry" temporary; TempIRS1096FormHeader: Record "IRS 1096 Form Header" temporary; TempCreatedIRS1096FormHeader: Record "IRS 1096 Form Header" temporary; -#if not CLEAN25 - TempIRS1096FormLine: Record "IRS 1096 Form Line" temporary; -#endif IRS1096FormHeader: Record "IRS 1096 Form Header"; IRS1096FormLine: Record "IRS 1096 Form Line"; EntryApplicationManagement: Codeunit "Entry Application Management"; PeriodDate: array[2] of Date; -#if not CLEAN25 - ConflictResolved: Boolean; -#endif begin PeriodDate[1] := StartDate; PeriodDate[2] := EndDate; @@ -95,13 +83,7 @@ codeunit 10016 "IRS 1096 Form Mgt." IRS1096FormHeader.LockTable(); IRS1096FormLine.LockTable(); repeat -#if not CLEAN25 - AddVendLedgEntryToFormBuffer(TempIRS1096FormLine, TempIRS1096FormHeader, TempCreatedIRS1096FormHeader, ConflictResolved, TempVendorLedgerEntry, PeriodDate, Replace); -#endif until TempVendorLedgerEntry.Next() = 0; -#if not CLEAN25 - InsertFromFormBuffer(TempCreatedIRS1096FormHeader, TempIRS1096FormLine); -#endif if TempCreatedIRS1096FormHeader.IsEmpty() then begin if GuiAllowed() then Message(NoFormsHaveBeenCreatedMsg); @@ -192,171 +174,7 @@ codeunit 10016 "IRS 1096 Form Mgt." IRS1096FormHeader.Modify(true); end; -#if not CLEAN25 - local procedure AddVendLedgEntryToFormBuffer(var TempIRS1096FormLine: Record "IRS 1096 Form Line" temporary; var TempIRS1096FormHeader: Record "IRS 1096 Form Header" temporary; var TempCreatedIRS1096FormHeader: Record "IRS 1096 Form Header" temporary; var ConflictResolved: Boolean; VendLedgEntry: Record "Vendor Ledger Entry"; PeriodDate: array[2] of Date; Replace: Boolean) - var - IRS1096FormHeader: Record "IRS 1096 Form Header"; - IRS1099Adjustment: Record "IRS 1099 Adjustment"; - ConfirmMgt: Codeunit "Confirm Management"; - General1099Code: Code[20]; - LineNo: Integer; - CalculatedAmount: Decimal; - begin - If (VendLedgEntry."IRS 1099 Code" = '') or (VendLedgEntry."IRS 1099 Amount" = 0) then - exit; - -#if not CLEAN25 - General1099Code := GetGeneral1099CodeFromVendLedgEntry(VendLedgEntry); -#endif - if General1099Code = '' then - exit; - - TempIRS1096FormHeader.SetRange("Starting Date", PeriodDate[1]); - TempIRS1096FormHeader.SetRange("Ending Date", PeriodDate[2]); - TempIRS1096FormHeader.SetRange("IRS Code", General1099Code); - if TempIRS1096FormHeader.FindFirst() then - If Replace then begin - IRS1096FormHeader.Get(TempIRS1096FormHeader."No."); - IRS1096FormHeader.Status := IRS1096FormHeader.Status::Open; - IRS1096FormHeader.Delete(true); - TempIRS1096FormHeader.Delete(); - end else begin - if not ConflictResolved then - if ConfirmMgt.GetResponse(StrSubstNo(FormPerPeriodAlreadyExistsQst, General1099Code, PeriodDate[1], PeriodDate[2]), false) then - Error(''); - ConflictResolved := true; - exit; - end; - - IRS1096FormHeader.SetRange("Starting Date", PeriodDate[1]); - IRS1096FormHeader.SetRange("Ending Date", PeriodDate[2]); - IRS1096FormHeader.SetRange("IRS Code", General1099Code); - if not IRS1096FormHeader.FindFirst() then begin - IRS1096FormHeader.Init(); - IRS1096FormHeader."No." := ''; - IRS1096FormHeader."Starting Date" := PeriodDate[1]; - IRS1096FormHeader."Ending Date" := PeriodDate[2]; - IRS1096FormHeader."IRS Code" := General1099Code; - IRS1096FormHeader.Insert(true); - TempCreatedIRS1096FormHeader := IRS1096FormHeader; - TempCreatedIRS1096FormHeader.Insert(); - end; - - VendLedgEntry.CalcFields(Amount); - CalculatedAmount := -VendLedgEntry."Amount to Apply" * VendLedgEntry."IRS 1099 Amount" / VendLedgEntry.Amount; - TempIRS1096FormLine.SetRange("Form No.", IRS1096FormHeader."No."); - TempIRS1096FormLine.SetRange("Vendor No.", VendLedgEntry."Vendor No."); - TempIRS1096FormLine.SetRange("IRS Code", VendLedgEntry."IRS 1099 Code"); - if TempIRS1096FormLine.FindLast() then begin - TempIRS1096FormLine."Calculated Amount" += CalculatedAmount; - TempIRS1096FormLine.Modify(); - InsertLineRelation(TempIRS1096FormLine, VendLedgEntry); - exit; - end; - - TempIRS1096FormLine.SetRange("IRS Code"); - TempIRS1096FormLine.SetRange("Vendor No."); - if TempIRS1096FormLine.FindLast() then - LineNo := TempIRS1096FormLine."Line No."; - - LineNo += 10000; - TempIRS1096FormLine.Init(); - TempIRS1096FormLine."Form No." := IRS1096FormHeader."No."; - TempIRS1096FormLine."Line No." := LineNo; - TempIRS1096FormLine."Vendor No." := VendLedgEntry."Vendor No."; - TempIRS1096FormLine."IRS Code" := VendLedgEntry."IRS 1099 Code"; - TempIRS1096FormLine."Calculated Amount" := CalculatedAmount; - IRS1099Adjustment.SetRange(Year, Date2DMY(IRS1096FormHeader."Starting Date", 3), Date2DMY(IRS1096FormHeader."Ending Date", 3)); - IRS1099Adjustment.SetRange("Vendor No.", TempIRS1096FormLine."Vendor No."); - IRS1099Adjustment.SetRange("IRS 1099 Code", TempIRS1096FormLine."IRS Code"); - IRS1099Adjustment.CalcSums(Amount); - TempIRS1096FormLine."Calculated Adjustment Amount" := IRS1099Adjustment.Amount; - TempIRS1096FormLine.Insert(); - InsertLineRelation(TempIRS1096FormLine, VendLedgEntry); - end; -#endif - -#if not CLEAN25 - local procedure GetGeneral1099CodeFromVendLedgEntry(VendLedgEntry: Record "Vendor Ledger Entry") IRSCode: Code[20] - var - IsHandled: Boolean; - begin - OnBeforeGetGeneral1099CodeFromVendLedgEntry(VendLedgEntry, IRSCode, IsHandled); - If IsHandled then - exit(IRSCode); -#pragma warning disable AA0139 - if StrPos(VendLedgEntry."IRS 1099 Code", '-') = 0 then - IRSCode := VendLedgEntry."IRS 1099 Code" - else - IRSCode := CopyStr(VendLedgEntry."IRS 1099 Code", 1, StrPos(VendLedgEntry."IRS 1099 Code", '-') - 1); -#pragma warning restore AA0139 - if not (UpperCase(IRSCode) in ['DIV', 'MISC', 'INT', 'NEC']) then - exit(''); - exit(IRSCode); - end; - local procedure InsertLineRelation(IRS1096FormLine: Record "IRS 1096 Form Line"; VendLedgEntry: Record "Vendor Ledger Entry") - var - IRS1096FormLineRelation: Record "IRS 1096 Form Line Relation"; - begin - IRS1096FormLineRelation.Validate("Form No.", IRS1096FormLine."Form No."); - IRS1096FormLineRelation.Validate("Line No.", IRS1096FormLine."Line No."); - IRS1096FormLineRelation.Validate("Entry No.", VendLedgEntry."Entry No."); - IRS1096FormLineRelation.Insert(true); - end; - - local procedure InsertFromFormBuffer(var TempCreatedIRS1096FormHeader: Record "IRS 1096 Form Header" temporary; var TempIRS1096FormLine: Record "IRS 1096 Form Line" temporary) - var - IRS1096FormHeader: Record "IRS 1096 Form Header"; - IRS1096FormLine: Record "IRS 1096 Form Line"; - IRS1099FormBox: Record "IRS 1099 Form-Box"; - IRS1096FormLineRelation: Record "IRS 1096 Form Line Relation"; - IncludeLine: Boolean; - TotalAmount: Decimal; - begin - TempIRS1096FormLine.Reset(); - TempIRS1096FormLine.FindSet(); - repeat - TotalAmount := TempIRS1096FormLine."Calculated Amount" + TempIRS1096FormLine."Calculated Adjustment Amount"; - IRS1099FormBox.Get(TempIRS1096FormLine."IRS Code"); - if IRS1099FormBox."Minimum Reportable" < 0 then - IncludeLine := TotalAmount <> 0 - else - IncludeLine := (TotalAmount <> 0) and (TotalAmount >= IRS1099FormBox."Minimum Reportable"); - if IncludeLine then begin - IRS1096FormLine := TempIRS1096FormLine; - IRS1096FormLine."Total Amount" := TotalAmount; - IRS1096FormLine.Insert(); - TempCreatedIRS1096FormHeader.Get(IRS1096FormLine."Form No."); - TempCreatedIRS1096FormHeader."Calc. Amount" += IRS1096FormLine."Calculated Amount"; - TempCreatedIRS1096FormHeader."Calc. Adjustment Amount" += IRS1096FormLine."Calculated Adjustment Amount"; - TempCreatedIRS1096FormHeader."Total Amount To Report" += IRS1096FormLine."Calculated Amount" + IRS1096FormLine."Calculated Adjustment Amount"; - TempCreatedIRS1096FormHeader.Modify(); - end else begin - IRS1096FormLineRelation.SetRange("Form No.", TempIRS1096FormLine."Form No."); - IRS1096FormLineRelation.SetRange("Line No.", TempIRS1096FormLine."Line No."); - IRS1096FormLineRelation.DeleteAll(true); - end; - until TempIRS1096FormLine.Next() = 0; - TempCreatedIRS1096FormHeader.FindSet(); - repeat - IRS1096FormLine.SetRange("Form No.", TempCreatedIRS1096FormHeader."No."); - if IRS1096FormLine.IsEmpty() then begin - TempCreatedIRS1096FormHeader.Delete(); - if IRS1096FormHeader.Get(TempCreatedIRS1096FormHeader."No.") then - IRS1096FormHeader.Delete(true); - end else begin - IRS1096FormHeader.Get(TempCreatedIRS1096FormHeader."No."); - IRS1096FormHeader."Calc. Amount" := TempCreatedIRS1096FormHeader."Calc. Amount"; - IRS1096FormHeader."Calc. Adjustment Amount" := TempCreatedIRS1096FormHeader."Calc. Adjustment Amount"; - IRS1096FormHeader."Total Amount To Report" := TempCreatedIRS1096FormHeader."Total Amount To Report"; - IRS1096FormHeader."Calc. Total Number Of Forms" := IRS1096FormLine.Count(); - IRS1096FormHeader."Total Number Of Forms" := IRS1096FormLine.Count(); - IRS1096FormHeader.Modify(); - end; - until TempCreatedIRS1096FormHeader.Next() = 0; - end; -#endif [EventSubscriber(ObjectType::Codeunit, Codeunit::"Guided Experience", 'OnRegisterAssistedSetup', '', true, true)] local procedure InsertIntoAssistedSetup() @@ -380,4 +198,4 @@ codeunit 10016 "IRS 1096 Form Mgt." local procedure OnAfterCheckFeatureEnabled(var IsEnabled: Boolean) begin end; -} +} \ No newline at end of file diff --git a/Apps/US/IRS1096/app/src/Processing/IRS1096FormSubform.Page.al b/Apps/US/IRS1096/app/src/Processing/IRS1096FormSubform.Page.al index 0135576cb2..4fdd76f4a2 100644 --- a/Apps/US/IRS1096/app/src/Processing/IRS1096FormSubform.Page.al +++ b/Apps/US/IRS1096/app/src/Processing/IRS1096FormSubform.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. // ------------------------------------------------------------------------------------------------ @@ -48,12 +48,6 @@ page 10020 "IRS 1096 Form Subform" ApplicationArea = BasicUS; ToolTip = 'Specifies the adjustment amount per period and IRS code calculated by the Create Forms action on the list page.'; -#if not CLEAN25 - trigger OnDrillDown() - begin - Rec.ShowAdjustments(); - end; -#endif } field("Manually Changed"; Rec."Manually Changed") { @@ -68,4 +62,4 @@ page 10020 "IRS 1096 Form Subform" } } } -} +} \ No newline at end of file diff --git a/Apps/US/IRS1096/test/src/Create1096FormsTest.Codeunit.al b/Apps/US/IRS1096/test/src/Create1096FormsTest.Codeunit.al deleted file mode 100644 index 8c437d88bf..0000000000 --- a/Apps/US/IRS1096/test/src/Create1096FormsTest.Codeunit.al +++ /dev/null @@ -1,742 +0,0 @@ -#if not CLEAN25 -codeunit 144041 "Create 1096 Forms Test" -{ - Subtype = Test; - TestType = Uncategorized; - TestPermissions = Disabled; - ObsoleteReason = 'Moved to IRS Forms App.'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - - var - LibraryTestInitialize: Codeunit "Library - Test Initialize"; - LibraryUtility: Codeunit "Library - Utility"; - LibraryRandom: Codeunit "Library - Random"; - LibraryPurchase: Codeunit "Library - Purchase"; - LibraryERM: Codeunit "Library - ERM"; - LibraryVariableStorage: Codeunit "Library - Variable Storage"; - Assert: Codeunit Assert; - DivCodeTok: Label 'DIV', Locked = true; - MiscCodeTok: Label 'MISC', Locked = true; - Div01CodeTok: Label 'DIV-01', Locked = true; - IsInitialized: Boolean; - FormsCreatedMsg: Label 'IRS 1096 forms have been created'; - NoFormsHaveBeenCreatedMsg: Label 'No IRS 1096 forms have been created'; - NoEntriesToCreateFormsMsg: Label 'No entries have been found by filters specified.'; - - trigger OnRun() - begin - // [FEATURE] [1096] - end; - - [Test] - [TransactionModel(TransactionModel::AutoRollback)] - [HandlerFunctions('MessageHandler')] - procedure CreateSingleFormCodeNoHyphen() - var - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - IRS1096Header: Record "IRS 1096 Form Header"; - IRS1096Line: Record "IRS 1096 Form Line"; - IRS1096FormMgt: Codeunit "IRS 1096 Form Mgt."; - VendNo: Code[20]; - IRSCode: Code[10]; - PostingDate: Date; - begin - // [SCENARIO 461401] Stan can create a IRS 1096 form for the IRS code without a hyphen - - Initialize(); - VendNo := LibraryPurchase.CreateVendorNo(); - // [GIVEN] IRS code "DIV" - IRSCode := InitializeDIVCode(); - PostingDate := CalcDate('<1Y>', WorkDate()); - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV" and Amount = 100 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, LibraryRandom.RandDec(100, 2)); - LibraryVariableStorage.Enqueue(FormsCreatedMsg); - - // [WHEN] Stan runs the "Create Forms" batch job for period from 01.01.2023 to 01.01.2023 - IRS1096FormMgt.CreateForms(PostingDate, PostingDate, false); - - // [THEN] One IRS 1096 form has been created - IRS1096Header.SetRange("Starting Date", PostingDate); - IRS1096Header.SetRange("Ending Date", PostingDate); - IRS1096Header.SetRange("IRS Code", IRSCode); - Assert.RecordCount(IRS1096Header, 1); - IRS1096Header.FindFirst(); - // [THEN] IRS 1096 form has one line with the following details: "Vendor No." = "X", "IRS Code" = "DIV" and "Calculated Amount" = 100 - IRS1096Line.SetRange("Form No.", IRS1096Header."No."); - Assert.RecordCount(IRS1096Line, 1); - IRS1096Line.FindFirst(); - IRS1096Line.TestField("Vendor No.", VendNo); - IRS1096Line.TestField("IRS Code", IRSCode); - IRS1096Line.TestField("Calculated Amount", DtldVendLedgEntry.Amount); - - LibraryVariableStorage.AssertEmpty(); - end; - - [Test] - [TransactionModel(TransactionModel::AutoRollback)] - [HandlerFunctions('MessageHandler')] - procedure IRSCodeNotIncludedInto1096FormIfTotalPositiveAmountLessThanMinimumReportable() - var - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - IRS1096Header: Record "IRS 1096 Form Header"; - IRS1096FormMgt: Codeunit "IRS 1096 Form Mgt."; - VendNo: Code[20]; - IRSCode: Code[10]; - PostingDate: Date; - MinimumReportableAmount: Decimal; - begin - // [FEAUTURE] [Minimum Reportable Amount] - // [SCENARIO 461543] The positive total amount of the IRS code does not include in the IRS 1096 form if it is less than minimum reportable amount - Initialize(); - MinimumReportableAmount := LibraryRandom.RandDec(100, 2); - // [GIVEN] IRS code "DIV-01" with "Minimum Reportable Amount" = 100 - IRSCode := InitializeDIV01Code(MinimumReportableAmount); - VendNo := LibraryPurchase.CreateVendorNo(); - PostingDate := CalcDate('<1Y>', WorkDate()); - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = 50 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, MinimumReportableAmount / 2); - LibraryVariableStorage.Enqueue(NoFormsHaveBeenCreatedMsg); - - // [WHEN] Stan runs the "Create Forms" batch job for period from 01.01.2023 to 01.01.2023 - IRS1096FormMgt.CreateForms(PostingDate, PostingDate, false); - - // [THEN] No forms have been created - Assert.IsTrue(IRS1096Header.IsEmpty(), ''); - - LibraryVariableStorage.AssertEmpty(); - end; - - [Test] - [TransactionModel(TransactionModel::AutoRollback)] - [HandlerFunctions('MessageHandler')] - procedure IRSCodeIncludesInto1096FormIfTotalPositiveAmountMoreThanMinimumReportable() - var - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - IRS1096Header: Record "IRS 1096 Form Header"; - IRS1096Line: Record "IRS 1096 Form Line"; - IRS1096FormMgt: Codeunit "IRS 1096 Form Mgt."; - VendNo: Code[20]; - IRSCode: Code[10]; - PostingDate: Date; - MinimumReportableAmount: Decimal; - TotalAmount: Decimal; - begin - // [FEAUTURE] [Minimum Reportable Amount] - // [SCENARIO 461543] The positive total amount of the IRS code includes in the IRS 1096 form if it is more than minimum reportable amount - Initialize(); - MinimumReportableAmount := LibraryRandom.RandDec(100, 2); - // [GIVEN] IRS code "DIV-01" with "Minimum Reportable Amount" = 100 - IRSCode := InitializeDIV01Code(MinimumReportableAmount); - VendNo := LibraryPurchase.CreateVendorNo(); - PostingDate := CalcDate('<1Y>', WorkDate()); - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = 75 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, MinimumReportableAmount / 2); - TotalAmount += DtldVendLedgEntry.Amount; - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = 26 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, MinimumReportableAmount - DtldVendLedgEntry.Amount + 1); - TotalAmount += DtldVendLedgEntry.Amount; - LibraryVariableStorage.Enqueue(FormsCreatedMsg); - - // [WHEN] Stan runs the "Create Forms" batch job for period from 01.01.2023 to 01.01.2023 - IRS1096FormMgt.CreateForms(PostingDate, PostingDate, false); - - // [THEN] IRS 1096 form has been created - IRS1096Header.SetRange("Starting Date", PostingDate); - IRS1096Header.SetRange("Ending Date", PostingDate); - IRS1096Header.SetRange("IRS Code", DivCodeTok); - Assert.RecordCount(IRS1096Header, 1); - IRS1096Header.FindFirst(); - - // [THEN] IRS 1096 form has one line with the following details: "Vendor No." = "X", "IRS Code" = "DIV-01" and "Calculated Amount" = 100 - IRS1096Line.SetRange("Form No.", IRS1096Header."No."); - Assert.RecordCount(IRS1096Line, 1); - IRS1096Line.FindFirst(); - IRS1096Line.TestField("Vendor No.", VendNo); - IRS1096Line.TestField("IRS Code", IRSCode); - IRS1096Line.TestField("Calculated Amount", TotalAmount); - - LibraryVariableStorage.AssertEmpty(); - end; - - [Test] - [TransactionModel(TransactionModel::AutoRollback)] - [HandlerFunctions('MessageHandler')] - procedure IRSCodeIncludesInto1096FormIfTotalPositiveAmountEqualsMinimumReportable() - var - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - IRS1096Header: Record "IRS 1096 Form Header"; - IRS1096Line: Record "IRS 1096 Form Line"; - IRS1096FormMgt: Codeunit "IRS 1096 Form Mgt."; - VendNo: Code[20]; - IRSCode: Code[10]; - PostingDate: Date; - MinimumReportableAmount: Decimal; - TotalAmount: Decimal; - begin - // [FEAUTURE] [Minimum Reportable Amount] - // [SCENARIO 461543] The positive total amount of the IRS code includes in the IRS 1096 form if it equals minimum reportable amount - Initialize(); - MinimumReportableAmount := LibraryRandom.RandDec(100, 2); - // [GIVEN] IRS code "DIV-01" with "Minimum Reportable Amount" = 100 - IRSCode := InitializeDIV01Code(MinimumReportableAmount); - VendNo := LibraryPurchase.CreateVendorNo(); - PostingDate := CalcDate('<1Y>', WorkDate()); - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = 75 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, MinimumReportableAmount / 2); - TotalAmount += DtldVendLedgEntry.Amount; - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = 25 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, MinimumReportableAmount - DtldVendLedgEntry.Amount); - TotalAmount += DtldVendLedgEntry.Amount; - LibraryVariableStorage.Enqueue(FormsCreatedMsg); - - // [WHEN] Stan runs the "Create Forms" batch job for period from 01.01.2023 to 01.01.2023 - IRS1096FormMgt.CreateForms(PostingDate, PostingDate, false); - - // [THEN] IRS 1096 form has been created - IRS1096Header.SetRange("Starting Date", PostingDate); - IRS1096Header.SetRange("Ending Date", PostingDate); - IRS1096Header.SetRange("IRS Code", DivCodeTok); - Assert.RecordCount(IRS1096Header, 1); - IRS1096Header.FindFirst(); - - // [THEN] IRS 1096 form has one line with the following details: "Vendor No." = "X", "IRS Code" = "DIV-01" and "Calculated Amount" = 100 - IRS1096Line.SetRange("Form No.", IRS1096Header."No."); - Assert.RecordCount(IRS1096Line, 1); - IRS1096Line.FindFirst(); - IRS1096Line.TestField("Vendor No.", VendNo); - IRS1096Line.TestField("IRS Code", IRSCode); - IRS1096Line.TestField("Calculated Amount", TotalAmount); - - LibraryVariableStorage.AssertEmpty(); - end; - - [Test] - [TransactionModel(TransactionModel::AutoRollback)] - [HandlerFunctions('MessageHandler')] - procedure IRSCodeNotIncludedInto1096FormIfZeroAmountAndMinimumReportableAmountIsNegative() - var - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - IRS1096Header: Record "IRS 1096 Form Header"; - IRS1096FormMgt: Codeunit "IRS 1096 Form Mgt."; - VendNo: Code[20]; - IRSCode: Code[10]; - PostingDate: Date; - MinimumReportableAmount: Decimal; - begin - // [FEAUTURE] [Minimum Reportable Amount] - // [SCENARIO 461543] The zero total amount of the IRS code does not include in the IRS 1096 form if minimum reportable amount of this cose is negative - Initialize(); - MinimumReportableAmount := -LibraryRandom.RandDec(100, 2); - // [GIVEN] IRS code "DIV-01" with "Minimum Reportable Amount" = -100 - IRSCode := InitializeDIV01Code(MinimumReportableAmount); - VendNo := LibraryPurchase.CreateVendorNo(); - PostingDate := CalcDate('<1Y>', WorkDate()); - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = -100 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, MinimumReportableAmount); - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = 100 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, -MinimumReportableAmount); - LibraryVariableStorage.Enqueue(NoFormsHaveBeenCreatedMsg); - - // [WHEN] Stan runs the "Create Forms" batch job for period from 01.01.2023 to 01.01.2023 - IRS1096FormMgt.CreateForms(PostingDate, PostingDate, false); - - // [THEN] No forms have been created - Assert.IsTrue(IRS1096Header.IsEmpty(), ''); - - LibraryVariableStorage.AssertEmpty(); - end; - - [Test] - [TransactionModel(TransactionModel::AutoRollback)] - [HandlerFunctions('MessageHandler')] - procedure IRSCodeNotIncludedInto1096FormIfZeroAmountAndMinimumReportableAmountIsZero() - var - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - IRS1096Header: Record "IRS 1096 Form Header"; - IRS1096FormMgt: Codeunit "IRS 1096 Form Mgt."; - VendNo: Code[20]; - IRSCode: Code[10]; - PostingDate: Date; - begin - // [FEAUTURE] [Minimum Reportable Amount] - // [SCENARIO 461543] The zero total amount of the IRS code does not include in the IRS 1096 form if minimum reportable amount is zero - Initialize(); - // [GIVEN] IRS code "DIV-01" with "Minimum Reportable Amount" = 0 - IRSCode := InitializeDIV01Code(0); - VendNo := LibraryPurchase.CreateVendorNo(); - PostingDate := CalcDate('<1Y>', WorkDate()); - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = -100 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, LibraryRandom.RandDec(100, 2)); - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = 100 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, -DtldVendLedgEntry.Amount); - LibraryVariableStorage.Enqueue(NoFormsHaveBeenCreatedMsg); - - // [WHEN] Stan runs the "Create Forms" batch job for period from 01.01.2023 to 01.01.2023 - IRS1096FormMgt.CreateForms(PostingDate, PostingDate, false); - - // [THEN] No forms have been created - Assert.IsTrue(IRS1096Header.IsEmpty(), ''); - - LibraryVariableStorage.AssertEmpty(); - end; - - [Test] - [TransactionModel(TransactionModel::AutoRollback)] - [HandlerFunctions('MessageHandler')] - procedure IRSCodeIncludesInto1096FormIfNegativePositiveAmountMoreThanNegativeMinimumReportable() - var - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - IRS1096Header: Record "IRS 1096 Form Header"; - IRS1096Line: Record "IRS 1096 Form Line"; - IRS1096FormMgt: Codeunit "IRS 1096 Form Mgt."; - VendNo: Code[20]; - IRSCode: Code[10]; - PostingDate: Date; - MinimumReportableAmount: Decimal; - begin - // [FEAUTURE] [Minimum Reportable Amount] - // [SCENARIO 461543] The negative total amount of the IRS code includes in the IRS 1096 form if it is more than negative minimum reportable amount - Initialize(); - MinimumReportableAmount := -LibraryRandom.RandDec(100, 2); - // [GIVEN] IRS code "DIV-01" with "Minimum Reportable Amount" = -100 - IRSCode := InitializeDIV01Code(MinimumReportableAmount); - VendNo := LibraryPurchase.CreateVendorNo(); - PostingDate := CalcDate('<1Y>', WorkDate()); - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = -50 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, MinimumReportableAmount / 2); - LibraryVariableStorage.Enqueue(FormsCreatedMsg); - - // [WHEN] Stan runs the "Create Forms" batch job for period from 01.01.2023 to 01.01.2023 - IRS1096FormMgt.CreateForms(PostingDate, PostingDate, false); - - // [THEN] IRS 1096 form has been created - IRS1096Header.SetRange("Starting Date", PostingDate); - IRS1096Header.SetRange("Ending Date", PostingDate); - IRS1096Header.SetRange("IRS Code", DivCodeTok); - Assert.RecordCount(IRS1096Header, 1); - IRS1096Header.FindFirst(); - - // [THEN] IRS 1096 form has one line with the following details: "Vendor No." = "X", "IRS Code" = "DIV-01" and "Calculated Amount" = 100 - IRS1096Line.SetRange("Form No.", IRS1096Header."No."); - Assert.RecordCount(IRS1096Line, 1); - IRS1096Line.FindFirst(); - IRS1096Line.TestField("Vendor No.", VendNo); - IRS1096Line.TestField("IRS Code", IRSCode); - IRS1096Line.TestField("Calculated Amount", DtldVendLedgEntry.Amount); - - LibraryVariableStorage.AssertEmpty(); - end; - - [Test] - [TransactionModel(TransactionModel::AutoRollback)] - [HandlerFunctions('MessageHandler')] - procedure IRSCodeIncludesInto1096FormIfNegativePositiveAmountLessThanNegativeMinimumReportable() - var - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - IRS1096Header: Record "IRS 1096 Form Header"; - IRS1096Line: Record "IRS 1096 Form Line"; - IRS1096FormMgt: Codeunit "IRS 1096 Form Mgt."; - VendNo: Code[20]; - IRSCode: Code[10]; - PostingDate: Date; - MinimumReportableAmount: Decimal; - begin - // [FEAUTURE] [Minimum Reportable Amount] - // [SCENARIO 461543] The negative total amount of the IRS code includes in the IRS 1096 form if it is less than negative minimum reportable amount - Initialize(); - // [GIVEN] IRS code "DIV-01" with "Minimum Reportable Amount" = -100 - MinimumReportableAmount := LibraryRandom.RandDec(100, 2); - IRSCode := InitializeDIV01Code(MinimumReportableAmount); - VendNo := LibraryPurchase.CreateVendorNo(); - PostingDate := CalcDate('<1Y>', WorkDate()); - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = -200 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, MinimumReportableAmount * 2); - LibraryVariableStorage.Enqueue(FormsCreatedMsg); - - // [WHEN] Stan runs the "Create Forms" batch job for period from 01.01.2023 to 01.01.2023 - IRS1096FormMgt.CreateForms(PostingDate, PostingDate, false); - - // [THEN] IRS 1096 form has been created - IRS1096Header.SetRange("Starting Date", PostingDate); - IRS1096Header.SetRange("Ending Date", PostingDate); - IRS1096Header.SetRange("IRS Code", DivCodeTok); - Assert.RecordCount(IRS1096Header, 1); - IRS1096Header.FindFirst(); - - // [THEN] IRS 1096 form has one line with the following details: "Vendor No." = "X", "IRS Code" = "DIV-01" and "Calculated Amount" = 100 - IRS1096Line.SetRange("Form No.", IRS1096Header."No."); - Assert.RecordCount(IRS1096Line, 1); - IRS1096Line.FindFirst(); - IRS1096Line.TestField("Vendor No.", VendNo); - IRS1096Line.TestField("IRS Code", IRSCode); - IRS1096Line.TestField("Calculated Amount", DtldVendLedgEntry.Amount); - - LibraryVariableStorage.AssertEmpty(); - end; - - [Test] - [TransactionModel(TransactionModel::AutoRollback)] - [HandlerFunctions('MessageHandler')] - procedure BlankDocTypeNotConsideredFor1096Form() - var - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - IRS1096Header: Record "IRS 1096 Form Header"; - IRS1096FormMgt: Codeunit "IRS 1096 Form Mgt."; - VendNo: Code[20]; - IRSCode: Code[10]; - PostingDate: Date; - begin - // [SCENARIO 461543] A document with blank document type is not considered for 1096 form - - Initialize(); - IRSCode := InitializeDIVCode(); - PostingDate := CalcDate('<1Y>', WorkDate()); - VendNo := LibraryPurchase.CreateVendorNo(); - // [GIVEN] A document with blank doc. type applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV" and Amount = 100 - MockBlankDocTypeVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, IRSCode, LibraryRandom.RandDec(100, 2)); - LibraryVariableStorage.Enqueue(NoEntriesToCreateFormsMsg); - - // [WHEN] Stan runs the "Create Forms" batch job for period from 01.01.2023 to 01.01.2023 - IRS1096FormMgt.CreateForms(PostingDate, PostingDate, false); - - // [THEN] No forms have been created - Assert.IsTrue(IRS1096Header.IsEmpty(), ''); - - LibraryVariableStorage.AssertEmpty(); - end; - - [Test] - [TransactionModel(TransactionModel::AutoRollback)] - [HandlerFunctions('MessageHandler')] - procedure Only1096FormsWithLinesCreated() - var - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - IRS1096Header: Record "IRS 1096 Form Header"; - IRS1096FormMgt: Codeunit "IRS 1096 Form Mgt."; - VendNo: Code[20]; - DivIRSCode: Code[10]; - MiscIRSCode: Code[10]; - PostingDate: Date; - MinimumReportableAmount: Decimal; - begin - // [SCENARIO 461543] Only 1096 forms with lines created - - Initialize(); - // [GIVEN] IRS code "MISC" without "Minimum Reportable Amount" - MiscIRSCode := InitializeMISCCode(); - MinimumReportableAmount := LibraryRandom.RandDec(100, 2); - // [GIVEN] IRS code "DIV" with "Minimum Reportable Amount" = 100 - DivIRSCode := InitializeDIV01Code(MinimumReportableAmount); - PostingDate := CalcDate('<1Y>', WorkDate()); - VendNo := LibraryPurchase.CreateVendorNo(); - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "MISC" and Amount = 50 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, MiscIRSCode, LibraryRandom.RandDec(100, 2)); - // [GIVEN] Invoice applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV" and Amount = 100 - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo, PostingDate, DivIRSCode, MinimumReportableAmount / 2); - LibraryVariableStorage.Enqueue(FormsCreatedMsg); - - // [WHEN] Stan runs the "Create Forms" batch job for period from 01.01.2023 to 01.01.2023 - IRS1096FormMgt.CreateForms(PostingDate, PostingDate, false); - - // [THEN] Only one MISC form has been created with the MISC code - Assert.RecordCount(IRS1096Header, 1); - IRS1096Header.FindFirst(); - IRS1096Header.TestField("IRS Code", MiscIRSCode); - - LibraryVariableStorage.AssertEmpty(); - end; - - [Test] - procedure CompanyInformationIRSFields() - var - CompanyInformation: Record "Company Information"; - Employee: Record Employee; - CompanyInformationPage: TestPage "Company Information"; - EINNumber: Code[10]; - begin - // [FEATURE] [UT] - // [SCENARIO 453564] "EIN Number" and "IRS Contact No." are editable on Company Information page - EINNumber := LibraryUtility.GenerateRandomNumericText(10); - Employee.Init(); - Employee."No." := LibraryUtility.GenerateGUID(); - Employee.Insert(); - CompanyInformationPage.OpenEdit(); - CompanyInformationPage."EIN Number".SetValue(EINNumber); - CompanyInformationPage."IRS Contact No.".SetValue(Employee."No."); - CompanyInformationPage.Close(); - CompanyInformation.Get(); - CompanyInformation.TestField("EIN Number", EINNumber); - CompanyInformation.TestField("IRS Contact No.", Employee."No."); - end; - - [Test] - [HandlerFunctions('IRS1096RequestPageHandler')] - procedure ReportIRS1096RequestPageInitialization() - var - CompanyInformation: Record "Company Information"; - Employee: Record Employee; - EINNumber: Code[10]; - begin - // [FEATURE] [UT] - // [SCENARIO 453564] 'IRS 1096 Form' report opens request page initialized with "EIN Number" and "IRS Contact No." from Company Information - Initialize(); - - // [GIVEN] "EIN Number" and "IRS Contact No." - EINNumber := LibraryUtility.GenerateRandomNumericText(10); - Employee.Init(); - Employee."No." := LibraryUtility.GenerateGUID(); - Employee."First Name" := LibraryUtility.GenerateGUID(); - Employee."Last Name" := LibraryUtility.GenerateGUID(); - Employee.Insert(); - CompanyInformation."EIN Number" := EINNumber; - CompanyInformation."IRS Contact No." := Employee."No."; - - // [WHEN] Run 'IRS 1096 Form' report - Report.Run(Report::"IRS 1096 Form"); - - // [THEN] The report's request page is initialized with values from "EIN Number" and "IRS Contact No." - Assert.AreEqual(EINNumber, LibraryVariableStorage.DequeueText(), ''); - Assert.AreEqual(Employee.FullName(), LibraryVariableStorage.DequeueText(), ''); - - LibraryVariableStorage.AssertEmpty(); - end; - - [Test] - [TransactionModel(TransactionModel::AutoRollback)] - [HandlerFunctions('MessageHandler')] - procedure EntriesBelowMinimumReportableAmountDoesNotAffectTotals() - var - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - IRS1096Header: Record "IRS 1096 Form Header"; - IRS1096Line: Record "IRS 1096 Form Line"; - IRS1096FormLineRelation: Record "IRS 1096 Form Line Relation"; - IRS1096FormMgt: Codeunit "IRS 1096 Form Mgt."; - VendNo: array[2] of Code[20]; - IRSCode: Code[10]; - PostingDate: Date; - MinimumReportableAmount: Decimal; - EntryAmount: Decimal; - i: Integer; - begin - // [FEAUTURE] [Minimum Reportable Amount] - // [SCENARIO 478509] The vendor ledger entries with IRS 1099 amount below "Minimum Reportable Amount" do not affect 1096 totals - - Initialize(); - MinimumReportableAmount := LibraryRandom.RandDec(100, 2); - // [GIVEN] IRS code "DIV-01" with "Minimum Reportable Amount" = 100 - IRSCode := InitializeDIV01Code(MinimumReportableAmount); - VendNo[1] := LibraryPurchase.CreateVendorNo(); - PostingDate := CalcDate('<1Y>', WorkDate()); - // [GIVEN] Invoice "A applied to payment with "Vendor No." = "X", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = 50 - // [GIVEN] Invoice "B" applied to payment with "Vendor No." = "Y", "Posting Date" = 01.01.2023 "IRS Code" = "DIV-01" and Amount = 100 - EntryAmount := MinimumReportableAmount / 2; - for i := 1 to ArrayLen(VendNo) do begin - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo[i], PostingDate, IRSCode, EntryAmount); - EntryAmount += MinimumReportableAmount; - end; - EntryAmount := DtldVendLedgEntry."Amount (LCY)"; - LibraryVariableStorage.Enqueue(FormsCreatedMsg); - - // [WHEN] Stan runs the "Create Forms" batch job for period from 01.01.2023 to 01.01.2023 - IRS1096FormMgt.CreateForms(PostingDate, PostingDate, false); - - // [THEN] IRS 1096 form has been created - IRS1096Header.SetRange("Starting Date", PostingDate); - IRS1096Header.SetRange("Ending Date", PostingDate); - IRS1096Header.SetRange("IRS Code", DivCodeTok); - Assert.RecordCount(IRS1096Header, 1); - IRS1096Header.FindFirst(); - IRS1096Header.TestField("Calc. Amount", EntryAmount); - IRS1096Header.TestField("Total Amount To Report", EntryAmount); - IRS1096Header.TestField("Calc. Total Number Of Forms", 1); - IRS1096Header.TestField("Total Number Of Forms", 1); - - // [THEN] IRS 1096 form has one line with the following details: "Vendor No." = "Y", "IRS Code" = "DIV-01" and "Calculated Amount" = 100 - IRS1096Line.SetRange("Form No.", IRS1096Header."No."); - Assert.RecordCount(IRS1096Line, 1); - IRS1096Line.FindFirst(); - IRS1096Line.TestField("Vendor No.", VendNo[2]); - IRS1096Line.TestField("IRS Code", IRSCode); - IRS1096Line.TestField("Calculated Amount", EntryAmount); - - // [THEN] One "IRS 1096 Form Line Relation" is created for the 1096 forn - IRS1096FormLineRelation.SetRange("Form No.", IRS1096Header."No."); - Assert.RecordCount(IRS1096FormLineRelation, 1); - end; - - [Test] - [TransactionModel(TransactionModel::AutoRollback)] - [HandlerFunctions('MessageHandler')] - procedure TotalsOfTwoFormsCreatedSimultaneouslyIsCorrect() - var - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - IRS1096Header: Record "IRS 1096 Form Header"; - IRS1096FormMgt: Codeunit "IRS 1096 Form Mgt."; - VendNo: array[2] of Code[20]; - IRSCode: array[2] of Code[10]; - PostingDate: Date; - MinimumReportableAmount: Decimal; - TotalAmount: array[2] of Decimal; - i: Integer; - begin - // [SCENARIO 480319] The total amount of two forms created simultaneously is correct - - Initialize(); - MinimumReportableAmount := LibraryRandom.RandDec(100, 2); - // [GIVEN] IRS code "DIV-01" - IRSCode[1] := InitializeDIV01Code(0); - VendNo[1] := LibraryPurchase.CreateVendorNo(); - // [GIVEN] IRS code "MISC-01" - IRSCode[2] := InitializeMISCCode(); - VendNo[2] := LibraryPurchase.CreateVendorNo(); - - PostingDate := CalcDate('<1Y>', WorkDate()); - // [GIVEN] Invoice applied to payment with "IRS Code" = "DIV-01" and Amount = 75 - // [GIVEN] Invoice applied to payment with "IRS Code" = "MISC-01" and Amount = 25 - for i := 1 to ArrayLen(IRSCode) do begin - MockVendorLedgerEntry(DtldVendLedgEntry, VendNo[i], PostingDate, IRSCode[i], MinimumReportableAmount / 2); - TotalAmount[i] += DtldVendLedgEntry.Amount; - end; - - LibraryVariableStorage.Enqueue(FormsCreatedMsg); - - // [WHEN] Stan runs the "Create Forms" batch job for period from 01.01.2023 to 01.01.2023 - IRS1096FormMgt.CreateForms(PostingDate, PostingDate, false); - - // [THEN] Two IRS 1096 forms have been created - IRS1096Header.SetRange("Starting Date", PostingDate); - IRS1096Header.SetRange("Ending Date", PostingDate); - Assert.RecordCount(IRS1096Header, ArrayLen(IRSCode)); - IRS1096Header.FindSet(); - - // [THEN] IRS 1096 form for "DIV-01" has total amount of 75 - // [THEN] IRS 1096 form for "MISC-01" has total amount of 25 - i := 1; - repeat - IRS1096Header.TestField("Total Amount To Report", TotalAmount[i]); - IRS1096Header.TestField("Calc. Amount", TotalAmount[i]); - i += 1; - until IRS1096Header.Next() = 0; - LibraryVariableStorage.AssertEmpty(); - end; - - local procedure Initialize() - begin - SetupIRS1096Feature(); - LibraryTestInitialize.OnTestInitialize(CODEUNIT::"Create 1096 Forms Test"); - if IsInitialized then - exit; - - LibraryTestInitialize.OnBeforeTestSuiteInitialize(CODEUNIT::"Create 1096 Forms Test"); - IsInitialized := true; - LibraryTestInitialize.OnAfterTestSuiteInitialize(CODEUNIT::"Create 1096 Forms Test"); - end; - - local procedure SetupIRS1096Feature() - var - PurchPayablesSetup: Record "Purchases & Payables Setup"; - begin - PurchPayablesSetup.Get(); - PurchPayablesSetup.Validate("IRS 1096 Form No. Series", LibraryERM.CreateNoSeriesCode()); - PurchPayablesSetup.Modify(true); - end; - - local procedure MockVendorLedgerEntry(var InvDtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; VendNo: Code[20]; PostingDate: Date; IRSCode: Code[10]; Amount: Decimal) - var - DocType: Enum "Gen. Journal Document Type"; - begin - MockCustomVendorLedgerEntry(InvDtldVendLedgEntry, DocType::Invoice, VendNo, PostingDate, IRSCode, Amount); - end; - - local procedure MockBlankDocTypeVendorLedgerEntry(var InvDtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; VendNo: Code[20]; PostingDate: Date; IRSCode: Code[10]; Amount: Decimal) - var - DocType: Enum "Gen. Journal Document Type"; - begin - MockCustomVendorLedgerEntry(InvDtldVendLedgEntry, DocType::" ", VendNo, PostingDate, IRSCode, Amount); - end; - - local procedure MockCustomVendorLedgerEntry(var InvDtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; DocType: Enum "Gen. Journal Document Type"; VendNo: Code[20]; PostingDate: Date; IRSCode: Code[10]; Amount: Decimal) - var - VendLedgEntry: Record "Vendor Ledger Entry"; - InvVendLedgEntry: Record "Vendor Ledger Entry"; - DtldVendLedgEntry: Record "Detailed Vendor Ledg. Entry"; - begin - VendLedgEntry."Entry No." := LibraryUtility.GetNewRecNo(VendLedgEntry, VendLedgEntry.FieldNo("Entry No.")); - VendLedgEntry."Document Type" := VendLedgEntry."Document Type"::Payment; - VendLedgEntry."Vendor No." := VendNo; - VendLedgEntry."Posting Date" := PostingDate; - VendLedgEntry.Insert(); - InvVendLedgEntry := VendLedgEntry; - InvVendLedgEntry."Document Type" := DocType; - InvVendLedgEntry."Entry No." := LibraryUtility.GetNewRecNo(VendLedgEntry, VendLedgEntry.FieldNo("Entry No.")); - InvVendLedgEntry."IRS 1099 Amount" := Amount; - InvVendLedgEntry."IRS 1099 Code" := IRSCode; - InvVendLedgEntry.Insert(); - - DtldVendLedgEntry."Entry No." := LibraryUtility.GetNewRecNo(DtldVendLedgEntry, DtldVendLedgEntry.FieldNo("Entry No.")); - DtldVendLedgEntry."Vendor Ledger Entry No." := VendLedgEntry."Entry No."; - DtldVendLedgEntry."Entry Type" := DtldVendLedgEntry."Entry Type"::Application; - DtldVendLedgEntry."Transaction No." := LibraryRandom.RandInt(100); - DtldVendLedgEntry."Application No." := LibraryRandom.RandInt(100); - DtldVendLedgEntry."Ledger Entry Amount" := true; - DtldVendLedgEntry.Insert(); - - InvDtldVendLedgEntry := DtldVendLedgEntry; - InvDtldVendLedgEntry."Entry No." := LibraryUtility.GetNewRecNo(InvDtldVendLedgEntry, InvDtldVendLedgEntry.FieldNo("Entry No.")); - InvDtldVendLedgEntry."Vendor Ledger Entry No." := InvVendLedgEntry."Entry No."; - InvDtldVendLedgEntry.Amount := Amount; - InvDtldVendLedgEntry."Ledger Entry Amount" := true; - InvDtldVendLedgEntry."Amount (LCY)" := Amount; - InvDtldVendLedgEntry.Insert(); - end; - - local procedure InitializeDIVCode(): Code[10] - begin - InitializeCode(DivCodeTok); - exit(DivCodeTok); - end; - - local procedure InitializeMISCCode(): Code[10] - begin - InitializeCode(MiscCodeTok); - exit(MiscCodeTok); - end; - - local procedure InitializeCode(IRSCode: Code[10]) - var - IRS1099FormBox: Record "IRS 1099 Form-Box"; - begin - IRS1099FormBox.SetRange(Code, IRSCode); - IRS1099FormBox.DeleteAll(true); - IRS1099FormBox.Code := IRSCode; - IRS1099FormBox.Insert(); - end; - - local procedure InitializeDIV01Code(MiminumReportableAmount: Decimal): Code[10] - var - IRS1099FormBox: Record "IRS 1099 Form-Box"; - begin - IRS1099FormBox.SetRange(Code, Div01CodeTok); - IRS1099FormBox.DeleteAll(true); - IRS1099FormBox.Code := Div01CodeTok; - IRS1099FormBox."Minimum Reportable" := MiminumReportableAmount; - IRS1099FormBox.Insert(); - exit(IRS1099FormBox.Code); - end; - - [MessageHandler] - procedure MessageHandler(Message: Text) - begin - Assert.ExpectedMessage(LibraryVariableStorage.DequeueText(), Message); - end; - - [RequestPageHandler] - procedure IRS1096RequestPageHandler(var IRS1096Form: TestRequestPage "IRS 1096 Form") - begin - LibraryVariableStorage.Enqueue(IRS1096Form.IdentificationNumber); - LibraryVariableStorage.Enqueue(IRS1096Form.ContactName); - IRS1096Form.Cancel().Invoke(); - end; -} -#endif diff --git a/Apps/US/IRSForms/app/Permissions/IRSFormsObjects.PermissionSet.al b/Apps/US/IRSForms/app/Permissions/IRSFormsObjects.PermissionSet.al index 6948e4f1fd..194c7047fb 100644 --- a/Apps/US/IRSForms/app/Permissions/IRSFormsObjects.PermissionSet.al +++ b/Apps/US/IRSForms/app/Permissions/IRSFormsObjects.PermissionSet.al @@ -64,7 +64,7 @@ permissionset 10032 "IRS Forms - Objects" report "IRS 1099 FIRE" = X, report "IRS 1099 Print" = X, #pragma warning disable AL0432 -#if not CLEAN27 +#if not CLEAN28 report "Upgrade IRS 1099 Data" = X, #endif #pragma warning restore AL0432 diff --git a/Apps/US/IRSForms/app/src/Document/IRS1099FormDocuments.Page.al b/Apps/US/IRSForms/app/src/Document/IRS1099FormDocuments.Page.al index f5cecf59c7..26f598930c 100644 --- a/Apps/US/IRSForms/app/src/Document/IRS1099FormDocuments.Page.al +++ b/Apps/US/IRSForms/app/src/Document/IRS1099FormDocuments.Page.al @@ -22,6 +22,11 @@ page 10036 "IRS 1099 Form Documents" { repeater(Group) { + field(ID; Rec.ID) + { + Tooltip = 'Specifies the unique identifier of the document.'; + Visible = false; + } field("Period No."; Rec."Period No.") { Tooltip = 'Specifies the period of the document.'; @@ -178,6 +183,23 @@ page 10036 "IRS 1099 Form Documents" RunObject = Page "Transmission Logs IRIS"; } } + action(Print) + { + Caption = 'Print'; + Image = Print; + ToolTip = 'Print selected forms. You can adjust the filter on the report request page.'; + + trigger OnAction() + var + IRS1099FormDocHeader: Record "IRS 1099 Form Doc. Header"; + IRS1099PrintingImpl: Codeunit "IRS 1099 Printing Impl."; + begin + IRS1099FormDocHeader := Rec; + CurrPage.SetSelectionFilter(IRS1099FormDocHeader); + + IRS1099PrintingImpl.PrintMultipleDocumentContent(IRS1099FormDocHeader); + end; + } action(SendEmail) { Caption = 'Send Email'; @@ -224,6 +246,9 @@ page 10036 "IRS 1099 Form Documents" actionref(CreateForms_Promoted; CreateForms) { } + actionref(Print_Promoted; Print) + { + } actionref(SendEmails_Promoted; SendEmail) { } diff --git a/Apps/US/IRSForms/app/src/Extensions/IRS1099PostedPurchCrMemo.PageExt.al b/Apps/US/IRSForms/app/src/Extensions/IRS1099PostedPurchCrMemo.PageExt.al index 8835fc9d61..25c4c8d084 100644 --- a/Apps/US/IRSForms/app/src/Extensions/IRS1099PostedPurchCrMemo.PageExt.al +++ b/Apps/US/IRSForms/app/src/Extensions/IRS1099PostedPurchCrMemo.PageExt.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. // ------------------------------------------------------------------------------------------------ @@ -10,14 +10,6 @@ pageextension 10061 "IRS 1099 Posted Purch. Cr.Memo" extends "Posted Purchase Cr { layout { -#if not CLEAN25 -#pragma warning disable AL0432 - modify("IRS 1099 Code") - { - Visible = false; - } -#pragma warning restore AL0432 -#endif addafter(Control46) { field("IRS 1099 Reporting Period"; Rec."IRS 1099 Reporting Period") @@ -39,4 +31,4 @@ pageextension 10061 "IRS 1099 Posted Purch. Cr.Memo" extends "Posted Purchase Cr } } } -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/Extensions/IRS1099PostedPurchInv.PageExt.al b/Apps/US/IRSForms/app/src/Extensions/IRS1099PostedPurchInv.PageExt.al index 51244b2924..8e91a42dba 100644 --- a/Apps/US/IRSForms/app/src/Extensions/IRS1099PostedPurchInv.PageExt.al +++ b/Apps/US/IRSForms/app/src/Extensions/IRS1099PostedPurchInv.PageExt.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. // ------------------------------------------------------------------------------------------------ @@ -10,14 +10,6 @@ pageextension 10055 "IRS 1099 Posted Purch. Inv." extends "Posted Purchase Invoi { layout { -#if not CLEAN25 -#pragma warning disable AL0432 - modify("IRS 1099 Code") - { - Visible = false; - } -#pragma warning restore AL0432 -#endif addafter(Control60) { field("IRS 1099 Reporting Period"; Rec."IRS 1099 Reporting Period") @@ -39,4 +31,4 @@ pageextension 10055 "IRS 1099 Posted Purch. Inv." extends "Posted Purchase Invoi } } } -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/Extensions/IRS1099PurchCrMemo.PageExt.al b/Apps/US/IRSForms/app/src/Extensions/IRS1099PurchCrMemo.PageExt.al index 8f827f8db2..ae99672c5e 100644 --- a/Apps/US/IRSForms/app/src/Extensions/IRS1099PurchCrMemo.PageExt.al +++ b/Apps/US/IRSForms/app/src/Extensions/IRS1099PurchCrMemo.PageExt.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. // ------------------------------------------------------------------------------------------------ @@ -10,14 +10,6 @@ pageextension 10059 "IRS 1099 Purch. Cr. Memo" extends "Purchase Credit Memo" { layout { -#if not CLEAN25 -#pragma warning disable AL0432 - modify("IRS 1099 Code") - { - Visible = false; - } -#pragma warning restore AL0432 -#endif addafter("Invoice Details") { field("IRS 1099 Reporting Period"; Rec."IRS 1099 Reporting Period") @@ -62,4 +54,4 @@ pageextension 10059 "IRS 1099 Purch. Cr. Memo" extends "Purchase Credit Memo" begin NewFieldsAreEditable := Rec."IRS 1099 Reporting Period" <> ''; end; -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/Extensions/IRS1099PurchInv.PageExt.al b/Apps/US/IRSForms/app/src/Extensions/IRS1099PurchInv.PageExt.al index 992fbfcc80..113e7a1314 100644 --- a/Apps/US/IRSForms/app/src/Extensions/IRS1099PurchInv.PageExt.al +++ b/Apps/US/IRSForms/app/src/Extensions/IRS1099PurchInv.PageExt.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. // ------------------------------------------------------------------------------------------------ @@ -10,14 +10,6 @@ pageextension 10052 "IRS 1099 Purch. Inv." extends "Purchase Invoice" { layout { -#if not CLEAN25 -#pragma warning disable AL0432 - modify("IRS 1099 Code") - { - Visible = false; - } -#pragma warning restore AL0432 -#endif addafter(Control88) { field("IRS 1099 Reporting Period"; Rec."IRS 1099 Reporting Period") @@ -62,4 +54,4 @@ pageextension 10052 "IRS 1099 Purch. Inv." extends "Purchase Invoice" begin NewFieldsAreEditable := Rec."IRS 1099 Reporting Period" <> ''; end; -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/Extensions/IRS1099PurchOrder.PageExt.al b/Apps/US/IRSForms/app/src/Extensions/IRS1099PurchOrder.PageExt.al index 94e823482a..5d1e6a1243 100644 --- a/Apps/US/IRSForms/app/src/Extensions/IRS1099PurchOrder.PageExt.al +++ b/Apps/US/IRSForms/app/src/Extensions/IRS1099PurchOrder.PageExt.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. // ------------------------------------------------------------------------------------------------ @@ -10,14 +10,6 @@ pageextension 10058 "IRS 1099 Purch. Order" extends "Purchase Order" { layout { -#if not CLEAN25 -#pragma warning disable AL0432 - modify("IRS 1099 Code") - { - Visible = false; - } -#pragma warning restore AL0432 -#endif addafter("Invoice Details") { field("IRS 1099 Reporting Period"; Rec."IRS 1099 Reporting Period") @@ -62,4 +54,4 @@ pageextension 10058 "IRS 1099 Purch. Order" extends "Purchase Order" begin NewFieldsAreEditable := Rec."IRS 1099 Reporting Period" <> ''; end; -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorCard.PageExt.al b/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorCard.PageExt.al index a1a1420c97..28e0644781 100644 --- a/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorCard.PageExt.al +++ b/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorCard.PageExt.al @@ -10,18 +10,6 @@ pageextension 10053 "IRS 1099 Vendor Card" extends "Vendor Card" { layout { -#if not CLEAN25 -#pragma warning disable AL0432 - modify("IRS 1099 Code") - { - Visible = false; - } - modify("FATCA filing requirement") - { - Visible = false; - } -#pragma warning restore AL0432 -#endif addafter("Exclude from Pmt. Practices") { #if not CLEAN28 @@ -103,30 +91,6 @@ pageextension 10053 "IRS 1099 Vendor Card" extends "Vendor Card" actions { -#if not CLEAN25 -#pragma warning disable AL0432 - modify("1099 Statistics") - { - Visible = false; - } - modify("Vendor 1099 Div") - { - Visible = false; - } - modify("Vendor 1099 Information") - { - Visible = false; - } - modify("Vendor 1099 Int") - { - Visible = false; - } - modify("Vendor 1099 Misc") - { - Visible = false; - } -#pragma warning restore AL0432 -#endif addlast("&Purchases") { action(IRS1099Setup) @@ -155,4 +119,4 @@ pageextension 10053 "IRS 1099 Vendor Card" extends "Vendor Card" begin IRS1099VendorFormBox.GetVendorIRS1099FormBoxSetupAsOfWorkdate(IRSReportingPeriodNo, IRS1099FormNo, IRS1099FormBoxNo, Rec."No."); end; -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorLedgerEntries.PageExt.al b/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorLedgerEntries.PageExt.al index 73d8d66393..e73bb6fbb7 100644 --- a/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorLedgerEntries.PageExt.al +++ b/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorLedgerEntries.PageExt.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. // ------------------------------------------------------------------------------------------------ @@ -10,18 +10,6 @@ pageextension 10048 "IRS 1099 Vendor Ledger Entries" extends "Vendor Ledger Entr { layout { -#if not CLEAN25 -#pragma warning disable AL0432 - modify("IRS 1099 Code") - { - Visible = false; - } - modify("IRS 1099 Amount") - { - Visible = false; - } -#pragma warning restore AL0432 -#endif addafter("Exported to Payment File") { field("IRS 1099 Reporting Period"; Rec."IRS 1099 Reporting Period") @@ -46,4 +34,4 @@ pageextension 10048 "IRS 1099 Vendor Ledger Entries" extends "Vendor Ledger Entr } } } -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorList.PageExt.al b/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorList.PageExt.al index 7dee829de7..b79b2450f1 100644 --- a/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorList.PageExt.al +++ b/Apps/US/IRSForms/app/src/Extensions/IRS1099VendorList.PageExt.al @@ -87,34 +87,6 @@ pageextension 10050 "IRS 1099 Vendor List" extends "Vendor List" } actions { -#if not CLEAN25 -#pragma warning disable AL0432 - modify("1099 Statistics") - { - Visible = false; - } - modify("Vendor 1099 Div") - { - Visible = false; - } - modify("Vendor 1099 Information") - { - Visible = false; - } - modify("Vendor 1099 Int") - { - Visible = false; - } - modify("Vendor 1099 Misc") - { - Visible = false; - } - modify(RunVendor1099NecReport) - { - Visible = false; - } -#pragma warning restore AL0432 -#endif addlast("&Purchases") { action(IRS1099Setup) @@ -153,4 +125,4 @@ pageextension 10050 "IRS 1099 Vendor List" extends "Vendor List" begin IRS1099VendorFormBox.GetVendorIRS1099FormBoxSetupAsOfWorkdate(IRSReportingPeriodNo, IRS1099FormNo, IRS1099FormBoxNo, Rec."No."); end; -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/IRIS/TransmissionIRIS.Table.al b/Apps/US/IRSForms/app/src/IRIS/TransmissionIRIS.Table.al index 2210c84660..645c989d7b 100644 --- a/Apps/US/IRSForms/app/src/IRIS/TransmissionIRIS.Table.al +++ b/Apps/US/IRSForms/app/src/IRIS/TransmissionIRIS.Table.al @@ -84,6 +84,8 @@ table 10050 "Transmission IRIS" if Rec.FindLast() then DocID := Rec."Document ID"; DocID += 1; + + Rec.Init(); Rec."Document ID" := DocID; end; } \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/Printing/IRS 1099 Print.docx b/Apps/US/IRSForms/app/src/Printing/IRS 1099 Print.docx index 5711c839d71e56c61952284af0aacbd51f462599..a79e6812927a7bd42684193c8cc7091b49ce0df3 100644 GIT binary patch delta 21037 zcmZUaWmFhVu%?j!!QI_mf;+(-0>Rzg-3NDfcXxLQ?(PsgxVyvV`>yQ0yFdCpQ$2I4 z=giEh>8H9nd;)Y}9hBgQH24=Z5J-@(ARr*bAV}z-cO9T0AcoK&AgCZ;!4h_iQR}F` zf&mlBvX<-Lk%BLS-k|E14XP4^sRtbp-hGAEAWwv<_cr3XoO)KUDX)7jrJ6bNTI))0 zoslJ2Zo6Y##Cg&)x41R64M|YFNaarJN@pr^qjXt!m(RwJx=KTPEo*xXNtYycy*zGA zm^H-MxYvc`&s^zWeJ5{}bRx zXd*$l7*jXL+AxNRlZzRm&d(yCU{_nRBkEsuWVw44>}-~Z>A}U_=zkc=gv|!itMEeF zfjkt*iQLV85{zYkozkneVupF87$mo*RpBf>9vlLtUBKlbfnD6 zd>9v=ae7_i$#@%UJavY6&6__DbaFh{K)Nm#a30+;M616XJ@(slS}yc=^$-U@Lb`)G zHtKrgLVj<}vah21LvP(8xNeRnzWPZb`0L1% zZvEpA(4xKD5Jmw3Nk{+zLH_&MxY{}xF&fz#I$ImtI5D_cTb*g2+U`j>d=e0Sg70{( zeBq2~&#>J)1JCI|xPS~ctxu6gf-@_({ze)HBl%p{`+lkVP9&)gJi_g;)rI<1{ za=y+l3VhBJ<}eJYcc#uZD*1|NXz@<&jW?FvQl3LcbPa$h`%m_%Kb+#KS5TnI8)Zs}<`X3L5j} z8k8ZX4_JeyUg>f~$?*;l3)B+D_)v}4x{u$#_y=u=xJ1vJr}*mk>%7A3)fR< z6SH)<^JU!CrA8^H5xiZod()@ak@v8`Hyxh^(j%u1bA4`4k(_aJ1r@_vYa`0w*SR{o zvM2{`2rd)zZ;}U1uBqqJ@Z6N>al^}Bt~fJP4*4dplZ%_Dnw|}?lfSg+>sD`A(QpD; zBx0JC6r>6bH@>rGKNgg-mIY%n!b?s{FYx$xfarA zxITmVzOBvfqo1?Cq2%-X&&_zrjWG->BLV4;vxU&yhCqGoMU(g|pj(QXt ziRv5ghjgzR@M7ux@*VOw`JIz`XeJ@^5(M--T~_U>--tBtRpH+fSziYs04hzwcbaIX z45tN??7FdT{$G?cNS!G2a}WVlCc+$U4MYl2bdE<5T72C>&qyw;k>05omYBCxG1dAy z;MgM$^s6x63yi9Y--gwU`UMWHc<11R(McE$uT^hwqy-%gEYzcO3c|_VcRSfyEHr~J zpKMGon4G-Em&)7LDGN0Rwii_|F z8{}`POm-q+IWP}@UkC8iZ08KxF0P7H3tnfaHm-{~oRwxnIjQ)B?gdB+XfuH$^IpNlC+2*8o`v5YKCz`nUBlMJ4ISteu*`Gt7{ja__q!|7j zP@(s*QND-e@^DW#*nkppI@V(TgoB6n+-eix{_t6SVxE1%c}R?~;TV;=)&{G{$q{z2 zrmvUQF7?46s#t^XbzR^1g=#n`%XHN{mW31*M|a{F%?rVfs;RWBpMfs^&;cIrJH%MU z5QGCRYS-yAjN--9!2W_NF@kEU^~wvjWbH@W0n&r^8InPJaP<{F>vS*ArCp?J4m+8BLQf;-q) zbC55zi?^(6JFz}2DD21LubDUxr7}iQ-za6|(B>$IWUmX!8C+2I0>i$8^^-FAc4d@`E1%e~ zmI@j)#&?xuWfF_O1ZY7LSD{@Kwa@u{qY6`J>J&|+xPUwuJwL>;dp=E1@-b?<&rkYz zt-CEsy+vf!B&HL@EBYeD`9FTe-;@tnql)(rL>ZZ|O-n(zXZp-2 zADQs?Sb_pWn1g-ggY`IpcvNEJeut zP&1mBjsXmW+6!jBjY4OJUK6Z4YPF6K+SG-%VE=bpttt&Toy>!pFL|69CNeBftNJ4f zZX9-ZW&viWH0tOikkhAHSFo&%PYUccBZcZxtG>G&T#7H~A6dF;2@{E%%e5XYajxp> zCJpaH2c!K))8+|iDybh1Bip)<*mQR-)Hm}ol>i&8<*tEe21MA$Kznn3u)D#0E&ei# z4u^c4+W2**9q@fui)tN`tTG)-SZF?5Q+!1T!Gdy$r!5#VM;VQ?9aSxi6`q1!a3Lyz zX?Z+;7$KPJrijlv1MysgYsKKeEM3I;u;;stcV2C#7kPvYd-O_9%xt6-6wbHGS)w0@ zcK~l1W>}{au5;Gz?>@B#qOxRO1f3F2xukr1(Sn>*dN_qNvpZ$kq(DzvbcuVdUDDUz z&DOVCj@o;_;j6BG3szU4PE(To>QuZQu-29^jg1e&M?v&#az%oq!i8e{?sAU5zf}@C z+b0js^%IrZK#lHrlh!nx_Xo_ddj11w<}rX`dd(+fSXgyL4VuAmln<~IhF|QGjdNAm^e>ul`ZHU4*=eI^;)PA2I|oaCZ%zbe3! zoA!`_o|ZLiM-Bf+UANZe5D}$`O~+I3US7#i{pHb*pu@8s!baCs(UeD>!N^-Rn0##r zH%9RV#dCV`qme|0TJ7kWCMk%eWKz1A6^YG)@=Gnhs=b-x+?5Z9FH6pq!6a%mZPT`; zm9?`vJ568HiRf#sSgfX_oOGR)WHf;8Jd-YCX7*H`nqgOO;a8^%Tvpv%I)zXj-2ydm zKV7Z_^~I>$mhFdpV}1IoIvuU@SqV<|FllGLWeN+^GFBG2I$XLzrpQ)2Ba2`=ap8zl z_N!{!>VTLWU1aQ6q!QZ&y|eZK=q8R?Jz-e9$j+(X?fPxyODleJ4P=_M6=(pCbm01p zhXtwm@E0tj2CTIP9K~ho z0DTh<0doTsEDMgbdHm%j-tICh`2wp}kzSpiG<#|Mi6x(+W6lbG$Xd>El95KT`u8|^ zIf+JZr<yKjNV;&FloNZV68$JMe)H6L*S))Sv?J^N_@9^HtH9 z#D12?e$AaN3x=b(kuDuf-gJhRP-mbr2)M!32384GRu@okYb7Q=*3Fwta;Uh~c!`Jf zyR7v>C@U5v7t(aYi%45<^~7?QCO6`t^Id11yYihPXXtbdB~DK>lcj{)A}f~%GO|rp zIwoE*>(Y7IS~DgxS!Te%kRPOf*@>+)=$swf7Dh)HV$4d3zRNk0Pwuro{Bb+9dB_XF zFHi6%$yNP;5)QZxs=&9k`mMs!D&&0b?4{N3Hmz6?&HdXim-J2nD2a(&$Z9*oWKmFb zTZ=k;nuSnY$Vo&-hN#v}8OI^e+gjx%n0;KDlsE&jn&Kmm+`j-k%V=ndPZ}lx9VCH# zP#2QtJQFiRTuU7GtxL5k==~DoIQr^Mrp(jsYHt3m`K!r(u0P)87B_2ds7;p5mz)<4 zq3%gz|M@-rvo40yA{0s5e@HA*L$pPlTybq098z=H@|t;F-&@%^$2Hhys;&pFvG^% z=L+FH{It!IHTO&=T^4U*8}Stjm9T>H_gN5BtUj*Q=c` z=~16WgxB!rXLFk|xPT}2x8SZWbDe*(1xHp2aBJRoX2&}YCXD~}-pzrm3-IBdGrJV}PV>KH14d6OxumB3-e5K!$-zR-&y^zw@+O*m zeRo7E!np^iFxPi{u|+Vc{(I<~bi?d$J+~AvzmS`2EY5Y`&hM=57efZEZWAxru%4$ae#M;lqZ*+Cw;&pK&n+CbnMONn1Crorrr6f;Ukm2zo=+5`pVdwXw?V}zL{RLH&mVEIQ(v(J z^Ksf*wi2TH5O9NrwMV|L= zbnhiM?k!=^No5zC>3MrFzAv2IlUk$jb=K4RByG8LiSQSfXzvZQ9~1kSIy!a@^opP| z&ST5PiJwj9$;0#}TbRdoBR|(i5psFdNVJ}mLU`ZJbW!xM$GK&vgkon9s8y;rqXIZy z*q%CM_`mkbHV$p$rFl>6CJfn+}3QV(tfS?HS<8CQ$Z^H3rUXj#Hctj$=TsN#sI zJs|;4 zUF45>woT1Yy5Kvd-JXs0liB&%GyWo_iYG(8RXW1#%gm~~{bhE+2w0CCC`F~44@4qS zR*x-9*!kf||MQ&a;e%NgJSZnyI|^s3CzJ(|iOmYD+!{rbZwb`^Ky220td{uj6+$}7 z1GQkwrW5x>#R2Fs8paz^0M{J&!yCnLrxvATD1@Q_7PZ!+&#vGYVde7!RSDOuUodNk z`!(klJh9Z15)YM$Kr|#&+B$jxWbHOaWn%h_e}Xu*Rh0?e*2*f}{R@GLWiztiB}cgH z701?16u;#gjCi)@EBb^;(39bAdRj*S_%!oc+H18B`S&Q@q8xu+bH@vu6$pvCmdWOg z@x05sXBB7ev!mvS{wa?~l}V4~j`Hdd{-! zY~0>_RoD>-F~|iHSKx27ihnZSvsHAQZ2wSC9xvPdi?fxkd0CbHH zF}}gVsn@;}fT{kQ)Z1MnW`VbjXFJc@H9DDjX+bxj zF<=g>5-!;ES|gy4MWi`LRzl7n{mh_fWr#>+jha=vj>@beJ=cK|{5=%-6gUY>^dhg{ z+{*Ipiv#NY^;=$QBD5cYx6D4rKZ(4CK};wp7{X-}O(F;o5EP_@B?1ay3HIKgz=n8y zX^uoaglmw09>p3pPQGr<7TkLlfH@<4>R?8%nsd50h_I&(U|B7R#-O7CJYVH1gV+ocr z>!D0-loG|y=GB?ZJ7CDaXUNvHUe8@KPQxO`P);h;Z_z*;SAV5E#~9qsRD!_g4h2!! z{O+OpHhg)5MF)>w2Q{17jB`8;sa8t;-YY3IV{fN5G=E<=)6B+GX6fN6!_XjZc7AcKZzoIQ>`e0UR zRX4yx7mdF9&1P&IYZlv3RgZl9a++(@SQ0imFyy2$WY<_Nx%?s*xBVd1m9K#Dm?p>P z_fq7ZGxW}PbHrSL8;YCz9yX)$<1U`pqHWB&XC=`BvxBNY3wkF2Rk=bX*2+Bqu`=+QZ#L?UZa#F#08;RyqX&bQ*IM4iUA{E?zaUrwkGrHfS7;(mAAAs%SJf433 zIS>=ubA~w2VzeuAF%V4j#d{{gMZi8u^3Zzj6cCsxgsSWw4o`u?$kCd|v$U?ZsQP;7NB zJn(|I{y>kwQ;xZX1eH?ae1ti@W9eNIoFk%Ap`@%~1ckQVDSslpMf8j^Y*8NLDcZJa zl!WmOh?eyy8BTApI_~I>w*D<>H&;=Xp8fg9q^LSVa8bRmRl_kHs>Pz4fHsP)Cue?b z+Y(F|j7wbQe9gB&0V)(G#TYVb9OQ*bW!^vBM3CJ>d()ts@A?7fH%(B-+kBk#BxK;{ zl=}MLB+FiL2V`V;#1C6ZOLt*fQp|G?<4OxGz;Y_LnSo!xF016H$HPx(Yh~RM4z(83 zD(REi6y=n&&Ofw^9;5U&>D2)>Ef-d5bLVpH<;PNPG}|mP0+lT~G443G+%f{&T3y&? zj}ZwIEcGmWTO)4?aM;+~qhO@4a`iJKLgeecS(Ey??IGg>bV*+QWAW#b_TGKEq3vX$ z0KUygenv}fryAuE6w^1i)OhjK1BtvLp4plFzAN(G2ic}&hI`I?5mkMuHutey6KlsP zzHdw9A9NUOPzPvZ_RghCCD#|_u$_fq)titMf}^dyKJ%#&#Sr5HeUko3$^BIr;^qtY zo*bNgf>3}oMuKQ+z8h5s> z!2b7F)041HN(#uvth4`J4TE?g{F+sfWaN!|4cTl|)P^nVF;ccI)ksc94nt;Lqj1;b zTFN+nN*3EiKXYIZw>!~4J24)2?s};!6^;-X;jauk>A}P%Ql4lm+N5dL1IXQd7Z%#3 z=}%NP%F7C!*%bJAoA2235>G=)%`r&6kXDrZQYtkO;|#RVI8dLq>4&mXl4Bqm$2m}} zsPGq7vaYyj77lPSXJfO>GiNAFs!Ij>dXsA5*UoTjy)Z{5+k1U6g>Z^w9oC9ZVd-zj z-o?p7)(S9j_1%UxU1A&S#@@%KDW{Ef#Qd7yPSW-m*L`ER>0P+WHrf+oq?_RXDxvB? zQv)$&p$PQuCSRjSr`}{K7<_crID;&!VaP+!|A9^|UN*E-;M+n*c7qR`o3f#J5*uX} zIbyds}-kgINKfZ&Nc z6`5##D=>A{8}B6lw>Vwg=wDo2ULN_;t+tC7u`|;+a6TY5gPMh0hmK`@JTr}!@H?5+ z6$Hp0Q-D9+SVuU4ntHfTQ|XL)xc*%qb0WO}UwQE>CL`8OlPSkROPG>z{&`q?kkcn0 z2^mlK3nda8`i~qUBWLsAKSgadck}SgO7Qi3iu4Mefs6sz(i~UuXa(11tveQqJ18r+ z;E=NeMiGxnHdJzwQ)XgMgzf09(dMhsh893@y?h-R&yakLw?J&Tos4DyesSW}&mNT= zKZ}jl!jYe{=}3#YuI?UdGk43CEreFt648hddzcBE)W%7HDUyed`t9o#zne^e>g7>p zCQ@Bp?&=zz?v^>#3bLi;54!N*Gn(tYCpFOyag{dp2I{Ep@FGv~+3(FWGV`)ll=VQ< zhf0cc6N-n=8HB8;Qt9MPa7EIuM!I23)iwMlO80zW46&pqINLLZ!YL(wu||m;WZs?u zwlQc*3FfCFBIw_sw;>dcRnoWWF*&8)p|@{2NMYw6oFwW)f{l&z@+}EO3t36nCxWT1 z9;pNT3-h|c3QqviX!|U9wOpyE0~z2*Hyb8c@XKNdiIT1N22)9idZR)&EmSggeml21 zQ{mdT+gCN5Hn2=jkKwCotI!?ASK*jyW+XBvrh!!jUvw(gpYdlLLQNJ@q1MPY@Spg3 z4DU?P_*<^@EcPnWw%F=AyCMuqY|JUrpTlt$Se}xt?AG}FU>nyY(uky6i-v6D%vn@m ztLfL1itzL-q5UNbV~3R@oX_I(N25C!9(NmNj7}y0L{usYH?f7 z$B-}hvWMzq^$W^`7t2=UaDU|O&Yq*XOg2*ubirwvyP*taYB3$@U2V3HXQ=6ilOn7L zixN}#@;pm*385|UdERfXY)JgQDjNi%O4YbMn;@uE<<>n5Ag~WR!Bx?R(VKD$`_g&S z-zoA|S7t&@OG_pp1Vb|AIL_2*F5ka2A3U!t|BY61OnuUUSXPB@S~C1Kq<-7>dOgib zZ7nf1d}%Lp56nQXkw3m%#cF@L9@I^VOkQAZ;HNrOSAuz`eh1}HL&TtFUjih$DRs3a zXKwuuP!w)Xz(ogH+iT1B(kFr*JvBqD14sNqM_jLqhUCi3v+&_RJ1;y{2Kh{u7rzCN+-hzaaV_d>= zG}|Vudq!Z}d>6Kaq&-QVSpA^*DlkQTXr(V(~ z_F-avqv51Y)EW9PAn}hL-U&FPU;Cg`m5tgv=i_b=i;VSN*7WnsM`6G3@o6)}W))!C z|8owkra)S=7V{wN6p=zU_$I&!j2K-Ew*C5MWg`DE2s+8n(M0rX#br`AbXy!$kA@HM z+XFaNIfo=zW1C$ama=8EVlBiuP2W%_bF+FfSmF;;1Hk>iYzlHAPsv$lUows9ed$Ti zEv*HueX6A^K&#m91FzopRjy(He z$<)5+6bf7QBgoQcbTRGjD~50$kVH1V+T%@YSdiLz@kBOZJHroeT3Bl>YjAt7yZHfh z^ptbinH|@aLD}@pStCot1cmF-O`*qw-Rvi#dbn}yJP}oxLu-*QwaZlxXvxJpwvAR> zHJip(R=ZUQ&}TumX48~*bhZ_fX4_mUg;De?-}TK`h34T5tgHJ+9K5?^{{$zq7sMHR zm!P!NnbQe}P4Il}zH=aF>;@d0;`aapMHdWY8dSL%Bg&c~$FjJq;n*KRlvoEm1f;JN z3fopoplmWbB*8;PzAgp(G^EZ=z3v?hE}?{wn>qoOMNH!Yx~+<4!>OO6>OY;2!V1c9 z!KDVBGB@LY*vm_i*JK#gR8swx5c?tAz$o82IUk!nFZEs1dia>nV%@PK;`j_$@0NDa zxazX%atkRhKiwYf)slyG;Dq_ft_^C7{T5)M8y~P}s1l)$zto+pbOG1+I!M%zXjN!R zo5nYSNA3ujR$+8ObelMlP)|BxrGxbHwO@q3h}TrKSB|p-_ewRN0UBElI`ip6i=rR? zq_`hOvEQj;yPh0Nb%l`Lr2QO?UZxQh!Qm18kht7_X|epJ!sC_j-=dL#nWp`Nge^KI zpfX-odVuNgWXJ!Lcw(ctBRtfq9TWMX{2t0^{urt_Ar@QUfUeWS0LQ_$&JBn;HDJ+u1{zsbI{6n zMwH7YljS|Lwy((4wrjCswC*xl(Mw%x0K$Dcovm{^OD?xTxwawEdAj9~d$enTvzg|A z{*diWF)}WNJOR7UNRns!%sO^wDo7LkxUgLLh{_bS9RZAxKbd_N3J__$QxM&Uj`tkW zOD%qd&7LtmkOH%ULWJJ+C$JzOpP%3$|GN-sO}w`;@Nbkp!cO?gAP6L?Tg#&gB4tlg ze1yPmAukMw{FL?;A_AQ=6MbJ;Xx0O#U&$8v=zN*5X?bOC@LXn1>_{`sHhtJPdD!0C zLcpIPOrPgdz7zSWF&A!f_Z{{{g6A$>XO`bb^@`36?)A$i#0Ji#ZTWGqi=RhG2l$C% zNVVCQ?3(Wke(!;;;*Nm!JV(J?NX}(>(+QYIvSrvQV(nyZgUAGo0LS+W|3mEV*|iq` zpv!DCM9%4+zIQG(fq5kC^LbCN;2F*INK3cXc6r-l_-fbKb7>DhUK%5Bkzs}E!_d}m z%Z^lwr`XrX>@<V`)w6DD2d4BBYfmsFj_ZT<2a&8fwMMsH6L!!g0 zo8P=p&w~$cR&A*i58107F)P9a`6`jL=7(4r%yqOmC+)ymu|D}8CY2-GefboMDV=?M zg=uyib@m;^LhG1XVS_3~3iPVQeyXEF{Ab_5)-E*ePR6&gpl32E=B#werEG$yvaXH0 z_!+~BwA*j4{0suPHX_TdJ-Vt;VJ+XbcJ@)#Tpb6?H_OGf)A1~n7HO}h6-=$=A6#^# zFZHLiBCCO4hC5lP0j0fkrUtRnI(ejH|x0gcxk1k z3e2BMDO_~C*Vmn*W@=~$;jHh+EMzq%rAktDJMw|ftyU>%zOY#(w&Hr1YH9bF;(}$5 z(M@smoee(Gfq;DESGJhZ?9`8ZbpyiDo*8j4zHq#f`Rqe$Ro!F!{S|ZspBwy)t^PDoA=sE zl{p&Prdh5*UPL6vP)pbPU043c?i34-9b`EJWJKSkbA9KWv-zi4j^SJNJf!ki$=yMsW>m5Jl=y=Lpt<*T6BW|> zV|lLV-?S%U>$6PK``@ZN>A$H@ED)-MS_A9^c19{dE4J67p9wDbGN4QNYNKh-MjL-O zu}z(*W!9!v^IO|;#8Wgx(u9v7nu{Knfy{X^k z7EY(Adg$1_#g`HY2Va-PckR`Xd{u>@uR1LX>vU`~<<|5w9NL%U71YC-x0G*0`;g-% z>)WOP%|7Y+a%9&Z0V-*Wl&LR%4BzA+i1RwkD*9k3&gbkvY?Wn>roRODI<*JeG_Q&F zQEkN9$a%c#i!0H)e>5X{d~InJ$>>5hd#J80zD3dtZT)nhQTQdN9kz`6geBq0ne8z4 ze7u-ZI7+R};xC~b5BLY!68v}v`_Jf|a7|AO%G`j@fCdW6oPf_jm!QLV1-Pa=DwM;4 zfb_b7fFS-?siLEkyOpuyKZS~&S+b7noG8JUnoXa6Me`TLamM2gyEvv}grjRs_Pb%3 zqu3pqYji>0kp56mv9Fxs8H5=KfXu$L&!AC%JiPuyf$DKfhE2ePzgtnMamXDdwc(twr_igvnOHTTWCQwvLTUPry^;f4SUu3Bg*k}iY2J+nq2np~e#Ly{Dh2zGH zzCI_xaX`z%8VXFgRfaN8sv2Z1HxBbRil>R5$^`RHFA7ou_M_6N61WpaFyF(zvZRe0 zU#sBDERqH&9wdO@(uB468scpuftU~jecv{fBkSrLxk&o#P2j~vFotVbFo@Q2kwV0s z1?~u~ZR&1HLsdAn&I{_AjUhDayqcu7hB$W@NRmM@#;-~y|FjD7*!WI|J?NukZ}Jv0 z8%C(bDJek$G__#hOP{o#M*;`r0Q35NtrBB$oll?{rVY0#iq*T zM2ctVroY&Gfuhif>HMaG9$k*ie`+-={Q7ct2< zoKrF2hEAFA)4<{kaa{IUcQV+#YhUrv(o}O|F2n=CmEZEpS$}U}r&s!EN}Al2mV?_r zddG@^Sh-?ElXUDF{KKS^u3bs^S57#5#QoHsh1FQkQfQTKH%pgR!;e(CI^$ktgNz9T zCq#q1+oPS)j+e=nC>P3gw0esHkg*Y z?()7oq1`meb)C#7n&4dgYCR25j8 z+UVeQtimqN%v!RsdRGNU>sI8gTCzFaXut#5<~?G4?WsT~?Z0rR?}Zw&4kH(Tl_M5bMbqf@`4jqJbMe8|7t;YqUF}`u zfWEc9qIMIy0zQv>7xITbzu#BaV>$%X_uBRqX$m-M?huOWlAouWw^9)z zNMD@$`eYC;(~XRtcN#`QVv>TtU}gZE2O^b>ti&d2{g&VX*g7~^6IWxu^nx)Vlc!6A zOY@PVltf8!YQx1?ZH&DXqcr~-E&mwk)=#Y)5hU!?n>x-iFF73@kwqUk#&!Y+yToj! z#!w06j>WzB<14~LOBLU9R&0jXh9j*Hg~X`-rx5_|Y2PTXn0 zJ#LhF$!e4kC*>~wZ5S}>GH7FJnnTF{RMOS;MgCoXzYX3VktSjO_HZrRCxSOqMO1xh zD**NAP&F>Y$He*zRvnF**igk3?DIN+@k4UH*HQUP$+U>Lr<{|=$S($nUb3I@Mj|4L z<1%qD@mvd6ACozl@y5vT=L~!MRH&4#AH#G9pG(OiVQLSXfE8aFJtBkYXpkJE})&wL2-te`Wb3ktv_t z7os4XW$rlVNRt3o4BZs+e>8DbP+f*al2n`Ux>%)ero_h->5bc?8YXm}6hc0c&)}q- zf*Nxd%xw!C{UeQ?p&1}$(+b0Z5$7o4!2TaXFTo|Y$^0|SUTg)7VMUZI&2>4>A&1Ac zCU27ix!7Lq)(G_xRpw~715S#Ts`8Y>eQRvS4%_zG)5b&7>slKB=W?!fTSF5lPx@1T z?_nz-z}k?%!Y0m~tz$oKh0IxeXA-TU;A4m)-!<}d-G)1|g*FU-d@nn>c5>AR7(b_R zAHFFpA-B5KmX|J=#~)|l)2cf&wIs@P8kGOJ$K`)nNE?o`w`9@*R#s;P+nZ2LwH7C3 zM-cq74tA8~lWxEMh#Ip_P(Z=~K}yL{)KdLBl)=w?uO~2j^_%2;2nBM^1l2;i|2hi&|9#&Y?|>wfNqz&+a~4$-tH;kMpBl2K zXdhkyXJzM;3~$<&DDIP(a?gE}`yR|4p|Kpn)2I;f;>{x{-NN6rClt~KUB(%(sG^unCKw4Ya)c@dl(e9XOnJ7$_p z-WU1Kphsiu49FhANFP;j;|uHGIj3jLEPL7r>2kC~QvuxH+=kl~%n&;ie5!+)``g!a zOKrfG7Gt;fEqt$C*+kqsaPr@@;898c_W3$D0S+#xoq!fR(?@kMm9469Vot@5Qm``{ znVvR0w3;enW^5J~@VC3Af_Q9t(at{PzfTGKr&NFrZ7m}0pIe09II@+-&sGP2sjMId zJ++Xya$x)Q^mn9AZFmLkYIaiv7pgEu=lQT+o~0-u&y}dZ{;M@C9GiN6Z2TR!PNLkwY ze~X;zUU|`f3wg`mVHGp}m;66>ajcT|)j!8Kosy0gtbHq@!{oVKuOG;~@=U+h8tQRF zn;|$cT~LT7bR__aRu9YrEk1>!(mo)ZP63yq(l>||7&Dj7u=HUibHj~S**U|z9b9UN}rCgS*3g2#z|SF157hr_OquvjrllhkR?x5;dcBQhn}q2lQY*m z@a}?XF{CU*C5xfO-bZDWm1W_@98oQPX4$S*Nm2;6N&-xk2UZUQaw%`0(Y>eSB*1gL z$#XfCG2&)^)bDxJA2Ww>On1w1&6Glx2Xt>^D$%xLxS4CHU6T^`IYhQj7)jT1lqA}PlD&WnP$_# zzdIi2i@LqrP5~X+Ez6{#_sRhp)QW{>x;833zY%JA!bff1#B3jT?H^f|1)>JIr+(I# z28w4o(l92tR@Qa4=jXSblVGx`pZ#TEq)UaU(Z6jsdpay5R1yUOA6w_hCB9Y9Sjk#k zW{}9@R|FN?Kt?eEoa%my3wtv*KV{FytJ@56aZik?lkT*+r|Z$NnI7oTN@+$1NNck& zhQz%sf`mx0RL6(#&CfN>=+!pW^!m6e#VfK)%2+97x;sJ4N9j0A-{2y!nZv0P57qA) zxxuSTKo2l|(NROpBQyNs@*O7Pyl_mNcP03D-*lNtLAGQ8p$W`kUVrEt>@#FzN)ecT~u1Os8&4WSJ-0TuE;clwPNiY-z)^vQuS+d%U^Sf#L%|J{+P63+gF3P z&=l>vNPGI4kR^(}z1r*Bulo*{kQt4lt;o;kBsq*KEfL0AKfo>t_Woq=vi~82SMchV z&%YTqa|!p+NLha&+%Yv{2teHCJL=g@9RY9Yy)}*MZ5FoM_6c$BHK#%inEnpx0^5E& zL%KlKU_N%EEH>ZhqV~b#@1Pb-)6!k!CJ)!wW>V!!aYd$c|V^=Ek zhuhLdVyGR73nj4&JyFoJOB;a?WFZ&m_Ld?y)jXjt)br5AqBSu`; zPx6&HhGe5te`W2BL~#5uCZssVd)`TWJ%4#kB1HsT3-^9sNT|8pP2^z|zQWeR-%n`tOd5D?^~tVdnW9txBH!@7(Ft!^eEv@dS;xQq!x4Sj=xhWVQt zvrfdG(AUj1AzKg^vJ=Y-X!S|x5#$3nWz-%Tw0dBT>rH~xLe|qgF4E<1F!$aQTOrZZS-UnzDLiZA6{|E5@ z7Awg6PvDpT2l!V=R1p3f_&30GQL6p|{}zAozrdfU3OQEyFYkNb5#GiNWSo1bonVfu z_53J!=z!Uf2qt`vPqL3YZCUkJ>8aXE6IlL-_m4CG@;>6fybqK<*qWF#K%SsZ-54ap zngCB_o5cdU$N0GP{hhV!y5SOV!R@m-ywZ!qJ*haadlo-Gw$6jEO~#WhmN%PIi()dY zdA%RKZ62rB8h^-Y!>K*k@UsLLT)Wc|s4JNK2k#sI<$cA!ydM!i=y9me$G)g*Ij~f- zm8MgzP6f!6tkiGQ)J0Ke-c< z7Kj(21_B>6S&f)Jr-Mas%E|`L5Hmm*gz>~#^SPq+gdOqf0uMNa{*t^1So)rw6YKEK zuvv7!EOMq$Fau*_=KH|T`T6gD$3ViztHkYLK3?!Adqhevfs38Di($UZsrS~9h8Ds{ zyZRx=iXs)eiat7e5AjvSF_I(*#Jl_!j;Nw=z&P9iCp-JjP0S(oODavnBC5Tu#>m8L zKY@Y&0>IDcbdEJ*T#FXd{^xkZKKo<0PV3fJG;S9ejHNo9c{udx$!REsch7u;8b1S} zoVJ&UJ^{kdwtAHmJE8>n`pP<#Oj7@Jrrby8moL7cg9jYzVq?jC_WhcRv%%?GV87ui#Jrd(|OYuNv5 z%)i8}2T&O#?4BzRm%g@jRH&VdQ+2(5!;C58qFv8W%3*=OP#+>-Y1V;w8E|1);y1D4 zNn!SYCZIZKqz|*uw$=K(#TLUHSOva6nkn@*?IQ;*CyS%$Y3h6;b^IJR>iXW1S7v&! zpKk`IA$)??=!lWB=-&)9*5&tvoP%v^7;&j%u^K}2K1JwES#VJ^Z&jzf^E4aYBUUV{ zhc$Y##pkBHq|?gcbi1qH$|M;JcqUXE~HNJx!htcwM|a^@<4UQ@?)W~8~9P5 zS_r+aUDFY!l#nyKk?_wWkM3gqw4wbai%CX9LkpABNYKd~OLyKAdg#c;NpRM@hblA` zVdO+I8;rE+xxX4n?+;P}Nx)YX;owKcWN2@lP?}N#3B4ur{!Xp8jF9)A8<^O!nbL)ms+*+T;eFW8?D7~d+#Zc!xU!XcdPJvoa&hmh+aP@51L-K!7-o|ZVc)jPT z!ksyJwLbC~(hi&qw--Lv>Z`F9g}I#jK(M&muV8WS&Oio3H{eUjAGk}xw9t`(zbH=* z7byh^UNHCTmjuKS5E2b>3S|5vHF6N78enQnGyVHf!ZB-Wq~&w+-+4D7g|ofrw#c`Ta!J^PX+WSLYXCDjvIrpVG@EQL@ABSfUEjlE>w z-=r^F-wT*K?kGIp;a&dS>Q#&+on;Ev0h$KJsW6`phSra3(~B-nDc_ zI3mR32TIsx7HlP0Brkl;U62@;}Qp;w%`OF}~!;A3oVz<21 z08NqubL_e&%p7aeUbRq74iGtmmM^s+X6VlAvlH6oW8hG_{yo_#&wojLw_0kic|dC=)QyB1`dF>Gg1gGL}ODofSB8mJca(NFmEiFd!}4 z^mclelEPEEd(a(@=+_qh+V!qt?uoA~-i!#@9E&%qn0-v`&xe$v9NHh0sj&}f9A3yc zwBJ0FG_d4o4C9YmJfxg?{;*gYbN58hml*PHegORwJOlnqNzoQeflU-K%9%{7#>aZLoO=)h1&eYu^oTbs-Dx_ zd2hH_^1wokd73~c|E0X6L`|1>lzj5^9-rurCOlU(^}<=uBf(N4_AF<2R%$>BX4-v< z@~>`@SG$7KxAvp^y2DzczUWy7W1kZe0|xV;#XN(Op~A&ZUR%`H!|oBw%P)F3h7UQ> z(Rdh|C`;l7Z3Ff8&Elu}ace>m-stn4Qg#IyG1C3|u!x~vdW;!c<Da+! zhh8P$SI;X1QYcz{bo*aSOg?0k zgK$91u&{c*V~S($+Cg&#n3x=Ys4jr~rU2LXz$b*{^sigx^T5P@L<4dtSkd`BZ8iYa zL+pmG-z6X(kh`eFqb##)V>{%S3-Er=%?nBF^fh~o%v;@w?&R2jRqQ^gd|0zRaF)!T zHIM^B0c$zhB9NLM2ih2yFj?i<%G_ZvU2s4B%}H$qST2^~5(|L*V)NQxbpbk0%lWzB zV(S1D7+dE8oL*!)ULa7}0|EfLM8wbkbJ;&7xfb~#K49}*LJS(*20;Kh-QhqY;NN47 z{%QV8N$HpLpFM!tF<|2FLQ@==eZ~;L{gR(>f9YDaBY^u`b$`Nr+KjcRZB$uD30=V! zjog`ajyFXuNm;WT4qoU?!ixOBwtkX)pDNX?{Xv{UI&J@5FC23MkGH68eg%HL8iz3G z9X(bZ8P^s;wlEjVX>aa@EDfyh82Nm2u^Bhu=T~mMVds9uZ>EeYu1}`G3E=%QBo$)z z!E7gQaTF2n8vwjtfR-$r^;m5ey|ca<-?GAqTTAx(QY?eEXYR#j^L2Qy%HJ|SqP;uXSW;3Qc z@9C22xq!RjH;DUU#~pI$lw`SCirtMH&Eu^rr&JI3sGnq=#ncjfus-m=x~2E{FwSj#d9mrd}dj-AXrHW$5stO-l{ zw*4K2Qwxr)pYQ`HTw))DH4s1#`{EBVl8kK#gkOmb&qd1VIm?}5zB??gSD{LR&le!Y z!fb<$)bo0KL!Cp+Xy1IASXQuKe1dx3fV?UwlhhpS{o4z{vix z6^1w^xwteLY|*$*R&x;jj9<9fHEk+q^?93caLvAsA-I^dW9d;`>Onhn^@B9RLNU94 z57VariKJCZq+vIk2V3~Hi&{KNDtx0J($8D5%;xa7Ri+k;IlYzca@HoNK91R1C0ghh z9rk$L?jAty(JFxy-;@@ASd{lbV_n#Xw`lu zb(2(+oLzr8MUau3Kw`L2Mix0mnSb)#DaC7CX=JsZJxS6Z>ZX|_R&1DUs-e%%7$qdl zl+s^_m&}OYkoL>A6}}l#{h{Kb4+nqM^y3c!c7C#(EVGjcZ}Tr)O)0C+FOA(c=2HCY z$zJ9S$48F(PuCJkCYezEFS_hMm)%3&GX$RNS+7Wk7gTn&aLEY<><>r>Vi(%Ui5+v!Aa zK{YO3{I_cJW;{1{gPA{tVd^)Dn-5uIGa?wyQ+wNoU6N_Aw>V=fn#y;lNaa& z$d7a2g<-r?!!qB4lX+*N_}eL)C&JgI@&iiySu$|7LTa>3=SJc#Z$2135;$Q>>3#e` zfNlyZluRAur?b?#?FSyl4xPZicU&Ahd??}FD-LNc$(v(3}5 z#^ca0U`A{rqTKMX> z4U_8H7%e-QGOT-MzNaxO=K(cCil~h(PqO%?<_1Z|xAmNC6~j|H;V+s{R4elgxUA#y z(${kQiU=L7;+A)$lV6=svJ!E=A5^;NE!1NltWw+ewGK86<MXed zy=K&sj`&0k@px%C#n{HhCHSPTnQEN4L9O^jgXh*f04!jp4NgDo!W^Fh)zG zb@?N`I(+dCPqQvRwxwumK(T$wgM!iLj@K5?`6j&ncEH_UKY04UN6k9Y-eHC)r*7%c zE9xI5Vc9kLZx-ZCBo%B>ox=&z zLkNh)Thk&q-aKuiM0qvhkAH^Z0 zFala~WMrKLHbo$aEwIPSBN>RpNdd7-fF)J}{JjxmAzvo}#9kiS?+O(PP>GW$Wa`Au zK&J$12?hrS`T1D+cuRQ%x%$XLXeUWh9wbmRcJKRH{wt{s)3&rUpuoqt+D z)+*z!6kI8ufOu4yAvPB{VkbgR0a9D{D4|dgk2)h1=L|>e1Z{(fT)N*|q&`&cEQ;9u zIY~mo`MaFtlNE$B;QpVfIQA&rvxc->BoI4agJ83X1@m?r!4|sV!iU)T_y!8_T`9P- zwud@gR7h!@AdCeEBjt6&%Y0q4H^c0*yJ-#+eF38*gZuKETyG d@W-hT4?>bSG}a>rJ4W0NRuV68rRhc-{TJs025JBR delta 20111 zcmeFZV{~mzx9=OYNuh_=T^X|RhefGKSw06GV`=S1= zs`pW|dK;t78ujb5Y7VRehfe^b%1MHPp#ebvK>+~)5d*!Y8H-`pLxK^209PhZKu`b= zCP+iH%NP}A@rXKl2M*z&b2?-x#N9w^*#e)-8tJ=Br?#P4VgxNVV-3I zu|`S7bJf>JhzP}{sm(VXBpql?8GOBANJu0bt;SVLxE9Zb(ksvxtyGtq!Q>_r}=|Monkk(#fWiv$p4z>vuyxXQ1xuJ|oYShdS=14C+awRbGH_hnF zC{NUM_+zoM=hSPOm9Cc({Ys&3^9(+I&9PVfq49b{%(;?JW>kT? zF@DjyLco~4#DRSl5J7RmZC5e&WvNBER0d^;zCaD)+u({cW&GU(8uKZ0dZzGVJ|gTS zpQKC?QvfEuEqQvnoxSY7B8prJ6c+IrGzK|*c`h>)=Gx?6Vcx~ELQ=7y`7jLsL0)UU zj5Hj-Suau)8tRuF!VdQ+6#&PW*#6{5k|EoUbpQ_*r1~GWOp^6;;D_*y@dk>k)qb1b z502>*rmz;XHVX`xM-O2?xp8M`66NZnbu_0M&+UBp%Z;55*c5FcK{K}|v>BF&r zKQSrrzmRlS>#2?nC%Yq$V45{3F?WhL$qO())3&9l8M=1%pEgDK~qegs( zT_)nSIzNw z{1aFu=Xh|nbO764y`giAHe>#o-mSk2IFCJ`ZGMuR?obBBtg*T!>&-#_dN_Byes-mw;MirXq$S=*%$E0cDSKukMV~ONmhJDb@2xtQt=hrEI;7esK>h zY8k8-^F3xMO0zdALKfOtl%)%O6yEw1!p{s4qIUN;ShFBO-78t!l#_+RJ; z-bLVi2?iNikID=Nb!hDs6_vm31h0S8!=ZsK;86S;niF$z$YaB@w6BpdexfMMc+pN4 zd&zv8wx*s8X-v;uU)Rk*_TBgsP*fk4fk4s`t)-tU=MowzyfnuMdw8*8qx92gX-52z; ziO!^4Xd>ULdDb(DjxcxKK9TzUD-riE(Nq$Tn+hObZ75kU67Bl*8QwLL|ALpuFfnRX zd=!;du_qdr99zGp9%8mSi|;a$Yf zJOL<6Y1E$+?L#^M^F)d%5g4Cpx1qrEB>E0JKyivwsE0B{vsbq_jKzQnO%aJ(DJDQG z%mDySLP9R%Ks0I~;{OBJTZ8xKO9&lp$MsRgJU!1qTmSK2%law#+P{eH6l(RNQZ)us zixeyT{SFI)OzL#nhW7nN@z-g@myh1NEKQY0!&b4z7ZNIK{hg4+2rJ;pCVMn#Nk)5Q zCVj;(m1gR`_0J3h6*4A$m$Za-^~tUh*_43!i?yQJez$R(0xZ$gk2=YH-DY#TV_WTm zD^{2Vx=`=IeisZ$ludcPKO*c814RPX!|Y4t#gQNpkN$Q)h@cq~yLj z>5U3Z&|2cmOK#NjdwQdKQ05j=-6jb=8&PdM+zaQK`VMmfc-Itlj{);c&0^ENWH5lT zv27tDx1wtx2kL`zOoZp0>E1+i2)3Or(WqbOzTqQ^qFF(!CH|+1p(X6FBt8Daosf$m z(505LY|mk5eSCc<8rtegzgt)%WUX`jF@3#|RrsN` zQ|A7n>MH6w*J@ICFI4B-Rlg1rR$c&3oJ2O@zf5I^W&*F_1GQ6+=degHAr_l3b)EXwSf4T zSwKh9Nx1JtZ#lfhr2wZL6DmkIL1rmzE5F;=6|DDCWVb30dM$UXm!{m!D%G5f#-H*m zjj~uL`aQnOpg7$$trK)fNckFD0A+c}5S$)=5CxNoL+i_Ti zhR(=Vwu~2TsJCt79=Ey6v*Zkr@(L@W)j7opq=ZN(?U)Ntj^k)3`TOHdv`x&)e=*ob zwc>}9zkge}my2d|Ml>|#3hqlGJV9Uo6SSrc8rVeTkxwfO6irJ@h zHcK*XuNj!g>ZjE&b0upDH%!o9?4S$VGvVnE5Ir2Fvh4E<%(v`-VGb)y+^(b3Drr49 z>$uc+0;c-dvt4vu3-|K%W`7AG<=P@mdfHqBd`Uu!h!jHn^yl!ohk#KbYDrY4r(Bj5 zCMSPpWzWA8h*0TbDmf(&Cvv~#qZy_==-jJj{fMG+6fqat5N52f%JOW%c_Z-`xRJRi3W$HUIWspfb zwwSTS!gkW5H@OUo(904YHK8^e|8*HYpa#@mF{NUS42aNKBO%Xo`L^*&i%Ll=RZAK` zR-9PyrIVYRSMc1nw?w8JP!n?p%;EjKML9I}858?ikwEeQix78AsaMF!24 z4A5Q2wuBUb4bpGrto2*OKpPULR}Q4j^c1lHGte|4;ep$hw$>YJH@nYlh5qe&6&K%6 znKlV_ZFagdQqWF>hnV6&lRAiDZ!~q#92-k8&HFoDW$@lfCzXWb#N(7SHkFwlM|NNQ zjMXje07O)BkI*Fb_`_ad=!Dr@oKkiO!z(HuaIYRf1I|U=5GXFqB7N2gVd*JOv}!yr zN4zS2H+u4!(BfUkBZ|;GDaTNMzv0Wz`34G>E1_*TA@FwComaoftQ9Y(Ny{fsaW9Te zVvfI--Rs;lYx>J_^qn7X(u=Nes_5n1UHV>K#;6>)l+22I2iC}GtT(M2#D=syq7dxQ zr*S#}{_9WuYqhb56EnJYZ(6#cDpSksO%K)}p2a%7(5HaGTfYmYgW0fKcfL-;$(-`4 zrkd}P9?^Da`I_(KGc`C)l&3l5sF zqE7vHi+Oj}jC*Y@o$v2OBj>CwFcc|U2pIkVB;|SM`sHe3A2g$?0}m^!DsCTIClzZc z{CVrn6Be)K-uEB%o&v|NC34c&n;{zdku{}?=uQmKq??|;RuKO&ekPzAjt=AVL!%;f_EF6@FDSv31-s) z-JEM?q+5rR1g}=m?FK23d?<&cXe+d0Q_Z&88CUb8#U8cJl>C1Co$txb#=M-(x>evA znd90WuIQR&K@Bl~7|J8XC6_{)$;*q>jCC~d9-3LKvqZ9O^*>?uojq@ToSM86g>1%O zL9OHr1hFUxJKeE@h!xM{g;yOc+m+D(zm?xv2Y$7u(nu)_)z^d@E#^%zo2_6N>kb*K zqx@7uc5~9p0O#U4fk#~zscxjcxG9H4Cyg@mMlC)A@=f%d{2}3VJ(lA}-#zIiR68lk zIvnCWFS0kecJ=~+Tb|Ctr4K-L@A*1!Qv_-X{Uh*Ph~WwTF>=yQwp*8va^IT=a24^Q zl`;;(uC{(IRiCLQPPSSyp{PZ|_n0C{wU#<3mt!vh&h|i6!nCY~DQ-lOS_d@)L({(O z`9$Ac)?)!EqqfP0n$v>wKgXD@Fd;UoUj6U{n({zL7Mdv~_2k4dHO|L~cv*L3)EaKq zTHL>D%P#pdFju<5&=F&Sw&Ya_umE!n+HWZ<*;2kp%@HgPB>SO4qeE+}E#F=ye|!Uz zn3_Dl#Q+QTCmq4M%cUu}jqiL*yI7u7_;5WvYz&_*!<}nWR8Q=U4ATV;0tV3SA}H1? zw;zZgKlEoCW@TK**v2+AF7HQ^;dUS$q5cdTxY8ptlrGxOi9u!@)!xWI09lDwPrY3GVckv(n}PYEG*?tI@K|A+9Sq>;k_rDxj9 zso1(9??|)EH|42VHDK+D@pcMd2_6?Bujuz^o=fCAfm3stcKka+81Ww-e~;NU{Q7H4 zj-2eAXZf9vH{I!J*f<*u9K$XWnZLL=X9SPX=EI&e58Bs(8P&41ou|iSZ9+*D2o3(qil*Fw(m8Zd0+)gw^Sy8XIE(8;phkFo+K9^`#*$}I<DejEqtvfsj1Lp_`sj1vJ?H;PyHd_!l03y?fKfHE0_XK)~Fs`Fo z#XyfrYorhX(3~QnrCc;5$i-oyNk8Hw8i;UMC~%rjlk>dUDRhrJH%%-;?iBdT3TPei=@C>*5?btfDr8b#dD3CY@`gbh8oX7 zMxjtw%AV{KyG4&A5#)izrF&YRZ0=6;8eJbhyS(1uI6!VFO_DO(c}es|qp3Ddn<0pZ zpyxezr8MJQgH~M3B7O{IgRVqs#~q3+$vqrW#1~(uPPE}#Q%I@U-}6i9VesY$n0WjZ z(3Xuyz<(crQ3>k;59`KaZ7}tVPdr0m%F8*Vg2-ksI7p>bBD|v~w_=A15CSzR z!m>2|GMW4^E{NRqNHsBuFYUjrP6l;uq)0r0FMIqn+!Wq-uOG7rT)lg<>BkaAz5 z>$|1rLc2*vla1X3&iA&7XrU9P2qDv8uQ$a?*kcO(!iysWUY%f~9AV*)5D*r@3R?Dp zV|4s1`}kQ;goh3Z(`?-HxC{maM2eWePf7uxAU_=xofq_(jVDnL;Tq(dN3lkY6ZR|I zYZ?4}i;g$@Nv%n?c{^Bi)#`ca#zQcD#mAF8xZ@`=DB{dDfN935r%d6XW6c?cF|IJ+f^!-MrB#{l8&iGI7A@0TT_gj(l4qqpKYLYD+NQ&v6d<|XwuKR1W<>4 zLFvvK6*Q6_rP=hrlT`Tym#^?shjv`$lMdJSr{wK*fizEI(Bit`z5m5!&_oOdBlI-Z zf`XA0HD_*J4e;&hL8_OK)4exv*Bd>cNl7nSzMVUU#|_`_30@$zc6ix-fOi;+Zra`L zlRNu*q+d2{aCaKqQ8e~Pb^f&%ZpaJEk*OBV^2?>O(_`e&P_ji^!KqqYa9pQNKyTco zT=s2cc#4u9mws4=JSZ=8nNG+9ohyG4doL)sqzcP7}8 zDbEvb-9ReHH}gp&2vtN448i_dV27qW>Ab5Gk3S;tG>B+|Q5^(RE=qG!tgU6{5X}Y* zH1s0+4-PjWGma;}Q5d9cXCJBREzl%We%uq`cn4RseL}*a)9bU!daPBB+zNCJO4Pa%H|{aP4QnC+zqtPTJ&UwxGRnOshs7T}ySv>6X-V z3t-!10U(V%_)#??ZcpW|h?c+lC8DRtu?gO^RtI$j&C0{&Py!>=S41oTGpPRJSg!+N z!n0m+ZAg(LaP4tKJzcmGHDZ}Qc7jYgEl7+|`-R=dvdH`-pLN|*)3MOu*8@RFd!*B8 zpmjudE3PDx@k80L(3Hf2wXk8(zc;a?jtPX1g_8wpoJdgpQJ<)#fa>56vEw})d0dI1 z!^KZTYY54v6rX)A$l|U5(wVK)D&-uH`3I5U0q__mSnz|h_*h)IKI{c2hx}8Pd20%O8 zZ4?zut?A1m^q1%Yxxj_lB*tbS*daN$06$Ap`fQnHK&Q(r z!Y^4Tc$37lVmOoM2E=L9{icDOK?92BNFlB&gu_?1SZyaiNldL?L-qdiqM(KqTl(Np zHq2G_4KlSx2e*(tGXiIP97r+Flbz~OgF2{VGJ;78WSlrEanXcSDN%x3P_zPa;`)=E zPm(o2^VJu40x>BXG}MBwI?4C+W{?m?MGBCNS?56Vy#jwFgvu&UGU|+S1J$gX+lZv# zJy5cvUPDPn0grE5rh47}xzHcuj54x?VdfYoJ~=VGJ7Gumw)vJ4o`;WKcknP_M_>gy zn||F<@q=~$X*vxXTbxGgIQ1rdDiSnl=xsO$;L)68gO!33Av8AHl;0@mTXyKQ9Sca4 zr&^SvmyGvUQR7o0N7lM+^dRb}d-l*qvAAd*sSLYVxhO%-l%v+)1Y7<|7eyeZGc@bq z_oP?hmn{NAhvv=2oS8w~g|0cvZsq_9<-%!SC4V_t(le){?bp%%YiALCv^(ZLX%hS? zj$*m+nlIi{I{cDUJ4w-5d#59h9SX3lrKHxYWK{tZacpe}($ZVzMWbGd(9;kA95DX+ zf)LYlDqgbjZX#%=%u_ru2?>*fttl_->3L^Xt)1iY_;Fz-u-am*-@1~|7%suS63$$E zHW4y3Cpw9eD1hfqA5q8U5^}180~G;W_of5nf{uIt7{z*9;$7bOM;k|`hZ%7B)LO1~ z{PGkQ%}bJjW8Z+a-*=cEK#8t&ZNA$s=!l_ZYIKJUltBCI*U3oAU{9z=u!u~trsG)L zu*Hs(`fTPcnwqH*qSwU)HqrK0U}{SM;cL<4v>J=5yFISWNZcRm+CK2)VWEPs`zH8T zv5h?L2-kY|^}JW2=O(V%v1Y(5U-sIW4&ZvD=M?eSy+790@kr4R_oNLy&1YjlYljko zpjTeVPD3sO*gGhHzS%`wckP&a*(26A?owlj)T{b1vtoyrVtUB5KWQcbN7Xm;l8Nm( zvFawd6umzXBlA${U7tJdYBl=Iy-DBP+aG zAs-Ul#BkcHcYEJpaIow(!+**%3v%_Ffq^0bdAHHuXM0_%#HNYcC~GZe+?XTgoQ&-_ zn=oAmi*90&L~_!YQv!t_A=#$kxx82ltUQO#ZOdZ|2)V1^Zrdc-`Yr8@yo#CU)UcG? z9;rxR!9=)yEnHPlk_51B-;tZ(L>nr5+7m6$IX+%Zk`svA zyJoJY;sJgL;c&>3@U)(CU9jF``=SgVcmQOQq!r7vxMuY@)l+eF2H|JOXTF$Z{vkeK z%^a3^2T;WuYa+Jr<@y|pqpRhChKTw-M3M^NhA%RfR6wtv5(4}~X{m|}{JLPL4nSW) zRKS*@SVsl474q!=;3**mFKHdi#m=B<41`orJbDp)a{j?77QkS%UJjHr@(|cdwMTh1Ipu6hA(Lxz@o+31 zipKwQv;2GU&YwiW3Ne0hwE$x-FCzj6KLIxDsjKU2T>F+S`QqRqha?67`mad?=PVuD z<$Kc5O?aat1z6keaUy;C%zZ!(92Xp9`6gGz|Eg-IX)gX#{&r3VQ9vk%IxuEq~vkMrH1OgEyeod_WghJi&K@zj-_g{lqg`E*5mM=5UqQ+_nKMNYdcDr zk}8L(hsg(eN;qRR%$iP3SAlrU;)@B%Z&q-Ntf{=!OM*Ae8?g z#Lo2AJ^{i{&fg%so~XZ|5c{MKA zj=fq)Xp_ol(dGMch{is>gu3kGp&K_A=qx} znNp)?!25@(QFA{Y9unCN#9El0i`AJ|h&*ud!Oxc3i9$xnFnBt z56hpck6-t7S-TaCfjVBsQrXIt?o68C`T)#QLCAr+%mvs;aikXcoK0A=CeY!~6_;4B zIAnXTpDdz!Azhe1DF*BVoLg8(e2_#xz})#4-0LM>Zst&JQ_Rk(99kfyT-!|C(7 z$ip1p9b6f9zBXYa_#CqOROrl#T_j&q#+P3HL}S_YX?2RMqlpOgygRCRxeSmTanaM8x%o zESJCL>|OxAH&Og2<0kwRhXoIqX*}Fb=x1gERK`#L24zMHx$?h4I=VE`6cJ9p5P|7D zeFd67KPQ}^AZAs5x`6j@8YJO8w>KGidJCSg_~7DxkO>Rffu{>cL377V?{$UHIh&jW zrNX#}Z`&E|5r#WEeYJRyLLleg^9ikB8LaoyA>*@{Y$`@>g^KgaZXk}LYL&{0HruYz zC+(yg_sojMmdj#VY+{aWnxrrB2zP@1*>IuvmwM$xTxUx71aYl1R$M2V6+=Dl^2{3L<2yek2Ti#`FI zl|I3O>m=d$2Ymv7`x>w{=A4rX2Lxo~1_XroeQ#WC9gG+qo!qUA9U0uLtva&Q9oIQg zhPRt7x;errQ(*3Sx$yn!1TrLQg`@XI>++$8dRtm&UyI=U4#Mm`xD@Mq#f@{iytV$B@2C%qDWe^zv(7V5~9?zP*5$a0ulyd|+ zWR*=r4lA<8?(w|70|EZ08dNyZ|uB=ENt7OaN+d zfZWSH&V|q;&Vk?~&W6Av&O-kq&P3lMP6+PweXL=#Xv0(z&LBALf*G81$mrRv$xU9d zXM0y!XrGNuR$oF_*Pf^S%jm1`*6v13`%jNIdsj$Ho@Olz@a5ko=FDowu+$Ms7(6o( zTfJ<_G|8hG=58Ky``8ks&`icg-iFw;t9G$acowmk=g7a2jBZ2ov5E**+$B?B0Zv&H&_hSzn+dgUILNNL(qzyu zlfEi1cM1{0NN}ftL1}n8?4u)l{i<<@SG4fZQ_J=fVQSlE!KwQ2)9`R6ZWej~rhZn? z0PJimHNJw={BY3)Mf9kWei|J4?xg*Mvh9B=%53>Q~FY{y)RHDv9MQ&nA&(hwDVz z2)6Px*=X$9c}U#9iywOjU>Bube%z?@S9|`bsmYo9ERBZHDft?9#PXrPOUs%Xvsa)s z*tLieR~p<}Eg0!@hR&3QtAcQsG<}GwRX+|x`LcXig9mziZgMRgp;_Pc;&`|z4ZSCp z)GNup8sAN5G$$>KdNjM{?b{G}C)pR5I=woBR8>RJ3IF2qvN+fefE9a-Kr=Hcb<{Rr zw`6K4XdC*#;^yS?j!czPdg;$#2sefZK?spPLtca~ijz_?`Qpl15YEkPx_Y zK_n>_atTpkvc?ItQlc~=_^a)AV+M7M*%=#F9i3z)JCeOf@^Xh+fn0iY%p9e6Vl{Z| ztsFYk*A}Ftl1p(tz>VAw#sb$4qyZ#ht&6ZtBuzhKE z-jf^2nHBnt>mi%n5*$zDdLGOv#gZ+avZE!Q(?1m&;o}5fS>$JPmef0(>n}4EXO;` zKcbO^BH92}qo=eV>GVp;J#N@rGL+^gAH@nT89 z6BAa)lLSaOSy{90VvS!|F1w_q{S<&u-Q_SL)*a*AODmAJ(M)2T9$RP8QQcN5Sk|Ae z-t$oht2cIR*dCI4a?x0VeoJ1x1X+Le(%2-Kw{Ynvt(7?q@5`Vrg8Yb@4BcX>vTgs% zv{gaYL>J?s(Z^EUPXD9)fPQ>GJGo{8k(WM7rWrujes4Eg7qaAMx54g{jyKKx9NjJ| zZ@8ghwfxJ1ZasL%ewk`5{^ax1O*!~ZjD}SV9d%~UIq;T&m1#wYQ9;E9-5x0 zlTJK4(iy=Zs0KO63bYNVL^;3K6ggsWdZo}`u;?V;9$2PKxjbH(l9?^BlGr^`C2@iO zuz&X;2Km=zi;mV;Y)>dOg}Hzr7-X|NK`@OHlTOZGB{Kw+N@iEzU2c%So&WYB`C-rq z|I?((194=`6NJ$y`A?I^mczO;*(qTmq0ra% z0}~{LZ~??1Y!AYlf`)fg2xs>p+a)aYEm%pqkDP!?V zC(x0a(0>UR5mBmZ7LnwrHueaqalfH$l08K@SH{by`=qOXxCqhfM8TOckjoTiC&Zh+ zmpQ4wir7}upX{o}vT!|FZ_#}P-P;-<$plZ}0hsmISXITDu?RwG3fc4$C|1 zh~oYsJ7Z=!$_8XCM+R=I)&^~@-zG7qJa3|=>JhUn!`GRe%&iqi?_C>Seya))OvSI- z-xK<6)YHBo%-jTHR0WOfE+-yaUqm`Qw%|9Z=B%2riKDW!Z;K9OFv zfX6CrA45Nx7+@pV1ZUs7%5p!FOlLW5HA>=UA~~blIBmZgf5G-6uli{tu*=2?RqoTt z;5yp5V1~e@;9VG(m_Yhi52Ttq^ny3F3hjyG4`o`9O$r?XrJG4&Kkg;Ue zzr{v%zwQsme+uBADq?1A78c+ii_Eu>H<#P5DrEc*iJxC=u`2zyj9z>XyKwYB8;b0Gg~eWAKUB{~PtqyzY~dKBbm@g?|> z<^$5^+^(R+2iydbj$d7H#IC%iwoF#CMWABMfnFuEoJ@`*q^8uOWE`|uUydiDJe_N8 zlg}cX>#be0FVI*-k^!uCrS1H;sC(?A$)mh}D~RA4-$qWB zD%AyKXg!I#Tcz6C@!s`?=kxRx_&9crORr) zRMMmN**d}Ex)9-VEFGqYT&nit<5YA}%JCwbdS@Ba0&_cH%h2LeS*C1zxmgl)y+DVM z544h=66#J-^QUzyXS(V($(2pa*`nWL1Snz#;{_wa#?pN2M53ouAl-vP*S6ejdGObt zBFj60q|uC&_tMXeSX_4ZRgT|xbydzM#&imc^Y0d^FF8I(#^Ppe-Lioz=?xXBa{P6< z=IT*waWpv4lbN&S_%kV%eIKto?>P%I5P^T8O@#?S8oklm*!0Z_{%xB zvS0s^NfJe1b)EYDVbUx?RvaH7Z@W%}G`vlD@l&niM^gfaMI}X2S=nM?RYsG|6_#Bj zL?$>{^xI!oq@Op*ybGQ;_>f;YSHAm?Hr2{?s7n$|wDHp{@lgG~lJ)9wgw-*a%VhT1 zI5Oy1wIo?~2R0u!{nnZd`R@!J!$}MR;r2l$vy|+Uk zs8jm98u)JMza0k-QcQ{H)4(B#!dfwq`j12gr>^E5zl%l!f zW%ub~@J7Wlza&k-cGe{Tp)Up_q^U%NwRle**}=F|RPY+7=F-}{6yfIJI{5Zk2yd0@ zH|B;ta|*=JwsQU{L}5GEgPm{`Z3cw(Fe#vIb>pK-HnmH4WBBI()Td@TV{kO7P`PlNC8?|1;gB>%^= z@p%Cb55nbc;D2QaK}4TX?!KR`TY~;?T!6G~CKFQdRnjXV-F7|JBPlK#$M1}a1xZBZ zSI~|jI+dCzo-N~-r^ZRK(8rlS!z6wouBl>o(Ubf0A}S{n@KBX3c#Ke@TFhCn&J)*H z%^#Z>q%}&14Rhh9Er-52F1p=39OijR;0LGZh4IEM4NWoyP->&(K|xim4x@s&5`aoi z_F-{_JD;+v)MWO?Jt7+Ybt+<`0ME$Qp!^6yrqBFU2?t{#ZzH$EPz?cU3oNrq`UcUA z4vuttpks9vd|8D&QK^nL5Q*MM25 zO5)XY{Iqm-eU|SvS4oI6C#LqzAw*Gs8Mw{W>lK5^PAevmCm$0qyA{{o9mt_BJ`4ZcnPVsQmO? zdqUq8Z%j2G@$QeC%z<9U>_fpK%z)Xq0)d`+IZ+bt7OeM{ZjS^sXFkN`c?#=A1k(^;216r$Acq|}ZKkd4K>9Id@IGk$Ui+t%N_;DfVk*wYp`C+?9lB@oe@B@|ujnHEX?$QMoRGWSd)3gkxM$ zvbT8(Sqvl8;*`L^X`nzrm%hqt7XTBIpH@w0LNkmDejil}=%d%Dx^*lJ4j&xtbz1UR2<|BW#6kqv|z&feLvxL6` zU<#RHIXOaIORMtU=`0uX)oVmco+$>)EzDoj5FBMtn@dLBds4E<2}ZKi0P#0^9G28C zQz4S51vrDpkV&9Z;%K2LvuGi!?;`nKXub=ySv2X)ES?x%0arAWh#d@eTmB5pBdS1pqCer&HQdfHZ|3z!OUPY2;gcQr(>}q}*0*mIXSy<3qcUo!iK?I6)l8gem7FE)A9pNM1m+%Ix)KGf}*LpZ*$2Hs4Wzq&yjOhAs3 zZo=rRNN?NPtu433pSe}G|6-M zzu4cXOPle{)oS>Zv3yxQtih8#J~!o?{mtjDAI8&7%ji7MrQ71|>2lnJ#WFF|Dhwu* z-)rq9C`SP@OSH+binJHRZL$v;o@D--O_$!kT$xb;|10}Hd|agL=u|nUl|lwXJj-JQ zNsXjFr1f-v97J@_JJ}V5f3yFInW=E`H~TAmvp@R(VE>$VW8#0<|B^*#^IzmH07R z2rj$CVz>&6eCs$th}8={7w(cW`o~8{q-ark15DgInwvt)N|lp_^6LP$uF4$4xEpFJ zw2m`5{$yj#rjI#+KoJgDJAqaao1r^2L>YNPb-n(B!^FX9#zC>>Dh=PJ#(aYEfs`f6 zq?rfBxb82NSE_--+~$gKf`cLnz^To2wJ1cE&eIAm&|LG~%92OyT6#U-%yMJJN|VT% zK10xM4MW6J0op{rq#EPbmD7CWdRKMbD>W8ZD|MFhp=bm2`Oh!%`-y0Y^rFs- zO;n<*3=yZ|i5FAq^1DY*%*;0a1?K_`8S|+C(J6^1SXEE;A>Qb$`6%330M}Iuau#YV z?kqJb*Q7l4sPx~=jE&GKiLt0(rnH=-J9X#{!^X5`R|%CwgOr*NYT)0Or-0gg1NS#U zTf`*!s01+~LahItr@z6!TnzprD8XBZ1?l%#_LR#p>G=uE|*IDX~p&(o62{nU@{bZ)9D`kI1&l`CHsEHba z3Pe)dpsn?xy&EOI8C(0Cv7P>5?8W~}#{LBw)$=lp}%fd3<7^Zws6cG>@lu`|ji z)f0LDo3a0e*rVTwUGfiNTYMunK;@gUadY;|$k)wn1XZtEp|v+pD01Kb4(#BciRSU1 zi@vntsM52yuIZN8e3O5R#pquPt;U7Z|B?e2_9_hvhkr>Uz`+HzLo2F0Sws83WTR?G zSyK9ckxMS(pUj{C7%IO7Ao&g9Wq&CChmaSS+b=4V|ChwCe-B$a`ak4}!%**uH zb+az6znZS&?Q44z0=&O`S;?FkEU;`GStYmQF0uO8x71`cG9W8;U152`w4>-0E4}Am zn+iPm@9iPu4+SBERu50ic(Umxh=KuaZIk9-R=Sb6z{(dIo^W&?dhqG23;6jcwxeq-q_*)%gfG@&-*2gei zJ}w42-+VL!ngFX#4v?4aV?qMjaYg;=pL0F=MI6i|9@+bBAhkd!w}xwJ7kG5P3<SEd@3n9iRd9Naz4tRxc?gLnz`3Y-Alq|2E zv>fmAip(kcCBeRyuZKNHbN93~?t8bV~b zdtcZoC4}2or7cTe=!>H{gWk_=QQoZ=^tok-+H==H7ukDs_!39)KFzD;^&feL|7Ot! z4YL2AMgKp?q7ZB4?xNq{HRJkgEh1n*V7#_v9}`;e733Qt`IB|LOK5OYA4f+z(~Ngb zdn_LNN+I!R#phdN)>12UJ5R^7JLmTyb*JibGsvm(HMCF)FcCdr`XqJC6JxH3VX9j{ z+|ly2Uw#NXvke`cqd~^`F4yN4unbh!@|G;w(3-i@P|5n|gAi;_5|XJLT8lD(yP0I0 zD0)oIE{IGNmOdPi6dt<`Xv3dav+~q~xeYm0r{D^DCBFio3FZU$SaEyI0gZXGKCv1> z0YT*_)OaVIs-P=u(sM?y$HRxIc0HgYCHUdq)pozP>OzJO;gYB&t_%eCo$3k$ zjZsBM#G(NYIYF6dQh(!%BBL3jC!#Ndk{#pX{aF4yYxArJ(b!Sf7_($EWxgxw6dT z>s}SN+upvM{&AG}NY1MSt0IGQk0=^VN?@r|$h(EWb82sd8PhFS4Y6-0EX}QhItZ@d zN&^X0+K8YIM#=&g@XnBD!5{Gh2EYPK%gJdXFF_HJ1&Do z&-aP@3I6X*FyH?y^3Oq!dTawGVBn4fIb*_lb3+thKv0Z8#P@3@=nD3Yuy4b9jW?7| zx-)dgI*!2&{%-?3M_Mel$XBPnEG-nlG4IwB^Ti_uhV$UW|I@~mM?>Ac@kvRx8v8b= zjEwLb+dCApros@au}*4?F=ob+L5xg}BELfVBFc;x4S6lmU}UQ#3S*0u{jDsKvKtD& zsrURWo%eqKx!-f2`?=@d=bn3?=iJZp(6b_Q{xZEl*5&BSaHf{>g<+C%d{w6{c7}Mq z3(ioS5|L8F)-&x21e6~~Izz7z*uD)OPqMC+=qinPFw#RiUsp0|r>WfwRF|=Jp>cZZ zgr@YXn9LpBLylTcac}g)Vhk?by=sq!l~xs>*1tZY;;8l4;3)sgt5QN#dq;^w<3-(e z>p}be319(nGp0y;Vq6Af5jVWKq(ia{2qea(xL|?;$$lg!5)qCkV@WzcX)ejmBs(!v zFum>2T8!Y3NLM}8!qNJwnK#chSXP9Ok85#c`8&GBTJ=hcFYCKDlhUKxUKJWjf1g&9 zX2e-yne)xZc+Hzg7wz&1%GIMS9jN2loR~II)81#Xl0IH^k;#v+WfaIf&MPkYULth69jLM=rOe){dJe5 z^xN8ndnzTM;Y${j;yI35|I%|#+U^@Z8G|2nKtr7t?&i&%SHi6Q{A-x;6?M7hC&-YO zy)li2Pw0_(Xqg@>=ni=d_c7(i^|E5@U z5;n5{1Y^}RmZaeYDZcQ4eTgrwhXy}NJl={O4;4NY2Vp*96(Gvbibk@=qQmyP+w=i+@}eryo@~CRIiOVLifELh!$P%=L}sqzi;L~$$|glDYaO#tW7|~xvvO$!>%)l@g;K+ z%ft$af#J0at2S1Y$vJtKWBfsSsFn#vWzY54OiOsxt~H?nwyha_%q2`1Ga63bjcyLS zh{uXLGrR5EY^1zusxDID?81~PS4k;EmhiTut_ZL_8x34Mu(XpaVWP#zZxZW6g6ZkPE+cd zw9ztit<`oFL+QLxoh7I>eP`2W?vZrQ3Fo!Y?wg~tXU1#LS?4ovPJg98!({qX>%-zy zk9&Xkxb!THMs2;;kk&h1Evh;i+&1DN?;Nh!x(g@ry>Ftz%BQSSJNeU^=Ag$(844j~ zS!Z~^e(v~e>C@{9%5KI9=9 zt4*Tw@vTO!h9%Y3tQ{}fa=@>xshH~aqclvPmr7BbB-SmF9Gz79n9ksTP$HkE!cmA& zn$v^zMU|}rtR(xS)AtX~&LQtwBd#2rcsFCAhW~^9!%&@>T+w7hx@?;`M&Lj`^wJ7A z$mSX>qaV4bP4|i(l^%IOdffg2)<&q2s#M5sE~BS@vnpXA7VfD-&(Bf6+%jrf?L~HU z_PMmp^Q{?7iw`tsgwo^;Ls`uk$0Hp9Ic(BM}X$r6KMm_gTlIZI{ieOi{NU66J4XqsM|pHL>Xv z4k)46y3C|g!X0K!S4Z@0gBSh!;{-Gg7r{QYO8 zA^Jt7d(g)p@fTlC2<&<8&08OEB={wt)nwf5Kr9W2KKel37M%7&+&-oj+9L3%Ld;$& z)!qDob#eM3#c*}czq?;u!q+;DiRIR+m(}IeItX^C*~GdMk%JcM-Yn*;8?wr?i>972|^7kiJ*Q&N9m1>C@2(D=Lm?wSa^to zHb-)0x8AqxMD*8-9^qDC73xf0i_?(*!jN^auczQ!UyK(;G5~`&IHxm1eDOJ8)u=qh z`PHYcFypZcGSul|Cf?~RtIkI*G|F?TECZZ>#?;kgMwr7ZDsHmBEi+-XB{_muD%i3$ zc}GNHxC?8Zh00hGIBmUyM+5X*imspPz$I@L=w^)J??AN*|L1Z7YXmvSMzjuhIN5E0 z^-93Jw>o5lnZNgU0R`9{4G6$b1VestWx1UTx${!q2GXJqv}maS`FJp3<|E59tpW7l zm4PU36$A$|d?Wx39|_3sRMSla6HQ>m=fJ^@H(joIBEH$mt??TDGaF!;uphGFlI;e8 zM7N6>1D*sZWaIrP2n3SeCIB-99uN*gHXUdXNPe3@0utEgtoUoTTZfU`CIqtsp18;Z zmkD6VhI_zWlI@y2V-G|Sl^`3YE>{4&4W+{os398iTs;STC&Hzxxot4+p5dx(ODRAB z@gzyWiL@6l{%cA8-J;p-QQ-Wq_RY^7x)tE}17{Q9I2!Q7Ns04v*A@hlK; G`S(9eoCVGR diff --git a/Apps/US/IRSForms/app/src/Printing/IRS1099Print.Report.al b/Apps/US/IRSForms/app/src/Printing/IRS1099Print.Report.al index 45e3568f08..f4b0da7de0 100644 --- a/Apps/US/IRSForms/app/src/Printing/IRS1099Print.Report.al +++ b/Apps/US/IRSForms/app/src/Printing/IRS1099Print.Report.al @@ -11,12 +11,15 @@ report 10032 "IRS 1099 Print" { ApplicationArea = All; DefaultRenderingLayout = WordLayout; + WordMergeDataItem = IRS1099FormDocHeader; dataset { dataitem(IRS1099FormDocHeader; "IRS 1099 Form Doc. Header") { DataItemTableView = sorting("Period No.", "Form No.", "Vendor No."); + RequestFilterFields = ID, "Period No.", "Vendor No.", "Form No.", Status; + column(Period_No; "Period No.") { } column(Vendor_No; "Vendor No.") { } column(Form_No; "Form No.") { } @@ -35,6 +38,8 @@ report 10032 "IRS 1099 Print" dataitem(IRS1099ReportLine; "IRS 1099 Report Line") { DataItemTableView = sorting("Line No."); + UseTemporary = true; + column(Line_No; "Line No.") { } column(Line_Name; Name) { } column(Line_Value; Value) { } @@ -103,6 +108,7 @@ report 10032 "IRS 1099 Print" requestpage { ShowFilter = false; + SaveValues = true; layout { diff --git a/Apps/US/IRSForms/app/src/Printing/IRS1099PrintingImpl.Codeunit.al b/Apps/US/IRSForms/app/src/Printing/IRS1099PrintingImpl.Codeunit.al index cd789ac4c2..a8e7f04261 100644 --- a/Apps/US/IRSForms/app/src/Printing/IRS1099PrintingImpl.Codeunit.al +++ b/Apps/US/IRSForms/app/src/Printing/IRS1099PrintingImpl.Codeunit.al @@ -4,6 +4,8 @@ // ------------------------------------------------------------------------------------------------ namespace Microsoft.Finance.VAT.Reporting; +using System.Text; + codeunit 10049 "IRS 1099 Printing Impl." implements "IRS 1099 Printing" { Access = Internal; @@ -37,12 +39,31 @@ codeunit 10049 "IRS 1099 Printing Impl." implements "IRS 1099 Printing" procedure PrintContent(IRS1099FormDocHeader: Record "IRS 1099 Form Doc. Header") begin - if not (IRS1099FormDocHeader.Status in ["IRS 1099 Form Doc. Status"::Released, "IRS 1099 Form Doc. Status"::Submitted]) then + if not (IRS1099FormDocHeader.Status in ["IRS 1099 Form Doc. Status"::Released, "IRS 1099 Form Doc. Status"::Submitted, "IRS 1099 Form Doc. Status"::"In Progress"]) then IRS1099FormDocHeader.FieldError(Status); IRS1099FormDocHeader.SetRecFilter(); Report.Run(Report::"IRS 1099 Print", true, false, IRS1099FormDocHeader); end; + procedure PrintMultipleDocumentContent(var IRS1099FormDocHeader: Record "IRS 1099 Form Doc. Header") + var + SelectionFilterMgt: Codeunit SelectionFilterManagement; + RecRef: RecordRef; + DocumentIDFilter: Text; + begin + if IRS1099FormDocHeader.FindSet() then + repeat + if not (IRS1099FormDocHeader.Status in ["IRS 1099 Form Doc. Status"::Released, "IRS 1099 Form Doc. Status"::Submitted, "IRS 1099 Form Doc. Status"::"In Progress"]) then + IRS1099FormDocHeader.FieldError(Status); + until IRS1099FormDocHeader.Next() = 0; + + RecRef.GetTable(IRS1099FormDocHeader); + DocumentIDFilter := SelectionFilterMgt.GetSelectionFilter(RecRef, IRS1099FormDocHeader.FieldNo(ID), false); + IRS1099FormDocHeader.SetFilter(ID, DocumentIDFilter); + + Report.RunModal(Report::"IRS 1099 Print", true, false, IRS1099FormDocHeader); + end; + local procedure ContentForPrintingExists(IRS1099FormDocHeader: Record "IRS 1099 Form Doc. Header"; IRS1099PrintParams: Record "IRS 1099 Print Params"): Boolean var IRS1099FormReport: Record "IRS 1099 Form Report"; diff --git a/Apps/US/IRSForms/app/src/Setup/IRS1099TransErrorHandler.Codeunit.al b/Apps/US/IRSForms/app/src/Setup/IRS1099TransErrorHandler.Codeunit.al deleted file mode 100644 index 80fdce9ad1..0000000000 --- a/Apps/US/IRSForms/app/src/Setup/IRS1099TransErrorHandler.Codeunit.al +++ /dev/null @@ -1,33 +0,0 @@ -#if not CLEAN25 -// ------------------------------------------------------------------------------------------------ -// 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.VAT.Reporting; - -using System.Telemetry; - -codeunit 10053 "IRS 1099 Trans. Error Handler" -{ - Access = Internal; - InherentEntitlements = X; - InherentPermissions = X; - - var - Telemetry: Codeunit Telemetry; - - trigger OnRun() - var - IRSFormsSetup: Record "IRS Forms Setup"; - begin - IRSFormsSetup.InitSetup(); - Clear(IRSFormsSetup."Data Transfer Task ID"); - IRSFormsSetup."Data Transfer Error Message" := CopyStr(GetLastErrorText(), 1, MaxStrLen(IRSFormsSetup."Data Transfer Error Message")); - IRSFormsSetup.Modify(); - Telemetry.LogMessage('0000MKE', StrSubstNo(FailedTransferDataTxt, GetLastErrorText()), Verbosity::Warning, DataClassification::SystemMetadata); - end; - - var - FailedTransferDataTxt: Label 'Transfer data has failed: %1', Comment = '%1 = error message'; -} -#endif \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/Setup/IRS1099TransferFromBaseApp.Codeunit.al b/Apps/US/IRSForms/app/src/Setup/IRS1099TransferFromBaseApp.Codeunit.al deleted file mode 100644 index c67e3def45..0000000000 --- a/Apps/US/IRSForms/app/src/Setup/IRS1099TransferFromBaseApp.Codeunit.al +++ /dev/null @@ -1,273 +0,0 @@ -#if not CLEAN25 -// ------------------------------------------------------------------------------------------------ -// 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.VAT.Reporting; - -using Microsoft.Purchases.Document; -using Microsoft.Purchases.History; -using Microsoft.Purchases.Payables; -using Microsoft.Purchases.Vendor; -using System.Telemetry; -using System.Reflection; - -codeunit 10040 "IRS 1099 Transfer From BaseApp" -{ - Access = Internal; - InherentEntitlements = X; - InherentPermissions = X; - Permissions = - tabledata "Purch. Inv. Header" = rm, - tabledata "Purch. Inv. Line" = rm, - tabledata "Purch. Cr. Memo Hdr." = rm, - tabledata "Purch. Cr. Memo Line" = rm, - tabledata "Vendor Ledger Entry" = rm; - - var - Telemetry: Codeunit Telemetry; - UpgradeDataDict: Dictionary of [Integer, Integer]; - CreatedDuringDataTransferMsg: Label 'Created during data transfer'; - - trigger OnRun() - var - IRSFormsSetup: Record "IRS Forms Setup"; - IRSReportingPeriod: Record "IRS Reporting Period"; - begin - IRSFormsSetup.Get(); - IRSFormsSetup.TestField("Init Reporting Year"); - CreateReportingPeriod(IRSReportingPeriod, IRSFormsSetup."Init Reporting Year"); - TransferIRS1099Setup(IRSReportingPeriod, IRSFormsSetup."Init Reporting Year"); - TransferIRS1099Data(IRSReportingPeriod); - - Clear(IRSFormsSetup."Data Transfer Task ID"); - Clear(IRSFormsSetup."Task Start Date/Time"); - IRSFormsSetup."Data Transfer Completed" := true; - IRSFormsSetup."Data Transfer Error Message" := ''; - IRSFormsSetup.Modify(); - end; - - procedure TransferIRS1099Setup(IRSReportingPeriod: Record "IRS Reporting Period"; ReportingYear: Integer) - var - IRSFormsData: Codeunit "IRS Forms Data"; - begin - Telemetry.LogMessage('0000PZA', 'IRS 1099 setup transfer started', Verbosity::Normal, DataClassification::SystemMetadata); - TransferVendorSetup(IRSReportingPeriod."No."); - IRSFormsData.AddFormInstructionLines(IRSReportingPeriod."No."); - Telemetry.LogMessage('0000PZB', 'IRS 1099 setup transfer completed', Verbosity::Normal, DataClassification::SystemMetadata); - end; - - procedure TransferIRS1099Data(IRSReportingPeriod: Record "IRS Reporting Period") - var - NoDataWasTransferredLbl: Label 'No data was transferred during the upgrade.'; - begin - Telemetry.LogMessage('0000PZC', 'IRS 1099 data transfer started', Verbosity::Normal, DataClassification::SystemMetadata); - TransferPurchaseDocuments(IRSReportingPeriod."No.", IRSReportingPeriod."Starting Date", IRSReportingPeriod."Ending Date"); - TransferPostedPurchInvoices(IRSReportingPeriod."No.", IRSReportingPeriod."Starting Date", IRSReportingPeriod."Ending Date"); - TransferPostedPurchCrMemos(IRSReportingPeriod."No.", IRSReportingPeriod."Starting Date", IRSReportingPeriod."Ending Date"); - TransferVendorLedgerEntries(IRSReportingPeriod."No.", IRSReportingPeriod."Starting Date", IRSReportingPeriod."Ending Date"); - Telemetry.LogMessage('0000PZD', 'IRS 1099 data transfer completed', Verbosity::Normal, DataClassification::SystemMetadata); - if not GuiAllowed() then - exit; - if UpgradeDataDict.Count() = 0 then begin - Telemetry.LogMessage('0000PZE', 'No data was transferred during the upgrade', Verbosity::Normal, DataClassification::SystemMetadata); - Message(NoDataWasTransferredLbl); - exit; - end; - Message(UpgradedDataDictToMessage()); - end; - - procedure CreateReportingPeriod(var IRSReportingPeriod: Record "IRS Reporting Period"; ReportingYear: Integer) - var - NewIRSReportingPeriodCreatedLbl: Label 'New IRS Reporting Period created for year %1', Comment = '%1 = Reporting Year'; - begin - IRSReportingPeriod.Init(); - IRSReportingPeriod."No." := Format(ReportingYear); - IRSReportingPeriod."Starting Date" := DMY2Date(1, 1, ReportingYear); - IRSReportingPeriod."Ending Date" := DMY2Date(31, 12, ReportingYear); - IRSReportingPeriod.Description := CreatedDuringDataTransferMsg; - IRSReportingPeriod.Insert(); - Telemetry.LogMessage('0000PZF', StrSubstNo(NewIRSReportingPeriodCreatedLbl, ReportingYear), Verbosity::Normal, DataClassification::SystemMetadata); - end; - - procedure TransferVendorSetup(PeriodNo: Code[20]) - var - Vendor: Record Vendor; - IRS1099VendorFormBoxSetup: Record "IRS 1099 Vendor Form Box Setup"; - begin -#pragma warning disable AL0432 - Vendor.SetFilter("IRS 1099 Code", '<>%1', ''); - if not Vendor.FindSet(true) then - exit; - repeat - if IsOld1099FormBoxTransferable(Vendor."IRS 1099 Code") then begin - IRS1099VendorFormBoxSetup.Init(); - IRS1099VendorFormBoxSetup."Period No." := PeriodNo; - IRS1099VendorFormBoxSetup."Vendor No." := Vendor."No."; - IRS1099VendorFormBoxSetup."Form No." := GetFormNoFromOldFormBox(Vendor."IRS 1099 Code"); - IRS1099VendorFormBoxSetup."Form Box No." := Vendor."IRS 1099 Code"; - IRS1099VendorFormBoxSetup.Insert(); - end; - Vendor."FATCA Requirement" := Vendor."FATCA filing requirement"; - Vendor.Modify(); - IncValueInUpgradedDataDict(Database::Vendor); - until Vendor.Next() = 0; -#pragma warning restore AL0432 - end; - - local procedure TransferPurchaseDocuments(PeriodNo: Code[20]; StartingDate: Date; EndingDate: Date) - var - PurchHeader: Record "Purchase Header"; - PurchLine: Record "Purchase Line"; - begin -#pragma warning disable AL0432 - PurchHeader.SetFilter( - "Document Type", '%1|%2|%3|%4', PurchHeader."Document Type"::Invoice, PurchHeader."Document Type"::"Credit Memo", PurchHeader."Document Type"::Order, PurchHeader."Document Type"::"Return Order"); - PurchHeader.SetRange("Posting Date", StartingDate, EndingDate); - PurchHeader.SetFilter("IRS 1099 Code", '<>%1', ''); - PurchHeader.SetRange("IRS 1099 Reporting Period", ''); - if not PurchHeader.FindSet(true) then - exit; - PurchLine.SetRange("IRS 1099 Liable", true); - repeat - if IsOld1099FormBoxTransferable(PurchHeader."IRS 1099 Code") then begin - PurchHeader."IRS 1099 Reporting Period" := PeriodNo; - PurchHeader."IRS 1099 Form No." := GetFormNoFromOldFormBox(PurchHeader."IRS 1099 Code"); - PurchHeader."IRS 1099 Form Box No." := PurchHeader."IRS 1099 Code"; - PurchHeader.Modify(); - IncValueInUpgradedDataDict(Database::"Purchase Header"); - PurchLine.SetRange("Document Type", PurchHeader."Document Type"); - PurchLine.SetRange("Document No.", PurchHeader."No."); - if PurchLine.FindSet(true) then - repeat - PurchLine."1099 Liable" := PurchLine."IRS 1099 Liable"; - PurchLine.Modify(); - until PurchLine.Next() = 0; - end; - until PurchHeader.Next() = 0; -#pragma warning restore AL0432 - end; - - local procedure TransferPostedPurchInvoices(PeriodNo: Code[20]; StartingDate: Date; EndingDate: Date) - var - PurchInvHeader: Record "Purch. Inv. Header"; - PurchInvLine: Record "Purch. Inv. Line"; - begin -#pragma warning disable AL0432 - PurchInvHeader.SetRange("Posting Date", StartingDate, EndingDate); - PurchInvHeader.SetFilter("IRS 1099 Code", '<>%1', ''); - PurchInvHeader.SetRange("IRS 1099 Reporting Period", ''); - if not PurchInvHeader.FindSet(true) then - exit; - repeat - if IsOld1099FormBoxTransferable(PurchInvHeader."IRS 1099 Code") then begin - PurchInvHeader."IRS 1099 Reporting Period" := PeriodNo; - PurchInvHeader."IRS 1099 Form No." := GetFormNoFromOldFormBox(PurchInvHeader."IRS 1099 Code"); - PurchInvHeader."IRS 1099 Form Box No." := PurchInvHeader."IRS 1099 Code"; - PurchInvHeader.Modify(); - IncValueInUpgradedDataDict(Database::"Purch. Inv. Header"); - PurchInvLine.SetRange("Document No.", PurchInvHeader."No."); - if PurchInvLine.FindSet(true) then - repeat - PurchInvLine."1099 Liable" := PurchInvLine."IRS 1099 Liable"; - PurchInvLine.Modify(); - until PurchInvLine.Next() = 0; - end; - until PurchInvHeader.Next() = 0; -#pragma warning restore AL0432 - end; - - local procedure TransferPostedPurchCrMemos(PeriodNo: Code[20]; StartingDate: Date; EndingDate: Date) - var - PurchCrMemoHdr: Record "Purch. Cr. Memo Hdr."; - PurchCrMemoLine: Record "Purch. Cr. Memo Line"; - begin -#pragma warning disable AL0432 - PurchCrMemoHdr.SetRange("Posting Date", StartingDate, EndingDate); - PurchCrMemoHdr.SetFilter("IRS 1099 Code", '<>%1', ''); - PurchCrMemoHdr.SetRange("IRS 1099 Reporting Period", ''); - if not PurchCrMemoHdr.FindSet(true) then - exit; - repeat - if IsOld1099FormBoxTransferable(PurchCrMemoHdr."IRS 1099 Code") then begin - PurchCrMemoHdr."IRS 1099 Reporting Period" := PeriodNo; - PurchCrMemoHdr."IRS 1099 Form No." := GetFormNoFromOldFormBox(PurchCrMemoHdr."IRS 1099 Code"); - PurchCrMemoHdr."IRS 1099 Form Box No." := PurchCrMemoHdr."IRS 1099 Code"; - PurchCrMemoHdr.Modify(); - IncValueInUpgradedDataDict(Database::"Purch. Cr. Memo Hdr."); - PurchCrMemoLine.SetRange("Document No.", PurchCrMemoHdr."No."); - if PurchCrMemoLine.FindSet(true) then - repeat - PurchCrMemoLine."1099 Liable" := PurchCrMemoLine."IRS 1099 Liable"; - PurchCrMemoLine.Modify(); - until PurchCrMemoLine.Next() = 0; - end; - until PurchCrMemoHdr.Next() = 0; -#pragma warning restore AL0432 - end; - - local procedure TransferVendorLedgerEntries(PeriodNo: Code[20]; StartingDate: Date; EndingDate: Date) - var - VendorLedgerEntry: Record "Vendor Ledger Entry"; - begin -#pragma warning disable AL0432 - VendorLedgerEntry.SetRange("Posting Date", StartingDate, EndingDate); - VendorLedgerEntry.SetFilter("Document Type", '%1|%2', VendorLedgerEntry."Document Type"::Invoice, VendorLedgerEntry."Document Type"::"Credit Memo"); - VendorLedgerEntry.SetFilter("IRS 1099 Code", '<>%1', ''); - VendorLedgerEntry.SetRange("IRS 1099 Reporting Period", ''); - if not VendorLedgerEntry.FindSet(true) then - exit; - repeat - if IsOld1099FormBoxTransferable(VendorLedgerEntry."IRS 1099 Code") then begin - VendorLedgerEntry."IRS 1099 Reporting Period" := PeriodNo; - VendorLedgerEntry."IRS 1099 Form No." := GetFormNoFromOldFormBox(VendorLedgerEntry."IRS 1099 Code"); - VendorLedgerEntry."IRS 1099 Form Box No." := VendorLedgerEntry."IRS 1099 Code"; - VendorLedgerEntry."IRS 1099 Reporting Amount" := VendorLedgerEntry."IRS 1099 Amount"; - VendorLedgerEntry."IRS 1099 Subject For Reporting" := VendorLedgerEntry."IRS 1099 Reporting Amount" <> 0; - VendorLedgerEntry.Modify(); - IncValueInUpgradedDataDict(Database::"Vendor Ledger Entry"); - end; - until VendorLedgerEntry.Next() = 0; -#pragma warning restore AL0432 - end; - - - local procedure IsOld1099FormBoxTransferable(OldFormBox: Text): Boolean - begin - exit((OldFormBox.Contains('MISC') or OldFormBox.Contains('DIV') or OldFormBox.Contains('INT') or OldFormBox.Contains('NEC')) and OldFormBox.Contains('-')); - end; - - local procedure GetFormNoFromOldFormBox(OldFormBox: Code[20]): Code[20] - var - DashPosition: Integer; - begin - DashPosition := StrPos(OldFormBox, '-'); -#pragma warning disable AA0139 - exit(CopyStr(OldFormBox, 1, DashPosition - 1)); -#pragma warning restore AA0139 - end; - - local procedure IncValueInUpgradedDataDict(TableId: Integer) - begin - if not UpgradeDataDict.ContainsKey(TableId) then - UpgradeDataDict.Add(TableId, 0); - UpgradeDataDict.Set(TableId, UpgradeDataDict.Get(TableId) + 1); - end; - - local procedure UpgradedDataDictToMessage() Message: Text - var - AllObjWithCaption: Record AllObjWithCaption; - TableId: Integer; - Count: Integer; - StatisticsOfTransferreddDataLbl: Label 'Statistics of transferred data'; - begin - Message := StatisticsOfTransferreddDataLbl + '\'; - foreach TableId in UpgradeDataDict.Keys() do begin - Count := UpgradeDataDict.Get(TableId); - Message += '\'; - AllObjWithCaption.Get(AllObjWithCaption."Object Type"::Table, TableId); - Message += StrSubstNo('%1: %2', AllObjWithCaption."Object Caption", Count); - end; - end; -} -#endif \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/Setup/IRS1099Upgrade.Codeunit.al b/Apps/US/IRSForms/app/src/Setup/IRS1099Upgrade.Codeunit.al index 7a8e92fdd1..9e83464315 100644 --- a/Apps/US/IRSForms/app/src/Setup/IRS1099Upgrade.Codeunit.al +++ b/Apps/US/IRSForms/app/src/Setup/IRS1099Upgrade.Codeunit.al @@ -9,6 +9,8 @@ using System.Upgrade; using System.Telemetry; using Microsoft.Purchases.Payables; using Microsoft.Purchases.Vendor; +using Microsoft.Purchases.Document; +using Microsoft.Purchases.History; codeunit 10058 "IRS 1099 Upgrade" { @@ -24,7 +26,6 @@ codeunit 10058 "IRS 1099 Upgrade" var Telemetry: Codeunit Telemetry; - IRS1099TransferFromBaseApp: Codeunit "IRS 1099 Transfer From BaseApp"; trigger OnUpgradePerCompany() begin @@ -65,7 +66,7 @@ codeunit 10058 "IRS 1099 Upgrade" end; Telemetry.LogMessage('0000Q1U', 'Data transfer', Verbosity::Normal, DataClassification::SystemMetadata); - IRS1099TransferFromBaseApp.TransferIRS1099Data(IRSReportingPeriod); + TransferIRS1099Data(IRSReportingPeriod); end; local procedure TransferIRS1099Setup(IRSReportingPeriod: Record "IRS Reporting Period"; ReportingYear: Integer) @@ -74,12 +75,46 @@ codeunit 10058 "IRS 1099 Upgrade" begin Telemetry.LogMessage('0000PZA', 'IRS 1099 setup transfer started', Verbosity::Normal, DataClassification::SystemMetadata); TransferFormBoxes(IRSReportingPeriod."No."); - IRS1099TransferFromBaseApp.TransferVendorSetup(IRSReportingPeriod."No."); + TransferVendorSetup(IRSReportingPeriod."No."); TransferAdjustments(IRSReportingPeriod."No.", ReportingYear); IRSFormsData.AddFormInstructionLines(IRSReportingPeriod."No."); Telemetry.LogMessage('0000PZB', 'IRS 1099 setup transfer completed', Verbosity::Normal, DataClassification::SystemMetadata); end; + local procedure TransferVendorSetup(PeriodNo: Code[20]) + var + Vendor: Record Vendor; + IRS1099VendorFormBoxSetup: Record "IRS 1099 Vendor Form Box Setup"; + begin +#pragma warning disable AL0432 + Vendor.SetFilter("IRS 1099 Code", '<>%1', ''); + if not Vendor.FindSet(true) then + exit; + repeat + if IsOld1099FormBoxTransferable(Vendor."IRS 1099 Code") then begin + IRS1099VendorFormBoxSetup.Init(); + IRS1099VendorFormBoxSetup."Period No." := PeriodNo; + IRS1099VendorFormBoxSetup."Vendor No." := Vendor."No."; + IRS1099VendorFormBoxSetup."Form No." := GetFormNoFromOldFormBox(Vendor."IRS 1099 Code"); + IRS1099VendorFormBoxSetup."Form Box No." := Vendor."IRS 1099 Code"; + if IRS1099VendorFormBoxSetup.Insert() then; + end; + Vendor."FATCA Requirement" := Vendor."FATCA filing requirement"; + Vendor.Modify(); + until Vendor.Next() = 0; +#pragma warning restore AL0432 + end; + + local procedure TransferIRS1099Data(IRSReportingPeriod: Record "IRS Reporting Period") + begin + Telemetry.LogMessage('0000PZC', 'IRS 1099 data transfer started', Verbosity::Normal, DataClassification::SystemMetadata); + TransferPurchaseDocuments(IRSReportingPeriod."No.", IRSReportingPeriod."Starting Date", IRSReportingPeriod."Ending Date"); + TransferPostedPurchInvoices(IRSReportingPeriod."No.", IRSReportingPeriod."Starting Date", IRSReportingPeriod."Ending Date"); + TransferPostedPurchCrMemos(IRSReportingPeriod."No.", IRSReportingPeriod."Starting Date", IRSReportingPeriod."Ending Date"); + TransferVendorLedgerEntries(IRSReportingPeriod."No.", IRSReportingPeriod."Starting Date", IRSReportingPeriod."Ending Date"); + Telemetry.LogMessage('0000PZD', 'IRS 1099 data transfer completed', Verbosity::Normal, DataClassification::SystemMetadata); + end; + local procedure TransferFormBoxes(PeriodNo: Code[20]) var #pragma warning disable AL0432 @@ -100,7 +135,7 @@ codeunit 10058 "IRS 1099 Upgrade" IRS1099Form.Init(); IRS1099Form."Period No." := PeriodNo; IRS1099Form."No." := CurrFormNo; - IRS1099Form.Insert(); + if IRS1099Form.Insert() then; StatementLineNo := 0; end; IRS1099FormBoxNew.Init(); @@ -109,7 +144,7 @@ codeunit 10058 "IRS 1099 Upgrade" IRS1099FormBoxNew."No." := IRS1099FormBoxOld.Code; IRS1099FormBoxNew.Description := IRS1099FormBoxOld.Description; IRS1099FormBoxNew."Minimum Reportable Amount" := IRS1099FormBoxOld."Minimum Reportable"; - IRS1099FormBoxNew.Insert(); + if IRS1099FormBoxNew.Insert() then; StatementLineNo += 10000; AddFormStatementLine(PeriodNo, IRS1099Form."No.", IRS1099FormBoxNew."No.", StatementLineNo, IRS1099FormBoxNew.Description); LastFormNo := CurrFormNo; @@ -134,12 +169,124 @@ codeunit 10058 "IRS 1099 Upgrade" IRS1099VendorFormBoxAdj."Form No." := GetFormNoFromOldFormBox(IRS1099Adjustment."IRS 1099 Code"); IRS1099VendorFormBoxAdj."Form Box No." := IRS1099Adjustment."IRS 1099 Code"; IRS1099VendorFormBoxAdj.Amount := IRS1099Adjustment.Amount; - IRS1099VendorFormBoxAdj.Insert(); + if IRS1099VendorFormBoxAdj.Insert() then; end; until IRS1099Adjustment.Next() = 0; #pragma warning restore AL0432 end; + local procedure TransferPurchaseDocuments(PeriodNo: Code[20]; StartingDate: Date; EndingDate: Date) + var + PurchHeader: Record "Purchase Header"; + PurchLine: Record "Purchase Line"; + begin +#pragma warning disable AL0432 + PurchHeader.SetFilter( + "Document Type", '%1|%2|%3|%4', PurchHeader."Document Type"::Invoice, PurchHeader."Document Type"::"Credit Memo", PurchHeader."Document Type"::Order, PurchHeader."Document Type"::"Return Order"); + PurchHeader.SetRange("Posting Date", StartingDate, EndingDate); + PurchHeader.SetFilter("IRS 1099 Code", '<>%1', ''); + PurchHeader.SetRange("IRS 1099 Reporting Period", ''); + if not PurchHeader.FindSet(true) then + exit; + PurchLine.SetRange("IRS 1099 Liable", true); + repeat + if IsOld1099FormBoxTransferable(PurchHeader."IRS 1099 Code") then begin + PurchHeader."IRS 1099 Reporting Period" := PeriodNo; + PurchHeader."IRS 1099 Form No." := GetFormNoFromOldFormBox(PurchHeader."IRS 1099 Code"); + PurchHeader."IRS 1099 Form Box No." := PurchHeader."IRS 1099 Code"; + PurchHeader.Modify(); + PurchLine.SetRange("Document Type", PurchHeader."Document Type"); + PurchLine.SetRange("Document No.", PurchHeader."No."); + if PurchLine.FindSet(true) then + repeat + PurchLine."1099 Liable" := PurchLine."IRS 1099 Liable"; + PurchLine.Modify(); + until PurchLine.Next() = 0; + end; + until PurchHeader.Next() = 0; +#pragma warning restore AL0432 + end; + + local procedure TransferPostedPurchInvoices(PeriodNo: Code[20]; StartingDate: Date; EndingDate: Date) + var + PurchInvHeader: Record "Purch. Inv. Header"; + PurchInvLine: Record "Purch. Inv. Line"; + begin +#pragma warning disable AL0432 + PurchInvHeader.SetRange("Posting Date", StartingDate, EndingDate); + PurchInvHeader.SetFilter("IRS 1099 Code", '<>%1', ''); + PurchInvHeader.SetRange("IRS 1099 Reporting Period", ''); + if not PurchInvHeader.FindSet(true) then + exit; + repeat + if IsOld1099FormBoxTransferable(PurchInvHeader."IRS 1099 Code") then begin + PurchInvHeader."IRS 1099 Reporting Period" := PeriodNo; + PurchInvHeader."IRS 1099 Form No." := GetFormNoFromOldFormBox(PurchInvHeader."IRS 1099 Code"); + PurchInvHeader."IRS 1099 Form Box No." := PurchInvHeader."IRS 1099 Code"; + PurchInvHeader.Modify(); + PurchInvLine.SetRange("Document No.", PurchInvHeader."No."); + if PurchInvLine.FindSet(true) then + repeat + PurchInvLine."1099 Liable" := PurchInvLine."IRS 1099 Liable"; + PurchInvLine.Modify(); + until PurchInvLine.Next() = 0; + end; + until PurchInvHeader.Next() = 0; +#pragma warning restore AL0432 + end; + + local procedure TransferPostedPurchCrMemos(PeriodNo: Code[20]; StartingDate: Date; EndingDate: Date) + var + PurchCrMemoHdr: Record "Purch. Cr. Memo Hdr."; + PurchCrMemoLine: Record "Purch. Cr. Memo Line"; + begin +#pragma warning disable AL0432 + PurchCrMemoHdr.SetRange("Posting Date", StartingDate, EndingDate); + PurchCrMemoHdr.SetFilter("IRS 1099 Code", '<>%1', ''); + PurchCrMemoHdr.SetRange("IRS 1099 Reporting Period", ''); + if not PurchCrMemoHdr.FindSet(true) then + exit; + repeat + if IsOld1099FormBoxTransferable(PurchCrMemoHdr."IRS 1099 Code") then begin + PurchCrMemoHdr."IRS 1099 Reporting Period" := PeriodNo; + PurchCrMemoHdr."IRS 1099 Form No." := GetFormNoFromOldFormBox(PurchCrMemoHdr."IRS 1099 Code"); + PurchCrMemoHdr."IRS 1099 Form Box No." := PurchCrMemoHdr."IRS 1099 Code"; + PurchCrMemoHdr.Modify(); + PurchCrMemoLine.SetRange("Document No.", PurchCrMemoHdr."No."); + if PurchCrMemoLine.FindSet(true) then + repeat + PurchCrMemoLine."1099 Liable" := PurchCrMemoLine."IRS 1099 Liable"; + PurchCrMemoLine.Modify(); + until PurchCrMemoLine.Next() = 0; + end; + until PurchCrMemoHdr.Next() = 0; +#pragma warning restore AL0432 + end; + + local procedure TransferVendorLedgerEntries(PeriodNo: Code[20]; StartingDate: Date; EndingDate: Date) + var + VendorLedgerEntry: Record "Vendor Ledger Entry"; + begin +#pragma warning disable AL0432 + VendorLedgerEntry.SetRange("Posting Date", StartingDate, EndingDate); + VendorLedgerEntry.SetFilter("Document Type", '%1|%2', VendorLedgerEntry."Document Type"::Invoice, VendorLedgerEntry."Document Type"::"Credit Memo"); + VendorLedgerEntry.SetFilter("IRS 1099 Code", '<>%1', ''); + VendorLedgerEntry.SetRange("IRS 1099 Reporting Period", ''); + if not VendorLedgerEntry.FindSet(true) then + exit; + repeat + if IsOld1099FormBoxTransferable(VendorLedgerEntry."IRS 1099 Code") then begin + VendorLedgerEntry."IRS 1099 Reporting Period" := PeriodNo; + VendorLedgerEntry."IRS 1099 Form No." := GetFormNoFromOldFormBox(VendorLedgerEntry."IRS 1099 Code"); + VendorLedgerEntry."IRS 1099 Form Box No." := VendorLedgerEntry."IRS 1099 Code"; + VendorLedgerEntry."IRS 1099 Reporting Amount" := VendorLedgerEntry."IRS 1099 Amount"; + VendorLedgerEntry."IRS 1099 Subject For Reporting" := VendorLedgerEntry."IRS 1099 Reporting Amount" <> 0; + VendorLedgerEntry.Modify(); + end; + until VendorLedgerEntry.Next() = 0; +#pragma warning restore AL0432 + end; + local procedure AddFormStatementLine(PeriodNo: Code[20]; FormNo: Code[20]; FormBoxNo: Code[20]; StatementLineNo: Integer; Description: Text) var IRS1099FormStatementLine: Record "IRS 1099 Form Statement Line"; @@ -153,7 +300,7 @@ codeunit 10058 "IRS 1099 Upgrade" if IRS1099FormStatementLine."Row No." = 'MISC-07' then IRS1099FormStatementLine."Print Value Type" := Enum::"IRS 1099 Print Value Type"::"Yes/No"; IRS1099FormStatementLine.Validate("Filter Expression", StrSubstNo(StatementLineFilterExpressionTxt, FormBoxNo)); - IRS1099FormStatementLine.Insert(true); + if IRS1099FormStatementLine.Insert(true) then; end; local procedure GetFormNoFromOldFormBox(OldFormBox: Code[20]): Code[20] @@ -211,12 +358,24 @@ codeunit 10058 "IRS 1099 Upgrade" end; end; Telemetry.LogMessage('0000PZN', 'Creating new IRS Reporting Period', Verbosity::Normal, DataClassification::SystemMetadata); - IRS1099TransferFromBaseApp.CreateReportingPeriod(IRSReportingPeriod, ReportingYear); - Telemetry.LogMessage('0000PZO', 'Transferring IRS 1099 setup', Verbosity::Normal, DataClassification::SystemMetadata); - IRS1099TransferFromBaseApp.TransferIRS1099Setup(IRSReportingPeriod, ReportingYear); + CreateReportingPeriod(IRSReportingPeriod, ReportingYear); exit(true); end; + local procedure CreateReportingPeriod(var IRSReportingPeriod: Record "IRS Reporting Period"; ReportingYear: Integer) + var + NewIRSReportingPeriodCreatedLbl: Label 'New IRS Reporting Period created for year %1', Comment = '%1 = Reporting Year'; + CreatedDuringDataTransferMsg: Label 'Created during data transfer'; + begin + IRSReportingPeriod.Init(); + IRSReportingPeriod."No." := Format(ReportingYear); + IRSReportingPeriod."Starting Date" := DMY2Date(1, 1, ReportingYear); + IRSReportingPeriod."Ending Date" := DMY2Date(31, 12, ReportingYear); + IRSReportingPeriod.Description := CreatedDuringDataTransferMsg; + IRSReportingPeriod.Insert(); + Telemetry.LogMessage('0000PZF', StrSubstNo(NewIRSReportingPeriodCreatedLbl, ReportingYear), Verbosity::Normal, DataClassification::SystemMetadata); + end; + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Upgrade Tag", 'OnGetPerCompanyUpgradeTags', '', false, false)] local procedure RegisterPerCompanyTags(var PerCompanyUpgradeTags: List of [Code[250]]) begin diff --git a/Apps/US/IRSForms/app/src/Setup/IRSFormsFeature.Codeunit.al b/Apps/US/IRSForms/app/src/Setup/IRSFormsFeature.Codeunit.al index 61ec1ce17c..10e2b29769 100644 --- a/Apps/US/IRSForms/app/src/Setup/IRSFormsFeature.Codeunit.al +++ b/Apps/US/IRSForms/app/src/Setup/IRSFormsFeature.Codeunit.al @@ -1,123 +1,4 @@ -// ------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -// ------------------------------------------------------------------------------------------------ -#if not CLEAN25 -namespace Microsoft.Finance.VAT.Reporting; - -using System.Environment; -using System.Environment.Configuration; -using System.Media; - -codeunit 10038 "IRS Forms Feature" -{ - Access = Internal; - InherentEntitlements = X; - InherentPermissions = X; - - var - AssistedSetupTxt: Label 'Set up a IRS Forms feature'; - AssistedSetupDescriptionTxt: Label 'Setup 1099 forms to transmit the tax data to the IRS in the United States'; - AssistedSetupHelpTxt: Label 'https://learn.microsoft.com/en-us/dynamics365/business-central/localfunctionality/unitedstates/set-up-use-irs1099-form', Locked = true; - - procedure IsEnabled() Result: Boolean - begin - Result := true; - OnAfterCheckFeatureEnabled(Result); - end; - - procedure FeatureCanBeUsed(): Boolean - begin - exit(true); - end; - - procedure UpgradeFromBaseApplication() - var - IRSFormsSetup: Record "IRS Forms Setup"; - begin - IRSFormsSetup.InitSetup(); - IRSFormsSetup.CheckIfDataTransferIsPossible(); - if IRSFormsSetup."Background Task" then begin - ScheduleTask(); - exit; - end; - Codeunit.Run(Codeunit::"IRS 1099 Transfer From BaseApp"); - end; - - local procedure ScheduleTask(): Boolean; - var - IRSFormsSetup: Record "IRS Forms Setup"; - DoNotScheduleTask: Boolean; - TaskID: Guid; - begin - if not TaskScheduler.CanCreateTask() then - exit(false); - - IRSFormsSetup.Get(); - if DoNotScheduleTask then - IRSFormsSetup."Data Transfer Task ID" := TaskID - else - IRSFormsSetup."Data Transfer Task ID" := - CreateTask(IRSFormsSetup); - IRSFormsSetup.Modify(); - exit(true); - end; - - local procedure CreateTask(var IRSFormsSetup: Record "IRS Forms Setup") TaskId: Guid - begin - CancelTask(IRSFormsSetup); - AdjustStartDateTime(IRSFormsSetup); - TaskId := - TaskScheduler.CreateTask( - Codeunit::"IRS 1099 Transfer From BaseApp", Codeunit::"IRS 1099 Trans. Error Handler", - true, CompanyName(), IRSFormsSetup."Task Start Date/Time"); - end; - - procedure CancelTask(var IRSFormsSetup: Record "IRS Forms Setup") - var - ScheduledTask: Record "Scheduled Task"; - begin - IRSFormsSetup.Get(); - if not IsNullGuid(IRSFormsSetup."Data Transfer Task ID") then begin - if ScheduledTask.Get(IRSFormsSetup."Data Transfer Task ID") then - TaskScheduler.CancelTask(IRSFormsSetup."Data Transfer Task ID"); - Clear(IRSFormsSetup."Data Transfer Task ID"); - end; - end; - - procedure InsertAssistedSetup() - var - GuidedExperience: Codeunit "Guided Experience"; - AssistedSetupGroup: Enum "Assisted Setup Group"; - VideoCategory: Enum "Video Category"; - begin - GuidedExperience.InsertAssistedSetup(AssistedSetupTxt, CopyStr(AssistedSetupTxt, 1, 50), AssistedSetupDescriptionTxt, 5, ObjectType::Page, Page::"IRS Forms Guide", AssistedSetupGroup::FinancialReporting, - '', VideoCategory::FinancialReporting, AssistedSetupHelpTxt); - end; - - local procedure AdjustStartDateTime(var IRSFormsSetup: Record "IRS Forms Setup") - var - Delta: Duration; - begin - Delta := 500; // Time to update the status record before the task is started. - if IRSFormsSetup."Task Start Date/Time" = 0DT then - IRSFormsSetup."Task Start Date/Time" := CurrentDateTime() + Delta - else - if IRSFormsSetup."Task Start Date/Time" - CurrentDateTime() < Delta then - IRSFormsSetup."Task Start Date/Time" := CurrentDateTime() + Delta; - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"Guided Experience", 'OnRegisterAssistedSetup', '', true, true)] - local procedure InsertIntoAssistedSetup() - begin - if not IsEnabled() then - exit; - InsertAssistedSetup(); - end; - - [IntegrationEvent(true, false)] - local procedure OnAfterCheckFeatureEnabled(var IsEnabled: Boolean) - begin - end; -} -#endif +// ------------------------------------------------------------------------------------------------ \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/Setup/IRSFormsGuide.Page.al b/Apps/US/IRSForms/app/src/Setup/IRSFormsGuide.Page.al index 6f3a789aa3..0b8fa807f4 100644 --- a/Apps/US/IRSForms/app/src/Setup/IRSFormsGuide.Page.al +++ b/Apps/US/IRSForms/app/src/Setup/IRSFormsGuide.Page.al @@ -395,7 +395,6 @@ page 10032 "IRS Forms Guide" begin SetupCompleted := true; Commit(); - IRSFormsData.AddReportingPeriodsWithForms(Rec."Init Reporting Year"); GuidedExperience.CompleteAssistedSetup(ObjectType::Page, Page::"IRS Forms Guide"); CurrPage.Close(); end; @@ -482,4 +481,4 @@ page 10032 "IRS Forms Guide" then TopBannerVisible := MediaResourcesFinished."Media Reference".HasValue(); end; -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/app/src/Setup/UpgradeIRS1099Data.Report.al b/Apps/US/IRSForms/app/src/Setup/UpgradeIRS1099Data.Report.al index 064ab4c25b..412d39956d 100644 --- a/Apps/US/IRSForms/app/src/Setup/UpgradeIRS1099Data.Report.al +++ b/Apps/US/IRSForms/app/src/Setup/UpgradeIRS1099Data.Report.al @@ -5,8 +5,6 @@ // ------------------------------------------------------------------------------------------------ namespace Microsoft.Finance.VAT.Reporting; -using System.Telemetry; - report 10063 "Upgrade IRS 1099 Data" { Caption = 'Upgrade IRS 1099 Data'; @@ -42,26 +40,5 @@ report 10063 "Upgrade IRS 1099 Data" var IRSReportingPeriodCode: Code[20]; - - trigger OnPostReport() - var - IRSReportingPeriod: Record "IRS Reporting Period"; - IRS1099FormBox: Record "IRS 1099 Form Box"; - IRS1099TransferFromBaseApp: Codeunit "IRS 1099 Transfer From BaseApp"; - Telemetry: Codeunit Telemetry; - IRSReportingPeriodCodeNotSpecifiedErr: Label 'Reporting Period Code must be specified.'; - SetupTransferLbl: Label 'Setting up data transfer for IRS Reporting Period: %1. Starting Date = %2, Ending Date = %3', Comment = '%1 = code, %2 = starting date, %3 = ending date'; - TransferingDataLbl: Label 'Starting data transfer for IRS Reporting Period: %1. Starting Date = %2, Ending Date = %3', Comment = '%1 = code, %2 = starting date, %3 = ending date'; - begin - if IRSReportingPeriodCode = '' then - error(IRSReportingPeriodCodeNotSpecifiedErr); - IRSReportingPeriod.Get(IRSReportingPeriodCode); - if IRS1099FormBox.IsEmpty() then begin - Telemetry.LogMessage('0000Q1X', StrSubstNo(SetupTransferLbl, IRSReportingPeriod."No.", IRSReportingPeriod."Starting Date", IRSReportingPeriod."Ending Date"), Verbosity::Normal, DataClassification::SystemMetadata); - IRS1099TransferFromBaseApp.TransferIRS1099Setup(IRSReportingPeriod, Date2DMY(IRSReportingPeriod."Starting Date", 3)); - end; - Telemetry.LogMessage('0000PZP', StrSubstNo(TransferingDataLbl, IRSReportingPeriod."No.", IRSReportingPeriod."Starting Date", IRSReportingPeriod."Ending Date"), Verbosity::Normal, DataClassification::SystemMetadata); - IRS1099TransferFromBaseApp.TransferIRS1099Data(IRSReportingPeriod); - end; } #endif \ No newline at end of file diff --git a/Apps/US/IRSForms/test library/src/IRSFormsEnableFeature.Codeunit.al b/Apps/US/IRSForms/test library/src/IRSFormsEnableFeature.Codeunit.al index 36448a7335..10e2b29769 100644 --- a/Apps/US/IRSForms/test library/src/IRSFormsEnableFeature.Codeunit.al +++ b/Apps/US/IRSForms/test library/src/IRSFormsEnableFeature.Codeunit.al @@ -1,21 +1,4 @@ -// ------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -// ------------------------------------------------------------------------------------------------ -#if not CLEAN25 -namespace Microsoft.Finance.VAT.Reporting; - -codeunit 148003 "IRS Forms Enable Feature" -{ - EventSubscriberInstance = Manual; - ObsoleteReason = 'Moved to IRS Forms App.'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"IRS Forms Feature", 'OnAfterCheckFeatureEnabled', '', false, false)] - local procedure EnableIRSFormsOnAfterCheckFeatureEnabled(var IsEnabled: Boolean) - begin - IsEnabled := true; - end; -} -#endif +// ------------------------------------------------------------------------------------------------ \ No newline at end of file diff --git a/Apps/US/IRSForms/test/src/IRS1099DocumentTests.Codeunit.al b/Apps/US/IRSForms/test/src/IRS1099DocumentTests.Codeunit.al index 9b1e1edb6a..b8ebb0ad01 100644 --- a/Apps/US/IRSForms/test/src/IRS1099DocumentTests.Codeunit.al +++ b/Apps/US/IRSForms/test/src/IRS1099DocumentTests.Codeunit.al @@ -871,4 +871,4 @@ codeunit 148010 "IRS 1099 Document Tests" begin Assert.ExpectedMessage(LibraryVariableStorage.DequeueText(), Text); end; -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/test/src/IRS1099E2ETests.Codeunit.al b/Apps/US/IRSForms/test/src/IRS1099E2ETests.Codeunit.al index da0755754f..e160951ca9 100644 --- a/Apps/US/IRSForms/test/src/IRS1099E2ETests.Codeunit.al +++ b/Apps/US/IRSForms/test/src/IRS1099E2ETests.Codeunit.al @@ -137,4 +137,4 @@ end; begin IRS1099CreateFormDocs.Ok().Invoke(); end; -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/test/src/IRS1099EmailingTests.Codeunit.al b/Apps/US/IRSForms/test/src/IRS1099EmailingTests.Codeunit.al index 2b2e0b7544..9c03255571 100644 --- a/Apps/US/IRSForms/test/src/IRS1099EmailingTests.Codeunit.al +++ b/Apps/US/IRSForms/test/src/IRS1099EmailingTests.Codeunit.al @@ -313,19 +313,11 @@ codeunit 148012 "IRS 1099 Emailing Tests" var IRS1099FormDocHeader: Record "IRS 1099 Form Doc. Header"; DummyVendor: Record Vendor; -#if not CLEAN25 -#pragma warning disable AL0432 - IRSFormsEnableFeature: Codeunit "IRS Forms Enable Feature"; -#pragma warning restore AL0432 -#endif VendorCard: TestPage "Vendor Card"; ConfirmQuestion: Text; begin // [SCENARIO 560521] Propagate email consent from vendor to released 1099 form document. Initialize(); -#if not CLEAN25 - BindSubscription(IRSFormsEnableFeature); -#endif // [GIVEN] Released 1099 form document without email and without consent. MockFormDocument(IRS1099FormDocHeader, "IRS 1099 Form Doc. Status"::Released); @@ -350,9 +342,6 @@ codeunit 148012 "IRS 1099 Emailing Tests" Assert.IsTrue(IRS1099FormDocHeader."Receiving 1099 E-Form Consent", 'Receiving 1099 E-Form Consent must be set to true.'); Assert.AreEqual('', IRS1099FormDocHeader."Vendor E-Mail", 'Vendor E-Mail must be empty.'); -#if not CLEAN25 - UnbindSubscription(IRSFormsEnableFeature); -#endif LibraryVariableStorage.AssertEmpty(); end; @@ -362,20 +351,12 @@ codeunit 148012 "IRS 1099 Emailing Tests" var IRS1099FormDocHeader: Record "IRS 1099 Form Doc. Header"; DummyVendor: Record Vendor; -#if not CLEAN25 -#pragma warning disable AL0432 - IRSFormsEnableFeature: Codeunit "IRS Forms Enable Feature"; -#pragma warning restore AL0432 -#endif VendorCard: TestPage "Vendor Card"; ConfirmQuestion: Text; VendorEmail: Text[80]; begin // [SCENARIO 560521] Propagate email from vendor to released 1099 form document. Initialize(); -#if not CLEAN25 - BindSubscription(IRSFormsEnableFeature); -#endif // [GIVEN] Released 1099 form document without email and with consent. MockFormDocument(IRS1099FormDocHeader, "IRS 1099 Form Doc. Status"::Released); @@ -401,9 +382,6 @@ codeunit 148012 "IRS 1099 Emailing Tests" Assert.IsTrue(IRS1099FormDocHeader."Receiving 1099 E-Form Consent", 'Receiving 1099 E-Form Consent must be set to true.'); Assert.AreEqual(VendorEmail, IRS1099FormDocHeader."Vendor E-Mail", 'Vendor E-Mail must be specified.'); -#if not CLEAN25 - UnbindSubscription(IRSFormsEnableFeature); -#endif LibraryVariableStorage.AssertEmpty(); end; diff --git a/Apps/US/IRSForms/test/src/IRS1099FormCalcTests.Codeunit.al b/Apps/US/IRSForms/test/src/IRS1099FormCalcTests.Codeunit.al index 77bad9b7cb..692e80c30c 100644 --- a/Apps/US/IRSForms/test/src/IRS1099FormCalcTests.Codeunit.al +++ b/Apps/US/IRSForms/test/src/IRS1099FormCalcTests.Codeunit.al @@ -529,4 +529,4 @@ end; DetailedVendorLedgEntry."Transaction No." := TransactionNo; DetailedVendorLedgEntry.Insert(); end; -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/test/src/IRS1099LiableTests.Codeunit.al b/Apps/US/IRSForms/test/src/IRS1099LiableTests.Codeunit.al index 06e29d64ee..d9e977be4a 100644 --- a/Apps/US/IRSForms/test/src/IRS1099LiableTests.Codeunit.al +++ b/Apps/US/IRSForms/test/src/IRS1099LiableTests.Codeunit.al @@ -193,4 +193,4 @@ codeunit 148019 "IRS 1099 Liable Tests" IsInitialized := true; LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"IRS 1099 Liable Tests"); end; -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/test/src/IRS1099PrintingTests.Codeunit.al b/Apps/US/IRSForms/test/src/IRS1099PrintingTests.Codeunit.al index f761441faa..232d57852c 100644 --- a/Apps/US/IRSForms/test/src/IRS1099PrintingTests.Codeunit.al +++ b/Apps/US/IRSForms/test/src/IRS1099PrintingTests.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. // ------------------------------------------------------------------------------------------------ @@ -229,4 +229,4 @@ end; IRS1099FormReport.CalcFields("File Content"); Assert.IsTrue(IRS1099FormReport."File Content".HasValue(), 'File content should exist for the document and report type.'); end; -} +} \ No newline at end of file diff --git a/Apps/US/IRSForms/test/src/IRS1099VendorTests.Codeunit.al b/Apps/US/IRSForms/test/src/IRS1099VendorTests.Codeunit.al index 22ec3ce507..ce29c4113e 100644 --- a/Apps/US/IRSForms/test/src/IRS1099VendorTests.Codeunit.al +++ b/Apps/US/IRSForms/test/src/IRS1099VendorTests.Codeunit.al @@ -468,4 +468,4 @@ codeunit 148011 "IRS 1099 Vendor Tests" IRS1099PropagateVendSetup.VendorLedgerEntriesControl.SetValue(true); IRS1099PropagateVendSetup.OK().Invoke(); end; -} +} \ No newline at end of file diff --git a/Apps/W1/AMCBanking365Fundamentals/app/Codeunits/AMCBankServiceRequestMgt.Codeunit.al b/Apps/W1/AMCBanking365Fundamentals/app/Codeunits/AMCBankServiceRequestMgt.Codeunit.al index 6effa9ff4e..804d9e105d 100644 --- a/Apps/W1/AMCBanking365Fundamentals/app/Codeunits/AMCBankServiceRequestMgt.Codeunit.al +++ b/Apps/W1/AMCBanking365Fundamentals/app/Codeunits/AMCBankServiceRequestMgt.Codeunit.al @@ -1,4 +1,4 @@ -#if not CLEAN28 +#if not CLEAN28 // ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. @@ -41,16 +41,6 @@ codeunit 20118 "AMC Bank Service Request Mgt." FeatureConsentErr: Label 'The AMC Banking 365 Fundamentals feature is not enabled. You can enable the feature on the AMC Banking Setup page by turning on the Enabled toggle, or by using the assisted setup guide.'; FeatureConsentQst: Label '%1\\Do you want us to open the AMC Banking Setup page for you?', Comment = '%1 = FeatureConsentErr'; -#if not CLEAN25 - [Obsolete('Use the procedure that receives Password as a SecretText instead.', '25.0')] - procedure CreateEnvelope(var requestDocXML: XmlDocument; var EnvXmlElement: XmlElement; Username: Text; Password: Text; UsernameTokenValue: Text); - var - SecretPassword: SecretText; - begin - SecretPassword := Password; - CreateEnvelope(requestDocXML, EnvXmlElement, Username, SecretPassword, UsernameTokenValue); - end; -#endif [NonDebuggable] procedure CreateEnvelope(VAR requestDocXML: XmlDocument; VAR EnvXmlElement: XmlElement; Username: Text; Password: SecretText; UsernameTokenValue: Text); diff --git a/Apps/W1/APIV2/app/src/pages/APIV2AccountingPeriods.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2AccountingPeriods.Page.al index 7cb7fcbd5b..68b1de6391 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2AccountingPeriods.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2AccountingPeriods.Page.al @@ -18,7 +18,7 @@ page 30086 "APIV2 - Accounting Periods" Extensible = false; Editable = false; DataAccessIntent = ReadOnly; - AboutText = 'Exposes read-only accounting period data including starting dates, period names, fiscal year status, closure indicators, date locks, and average cost calculation settings. Enables external systems to retrieve and synchronize fiscal calendar definitions for reporting automation, consolidation, and period-end processing. Supports GET operations only, ensuring accurate alignment of financial periods across integrated platforms without permitting direct creation, modification, or deletion of records.'; + AboutText = 'Exposes accounting period data including starting dates, period names, fiscal year status, closure indicators, date locks, and average cost calculation settings. Enables external systems to retrieve and synchronize fiscal calendar definitions for reporting automation, consolidation, and period-end processing. Supports GET operations only, ensuring accurate alignment of financial periods across integrated platforms without permitting direct creation, modification, or deletion of records.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2Accounts.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2Accounts.Page.al index b4427567c1..deb26e1540 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2Accounts.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2Accounts.Page.al @@ -19,7 +19,7 @@ page 30014 "APIV2 - Accounts" PageType = API; SourceTable = "G/L Account"; Extensible = false; - AboutText = 'Provides read-only access to chart of accounts data from the G/L Account table, including account numbers, names, categories, balances, posting settings, and consolidation attributes. Supports GET operations for retrieving account structures and financial statistics to enable integration with external reporting, consolidation, and accounting platforms. Ideal for synchronizing account master data and balances to maintain consistency across financial systems and support automated financial workflows; creation or modification of account records is not permitted.'; + AboutText = 'Provides access to chart of accounts data from the G/L Account table, including account numbers, names, categories, balances, posting settings, and consolidation attributes. Supports GET operations for retrieving account structures and financial statistics to enable integration with external reporting, consolidation, and accounting platforms. Ideal for synchronizing account master data and balances to maintain consistency across financial systems and support automated financial workflows; creation or modification of account records is not permitted.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2AgedAP.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2AgedAP.Page.al index 8dfa1438b6..b428185180 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2AgedAP.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2AgedAP.Page.al @@ -20,7 +20,7 @@ page 30032 "APIV2 - Aged AP" SourceTableTemporary = true; Extensible = false; ODataKeyFields = AccountId; - AboutText = 'Provides read-only access to aged accounts payable data, including vendor details, outstanding balances, and amounts overdue by aging period. Supports GET operations for retrieving payables aging reports, enabling integration with treasury management systems and automation of cash flow analysis and financial reporting.'; + AboutText = 'Provides access to aged accounts payable data, including vendor details, outstanding balances, and amounts overdue by aging period. Supports GET operations for retrieving payables aging reports, enabling integration with treasury management systems and automation of cash flow analysis and financial reporting.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2ApplyVendorEntries.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2ApplyVendorEntries.Page.al index 2bb9159b18..daa2a3beb8 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2ApplyVendorEntries.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2ApplyVendorEntries.Page.al @@ -19,7 +19,7 @@ page 30073 "APIV2 - Apply Vendor Entries" Extensible = false; InsertAllowed = false; DeleteAllowed = false; - AboutText = 'Exposes open vendor ledger entries with key details such as posting date, document type, vendor information, and remaining amount, enabling external systems to retrieve and update application status via GET and PATCH operations. Facilitates automated accounts payable reconciliation by allowing integrations to programmatically match and apply payments or credit memos to outstanding vendor invoices, supporting AP automation and bank transaction import scenarios. Designed for seamless settlement processing and accurate maintenance of vendor balances within Business Central.'; + AboutText = 'Exposes open vendor ledger entries with key details such as posting date, document type, vendor information, and remaining amount. Enables external systems to retrieve and update application status, facilitating automated accounts payable reconciliation by allowing integrations to programmatically match and apply payments or credit memos to outstanding vendor invoices, supporting AP automation and bank transaction import scenarios. Designed for seamless settlement processing and accurate maintenance of vendor balances within Business Central.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2Attachments.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2Attachments.Page.al index 5326da720b..4bbe448963 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2Attachments.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2Attachments.Page.al @@ -18,7 +18,7 @@ page 30039 "APIV2 - Attachments" SourceTable = "Attachment Entity Buffer"; SourceTableTemporary = true; Extensible = false; - AboutText = 'Manages file attachments linked to Business Central records such as invoices, orders, and journal entries, supporting upload, retrieval, update, and deletion operations. Enables integration scenarios for document management, compliance, and synchronization with external storage or workflow systems by exposing metadata and content for various attachment types and document categories.'; + AboutText = 'Manages file attachments linked to Business Central records such as invoices, orders, and journal entries. Supports upload, retrieval, update, and deletion operations, enabling integration scenarios for document management, compliance, and synchronization with external storage or workflow systems by exposing metadata and content for various attachment types and document categories.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2BalanceSheet.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2BalanceSheet.Page.al index 799a85a246..314c512b2f 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2BalanceSheet.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2BalanceSheet.Page.al @@ -20,7 +20,7 @@ page 30033 "APIV2 - Balance Sheet" SourceTableTemporary = true; Extensible = false; ODataKeyFields = Id; - AboutText = 'Provides read-only access to balance sheet reports, detailing assets, liabilities, and equity with account-level breakdowns and date filters. Supports GET operations for retrieving financial position data at specific points in time, enabling automated financial reporting, compliance, and integration with external accounting or consolidation systems.'; + AboutText = 'Provides access to balance sheet reports, detailing assets, liabilities, and equity with account-level breakdowns and date filters. Supports GET operations for retrieving financial position data at specific points in time, enabling automated financial reporting, compliance, and integration with external accounting or consolidation systems.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2CashFlowStatement.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2CashFlowStatement.Page.al index eeeb2ef4c2..cadba3a10e 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2CashFlowStatement.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2CashFlowStatement.Page.al @@ -20,7 +20,7 @@ page 30026 "APIV2 - Cash Flow Statement" SourceTableTemporary = true; Extensible = false; ODataKeyFields = Id; - AboutText = 'Exposes read-only cash flow statement data, including line-level details such as net change, activity type, description, and date filters, segmented by operating, investing, and financing activities. Supports GET operations for retrieving up-to-date cash inflow and outflow summaries, enabling automated financial analysis, liquidity monitoring, and integration with external reporting or consolidation systems. Ideal for developers building solutions that require accurate cash flow visibility for planning and multi-entity financial management.'; + AboutText = 'Exposes cash flow statement data, including line-level details such as net change, activity type, description, and date filters, segmented by operating, investing, and financing activities. Supports GET operations for retrieving up-to-date cash inflow and outflow summaries, enabling automated financial analysis, liquidity monitoring, and integration with external reporting or consolidation systems. Ideal for developers building solutions that require accurate cash flow visibility for planning and multi-entity financial management.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2ContactsInformation.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2ContactsInformation.Page.al index ac0415b3c6..507e052e1a 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2ContactsInformation.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2ContactsInformation.Page.al @@ -18,7 +18,7 @@ page 30072 "APIV2 - Contacts Information" InsertAllowed = false; ModifyAllowed = false; DeleteAllowed = false; - AboutText = 'Exposes a read-only list of contact records, including contact identifiers, names, contact type (company or person), and their association to related entities such as customers, vendors, bank accounts, and employees. Supports GET operations for querying and filtering contact data, enabling external CRM, marketing, or service applications to reference and synchronize contact-to-entity relationships while maintaining Business Central as the authoritative source. Ideal for integrations that require up-to-date contact context without access to personal details like address, phone, or email information.'; + AboutText = 'Exposes a list of contact records, including contact identifiers, names, contact type (company or person), and their association to related entities such as customers, vendors, bank accounts, and employees. Supports GET operations for querying and filtering contact data, enabling external CRM, marketing, or service applications to reference and synchronize contact-to-entity relationships while maintaining Business Central as the authoritative source. Ideal for integrations that require up-to-date contact context without access to personal details like address, phone, or email information.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2CurrencyExchangeRates.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2CurrencyExchangeRates.Page.al index 59b3c0b531..e08e5a0933 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2CurrencyExchangeRates.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2CurrencyExchangeRates.Page.al @@ -18,7 +18,7 @@ page 30085 "APIV2- Currency Exchange Rates" ModifyAllowed = false; Editable = false; DataAccessIntent = ReadOnly; - AboutText = 'Exposes currency exchange rate records including currency codes, exchange rate amounts, relational currency details, and effective dates for read-only access. Supports GET operations to retrieve up-to-date exchange rates for multi-currency transactions, automated currency conversion, financial consolidation, and reporting. Enables external financial systems and data providers to synchronize and consume Business Central currency exchange rates, ensuring accurate and consistent currency calculations across integrated platforms.'; + AboutText = 'Exposes currency exchange rate records including currency codes, exchange rate amounts, relational currency details, and effective dates. Supports GET operations to retrieve up-to-date exchange rates for multi-currency transactions, automated currency conversion, financial consolidation, and reporting. Enables external financial systems and data providers to synchronize and consume Business Central currency exchange rates, ensuring accurate and consistent currency calculations across integrated platforms.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2CustFinancialDetails.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2CustFinancialDetails.Page.al index 2a3068f16a..7a1efd8557 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2CustFinancialDetails.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2CustFinancialDetails.Page.al @@ -19,7 +19,7 @@ page 30048 "APIV2 - Cust Financial Details" DelayedInsert = true; Extensible = false; - AboutText = 'Provides read-only access to consolidated customer financial data, including outstanding balances, overdue amounts, payment history, and credit limits. Supports GET operations for credit management, collections, and customer risk assessment, enabling integration with CRM, credit control, and risk monitoring systems to automate credit checks and track payment behavior.'; + AboutText = 'Provides access to consolidated customer financial data, including outstanding balances, overdue amounts, payment history, and credit limits. Supports GET operations for credit management, collections, and customer risk assessment, enabling integration with CRM, credit control, and risk monitoring systems to automate credit checks and track payment behavior.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2DefaultDimensions.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2DefaultDimensions.Page.al index f296e60ac0..0338111137 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2DefaultDimensions.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2DefaultDimensions.Page.al @@ -14,7 +14,7 @@ page 30054 "APIV2 - Default Dimensions" SourceTable = "Default Dimension"; Extensible = false; ODataKeyFields = SystemId; - AboutText = 'Manages default dimension assignments for master records such as customers, vendors, items, and projects, enabling retrieval, creation, update, and deletion of dimension values and posting requirements. Supports automation and synchronization of financial categorization, ensuring consistent analytical tagging for accurate reporting and integration with external financial, ERP, or analytics systems.'; + AboutText = 'Manages default dimension assignments for master records such as customers, vendors, items, and projects. Supports retrieval, creation, update, and deletion of dimension values and posting requirements, enabling automation and synchronization of financial categorization, ensuring consistent analytical tagging for accurate reporting and integration with external financial, ERP, or analytics systems.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2DimensionSetLines.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2DimensionSetLines.Page.al index 1988a748cd..76de63c08f 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2DimensionSetLines.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2DimensionSetLines.Page.al @@ -23,7 +23,7 @@ page 30022 "APIV2 - Dimension Set Lines" SourceTableTemporary = true; Extensible = false; ODataKeyFields = "Dimension Id"; - AboutText = 'Provides full CRUD access to individual dimension set line records, enabling external systems to manage dimension assignments for transactions such as journal entries, sales, and purchases. Supports retrieval and modification of dimension codes, values, and parent relationships to ensure precise financial tracking and categorization for reporting and cost allocation integrations.'; + AboutText = 'Provides access to individual dimension set line records, enabling external systems to manage dimension assignments for transactions such as journal entries, sales, and purchases. Supports full CRUD operations for retrieval and modification of dimension codes, values, and parent relationships to ensure precise financial tracking and categorization for reporting and cost allocation integrations.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2DimensionValuesEntity.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2DimensionValuesEntity.Page.al index 7a71b93e3a..5bcc2d4466 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2DimensionValuesEntity.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2DimensionValuesEntity.Page.al @@ -17,7 +17,7 @@ page 30040 "APIV2 Dimension Values Entity" PageType = API; EntityName = 'dimensionValue'; EntitySetName = 'dimensionValues'; - AboutText = 'Exposes read-only access to dimension value records, including codes, names, types, consolidation mappings, and status indicators for analytical structures such as departments, cost centers, and projects. Enables external systems and reporting tools to retrieve and synchronize dimension values for financial analysis, transaction categorization, and business intelligence integration. Supports GET operations only, ensuring secure and consistent access to the latest dimension configurations in Business Central.'; + AboutText = 'Exposes dimension value records, including codes, names, types, consolidation mappings, and status indicators for analytical structures such as departments, cost centers, and projects. Enables external systems and reporting tools to retrieve and synchronize dimension values for financial analysis, transaction categorization, and business intelligence integration. Supports GET operations only, ensuring secure and consistent access to the latest dimension configurations in Business Central.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2DisputeStatus.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2DisputeStatus.Page.al index 266a1b8e66..63b1a26e02 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2DisputeStatus.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2DisputeStatus.Page.al @@ -14,7 +14,7 @@ page 30088 "APIV2 - Dispute Status" EntitySetName = 'disputeStatus'; SourceTable = "Dispute Status"; Extensible = false; - AboutText = 'Manages dispute status definitions including code, description, and on-hold update settings, supporting full CRUD operations for tracking and resolving payment or delivery disputes. Enables integration with external CRM, case management, and support systems to standardize dispute workflows and ensure transparent resolution processes.'; + AboutText = 'Manages dispute status definitions including code, description, and on-hold update settings. Supports full CRUD operations for tracking and resolving payment or delivery disputes, enabling integration with external CRM, case management, and support systems to standardize dispute workflows and ensure transparent resolution processes.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2DocumentAttachments.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2DocumentAttachments.Page.al index 6f8ceb73a4..e6bc38cbb3 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2DocumentAttachments.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2DocumentAttachments.Page.al @@ -19,7 +19,7 @@ page 30080 "APIV2 - Document Attachments" SourceTable = "Attachment Entity Buffer"; SourceTableTemporary = true; Extensible = false; - AboutText = 'Manages document attachments linked to sales, purchase, and financial records, enabling external systems to upload, retrieve, update, or delete files such as invoices, orders, and receipts. Supports full CRUD operations for integrating Business Central with document management platforms, automating digital archiving, compliance, and audit documentation workflows.'; + AboutText = 'Manages document attachments linked to sales, purchase, and financial records. Enables external systems to upload, retrieve, update, or delete files such as invoices, orders, and receipts, supporting full CRUD operations for integrating Business Central with document management platforms, automating digital archiving, compliance, and audit documentation workflows.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2FALocations.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2FALocations.Page.al index e35b2f6844..2b9ec5eea6 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2FALocations.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2FALocations.Page.al @@ -11,7 +11,7 @@ page 30097 "APIV2 - FA Locations" EntitySetName = 'fixedAssetLocations'; SourceTable = "FA Location"; Extensible = false; - AboutText = 'Manages fixed asset location records, including codes, names, and last modified dates, enabling full CRUD operations for tracking, auditing, and integrating asset location data with external asset management and accounting systems. Supports scenarios such as monitoring asset whereabouts and maintaining accurate asset records across buildings, departments, or sites.'; + AboutText = 'Manages fixed asset location records, including codes, names, and last modified dates. Supports full CRUD operations for tracking, auditing, and integrating asset location data with external asset management and accounting systems. Enables scenarios such as monitoring asset whereabouts and maintaining accurate asset records across buildings, departments, or sites.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2IncomeStatement.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2IncomeStatement.Page.al index 7522465f04..cc5b49c952 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2IncomeStatement.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2IncomeStatement.Page.al @@ -20,7 +20,7 @@ page 30035 "APIV2 - Income Statement" SourceTableTemporary = true; Extensible = false; ODataKeyFields = Id; - AboutText = 'Provides read-only access to income statement data, including revenues, expenses, net change, and account breakdowns over specified periods. Supports GET operations for financial analysis, automated reporting, and integration with external business intelligence or management dashboards to deliver timely profitability insights.'; + AboutText = 'Provides access to income statement data, including revenues, expenses, net change, and account breakdowns over specified periods. Supports GET operations for financial analysis, automated reporting, and integration with external business intelligence or management dashboards to deliver timely profitability insights.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2ItemCategories.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2ItemCategories.Page.al index 3363d9807f..17fe940332 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2ItemCategories.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2ItemCategories.Page.al @@ -15,7 +15,7 @@ page 30025 "APIV2 - Item Categories" PageType = API; SourceTable = "Item Category"; Extensible = false; - AboutText = 'Manages item category records including codes, descriptions, parent-child relationships, and hierarchy structure, supporting GET, POST, PATCH, and DELETE operations. Enables external systems to organize, classify, and synchronize product categories for catalog management, inventory reporting, and integration with e-commerce or product information management platforms.'; + AboutText = 'Manages item category records including codes, descriptions, parent-child relationships, and hierarchy structure. Supports GET, POST, PATCH, and DELETE operations, enabling external systems to organize, classify, and synchronize product categories for catalog management, inventory reporting, and integration with e-commerce or product information management platforms.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2ItemLedgerEntries.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2ItemLedgerEntries.Page.al index d0dc01c16d..409b1aa1d2 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2ItemLedgerEntries.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2ItemLedgerEntries.Page.al @@ -18,7 +18,7 @@ page 30069 "APIV2 - Item Ledger Entries" SourceTable = "Item Ledger Entry"; Extensible = false; ODataKeyFields = SystemId; - AboutText = 'Provides read-only access to detailed item ledger entries, including inventory transactions such as receipts, shipments, adjustments, and transfers. Supports GET operations to retrieve item numbers, quantities, locations, posting dates, and financial amounts for inventory analysis, audit, and integration with external warehouse management or analytics systems. Enables tracking of inventory movements and reconciliation of stock levels for compliance and reporting purposes.'; + AboutText = 'Provides access to detailed item ledger entries, including inventory transactions such as receipts, shipments, adjustments, and transfers. Supports GET operations to retrieve item numbers, quantities, locations, posting dates, and financial amounts for inventory analysis, audit, and integration with external warehouse management or analytics systems. Enables tracking of inventory movements and reconciliation of stock levels for compliance and reporting purposes.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2JournalLines.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2JournalLines.Page.al index 175a69cd4c..ce1be2fdea 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2JournalLines.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2JournalLines.Page.al @@ -18,7 +18,7 @@ page 30049 "APIV2 - JournalLines" EntitySetName = 'journalLines'; SourceTable = "Gen. Journal Line"; Extensible = false; - AboutText = 'Manages individual general journal line entries, including account details, amounts, dimensions, tax codes, and descriptions, with full CRUD support. Enables external systems to automate creation, retrieval, update, and deletion of journal lines for streamlined financial postings and adjustments. Ideal for integrating payroll, expense management, and accounting solutions to ensure accurate and efficient transaction processing in Business Central.'; + AboutText = 'Manages individual general journal line entries, including account details, amounts, dimensions, tax codes, and descriptions. Supports full CRUD operations, enabling external systems to automate creation, retrieval, update, and deletion of journal lines for streamlined financial postings and adjustments. Ideal for integrating payroll, expense management, and accounting solutions to ensure accurate and efficient transaction processing in Business Central.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2Journals.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2Journals.Page.al index 2cad02a232..563ef548fa 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2Journals.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2Journals.Page.al @@ -17,7 +17,7 @@ page 30016 "APIV2 - Journals" PageType = API; SourceTable = "Gen. Journal Batch"; Extensible = false; - AboutText = 'Exposes general journal batch data including template type, balancing account details, approval status, and VAT settings, supporting full CRUD operations for automating financial postings, accruals, and adjustments. Enables integration with payroll, expense management, and external accounting systems to streamline financial data entry and ensure accurate bookkeeping.'; + AboutText = 'Exposes general journal batch data including template type, balancing account details, approval status, and VAT settings. Supports full CRUD operations for automating financial postings, accruals, and adjustments, enabling integration with payroll, expense management, and external accounting systems to streamline financial data entry and ensure accurate bookkeeping.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2Opportunities.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2Opportunities.Page.al index 832299b1f1..5ce5957821 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2Opportunities.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2Opportunities.Page.al @@ -15,7 +15,7 @@ page 30070 "APIV2 - Opportunities" SourceTable = Opportunity; Extensible = false; ODataKeyFields = SystemId; - AboutText = 'Manages sales opportunity records including stages, estimated values, probability, related contacts, and status, supporting full CRUD operations for pipeline tracking and deal management. Enables integration with external CRM and sales automation platforms to synchronize opportunities, align sales processes, and improve pipeline visibility.'; + AboutText = 'Manages sales opportunity records including stages, estimated values, probability, related contacts, and status. Supports full CRUD operations for pipeline tracking and deal management, enabling integration with external CRM and sales automation platforms to synchronize opportunities, align sales processes, and improve pipeline visibility.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2PDFDocument.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2PDFDocument.Page.al index 80ccaaadc0..acd54b4b28 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2PDFDocument.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2PDFDocument.Page.al @@ -19,7 +19,7 @@ page 30056 "APIV2 - PDF Document" PageType = API; SourceTable = "Attachment Entity Buffer"; SourceTableTemporary = true; - AboutText = 'Provides access to PDF versions of business documents such as invoices, orders, and quotes for retrieval and sharing. Supports GET operations to fetch PDF files for integration with document management systems, electronic invoicing solutions, and automated distribution workflows. Enables external systems to streamline digital document handling and ensure compliance with electronic document standards.'; + AboutText = 'Provides access to PDF versions of business documents such as invoices, orders, and quotes. Supports GET operations to fetch PDF files for retrieval and sharing, enabling integration with document management systems, electronic invoicing solutions, and automated distribution workflows. Enables external systems to streamline digital document handling and ensure compliance with electronic document standards.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2PowerBILabels.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2PowerBILabels.Page.al index 45be0b847a..163c108afe 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2PowerBILabels.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2PowerBILabels.Page.al @@ -22,7 +22,7 @@ page 30078 "APIV2 - Power BI Labels" SourceTableTemporary = true; Extensible = false; ODataKeyFields = "Label ID"; - AboutText = 'Exposes read-only access to report label definitions, including label IDs and text values, from the Power BI Report Labels table. Enables external analytics platforms and reporting tools to retrieve and synchronize standardized or multilingual label terminology used in Business Central reports. Supports GET operations only, making it suitable for scenarios requiring consistent labeling and localization across integrated reporting environments without permitting direct modification of label data.'; + AboutText = 'Exposes report label definitions, including label IDs and text values, from the Power BI Report Labels table. Enables external analytics platforms and reporting tools to retrieve and synchronize standardized or multilingual label terminology used in Business Central reports. Supports GET operations only, making it suitable for scenarios requiring consistent labeling and localization across integrated reporting environments without permitting direct modification of label data.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2PurchReceiptLines.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2PurchReceiptLines.Page.al index 353a89a1cb..070de12ad3 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2PurchReceiptLines.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2PurchReceiptLines.Page.al @@ -19,7 +19,7 @@ page 30065 "APIV2 - Purch Receipt Lines" EntitySetName = 'purchaseReceiptLines'; SourceTable = "Purch. Rcpt. Line"; Extensible = false; - AboutText = 'Provides read-only access to detailed purchase receipt line data, including received items, quantities, unit costs, discounts, tax amounts, locations, and links to related purchase and sales orders. Supports GET operations for retrieving receipt line information to enable integration with warehouse management, automate inventory reconciliation, and facilitate three-way matching and supplier performance analysis. Ideal for external systems and reporting solutions that require accurate, up-to-date receipt line details for procurement and inventory workflows.'; + AboutText = 'Provides access to detailed purchase receipt line data, including received items, quantities, unit costs, discounts, tax amounts, locations, and links to related purchase and sales orders. Supports GET operations for retrieving receipt line information to enable integration with warehouse management, automate inventory reconciliation, and facilitate three-way matching and supplier performance analysis. Ideal for external systems and reporting solutions that require accurate, up-to-date receipt line details for procurement and inventory workflows.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2RetainedEarnings.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2RetainedEarnings.Page.al index 79485a2be4..c30ce05b3e 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2RetainedEarnings.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2RetainedEarnings.Page.al @@ -20,7 +20,7 @@ page 30029 "APIV2 - Retained Earnings" SourceTableTemporary = true; Extensible = false; ODataKeyFields = Id; - AboutText = 'Provides read-only access to retained earnings statement data, including net changes, descriptions, fiscal period breakdowns, and company-level summaries. Supports GET operations for automating financial reporting, enabling integration with external accounting, consolidation, compliance, and audit systems requiring up-to-date retained earnings insights.'; + AboutText = 'Provides access to retained earnings statement data, including net changes, descriptions, fiscal period breakdowns, and company-level summaries. Supports GET operations for automating financial reporting, enabling integration with external accounting, consolidation, compliance, and audit systems requiring up-to-date retained earnings insights.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2SalesShipmentLines.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2SalesShipmentLines.Page.al index 0f1f3a266f..66476b846d 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2SalesShipmentLines.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2SalesShipmentLines.Page.al @@ -19,7 +19,7 @@ page 30063 "APIV2 - Sales Shipment Lines" EntitySetName = 'salesShipmentLines'; SourceTable = "Sales Shipment Line"; Extensible = false; - AboutText = 'Provides read-only access to detailed sales shipment line data, including shipped items, quantities, unit pricing, discounts, tax information, shipment dates, locations, and links to related sales and purchase documents. Enables external systems to retrieve and synchronize granular shipment information for warehouse management, packing list automation, customer service, and inventory reconciliation. Ideal for integrations requiring accurate tracking and reporting of shipped goods within Business Central, with support for GET operations only.'; + AboutText = 'Provides access to detailed sales shipment line data, including shipped items, quantities, unit pricing, discounts, tax information, shipment dates, locations, and links to related sales and purchase documents. Enables external systems to retrieve and synchronize granular shipment information for warehouse management, packing list automation, customer service, and inventory reconciliation. Ideal for integrations requiring accurate tracking and reporting of shipped goods within Business Central, with support for GET operations only.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2ShipmentMethods.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2ShipmentMethods.Page.al index 5eda0091f3..bdbb484e20 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2ShipmentMethods.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2ShipmentMethods.Page.al @@ -15,7 +15,7 @@ page 30024 "APIV2 - Shipment Methods" PageType = API; SourceTable = "Shipment Method"; Extensible = false; - AboutText = 'Manages shipment method definitions including codes, descriptions, and CRM coupling status, supporting full CRUD operations to synchronize shipping options across Business Central and external logistics or e-commerce platforms for consistent order fulfillment and customer service.'; + AboutText = 'Manages shipment method definitions including codes, and descriptions. Supports full CRUD operations to synchronize shipping options across Business Central and external logistics or e-commerce platforms for consistent order fulfillment and customer service.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2TaxAreas.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2TaxAreas.Page.al index ebc83a39da..503b4dfd2e 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2TaxAreas.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2TaxAreas.Page.al @@ -15,7 +15,7 @@ page 30036 "APIV2 - Tax Areas" SourceTableTemporary = true; Extensible = false; ODataKeyFields = Id; - AboutText = 'Manages tax area definitions including code, description, tax type (Sales Tax or VAT), and last modified date, supporting full CRUD operations for synchronizing tax area data with external tax engines, e-commerce platforms, and compliance automation systems to ensure accurate tax calculation for sales and purchasing transactions.'; + AboutText = 'Manages tax area definitions including code, description, tax type (Sales Tax or VAT), and last modified date. Supports full CRUD operations for synchronizing tax area data with external tax engines, e-commerce platforms, and compliance automation systems to ensure accurate tax calculation for sales and purchasing transactions.'; layout { diff --git a/Apps/W1/APIV2/app/src/pages/APIV2UnitsofMeasure.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2UnitsofMeasure.Page.al index 7c736bd35f..ad9f786382 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2UnitsofMeasure.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2UnitsofMeasure.Page.al @@ -15,7 +15,7 @@ page 30030 "APIV2 - Units of Measure" PageType = API; SourceTable = "Unit of Measure"; Extensible = false; - AboutText = 'Manages unit of measure definitions including code, description, international standard code, and symbol, supporting full CRUD operations for synchronizing measurement units across product catalogs and inventory systems. Enables external integrations to maintain consistent units for accurate inventory tracking, sales processing, and cross-system data alignment.'; + AboutText = 'Manages unit of measure definitions including code, description, international standard code, and symbol. Supports full CRUD operations for synchronizing measurement units across product catalogs and inventory systems, enabling external integrations to maintain consistent units for accurate inventory tracking, sales processing, and cross-system data alignment.'; layout { diff --git a/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/UpgTagDefAutoAccCodes.Codeunit.al b/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/UpgTagDefAutoAccCodes.Codeunit.al deleted file mode 100644 index 387be6f1fa..0000000000 --- a/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/UpgTagDefAutoAccCodes.Codeunit.al +++ /dev/null @@ -1,30 +0,0 @@ -#if not CLEAN25 -// ------------------------------------------------------------------------------------------------ -// 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.AutomaticAccounts; - -using System.Upgrade; - -codeunit 4855 "Upg. Tag Def. Auto. Acc. Codes" -{ - ObsoleteReason = 'Automatic Acc.functionality is moved to a new app.'; - ObsoleteState = Pending; -#pragma warning disable AS0072 - ObsoleteTag = '25.0'; -#pragma warning restore AS0072 - Access = Internal; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"Upgrade Tag", 'OnGetPerCompanyUpgradeTags', '', false, false)] - local procedure RegisterPerCompanyTags(var PerCompanyUpgradeTags: List of [Code[250]]) - begin - PerCompanyUpgradeTags.Add(GetAutoAccCodesUpgradeTag()); - end; - - internal procedure GetAutoAccCodesUpgradeTag(): Code[250] - begin - exit('547087-AutoAccCodesUpgrade-20240830'); - end; -} -#endif \ No newline at end of file diff --git a/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/UpgradeAutoAccCodes.Codeunit.al b/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/UpgradeAutoAccCodes.Codeunit.al deleted file mode 100644 index 3fd3e6d9df..0000000000 --- a/Apps/W1/AutomaticAccountCodes/app/src/Codeunits/UpgradeAutoAccCodes.Codeunit.al +++ /dev/null @@ -1,132 +0,0 @@ -#if not CLEAN25 -// ------------------------------------------------------------------------------------------------ -// 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.AutomaticAccounts; - -using System.Environment; -using Microsoft.Purchases.Document; -using Microsoft.Sales.Document; -using Microsoft.Finance.GeneralLedger.Journal; -using Microsoft.Finance.GeneralLedger.Account; -using System.Upgrade; -using System.Reflection; - -codeunit 4854 "Upgrade Auto. Acc. Codes" -{ - ObsoleteReason = 'Automatic Acc.functionality is moved to a new app.'; - ObsoleteState = Pending; -#pragma warning disable AS0072 - ObsoleteTag = '25.0'; -#pragma warning restore AS0072 - Access = Internal; - Subtype = Upgrade; - - trigger OnUpgradePerCompany() - var - EnvironmentInformation: Codeunit "Environment Information"; - UpgradeTag: Codeunit "Upgrade Tag"; - UpgTagDefAutoAccCodes: Codeunit "Upg. Tag Def. Auto. Acc. Codes"; - Localization: Text; - begin - Localization := EnvironmentInformation.GetApplicationFamily(); - if (Localization <> 'SE') and (Localization <> 'FI') then begin - UpgradeTag.SetUpgradeTag(UpgTagDefAutoAccCodes.GetAutoAccCodesUpgradeTag()); - exit; - end; - - if UpgradeTag.HasUpgradeTag(UpgTagDefAutoAccCodes.GetAutoAccCodesUpgradeTag()) then - exit; - UpgradeAutomaticAccountCodes(); - UpgradeTag.SetUpgradeTag(UpgTagDefAutoAccCodes.GetAutoAccCodesUpgradeTag()); - end; - - local procedure UpgradeAutomaticAccountCodes() - var - AutoAccPageSetup: Record "Auto. Acc. Page Setup"; - AutomaticAccHeaderTableId: Integer; - AutomaticAccLineTableId: Integer; - begin - // if there is record in the AutoAccPageSetuptable then the feature is already enabled - if not AutoAccPageSetup.IsEmpty() then - exit; - - AutomaticAccHeaderTableId := 11203; // Database::"Automatic Acc. Header"; - AutomaticAccLineTableId := 11204; // Database::"Automatic Acc. Line"; - TransferRecords(AutomaticAccHeaderTableId, Database::"Automatic Account Header"); - TransferRecords(AutomaticAccLineTableId, Database::"Automatic Account Line"); - TransferFields(Database::"G/L Account", 11200, 4850); // 4850 - the new field "Automatic Account Group", 11200; the existing field "Auto. Acc. Group"; - TransferFields(Database::"Gen. Journal Line", 11201, 4852);// 4852 - the new field "Automatic Account Group", 11201; the existing field "Auto. Acc. Group"; - TransferFields(Database::"Sales Line", 11200, 4850); // 4850 - the new field "Automatic Account Group", 11200; the existing field "Auto. Acc. Group"; - TransferFields(Database::"Purchase Line", 11200, 4850);// 4850 - the new field "Automatic Account Group", 11200; the existing field "Auto. Acc. Group"; - - RemoveAutomaticAccountCodes(AutomaticAccHeaderTableId); - RemoveAutomaticAccountCodes(AutomaticAccLineTableId); - end; - - local procedure RemoveAutomaticAccountCodes(TableId: Integer) - var - RecordRef: RecordRef; - begin - if TableId = 0 then - exit; - RecordRef.Open(TableId, false); - RecordRef.DeleteAll(); - RecordRef.Close(); - end; - - local procedure TransferRecords(SourceTableId: Integer; TargetTableId: Integer) - var - SourceField: Record Field; - SourceRecRef: RecordRef; - TargetRecRef: RecordRef; - TargetFieldRef: FieldRef; - SourceFieldRef: FieldRef; - SourceFieldRefNo: Integer; - begin - SourceRecRef.Open(SourceTableId, false); - TargetRecRef.Open(TargetTableId, false); - - if SourceRecRef.IsEmpty() then - exit; - - SourceRecRef.FindSet(); - - repeat - Clear(SourceField); - SourceField.SetRange(TableNo, SourceTableId); - SourceField.SetRange(Class, SourceField.Class::Normal); - SourceField.SetRange(Enabled, true); - if SourceField.Findset() then - repeat - SourceFieldRefNo := SourceField."No."; - SourceFieldRef := SourceRecRef.Field(SourceFieldRefNo); - TargetFieldRef := TargetRecRef.Field(SourceFieldRefNo); - TargetFieldRef.VALUE := SourceFieldRef.VALUE; - until SourceField.Next() = 0; - TargetRecRef.Insert(); - until SourceRecRef.Next() = 0; - SourceRecRef.Close(); - TargetRecRef.Close(); - end; - - local procedure TransferFields(TableId: Integer; SourceFieldNo: Integer; TargetFieldNo: Integer) - var - RecRef: RecordRef; - TargetFieldRef: FieldRef; - SourceFieldRef: FieldRef; - begin - RecRef.Open(TableId, false); - SourceFieldRef := RecRef.Field(SourceFieldNo); - SourceFieldRef.SetFilter('<>%1', ''); - - if RecRef.FindSet() then - repeat - TargetFieldRef := RecRef.Field(TargetFieldNo); - TargetFieldRef.VALUE := SourceFieldRef.VALUE; - RecRef.Modify(false); - until RecRef.Next() = 0; - end; -} -#endif \ No newline at end of file diff --git a/Apps/W1/BankAccRecWithAI/app/src/BankAccReconciliationExt.PageExt.al b/Apps/W1/BankAccRecWithAI/app/src/BankAccReconciliationExt.PageExt.al index 52c155183b..1e5024d6e9 100644 --- a/Apps/W1/BankAccRecWithAI/app/src/BankAccReconciliationExt.PageExt.al +++ b/Apps/W1/BankAccRecWithAI/app/src/BankAccReconciliationExt.PageExt.al @@ -131,35 +131,6 @@ pageextension 7253 BankAccReconciliationExt extends "Bank Acc. Reconciliation" end; } } -#if not CLEAN25 - addbefore("Transfer to General Journal_Promoted") - { - actionref("Match With Copilot_Promoted"; "Match With Copilot") - { - Visible = false; - ObsoleteReason = 'Actions no longer promoted, but shown in the Prompting area'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - } - actionref("Transfer to G/L Account_Promoted"; "Transfer to G/L Account") - { - Visible = false; - ObsoleteReason = 'Actions no longer promoted, but shown in the Prompting area'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - } - } - addbefore(MatchAutomatically_Promoted) - { - actionref("Match With Copilot_Promoted2"; "Match With Copilot") - { - Visible = false; - ObsoleteReason = 'Actions no longer promoted, but shown in the Prompting area'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - } - } -#endif } trigger OnOpenPage() diff --git a/Apps/W1/BankDeposits/app/src/pages/BankDepositSubform.Page.al b/Apps/W1/BankDeposits/app/src/pages/BankDepositSubform.Page.al index fb7de69831..4a2e6f4e48 100644 --- a/Apps/W1/BankDeposits/app/src/pages/BankDepositSubform.Page.al +++ b/Apps/W1/BankDeposits/app/src/pages/BankDepositSubform.Page.al @@ -518,7 +518,20 @@ page 1693 "Bank Deposit Subform" if CustLedgerEntry."Applies-to ID" = '' then exit; end; - Rec."Applies-to ID" := BankDepositPost.GetAppliesToIDForLine(BankDepositHeader."No.", Rec."Line No."); + if CheckCustomerApplicationMethod() then + Rec."Applies-to ID" := BankDepositPost.GetAppliesToIDForLine(BankDepositHeader."No.", Rec."Line No."); + end; + + local procedure CheckCustomerApplicationMethod(): Boolean + var + Customer: Record Customer; + begin + if Rec."Account Type" <> Rec."Account Type"::Customer then + exit(true); + + if Customer.Get(Rec."Account No.") then + if Customer."Application Method" <> Customer."Application Method"::"Apply to Oldest" then + exit(true); end; [IntegrationEvent(true, false)] diff --git a/Apps/W1/BankDeposits/test/src/BankDepositPostingTests.Codeunit.al b/Apps/W1/BankDeposits/test/src/BankDepositPostingTests.Codeunit.al index e0cb2f11a6..ccc9ee057e 100644 --- a/Apps/W1/BankDeposits/test/src/BankDepositPostingTests.Codeunit.al +++ b/Apps/W1/BankDeposits/test/src/BankDepositPostingTests.Codeunit.al @@ -27,6 +27,8 @@ codeunit 139769 "Bank Deposit Posting Tests" PostedDepositLinkErr: Label 'Posted Deposit is missing a link.', Locked = true; SingleHeaderAllowedErr: Label 'Only one %1 is allowed for each %2. Choose Change Batch action if you want to create a new bank deposit.', Locked = true; BatchNameErr: Label 'Batch Name must be %1 on %2', Comment = '%1 - Batch Name , %2 - Field Name'; + RemainingAmountErr: Label 'Remaining amount must be 0.'; + CustLedgerEntryOpenErr: Label 'Cust. Ledger Entry must be close.'; [Test] [HandlerFunctions('GeneralJournalBatchesPageHandler,ConfirmHandler')] @@ -950,6 +952,37 @@ codeunit 139769 "Bank Deposit Posting Tests" PostedBankDepositLine.TestField("Reason Code", ReasonCode.Code); end; + [Test] + [HandlerFunctions('GeneralJournalBatchesPageHandler,ConfirmHandler')] + procedure VerifyCustomerLedgerEntryClosedWithApplyToOldestBankDeposit() + var + BankDepositHeader: Record "Bank Deposit Header"; + Customer: Record Customer; + GenJournalLine: Record "Gen. Journal Line"; + GLAccount: Record "G/L Account"; + InvoiceAmount: Decimal; + begin + // [SCENARIO 606537] When Posting a Bank Deposit with several lines the Apply to Oldest is not applied properly. + Initialize(); + + // [GIVEN] Create GL Account and Customer with Application Method Apply to Oldest. + LibraryERM.CreateGLAccount(GLAccount); + CreateCustomerWithApplicationMethod(Customer); + + // [GIVEN] Create and post sales order. + CreateandPostSalesOrder(Customer."No.", InvoiceAmount); + + // [GIVEN] Create Bank Deposit with Customer Line and G/L Line. + CreateDepositDocument(BankDepositHeader, Customer."No.", GenJournalLine."Account Type"::Customer, InvoiceAmount); + + // [WHEN] Update Total Deposit Amount on Bank Deposit Header and Post Bank Deposit. + UpdateBankDepositHeaderWithAmount(BankDepositHeader); + PostBankDeposit(BankDepositHeader); + + // [THEN] Verify Customer Ledger Entry is closed. + VerifyCustomerLedgerEntry(Customer."No."); + end; + local procedure Initialize() var InventorySetup: Record "Inventory Setup"; @@ -1237,6 +1270,70 @@ codeunit 139769 "Bank Deposit Posting Tests" Assert.AreEqual(ActualReversedValue, ExpectedReversed, ReversedErr); end; + local procedure VerifyCustomerLedgerEntry(CustomerNo: Code[20]) + var + CustLedgerEntry: Record "Cust. Ledger Entry"; + begin + CustLedgerEntry.SetRange("Customer No.", CustomerNo); + CustLedgerEntry.SetRange("Document Type", CustLedgerEntry."Document Type"::Payment); + CustLedgerEntry.FindSet(); + repeat + CustLedgerEntry.CalcFields("Remaining Amount"); + Assert.AreEqual(0, CustLedgerEntry."Remaining Amount", RemainingAmountErr); + Assert.AreEqual(false, CustLedgerEntry.Open, CustLedgerEntryOpenErr); + until CustLedgerEntry.Next() = 0; + end; + + local procedure CreateDepositDocument(var BankDepositHeader: Record "Bank Deposit Header"; AccountNo: Code[20]; AccountType: Enum "Gen. Journal Account Type"; Amount: Decimal) + var + GenJournalTemplate: Record "Gen. Journal Template"; + GenJournalBatch: Record "Gen. Journal Batch"; + BankDeposit: TestPage "Bank Deposit"; + begin + CreateGenJournalBatch(GenJournalBatch, GenJournalTemplate.Type::"Bank Deposits"); + CreateBankDepositHeaderWithBankAccount(BankDepositHeader, GenJournalBatch); + + BankDeposit.Trap(); + BankDepositHeader.SetRecFilter(); + Page.Run(Page::"Bank Deposit", BankDepositHeader); + BankDeposit.Subform.Next(); + BankDeposit.Subform."Account Type".SetValue(AccountType); + BankDeposit.Subform."Account No.".SetValue(AccountNo); + BankDeposit.Subform."Credit Amount".SetValue(Amount); + BankDeposit.Close(); + end; + + local procedure CreateandPostSalesOrder(CustomerNo: Code[20]; var Amount: Decimal) + var + Item: Record Item; + SalesHeader: Record "Sales Header"; + SalesLine: Record "Sales Line"; + begin + LibraryInventory.CreateItem(Item); + LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader."Document Type"::Order, CustomerNo); + LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item."No.", 1); + SalesLine.Validate("Unit Price", LibraryRandom.RandDec(1000, 2)); + SalesLine.Modify(true); + + Amount := SalesLine.Amount; + LibrarySales.PostSalesDocument(SalesHeader, true, true); + end; + + local procedure CreateCustomerWithApplicationMethod(var Customer: Record Customer) + var + PaymentTerms: Record "Payment Terms"; + PaymentMethod: Record "Payment Method"; + begin + LibraryERM.CreatePaymentTerms(PaymentTerms); + LibraryERM.CreatePaymentMethod(PaymentMethod); + LibrarySales.CreateCustomer(Customer); + + Customer.Validate("Payment Method Code", PaymentMethod.Code); + Customer.Validate("Payment Terms Code", PaymentTerms.Code); + Customer.Validate("Application Method", Customer."Application Method"::"Apply to Oldest"); + Customer.Modify(); + end; + [ModalPageHandler] procedure GeneralJournalBatchesPageHandler(var GeneralJournalBatches: TestPage "General Journal Batches") begin diff --git a/Apps/W1/ClientAddIns/.objidconfig b/Apps/W1/ClientAddIns/app/.objidconfig similarity index 100% rename from Apps/W1/ClientAddIns/.objidconfig rename to Apps/W1/ClientAddIns/app/.objidconfig diff --git a/Apps/W1/ClientAddIns/ExtensionLogo.png b/Apps/W1/ClientAddIns/app/ExtensionLogo.png similarity index 100% rename from Apps/W1/ClientAddIns/ExtensionLogo.png rename to Apps/W1/ClientAddIns/app/ExtensionLogo.png diff --git a/Apps/W1/ClientAddIns/app.json b/Apps/W1/ClientAddIns/app/app.json similarity index 100% rename from Apps/W1/ClientAddIns/app.json rename to Apps/W1/ClientAddIns/app/app.json diff --git a/Apps/W1/ClientAddIns/src/oauth/OAuthAddIn.ControlAddin.al b/Apps/W1/ClientAddIns/app/src/oauth/OAuthAddIn.ControlAddin.al similarity index 100% rename from Apps/W1/ClientAddIns/src/oauth/OAuthAddIn.ControlAddin.al rename to Apps/W1/ClientAddIns/app/src/oauth/OAuthAddIn.ControlAddin.al diff --git a/Apps/W1/ClientAddIns/src/oauth/js/OAuthIntegration.js b/Apps/W1/ClientAddIns/app/src/oauth/js/OAuthIntegration.js similarity index 100% rename from Apps/W1/ClientAddIns/src/oauth/js/OAuthIntegration.js rename to Apps/W1/ClientAddIns/app/src/oauth/js/OAuthIntegration.js diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/HumanResources/2. MasterData/CreateEmployee.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/HumanResources/2. MasterData/CreateEmployee.Codeunit.al index 536692b7f3..79ad2d2f2b 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/HumanResources/2. MasterData/CreateEmployee.Codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/HumanResources/2. MasterData/CreateEmployee.Codeunit.al @@ -17,6 +17,7 @@ codeunit 5164 "Create Employee" begin CreateEmployee(); UpdateEmployeesDetails(); + UpdateEmployeeManagers(); end; local procedure CreateEmployee() @@ -54,6 +55,18 @@ codeunit 5164 "Create Employee" ContosoEmployee.UpdateEmployeeDetails(InventoryManager(), 19631207D, 19960301D, BJamesRoadLbl, '', '4653', '1234-6545-8799', '0678-8712-5466', '', '0705491679', '234654-631'); end; + procedure UpdateEmployeeManagers() + var + ContosoEmployee: Codeunit "Contoso Human Resources"; + begin + ContosoEmployee.UpdateEmployeeManager(SalesManager(), ManagingDirector()); + ContosoEmployee.UpdateEmployeeManager(ProductionManager(), ManagingDirector()); + ContosoEmployee.UpdateEmployeeManager(Designer(), ProductionManager()); + ContosoEmployee.UpdateEmployeeManager(Secretary(), ManagingDirector()); + ContosoEmployee.UpdateEmployeeManager(ProductionAssistant(), ProductionManager()); + ContosoEmployee.UpdateEmployeeManager(InventoryManager(), ManagingDirector()); + end; + var EsterLbl: Label 'Ester', MaxLength = 30; HendersonLbl: Label 'Henderson', MaxLength = 30; diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoHumanResources.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoHumanResources.Codeunit.al index 142d8a436a..00cf591fe9 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoHumanResources.Codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoHumanResources.Codeunit.al @@ -327,6 +327,15 @@ codeunit 5171 "Contoso Human Resources" Employee.Modify(true); end; + procedure UpdateEmployeeManager(EmployeeNo: Code[20]; ManagerNo: Code[20]) + var + Employee: Record Employee; + begin + Employee.Get(EmployeeNo); + Employee.Validate("Manager No.", ManagerNo); + Employee.Modify(true); + end; + procedure InsertEmployeePostingGroup(PostingGroupCode: Code[20]; PayableAccount: Code[20]) var EmployeePostingGroup: Record "Employee Posting Group"; diff --git a/Apps/W1/EDocumentConnectors/Microsoft365/app/src/OutlookProcessing.Codeunit.al b/Apps/W1/EDocumentConnectors/Microsoft365/app/src/OutlookProcessing.Codeunit.al index 11f856b8b9..30ce297afa 100644 --- a/Apps/W1/EDocumentConnectors/Microsoft365/app/src/OutlookProcessing.Codeunit.al +++ b/Apps/W1/EDocumentConnectors/Microsoft365/app/src/OutlookProcessing.Codeunit.al @@ -205,23 +205,6 @@ codeunit 6385 "Outlook Processing" AttachmentsAdded := 0; EDocWithNoAttachmentName := StrSubstNo(TooManyAttachmentsTxt, GetMaxNoOfAttachmentsPerEmail()); end; - // if an e-mail message has no attachments of supported type, add it as well - // it must be represented as an e-document with no attachment - if (AttachmentsAdded = 0) and (IgnoredBecauseExisting = 0) then - if not IgnoreMailMessage(EmailInbox."External Message Id") then begin - Clear(Attachment); - Clear(TempBlob); - Attachment.Add('emailInboxId', EmailInbox.Id); - Attachment.Add('messageid', EmailInbox."Message Id"); - Attachment.Add('externalmessageid', EmailInbox."External Message Id"); - Attachment.Add('receiveddatetime', EmailInbox."Received DateTime"); - Attachment.Add('id', 0); - Attachment.Add('size', 0); - Attachment.Add('contentType', 'none'); - Attachment.Add('contentId', 'none'); - Attachment.Add('name', EDocWithNoAttachmentName); - DocumentsArray.Add(Attachment); - end; Clear(TelemetryCustomDimensions); TelemetryCustomDimensions.Add('Category', FeatureName()); TelemetryCustomDimensions.Add('ReceivedDateTime', Format(EmailInbox."Received DateTime")); @@ -248,25 +231,36 @@ codeunit 6385 "Outlook Processing" end; end; - internal procedure IgnoreMailAttachment(AttachmentLength: Integer; AttachmentContentType: Text): Boolean // this procedure is internal to be called by tests + internal procedure IgnoreMailAttachment(AttachmentLength: Integer; AttachmentContentType: Text; FileName: Text): Boolean // this procedure is internal to be called by tests + var + FileManagement: Codeunit "File Management"; + Extension: Text; begin if AttachmentLength > SizeThreshold() then begin Session.LogMessage('0000PKI', 'Ignoring attachment because it exceeds size threshold.', Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::All, 'Category', FeatureName()); exit(true); end; - if LowerCase(AttachmentContentType) <> 'application/pdf' then begin - Session.LogMessage('0000PKJ', 'Ignoring attachment because it the attachment is not of a supported type.', Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::All, 'Category', FeatureName()); - exit(true); + AttachmentContentType := LowerCase(AttachmentContentType); + + if AttachmentContentType = 'application/pdf' then + exit(false); + + if AttachmentContentType = 'application/octet-stream' then begin + Extension := FileManagement.GetExtension(FileName); + if LowerCase(Extension) = 'pdf' then + exit(false); end; - exit(false); + + Session.LogMessage('0000PKJ', 'Ignoring attachment because it the attachment is not of a supported type.', Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::All, 'Category', FeatureName()); + exit(true); end; local procedure IgnoreMailAttachment(EmailMessage: Codeunit "Email Message"; ExternalMessageId: Text[2048]; var IgnoredBecauseExisting: Integer): Boolean var EDocument: Record "E-Document"; begin - if IgnoreMailAttachment(EmailMessage.Attachments_GetLength(), EmailMessage.Attachments_GetContentType()) then + if IgnoreMailAttachment(EmailMessage.Attachments_GetLength(), EmailMessage.Attachments_GetContentType(), EmailMessage.Attachments_GetName()) then exit(true); EDocument.ReadIsolation := IsolationLevel::ReadCommitted; @@ -281,20 +275,6 @@ codeunit 6385 "Outlook Processing" exit(false) end; - local procedure IgnoreMailMessage(ExternalMessageId: Text[2048]): Boolean - var - EDocument: Record "E-Document"; - begin - EDocument.ReadIsolation := IsolationLevel::ReadCommitted; - EDocument.SetRange("Outlook Mail Message Id", ExternalMessageId); - if not EDocument.IsEmpty() then begin - Session.LogMessage('0000QIM', 'Ignoring mail message because it is already imported.', Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::All, 'Category', FeatureName()); - exit(true); - end; - - exit(false) - end; - local procedure PageCountThreshold(): Integer begin exit(10) @@ -352,18 +332,6 @@ codeunit 6385 "Outlook Processing" if Evaluate(MessageIdGuid, MessageId) then EDocument."Mail Message Id" := MessageIdGuid; - // this is the representation of email without supported attachment. register it in E-Document table. - if (AttachmentId = 0) and (ContentType = 'none') then - if EmailMessage.Get(MessageId) then begin - EDocument."Structure Data Impl." := "Structure Received E-Doc."::"Already Structured"; - EDocument."Read into Draft Impl." := "E-Doc. Read Into Draft"::"Blank Draft"; - ReceiveContext.GetTempBlob().CreateOutStream(DocumentOutStream, TextEncoding::UTF8); - if EmailMessage.Get(MessageId) then; - DocumentOutStream.WriteText(EmailMessage.GetBody()); - EDocument.Modify(); - exit; - end; - if EmailMessage.Get(MessageId) then if EmailMessage.Attachments_First() then repeat diff --git a/Apps/W1/EDocumentConnectors/Microsoft365/test/src/OutlookIntTest.Codeunit.al b/Apps/W1/EDocumentConnectors/Microsoft365/test/src/OutlookIntTest.Codeunit.al index e8c6dcbefa..5baf3f4dcd 100644 --- a/Apps/W1/EDocumentConnectors/Microsoft365/test/src/OutlookIntTest.Codeunit.al +++ b/Apps/W1/EDocumentConnectors/Microsoft365/test/src/OutlookIntTest.Codeunit.al @@ -398,7 +398,7 @@ codeunit 148198 "Outlook Int. Test" Mock: JsonObject; begin Mock.ReadFrom(JsonText); - if OutlookProcessing.IgnoreMailAttachment(Mock.GetInteger('size'), Mock.GetText('contentType')) then + if OutlookProcessing.IgnoreMailAttachment(Mock.GetInteger('size'), Mock.GetText('contentType'), 'file.pdf') then exit; MockArray.Add(Mock); end; diff --git a/Apps/W1/Email - Outlook REST API/app/src/EmailOutlookAPIHelper.Codeunit.al b/Apps/W1/Email - Outlook REST API/app/src/EmailOutlookAPIHelper.Codeunit.al index c076076e82..1b67c90f70 100644 --- a/Apps/W1/Email - Outlook REST API/app/src/EmailOutlookAPIHelper.Codeunit.al +++ b/Apps/W1/Email - Outlook REST API/app/src/EmailOutlookAPIHelper.Codeunit.al @@ -195,17 +195,6 @@ codeunit 4509 "Email - Outlook API Helper" exit(RecipientsJson); end; -#if not CLEAN25 - [NonDebuggable] - [Obsolete('Replaced by an overload that takes in SecretText data type for ClientSecret', '25.0')] - procedure GetClientIDAndSecret(var ClientId: Text; var ClientSecret: Text) - var - Secret: SecretText; - begin - GetClientIDAndSecret(ClientId, Secret); - ClientSecret := Secret.Unwrap(); - end; -#endif procedure GetClientIDAndSecret(var ClientId: Text; var ClientSecret: SecretText) var diff --git a/Apps/W1/Email - SMTP Connector/app/src/Authentication/OAuth2SMTPAuthentication.Codeunit.al b/Apps/W1/Email - SMTP Connector/app/src/Authentication/OAuth2SMTPAuthentication.Codeunit.al index e69df3e399..ee70fa868e 100644 --- a/Apps/W1/Email - SMTP Connector/app/src/Authentication/OAuth2SMTPAuthentication.Codeunit.al +++ b/Apps/W1/Email - SMTP Connector/app/src/Authentication/OAuth2SMTPAuthentication.Codeunit.al @@ -6,8 +6,9 @@ namespace System.Email; using System.Azure.Identity; -using System.Text; +using System.Environment; using System.Security.Authentication; +using System.Text; codeunit 4516 "OAuth2 SMTP Authentication" { @@ -17,12 +18,15 @@ codeunit 4516 "OAuth2 SMTP Authentication" CouldNotAuthenticateErr: Label 'Could not authenticate. To resolve the problem, choose the Authenticate action on the SMTP Account page.'; AuthenticationSuccessfulMsg: Label '%1 was authenticated.', Comment = '%1 - user email, for example, admin@domain.com'; AuthenticationFailedMsg: Label 'Could not authenticate.'; - SMTPAuthorityCannotBeEmptyErr: Label 'SMTP Authority cannot be empty.'; GetSMTPClientSecretFailedErr: Label 'Failed to get SMTP Client Secret Storage Id.'; GetSMTPClientIdFailedErr: Label 'Failed to get SMTP Client Id.'; FetchAccessTokenFromHttpsErr: Label 'Failed to acquire access token. HTTP Status: %1.', Comment = '%1 - Status code of http request.'; NoTokenInReposonseErr: Label 'The response does not contain an access token.'; FailedToParseResponseErr: Label 'Failed to parse the response as JSON.'; + AdminConsentErrLbl: Label 'Consent authorization failed. Please try again or contact your administrator.'; + TelemetryCategoryLbl: Label 'SMTP OAuth2 Authentication', Locked = true; + UsingCustomizedOAuth2TelemetryLbl: Label 'Using customized OAuth2 for SMTP authentication.', Locked = true; + UsingDefaultOAuth2TelemetryLbl: Label 'Using default OAuth2 for SMTP authentication.', Locked = true; /// /// Provide the credentials to authenticate using OAuth 2.0 for Exchange Online mailboxes. @@ -58,21 +62,26 @@ codeunit 4516 "OAuth2 SMTP Authentication" end; [NonDebuggable] - internal procedure AuthenticateWithOAuth2CustomAppReg(SMTPAccount: Record "SMTP Account") + internal procedure AuthenticateWithOAuth2CustomAppReg(var SMTPAccount: Record "SMTP Account") var - AzureAdMgt: Codeunit "Azure AD Mgt."; OAuth2: Codeunit OAuth2; - ClientId: Text; + EnvironmentInformation: Codeunit "Environment Information"; + ClientId: SecretText; ClientSecret: SecretText; PermissionGrantError: Text; + RedirectUri: Text; ConsentGranted: Boolean; - AdminConsentErrLbl: Label 'Consent authorization failed. Please try again or contact your administrator.'; + ConsentUrlLbl: Label 'https://login.microsoftonline.com/common/adminconsent', Locked = true; begin - if not IsolatedStorage.Get(SMTPAccount."Client Id Storage Id", ClientId) then Error(GetSMTPClientIdFailedErr); + ClientId := SMTPAccount.GetClientId(SMTPAccount."Client Id Storage Id"); + if ClientId.IsEmpty() then Error(GetSMTPClientIdFailedErr); - if not IsolatedStorage.Get(SMTPAccount."Client Secret Storage Id", ClientSecret) then Error(GetSMTPClientSecretFailedErr); + ClientSecret := SMTPAccount.GetClientSecret(SMTPAccount."Client Secret Storage Id"); + if ClientSecret.IsEmpty() then Error(GetSMTPClientSecretFailedErr); - if OAuth2.RequestClientCredentialsAdminPermissions(ClientId, SMTPAccount."Authority URL", AzureAdMgt.GetO365Resource(), ConsentGranted, PermissionGrantError) then begin + RedirectUri := EnvironmentInformation.IsOnPrem() ? Format(SMTPAccount."Redirect Uri") : ''; + + if OAuth2.RequestClientCredentialsAdminPermissions(ClientId.Unwrap(), ConsentUrlLbl, RedirectUri, ConsentGranted, PermissionGrantError) then begin if not ConsentGranted then Error(PermissionGrantError) end else @@ -142,12 +151,17 @@ codeunit 4516 "OAuth2 SMTP Authentication" if Handled then exit; if SMTPServer = SMTPConnectorImpl.GetO365SmtpServer() then begin - if SMTPConnectorImpl.CheckIfCustomizedSMTPOAuth(SMTPAuthentication.GetAccountId(), SMTPAccount) then + if SMTPConnectorImpl.CheckIfCustomizedSMTPOAuth(SMTPAuthentication.GetAccountId(), SMTPAccount) then begin // if it is customized, use the token stored. - GetCustomTenantOAuthToken(UserName, AccessToken, SMTPAccount) - else + GetCustomTenantOAuthToken(UserName, AccessToken, SMTPAccount); + Session.LogMessage('0000QPH', UsingCustomizedOAuth2TelemetryLbl, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', TelemetryCategoryLbl); + end + else begin // if it is not customized - use the normal way to fetch token GetOAuth2Credentials(UserName, AccessToken); + Session.LogMessage('0000QPI', UsingDefaultOAuth2TelemetryLbl, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', TelemetryCategoryLbl); + end; + SMTPAuthentication.SetOAuth2AuthInfo(CopyStr(UserName, 1, 250), AccessToken); Handled := true; end; @@ -178,15 +192,12 @@ codeunit 4516 "OAuth2 SMTP Authentication" Resp: HttpResponseMessage; RespTxt: Text; JsonObj: JsonObject; - Authority: Text; ClientSecret: SecretText; ClientID: SecretText; + TenantID: Text; BodyTxt: Label 'client_id=%1&client_secret=%2&scope=https://outlook.office365.com/.default&grant_type=client_credentials', Locked = true; + AuthorityLbl: Label 'https://login.microsoftonline.com/%1/oauth2/v2.0/token', Locked = true; begin - Authority := SMTPAccount."Authority URL"; - if Authority = '' then - Error(SMTPAuthorityCannotBeEmptyErr); - if not GetValueFromStorage(SMTPAccount."Client Id Storage Id", ClientID) then Error(GetSMTPClientIdFailedErr); if not GetValueFromStorage(SMTPAccount."Client Secret Storage Id", ClientSecret) then Error(GetSMTPClientSecretFailedErr); @@ -197,7 +208,9 @@ codeunit 4516 "OAuth2 SMTP Authentication" Headers.Clear(); Headers.Add('Content-Type', 'application/x-www-form-urlencoded'); - HttpClient.Post(Authority, HttpContent, Resp); + TenantID := SMTPAccount."Tenant Id".ToText(); + HttpClient.Post(StrSubstNo(AuthorityLbl, TenantID), HttpContent, Resp); + if not Resp.IsSuccessStatusCode() then Error(FetchAccessTokenFromHttpsErr, Resp.HttpStatusCode()); diff --git a/Apps/W1/Email - SMTP Connector/app/src/Notification/SMTPEmailAccountsExt.PageExt.al b/Apps/W1/Email - SMTP Connector/app/src/Notification/SMTPEmailAccountsExt.PageExt.al new file mode 100644 index 0000000000..2af768d780 --- /dev/null +++ b/Apps/W1/Email - SMTP Connector/app/src/Notification/SMTPEmailAccountsExt.PageExt.al @@ -0,0 +1,24 @@ +#if not CLEAN28 +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace System.Email; + +pageextension 4513 "SMTP Email Accounts Ext." extends "Email Accounts" +{ + ObsoleteReason = 'This notification is no longer needed after Exchange Basic OAuth deprecation date.'; + ObsoleteState = Pending; + ObsoleteTag = '28.0'; + + trigger OnOpenPage() + var + SMTPConnectorImpl: Codeunit "SMTP Connector Impl."; + begin + if not SMTPConnectorImpl.SMTPBasicOAuthIsUsed() then exit; + + SMTPConnectorImpl.SendSMTPBasicOAuthObsoletionNotification(); + end; +} +#endif \ No newline at end of file diff --git a/Apps/W1/Email - SMTP Connector/app/src/Notification/SMTPEmailOutbox.PageExt.al b/Apps/W1/Email - SMTP Connector/app/src/Notification/SMTPEmailOutbox.PageExt.al new file mode 100644 index 0000000000..6d21f8c554 --- /dev/null +++ b/Apps/W1/Email - SMTP Connector/app/src/Notification/SMTPEmailOutbox.PageExt.al @@ -0,0 +1,24 @@ +#if not CLEAN28 +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace System.Email; + +pageextension 4511 "SMTP EMailOutbox" extends "Email Outbox" +{ + ObsoleteReason = 'This notification is no longer needed after Exchange Basic OAuth deprecation date.'; + ObsoleteState = Pending; + ObsoleteTag = '28.0'; + + trigger OnOpenPage() + var + SMTPConnectorImpl: Codeunit "SMTP Connector Impl."; + begin + if not SMTPConnectorImpl.SMTPBasicOAuthIsUsed() then exit; + + SMTPConnectorImpl.SendSMTPBasicOAuthObsoletionNotification(); + end; +} +#endif \ No newline at end of file diff --git a/Apps/W1/Email - SMTP Connector/app/src/Notification/SMTPSentEmail.PageExt.al b/Apps/W1/Email - SMTP Connector/app/src/Notification/SMTPSentEmail.PageExt.al new file mode 100644 index 0000000000..0258bf7ee2 --- /dev/null +++ b/Apps/W1/Email - SMTP Connector/app/src/Notification/SMTPSentEmail.PageExt.al @@ -0,0 +1,24 @@ +#if not CLEAN28 +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace System.Email; + +pageextension 4512 "SMTP Sent Email" extends "Sent Emails" +{ + ObsoleteReason = 'This notification is no longer needed after Exchange Basic OAuth deprecation date.'; + ObsoleteState = Pending; + ObsoleteTag = '28.0'; + + trigger OnOpenPage() + var + SMTPConnectorImpl: Codeunit "SMTP Connector Impl."; + begin + if not SMTPConnectorImpl.SMTPBasicOAuthIsUsed() then exit; + + SMTPConnectorImpl.SendSMTPBasicOAuthObsoletionNotification(); + end; +} +#endif \ No newline at end of file diff --git a/Apps/W1/Email - SMTP Connector/app/src/SMTPAccount.Page.al b/Apps/W1/Email - SMTP Connector/app/src/SMTPAccount.Page.al index 5b803285fa..29df3ba710 100644 --- a/Apps/W1/Email - SMTP Connector/app/src/SMTPAccount.Page.al +++ b/Apps/W1/Email - SMTP Connector/app/src/SMTPAccount.Page.al @@ -25,158 +25,216 @@ page 4512 "SMTP Account" { area(Content) { - field(NameField; Rec.Name) + group(General) { - ApplicationArea = All; - Caption = 'Account Name'; - ToolTip = 'Specifies the name of the SMTP account'; - ShowMandatory = true; - NotBlank = true; - } - - field(SenderTypeField; Rec."Sender Type") - { - ApplicationArea = All; - Caption = 'Sender Email Account'; - ToolTip = 'Specifies whether emails appear to come from the email accounts that people sign in with, or the account you enter in the Email Address field. For Current User, everyone who uses this SMTP account must have the Send As permission on your mail server to the account in the User Name field. For Specific Account, only the account in the Email Address field must have the Send As permission.'; - - trigger OnValidate() - begin - SetProperties(); - end; - } + field(NameField; Rec.Name) + { + ApplicationArea = All; + Caption = 'Account Name'; + ToolTip = 'Specifies the name of the SMTP account'; + ShowMandatory = true; + NotBlank = true; + } + + field(SenderTypeField; Rec."Sender Type") + { + ApplicationArea = All; + Caption = 'Sender Email Account'; + ToolTip = 'Specifies whether emails appear to come from the email accounts that people sign in with, or the account you enter in the Email Address field. For Current User, everyone who uses this SMTP account must have the Send As permission on your mail server to the account in the User Name field. For Specific Account, only the account in the Email Address field must have the Send As permission.'; + + trigger OnValidate() + begin + SetProperties(); + end; + } - field(SenderNameField; Rec."Sender Name") - { - ApplicationArea = All; - Caption = 'Sender Name'; + field(SenderNameField; Rec."Sender Name") + { + ApplicationArea = All; + Caption = 'Sender Name'; #pragma warning disable AA0240 - ToolTip = 'Specifies a name to add in front of the sender email address on emails. The name depends on the Sender Email Address field. For Current User, this is the name from the account you used to sign in. For Specific Account, this can be any name. For example, if you enter Stan, and the address in the Email Address field is stan@cronus.coml, the sender name will appear as Stan stan@cronus.com.'; + ToolTip = 'Specifies a name to add in front of the sender email address on emails. The name depends on the Sender Email Address field. For Current User, this is the name from the account you used to sign in. For Specific Account, this can be any name. For example, if you enter Stan, and the address in the Email Address field is stan@cronus.coml, the sender name will appear as Stan stan@cronus.com.'; #pragma warning restore AA0240 - Editable = SenderFieldsEditable; - } + Editable = SenderFieldsEditable; + } - field(EmailAddress; Rec."Email Address") - { - ApplicationArea = All; - Caption = 'Email Address'; + field(EmailAddress; Rec."Email Address") + { + ApplicationArea = All; + Caption = 'Email Address'; #pragma warning disable AA0240 - ToolTip = 'Specifies the email address to show as the sender on email messages. This field is available if you choose Specific Account in the Sender Email Account field. For example, this lets all emails appear to come from the same account, such as sales@cronus.com. This account must have the Send As permission on your mail server to the account in the User Name field.'; + ToolTip = 'Specifies the email address to show as the sender on email messages. This field is available if you choose Specific Account in the Sender Email Account field. For example, this lets all emails appear to come from the same account, such as sales@cronus.com. This account must have the Send As permission on your mail server to the account in the User Name field.'; #pragma warning restore AA0240 - Editable = SenderFieldsEditable; - ShowMandatory = true; - NotBlank = true; - - trigger OnValidate() - begin - if Rec."User Name" = '' then - Rec."User Name" := Rec."Email Address"; - end; - } - - field(ServerUrl; Rec.Server) - { - ApplicationArea = All; - ShowMandatory = true; - NotBlank = true; - - trigger OnValidate() - begin - SetProperties(); - if AuthActionsVisible then - Message(EveryUserShouldPressAuthenticateMsg); - end; - } - - field(ServerPort; Rec."Server Port") - { - ApplicationArea = All; - MinValue = 1; - NotBlank = true; - Caption = 'Server Port'; - ToolTip = 'Specifies the port of the SMTP server. The default setting is 25.'; - } - - field(Authentication; Rec."Authentication Type") - { - ApplicationArea = All; - Caption = 'Authentication'; - ToolTip = 'Specifies the type of authentication that the SMTP mail server uses.'; - - trigger OnValidate() - begin - SetProperties(); - if AuthActionsVisible then - Message(EveryUserShouldPressAuthenticateMsg); - end; - } - - field(UserName; Rec."User Name") - { - ApplicationArea = All; - Editable = UserIDEditable; - Caption = 'User Name'; - ToolTip = 'Specifies the user account to use when authenticating to the SMTP server.'; - } - - field(Password; Password) - { - ApplicationArea = All; - Caption = 'Password'; - Editable = PasswordEditable; - ExtendedDatatype = Masked; - ToolTip = 'Specifies the password of the SMTP server.'; - - trigger OnValidate() - begin - Rec.SetPassword(Password); - end; - } - - field(SecureConnection; Rec."Secure Connection") - { - ApplicationArea = All; - Caption = 'Secure Connection'; - ToolTip = 'Specifies whether your SMTP mail server setup requires a secure connection that uses a cryptography or security protocol, such as secure socket layers (SSL).'; - } - - field(ClientId; ClientId) - { - ApplicationArea = All; - Caption = 'Client ID'; - ToolTip = 'Specifies the client ID of the third-party application registered in Microsoft Entra (Azure AD).'; - trigger OnValidate() - begin - Rec.SetClientId(ClientId); - end; + Editable = SenderFieldsEditable; + ShowMandatory = true; + NotBlank = true; + + trigger OnValidate() + begin + if Rec."User Name" = '' then + Rec."User Name" := Rec."Email Address"; + end; + } } - - field(ClientSecret; ClientSecret) + group("Server settings") { - ApplicationArea = All; - Caption = 'Client Secret'; - ToolTip = 'Specifies the client secret associated with the client ID for authenticating the SMTP connection.'; - trigger OnValidate() - begin - Rec.SetClientSecret(ClientSecret); - end; + field(ServerUrl; Rec.Server) + { + ApplicationArea = All; + ShowMandatory = true; + NotBlank = true; + + trigger OnValidate() + begin + SetProperties(); + if AuthActionsVisible then + Message(EveryUserShouldPressAuthenticateMsg); + end; + } + + field(ServerPort; Rec."Server Port") + { + ApplicationArea = All; + MinValue = 1; + NotBlank = true; + Caption = 'Server Port'; + ToolTip = 'Specifies the port of the SMTP server. The default setting is 25.'; + } + + field(Authentication; Rec."Authentication Type") + { + ApplicationArea = All; + Caption = 'Authentication'; + ToolTip = 'Specifies the type of authentication that the SMTP mail server uses.'; + + trigger OnValidate() + var + EmptyGuid: Guid; + begin + SetProperties(); + if AuthActionsVisible then + Message(EveryUserShouldPressAuthenticateMsg); + if Rec."Authentication Type" = Rec."Authentication Type"::"OAuth 2.0" then begin + Rec."Password Key" := EmptyGuid; + Password := ''; + Rec.Modify(); + end; + end; + } + + field(UserName; Rec."User Name") + { + ApplicationArea = All; + Editable = UserIDEditable; + Caption = 'User Name'; + ToolTip = 'Specifies the user account to use when authenticating to the SMTP server.'; + } + + field(Password; Password) + { + ApplicationArea = All; + Caption = 'Password'; + Editable = PasswordEditable; + ExtendedDatatype = Masked; + ToolTip = 'Specifies the password of the SMTP server.'; + + trigger OnValidate() + begin + Rec.SetPassword(Password); + end; + } + field(SecureConnection; Rec."Secure Connection") + { + ApplicationArea = All; + Caption = 'Secure Connection'; + ToolTip = 'Specifies whether your SMTP mail server setup requires a secure connection that uses a cryptography or security protocol, such as secure socket layers (SSL).'; + } + group(CustomizedOAuth2SettingsGroup) + { + Visible = (Rec."Authentication Type" = Rec."Authentication Type"::"OAuth 2.0"); + ShowCaption = false; + field(CustomOAuth2Settings; CustomOAuth2Settings) + { + ApplicationArea = All; + Caption = 'Use custom OAuth 2.0 settings'; + ToolTip = 'Specifies whether to use customized OAuth 2.0 settings for authentication.'; + trigger OnValidate() + var + EmptyGuid: Guid; + begin + if not CustomOAuth2Settings then begin + Rec."Client Id Storage Id" := EmptyGuid; + Rec."Client Secret Storage Id" := EmptyGuid; + Rec."Tenant Id" := EmptyGuid; + Rec."Redirect Uri" := ''; + Rec.Modify(); + TenantId := ''; + ClientId := ''; + ClientSecret := ''; + end else begin + Rec."Password Key" := EmptyGuid; + Password := ''; + end; + end; + } + } } - - field(AuthorityURL; AuthorityUrl) + group(OAuth2Group) { - ApplicationArea = All; - - Caption = 'Authority URL'; - ToolTip = 'Specifies the authority URL (token endpoint) used for OAuth 2.0 authentication. The format: https://login.microsoftonline.com/{Your tenant ID}/oauth2/v2.0/token'; - trigger OnValidate() - begin - Rec."Authority URL" := AuthorityUrl; - Rec.Modify(); - end; + Visible = (Rec."Authentication Type" = Rec."Authentication Type"::"OAuth 2.0") and CustomOAuth2Settings; + caption = 'Customized OAuth 2.0 settings'; + field(ClientId; ClientId) + { + ApplicationArea = All; + Caption = 'Client ID'; + ToolTip = 'Specifies the client ID of the third-party application registered in Microsoft Entra (Azure AD).'; + trigger OnValidate() + begin + if (ClientId <> SecrectContentLbl) and (ClientId <> '') then begin + Rec.SetClientId(ClientId); + ClientId := SecrectContentLbl; + end; + end; + } + + field(ClientSecret; ClientSecret) + { + ApplicationArea = All; + Caption = 'Client Secret'; + ToolTip = 'Specifies the client secret associated with the client ID for authenticating the SMTP connection.'; + trigger OnValidate() + begin + if (ClientSecret <> SecrectContentLbl) and (ClientSecret <> '') then begin + Rec.SetClientSecret(ClientSecret); + ClientSecret := SecrectContentLbl; + end; + end; + } + field("Tenant Id"; TenantId) + { + ApplicationArea = All; + + Caption = 'Tenant ID'; + ToolTip = 'Specifies the tenant ID of the email account registered in Microsoft Entra (Azure AD).'; + + trigger OnValidate() + begin + if (TenantId <> SecrectContentLbl) and (TenantId <> '') then begin + Rec.Validate("Tenant Id", TenantId); + TenantId := SecrectContentLbl; + end; + end; + } + field("Redirect Uri"; Rec."Redirect Uri") + { + ApplicationArea = All; + Caption = 'Redirect URI'; + ToolTip = 'Specifies the redirect URI configured in the app registration in Microsoft Entra (Azure AD).'; + Visible = IsOnPrem; + } } } } - actions { area(processing) @@ -208,13 +266,35 @@ page 4512 "SMTP Account" end end; } + action("Authenticate with Customized OAuth 2.0") + { + Caption = 'Authenticate OAuth 2.0'; + ApplicationArea = All; + Image = LinkWeb; + ToolTip = 'Authenticate with your customized Exchange Online account.'; + Visible = CustomOAuth2Settings; + Promoted = true; + PromotedCategory = Process; + + trigger OnAction() + var + OAuth2SMTPAuthentication: Codeunit "OAuth2 SMTP Authentication"; + begin + if IsNullGuid(Rec."Client Id Storage Id") or IsNullGuid(Rec."Client Secret Storage Id") or IsNullGuid(Rec."Tenant Id") then + Error(ClientIdAndSecretRequiredErr); + + OAuth2SMTPAuthentication.AuthenticateWithOAuth2CustomAppReg(Rec); + end; + } action("Authenticate with OAuth 2.0") { - Caption = 'Authenticate'; + Caption = 'Authenticate OAuth 2.0'; ApplicationArea = All; Image = LinkWeb; ToolTip = 'Authenticate with your Exchange Online account.'; - Visible = AuthActionsVisible; + Visible = AuthActionsVisible and not CustomOAuth2Settings; + Promoted = true; + PromotedCategory = Process; trigger OnAction() var @@ -229,7 +309,7 @@ page 4512 "SMTP Account" ApplicationArea = All; Image = Confirm; ToolTip = 'Verify that OAuth 2.0 authentication was successful.'; - Visible = AuthActionsVisible; + Visible = AuthActionsVisible and not CustomOAuth2Settings; trigger OnAction() var @@ -251,28 +331,41 @@ page 4512 "SMTP Account" ClientId: Text; [NonDebuggable] ClientSecret: Text; - AuthorityUrl: Text; + [NonDebuggable] + TenantId: Text; AuthActionsVisible: Boolean; SenderFieldsEditable: Boolean; + IsOnPrem: Boolean; + CustomOAuth2Settings: Boolean; + SecrectContentLbl: Label '***', Locked = true; ConfirmApplyO365Qst: Label 'Do you want to override the current data?'; EveryUserShouldPressAuthenticateMsg: Label 'Before people can send email they must authenticate their email account. They can do that by choosing the Authenticate action on the SMTP Account page.'; + ClientIdAndSecretRequiredErr: Label 'To use customized OAuth 2.0 settings, the Client ID, Client Secret and Tenant ID must be provided.'; + ConfirmClosePageQst: Label 'To use customized OAuth 2.0 settings, the Client ID, Client Secret and Tenant ID must be provided. Do you want to exit without these information?'; trigger OnOpenPage() begin Rec.SetCurrentKey(Name); if not IsNullGuid(Rec."Password Key") then - Password := '***'; + Password := SecrectContentLbl; if not IsNullGuid(Rec."Client Id Storage Id") then - ClientId := '***'; + ClientId := SecrectContentLbl; if not IsNullGuid(Rec."Client Secret Storage Id") then - ClientSecret := '***'; - if Rec."Authority URL" <> '' then - AuthorityUrl := '***'; + ClientSecret := SecrectContentLbl; + if not IsNullGuid(Rec."Tenant Id") then + TenantId := SecrectContentLbl; SetProperties(); end; + trigger OnQueryClosePage(CloseAction: Action): Boolean + begin + if CustomOAuth2Settings then + if IsNullGuid(Rec."Client Id Storage Id") or IsNullGuid(Rec."Client Secret Storage Id") or IsNullGuid(Rec."Tenant Id") then + exit(Confirm(ConfirmClosePageQst, true)); + end; + local procedure SetProperties() var EnvironmentInformation: Codeunit "Environment Information"; @@ -281,5 +374,7 @@ page 4512 "SMTP Account" PasswordEditable := (Rec."Authentication Type" = Rec."Authentication Type"::Basic) or (Rec."Authentication Type" = Rec."Authentication Type"::NTLM); AuthActionsVisible := (not EnvironmentInformation.IsSaaSInfrastructure()) and (Rec."Authentication Type" = Rec."Authentication Type"::"OAuth 2.0") and (Rec.Server = SMTPConnectorImpl.GetO365SmtpServer()); SenderFieldsEditable := Rec."Sender Type" = Rec."Sender Type"::"Specific User"; + IsOnPrem := EnvironmentInformation.IsOnPrem(); + CustomOAuth2Settings := (Rec."Authentication Type" = Rec."Authentication Type"::"OAuth 2.0") and (not IsNullGuid(Rec."Client Id Storage Id")); end; } \ No newline at end of file diff --git a/Apps/W1/Email - SMTP Connector/app/src/SMTPAccount.table.al b/Apps/W1/Email - SMTP Connector/app/src/SMTPAccount.table.al index e69ccd8002..98478ceb85 100644 --- a/Apps/W1/Email - SMTP Connector/app/src/SMTPAccount.table.al +++ b/Apps/W1/Email - SMTP Connector/app/src/SMTPAccount.table.al @@ -4,8 +4,6 @@ // ------------------------------------------------------------------------------------------------ namespace System.Email; -using System.Utilities; - /// /// Holds the information for all e-mail accounts that are registered via the SMTP connector /// @@ -119,14 +117,15 @@ table 4511 "SMTP Account" Caption = 'Client Secret Storage Id'; DataClassification = CustomerContent; } - field(16; "Authority URL"; Text[1024]) + field(16; "Tenant Id"; guid) { - Caption = 'Authority URL'; + Caption = 'Tenant Id'; + DataClassification = CustomerContent; + } + field(17; "Redirect Uri"; Text[1024]) + { + Caption = 'Redirect Uri'; DataClassification = CustomerContent; - trigger OnValidate() - begin - ValidateUri(Rec."Authority URL"); - end; } } @@ -145,7 +144,6 @@ table 4511 "SMTP Account" UnableToSetClientIdMsg: Label 'Unable to set SMTP Account Client Id'; UnableToGetClientSecretMsg: Label 'Unable to get SMTP Account Client Secret'; UnableToSetClientSecretMsg: Label 'Unable to set SMTP Account Client Secret'; - UriIsNotValidErr: Label '%1 is not a valid URI.', Comment = '%1 = a string'; trigger OnDelete() begin @@ -173,6 +171,12 @@ table 4511 "SMTP Account" [NonDebuggable] internal procedure SetClientId(ClientId: SecretText) begin + if ClientId.IsEmpty() then begin + if not IsNullGuid(Rec."Client Id Storage Id") then + if IsolatedStorage.Delete(Format(Rec."Client Id Storage Id"), DataScope::Company) then; + exit; + end; + if IsNullGuid(Rec."Client Id Storage Id") then Rec."Client Id Storage Id" := CreateGuid(); @@ -190,6 +194,12 @@ table 4511 "SMTP Account" [NonDebuggable] internal procedure SetClientSecret(ClientSecret: SecretText) begin + if ClientSecret.IsEmpty() then begin + if not IsNullGuid(Rec."Client Secret Storage Id") then + if IsolatedStorage.Delete(Format(Rec."Client Secret Storage Id"), DataScope::Company) then; + exit; + end; + if IsNullGuid(Rec."Client Secret Storage Id") then Rec."Client Secret Storage Id" := CreateGuid(); @@ -203,15 +213,4 @@ table 4511 "SMTP Account" if not IsolatedStorage.Get(Format(ClientSecretKey), DataScope::Company, ClientSecret) then Error(UnableToGetClientSecretMsg); end; - - local procedure ValidateUri(UriString: Text) - var - Uri: Codeunit Uri; - begin - if UriString = '' then - exit; - - if not Uri.IsValidUri(UriString) then - Error(UriIsNotValidErr, UriString); - end; } \ No newline at end of file diff --git a/Apps/W1/Email - SMTP Connector/app/src/SMTPAccountWizard.Page.al b/Apps/W1/Email - SMTP Connector/app/src/SMTPAccountWizard.Page.al index 2f18cb1cd4..e391a74ccc 100644 --- a/Apps/W1/Email - SMTP Connector/app/src/SMTPAccountWizard.Page.al +++ b/Apps/W1/Email - SMTP Connector/app/src/SMTPAccountWizard.Page.al @@ -13,7 +13,7 @@ using System.Utilities; /// page 4511 "SMTP Account Wizard" { - Caption = 'Setup SMTP Account'; + Caption = 'Set up SMTP Account'; SourceTable = "SMTP Account"; SourceTableTemporary = true; Permissions = tabledata "SMTP Account" = rimd; @@ -25,6 +25,9 @@ page 4511 "SMTP Account Wizard" { area(Content) { + // ------------------------- + // STEP 1 : Basic Setup + // ------------------------- group(Setup) { Visible = Step1Visible; @@ -94,7 +97,6 @@ page 4511 "SMTP Account Wizard" begin if Rec."User Name" = '' then Rec."User Name" := Rec."Email Address"; - IsNextEnabled := SMTPConnectorImpl.IsAccountValid(Rec); end; } @@ -137,14 +139,32 @@ page 4511 "SMTP Account Wizard" Message(EveryUserShouldPressAuthenticateMsg); end; } - field(Custom; CustomB) + } + + // ------------------------- + // STEP 2 : Ask Custom OAuth? + // Only visible when auth = OAuth2 + // ------------------------- + group(CheckIfCustomOAuth) + { + Visible = Step2Visible and CustomOAuthVisible; + ShowCaption = false; + InstructionalText = 'Do you want to use your own app registration with OAuth 2.0 authentication? (This requires an app registration in Microsoft Entra ID.)'; + field(Custom; CustomOAuth) { ApplicationArea = All; - Caption = 'Custom App Registration'; - ToolTip = 'Specifies if you want to set up a custom SMTP server.'; - Enabled = CustomBVisible; + Caption = 'Use custom app registration'; + ToolTip = 'Specifies if you want to set up a custom app registration for OAuth 2.0 authentication.'; } + } + // ------------------------- + // STEP 3 : Standard Credentials + Optional Custom OAuth Fields + // ------------------------- + group(Step3Basic) + { + Visible = Step3Visible; + ShowCaption = false; field(UserName; Rec."User Name") { ApplicationArea = All; @@ -158,28 +178,100 @@ page 4511 "SMTP Account Wizard" end; } - field(Password; Password) - { - ApplicationArea = All; - Caption = 'Password'; - Editable = PasswordEditable; - ExtendedDatatype = Masked; - ToolTip = 'Specifies the password of the SMTP server.'; - } - field(SecureConnection; Rec."Secure Connection") { ApplicationArea = All; Caption = 'Secure Connection'; ToolTip = 'Specifies if your SMTP mail server setup requires a secure connection that uses a cryptography or security protocol, such as secure socket layers (SSL). Clear the check box if you do not want to enable this security setting.'; } + group(PasswordGroup) + { + ShowCaption = false; + Visible = PasswordEditable; + + field(Password; Password) + { + ApplicationArea = All; + Caption = 'Password'; + Editable = PasswordEditable; + ExtendedDatatype = Masked; + ToolTip = 'Specifies the password of the SMTP server.'; + } + } + + // OAuth fields only shown when: Step3Visible + OAuth2 + CustomOAuth = TRUE + group(OAuth) + { + Visible = Step3Visible and CustomOAuth; + ShowCaption = false; + group(Secrets) + { + Caption = 'Azure Application registration'; + ShowCaption = false; + InstructionalText = 'Enter client ID and secret from your Microsoft Entra application registration.'; + field(ClientId; ClienStorageIdText) + { + ApplicationArea = All; + ToolTip = 'Specifies the Client Id.'; + Caption = 'Client Id'; + NotBlank = true; + ShowMandatory = true; + trigger OnValidate() + begin + SetClientIdInStorage(Rec); + UpdateVisibility(); + if AllOAuthFieldsValid() then + IsNextEnabled := true; + end; + } + + field(ClientSecret; ClientSecretStorageIdText) + { + ApplicationArea = All; + ToolTip = 'Specifies the Client Secret.'; + Caption = 'Client Secret'; + NotBlank = true; + ShowMandatory = true; + trigger OnValidate() + begin + SetClientSecretInStorage(Rec); + if AllOAuthFieldsValid() then + IsNextEnabled := true; + end; + } + field("Tenant Id"; TenantId) + { + ApplicationArea = All; + ToolTip = 'Specifies the Tenant ID.'; + Caption = 'Tenant ID'; + NotBlank = true; + ShowMandatory = true; + trigger OnValidate() + begin + Rec.Validate("Tenant Id", TenantId); + TenantId := HiddenValueTxt; + if AllOAuthFieldsValid() then + IsNextEnabled := true; + end; + } + } + } + group(RedirectUriGroup) + { + Visible = Step3Visible and CustomOAuth and IsOnPrem; + ShowCaption = false; + field("Redirect Uri"; Rec."Redirect Uri") + { + ApplicationArea = All; + Caption = 'Redirect URI'; + ToolTip = 'Specifies the redirect URI configured in the app registration in Microsoft Entra (Azure AD). This is required for OnPrem deployments.'; + } + } } - group(OAuth) + group(HyperLinks) { - InstructionalText = 'You must already have registered your application in Microsoft Entra and granted certain permissions. Use the client ID and secret from that registration to authenticate the email account.'; ShowCaption = false; - Visible = Step2Visible; - + Visible = Step3Visible and CustomOAuth; field(Doc; AppRegistrationsLbl) { ApplicationArea = All; @@ -204,40 +296,8 @@ page 4511 "SMTP Account Wizard" end; } - group(Secrets) - { - Caption = 'Azure Application registration'; - field(ClientId; ClienStorageIdText) - { - ApplicationArea = All; - ToolTip = 'Specifies the Client Id.'; - Caption = 'Client Id'; - - trigger OnValidate() - begin - SetClientIdInStorage(Rec); - end; - } - - field(ClientSecret; ClientSecretStorageIdText) - { - ApplicationArea = All; - ToolTip = 'Specifies the Client Secret.'; - Caption = 'Client Secret'; - - trigger OnValidate() - begin - SetClientSecretInStorage(Rec); - end; - } - field(RedirectURL; Rec."Authority URL") - { - ApplicationArea = All; - ToolTip = 'Specifies the Authority URL.'; - Caption = 'Authority URL'; - } - } } + } } @@ -245,6 +305,7 @@ page 4511 "SMTP Account Wizard" { area(processing) { +#if not CLEAN28 action(OAuthAuthenticate) { ApplicationArea = All; @@ -252,18 +313,23 @@ page 4511 "SMTP Account Wizard" Image = Setup; InFooterBar = true; ToolTip = 'Setup OAuth 2.0 authentication. The user will be prompted to sign in to their account and grant admin permissions to the application.'; - Visible = (Rec."Authentication Type" = Rec."Authentication Type"::"OAuth 2.0") and Step2Visible; + Visible = false; + ObsoleteState = Pending; + ObsoleteTag = '28.0'; + ObsoleteReason = 'Use the Next action to finalize the setup.'; trigger OnAction() var OAuth2SMTPAuthentication: Codeunit "OAuth2 SMTP Authentication"; begin if IsNullGuid(Rec."Client Id Storage Id") or IsNullGuid(Rec."Client Secret Storage Id") then - Error('Client Id and Client Secret must be provided before authentication.'); + Error(ClientIdAndSecretRequiredErr); OAuth2SMTPAuthentication.AuthenticateWithOAuth2CustomAppReg(Rec); + IsNextEnabled := true; end; } +#endif action(ApplyOffice365) { ApplicationArea = All; @@ -300,6 +366,29 @@ page 4511 "SMTP Account Wizard" trigger OnAction() begin + if Step3Visible then + if IsOAuthAuth() then begin + Step3Visible := false; + Step2Visible := true; + IsNextEnabled := true; + CurrPage.Update(); + exit; + end else begin + Step3Visible := false; + Step1Visible := true; + IsNextEnabled := true; + CurrPage.Update(); + exit; + end; + + if Step2Visible then begin + Step2Visible := false; + Step1Visible := true; + IsNextEnabled := SMTPConnectorImpl.IsAccountValid(Rec); + CurrPage.Update(); + exit; + end; + CurrPage.Close(); end; } @@ -315,22 +404,47 @@ page 4511 "SMTP Account Wizard" trigger OnAction() begin - if Step2Visible then begin - if IsNullGuid(SMTPEmailAccount."Account Id") then - SMTPConnectorImpl.CreateAccount(Rec, Password, SMTPEmailAccount); - UpdateVisibility(); // DO UPDATE (Rec) + // STEP 3 -> FINALIZE + if Step3Visible then begin + if IsOAuthAuth() then + AuthenticateWithOAuth2CustomAppReg(); + + EnsureAccountCreated(); Rec.Modify(); CurrPage.Close(); - end else - if Step1Visible then - if CustomB then begin - Step1Visible := false; - Step2Visible := true; - end else begin - if IsNullGuid(SMTPEmailAccount."Account Id") then - SMTPConnectorImpl.CreateAccount(Rec, Password, SMTPEmailAccount); - CurrPage.Close(); - end; + exit; + end; + + // STEP 2 -> go to STEP 3 + if Step2Visible then begin + Step2Visible := false; + Step3Visible := true; + + if IsOAuthAuth() and CustomOAuth then + IsNextEnabled := false // must fill ClientId/Secret/Tenant + else + IsNextEnabled := true; + + CurrPage.Update(); + exit; + end; + + // STEP 1 -> determine next step + if Step1Visible then + if IsOAuthAuth() then begin + Step1Visible := false; + Step2Visible := true; + CustomOAuth := false; + IsNextEnabled := true; + CurrPage.Update(); + exit; + end else begin + Step1Visible := false; + Step3Visible := true; + IsNextEnabled := true; + CurrPage.Update(); + exit; + end; end; } } @@ -340,6 +454,7 @@ page 4511 "SMTP Account Wizard" SMTPEmailAccount: Record "Email Account"; MediaResources: Record "Media Resources"; SMTPConnectorImpl: Codeunit "SMTP Connector Impl."; + EnvironmentInformation: Codeunit "Environment Information"; UserIDEditable: Boolean; PasswordEditable: Boolean; [NonDebuggable] @@ -349,17 +464,21 @@ page 4511 "SMTP Account Wizard" SenderFieldsEnabled: Boolean; TopBannerVisible: Boolean; ShowMessageAboutSigningIn: Boolean; - Step1Visible, Step2Visible, SetupAppRegVisible, CustomB, CustomBVisible : Boolean; - EveryUserShouldPressAuthenticateMsg: Label 'Before people can send email they must authenticate their email account. They can do that by choosing the Authenticate action on the SMTP Account page.'; + IsOnPrem: Boolean; + Step1Visible, Step2Visible, Step3Visible, CustomOAuth, CustomOAuthVisible : Boolean; [NonDebuggable] ClienStorageIdText: Text; [NonDebuggable] ClientSecretStorageIdText: Text; + [NonDebuggable] + TenantId: Text; DocumentationAzureUlrTxt: Label 'https://go.microsoft.com/fwlink/?linkid=2134620', Locked = true; DocumentationBCUlrTxt: Label 'https://go.microsoft.com/fwlink/?linkid=2134520', Locked = true; AppRegistrationsLbl: Label 'Learn more about app registration'; AppPermissionsLbl: Label 'Learn more about the permissions'; HiddenValueTxt: Label '******', Locked = true; + EveryUserShouldPressAuthenticateMsg: Label 'Before people can send email they must authenticate their account.'; + ClientIdAndSecretRequiredErr: Label 'Client Id and Client Secret must be provided before authentication.'; trigger OnOpenPage() begin @@ -372,24 +491,64 @@ page 4511 "SMTP Account Wizard" Step1Visible := true; Step2Visible := false; + Step3Visible := false; + + IsOnPrem := EnvironmentInformation.IsOnPrem(); + IsNextEnabled := false; + end; + + local procedure IsOAuthAuth(): Boolean + begin + exit(Rec."Authentication Type" = Rec."Authentication Type"::"OAuth 2.0"); + end; + + local procedure AllOAuthFieldsValid(): Boolean + begin + exit( + not IsNullGuid(Rec."Client Id Storage Id") and + not IsNullGuid(Rec."Client Secret Storage Id") and + not IsNullGuid(Rec."Tenant Id") + ); end; local procedure UpdateVisibility() begin - if Rec."Authentication Type" = Rec."Authentication Type"::"OAuth 2.0" then begin - SetupAppRegVisible := true; - CustomBVisible := true; - end; + CustomOAuthVisible := IsOAuthAuth(); + if not CustomOAuthVisible then + CustomOAuth := false; end; local procedure SetProperties() + begin + UserIDEditable := + (Rec."Authentication Type" in [Rec."Authentication Type"::Basic, Rec."Authentication Type"::"OAuth 2.0", Rec."Authentication Type"::NTLM]); + + PasswordEditable := + (Rec."Authentication Type" in [Rec."Authentication Type"::Basic, Rec."Authentication Type"::NTLM]); + + ShowMessageAboutSigningIn := + (not EnvironmentInformation.IsSaaSInfrastructure()) and + IsOAuthAuth() and + (Rec.Server = SMTPConnectorImpl.GetO365SmtpServer()); + + SenderFieldsEnabled := + Rec."Sender Type" = Rec."Sender Type"::"Specific User"; + end; + + local procedure EnsureAccountCreated() + begin + if IsNullGuid(SMTPEmailAccount."Account Id") then + SMTPConnectorImpl.CreateAccount(Rec, Password, SMTPEmailAccount); + end; + + local procedure AuthenticateWithOAuth2CustomAppReg() var - EnvironmentInformation: Codeunit "Environment Information"; + OAuth2SMTPAuthentication: Codeunit "OAuth2 SMTP Authentication"; begin - UserIDEditable := (Rec."Authentication Type" = Rec."Authentication Type"::Basic) or (Rec."Authentication Type" = Rec."Authentication Type"::"OAuth 2.0") or (Rec."Authentication Type" = Rec."Authentication Type"::NTLM); - PasswordEditable := (Rec."Authentication Type" = Rec."Authentication Type"::Basic) or (Rec."Authentication Type" = Rec."Authentication Type"::NTLM); - ShowMessageAboutSigningIn := (not EnvironmentInformation.IsSaaSInfrastructure()) and (Rec."Authentication Type" = Rec."Authentication Type"::"OAuth 2.0") and (Rec.Server = SMTPConnectorImpl.GetO365SmtpServer()); - SenderFieldsEnabled := Rec."Sender Type" = Rec."Sender Type"::"Specific User"; + if IsNullGuid(Rec."Client Id Storage Id") or IsNullGuid(Rec."Client Secret Storage Id") then + Error(ClientIdAndSecretRequiredErr); + + OAuth2SMTPAuthentication.AuthenticateWithOAuth2CustomAppReg(Rec); end; local procedure SetClientSecretInStorage(var SMTPAccount: Record "SMTP Account") @@ -412,9 +571,7 @@ page 4511 "SMTP Account Wizard" begin if IsNullGuid(SMTPEmailAccount."Account Id") then exit(false); - EmailAccount := SMTPEmailAccount; - exit(true); end; } \ No newline at end of file diff --git a/Apps/W1/Email - SMTP Connector/app/src/SMTPConnectorImpl.Codeunit.al b/Apps/W1/Email - SMTP Connector/app/src/SMTPConnectorImpl.Codeunit.al index bd635b1934..80b6fb8ee9 100644 --- a/Apps/W1/Email - SMTP Connector/app/src/SMTPConnectorImpl.Codeunit.al +++ b/Apps/W1/Email - SMTP Connector/app/src/SMTPConnectorImpl.Codeunit.al @@ -45,6 +45,9 @@ codeunit 4513 "SMTP Connector Impl." implements "Email Connector" CouldNotConnectErr: Label 'Could not connect to the SMTP server.\\%1', Comment = '%1 = the error message returned by the SMTP server.'; CouldNotAuthenticateErr: Label 'Could not authenticate on the SMTP server.\\%1', Comment = '%1 = the error message returned by the SMTP server.'; CouldNotSendErr: Label 'Could not send the email.\\%1', Comment = '%1 = the error message returned by the SMTP server.'; + UrlTxt: Label 'https://go.microsoft.com/fwlink/?linkid=2340938', Locked = true; + LearnMoreAboutSMTPBasicAuthObsoletionTxt: Label 'Learn more'; + SMTPBasicOAuthObsoletionNotificationTxt: Label 'Update email accounts to OAuth 2.0 as Exchange SMTP Basic authentication is being deprecated.'; /// /// Gets the registered accounts for the SMTP connector. @@ -348,6 +351,30 @@ codeunit 4513 "SMTP Connector Impl." implements "Email Connector" Error(ErrorWithStatusCodeErr, StrSubstNo(CouldNotSendErr, GetErrorContent(ErrorResponse)), NewLine, ErrorCode); end; + internal procedure SMTPBasicOAuthIsUsed(): Boolean + var + SMTPEmailAccount: Record "SMTP Account"; + begin + SMTPEmailAccount.SetRange("Authentication Type", SMTPEmailAccount."Authentication Type"::Basic); + SMTPEmailAccount.SetRange(Server, GetO365SmtpServer()); + exit(not SMTPEmailAccount.IsEmpty()); + end; + + internal procedure SendSMTPBasicOAuthObsoletionNotification() + var + Notif: Notification; + begin + Notif.AddAction(LearnMoreAboutSMTPBasicAuthObsoletionTxt, Codeunit::"SMTP Connector Impl.", 'LearnMoreAboutSMTPBasicAuthObsoletion'); + Notif.Message(SMTPBasicOAuthObsoletionNotificationTxt); + Notif.Scope := NotificationScope::LocalScope; + Notif.Send(); + end; + + internal procedure LearnMoreAboutSMTPBasicAuthObsoletion(Notification: Notification) + begin + Hyperlink(UrlTxt); + end; + procedure GetSmtpErrorCodeFromResponse(ErrorResponse: Text): Text var Regex: Codeunit Regex; @@ -462,7 +489,6 @@ codeunit 4513 "SMTP Connector Impl." implements "Email Connector" SMTPAccounts.SetRange("Authentication Type", Enum::"SMTP Authentication Types"::"OAuth 2.0"); SMTPAccounts.SetFilter("Client Id Storage Id", '<>%1', EmptyGuid); SMTPAccounts.SetFilter("Client Secret Storage Id", '<>%1', EmptyGuid); - SMTPAccounts.SetFilter("Authority URL", '<>%1', EmptyGuid); exit(SMTPAccounts.FindFirst()); end; diff --git a/Apps/W1/Email - SMTP Connector/test/src/SMTPAccountAuthTests.Codeunit.al b/Apps/W1/Email - SMTP Connector/test/src/SMTPAccountAuthTests.Codeunit.al index 54f9269c30..3beabc4cf6 100644 --- a/Apps/W1/Email - SMTP Connector/test/src/SMTPAccountAuthTests.Codeunit.al +++ b/Apps/W1/Email - SMTP Connector/test/src/SMTPAccountAuthTests.Codeunit.al @@ -21,12 +21,11 @@ codeunit 139762 "SMTP Account Auth Tests" #pragma warning restore AA0240 AuthenticationSuccessfulMsg: Label '%1 was authenticated.', Comment = '%1 = username'; AuthenticationFailedMsg: Label 'Could not authenticate.'; - EveryUserShouldPressAuthenticateMsg: Label 'Before people can send email they must authenticate their email account. They can do that by choosing the Authenticate action on the SMTP Account page.'; TokenFromCache: Text; - + NotificationIsSent: Boolean; [Test] - [HandlerFunctions('OAuth2AuthenticationMessageHandler')] + [HandlerFunctions('OAuth2AuthenticationMessageHandler1')] [TransactionModel(TransactionModel::AutoRollback)] procedure SwitchingToOAuth2Authentication() var @@ -66,6 +65,65 @@ codeunit 139762 "SMTP Account Auth Tests" SMTPAccountPage.Close(); end; + [Test] + [HandlerFunctions('BasicAuthNotificationHandler')] + [TransactionModel(TransactionModel::AutoRollback)] + procedure SMTPBasicAuthenticationObsoleteNotificationTest() + var + SMTPAccount: Record "SMTP Account"; + SMTPConnectorImpl: Codeunit "SMTP Connector Impl."; + EnvironmentInfoTestLibrary: Codeunit "Environment Info Test Library"; + EmailOutboxPage: TestPage "Email Outbox"; + begin + // [SCENARIO] + // Verifies that when an SMTP account uses Basic authentication, a deprecation notification + // is displayed on the Email Outbox page. Once the user switches the authentication method + // to OAuth 2.0, the notification should no longer appear. + + // [GIVEN] An SMTP account configured with Basic authentication. + SMTPAccount.DeleteAll(); + SMTPAccount.Id := CreateGuid(); + SMTPAccount."Authentication Type" := SMTPAccount."Authentication Type"::Basic; + SMTPAccount.Server := SMTPConnectorImpl.GetO365SmtpServer(); + SMTPAccount.Insert(); + + // Reset the notification tracking flag before test execution. + NotificationIsSent := false; + + // [GIVEN] Simulate OnPrem environment (not SaaS) so that the local SMTP implementation is used. + EnvironmentInfoTestLibrary.SetTestabilitySoftwareAsAService(false); + + // [WHEN] The Email Outbox page is opened while Basic Auth is still in use. + EmailOutboxPage.OpenView(); + + // [THEN] A notification should be triggered warning about Basic Auth deprecation. + Assert.IsTrue(NotificationIsSent, 'Notification about basic authentication being obsolete was not shown.'); + EmailOutboxPage.Close(); + + // [WHEN] The SMTP account authentication is changed to OAuth 2.0. + SMTPAccount."Authentication Type" := SMTPAccount."Authentication Type"::"OAuth 2.0"; + SMTPAccount.Modify(); + + // Reset the notification tracking flag to verify that no new notification is triggered. + NotificationIsSent := false; + + // [WHEN] The Email Outbox page is opened again (after switching to OAuth 2.0). + EmailOutboxPage.OpenView(); + + // [THEN] No notification should appear, as Basic Auth is no longer used. + Assert.IsFalse(NotificationIsSent, 'Notification about basic authentication being obsolete is shown.'); + EmailOutboxPage.Close(); + end; + + [SendNotificationHandler] + procedure BasicAuthNotificationHandler(var Notification: Notification): Boolean + begin + if StrPos(Notification.Message(), 'Basic authentication') > 0 then begin + NotificationIsSent := true; + exit(true); + end; + end; + [Test] procedure GetUserNameTest() var @@ -350,6 +408,163 @@ codeunit 139762 "SMTP Account Auth Tests" SMTPAccountPage.Close(); end; + + [Test] + procedure TestEmailAddressDoesNotOverwriteExistingUserName() + begin + // [SCENARIO] Email Address OnValidate does not override User Name if it is already set. + + // [GIVEN] A new SMTP Account record with a pre-set User Name + CreateSMTPAccount(); + SMTPAccount."Sender Type" := SMTPAccount."Sender Type"::"Specific User"; + SMTPAccount."User Name" := 'existing-user@example.com'; + SMTPAccount.Modify(); + + // [WHEN] Opening the page and changing Email Address + SMTPAccountPage.OpenEdit(); + SMTPAccountPage.GoToRecord(SMTPAccount); + SMTPAccountPage.EmailAddress.SetValue('new-mail@example.com'); + + // [THEN] User Name remains unchanged + Assert.AreEqual('existing-user@example.com', SMTPAccountPage.UserName.Value(), 'User Name should not be overwritten by Email Address if already set'); + + SMTPAccountPage.Close(); + end; + + [Test] + [HandlerFunctions('ConfirmCloseCustomOAuthHandler')] + procedure TestCustomOAuth2ActionsVisibility() + var + SMTPConnectorImpl: Codeunit "SMTP Connector Impl."; + EnvironmentInfoTestLibrary: Codeunit "Environment Info Test Library"; + begin + // [SCENARIO] When Client Id Storage Id is set (custom OAuth), + // the custom authenticate action is visible and standard OAuth actions are hidden. + + // [GIVEN] OnPrem + an SMTP account + EnvironmentInfoTestLibrary.SetTestabilitySoftwareAsAService(true); + CreateSMTPAccount(); + + // [WHEN] Open the SMTP Account page and configure OAuth 2.0 with O365 via the UI + SMTPAccountPage.OpenEdit(); + SMTPAccountPage.GoToRecord(SMTPAccount); + + // Set Authentication to OAuth 2.0 (fires OnValidate(Authentication) -> SetProperties()) + SMTPAccountPage.Authentication.SetValue(SMTPAccount."Authentication Type"::"OAuth 2.0"); + + // Set server to O365 SMTP (fires OnValidate(ServerUrl) -> SetProperties()) + SMTPAccountPage.ServerUrl.SetValue(SMTPConnectorImpl.GetO365SmtpServer()); + + // At this point, standard OAuth 2.0 actions are visible (already covered by SwitchingToOAuth2Authentication test) + SMTPAccountPage.Close(); + + // [GIVEN] Custom OAuth is considered "enabled" when Client Id Storage Id is not null + SMTPAccount.Get(SMTPAccount.Id); + SMTPAccount."Client Id Storage Id" := CreateGuid(); + SMTPAccount.Modify(); + + // [WHEN] Reopen the page (OnOpenPage -> SetProperties() sees Client Id Storage Id <> GUID_EMPTY) + SMTPAccountPage.OpenEdit(); + SMTPAccountPage.GoToRecord(SMTPAccount); + SMTPAccountPage.Authentication.SetValue(SMTPAccount."Authentication Type"::"OAuth 2.0"); + + // [THEN] Custom OAuth authenticate action is visible + Assert.IsTrue(SMTPAccountPage."Authenticate with Customized OAuth 2.0".Visible(), 'Custom OAuth 2.0 authenticate action should be visible when Client Id Storage Id is set'); + + // [THEN] Standard OAuth 2.0 actions are hidden + Assert.IsFalse(SMTPAccountPage."Authenticate with OAuth 2.0".Visible(), 'Standard OAuth 2.0 authenticate action should be hidden when custom OAuth is enabled'); + Assert.IsFalse(SMTPAccountPage."Check OAuth 2.0 authentication".Visible(), 'Check OAuth 2.0 authentication action should be hidden when custom OAuth is enabled'); + SMTPAccountPage.Close(); + end; + + [Test] + procedure TestCustomOAuth2ToggleClearsSecrets() + begin + // [SCENARIO] Turning off Custom OAuth 2.0 clears secret-related fields. + + // [GIVEN] An SMTP account with custom OAuth 2.0 GUIDs filled + CreateSMTPAccount(); + SMTPAccount."Authentication Type" := SMTPAccount."Authentication Type"::"OAuth 2.0"; + SMTPAccount."Client Id Storage Id" := CreateGuid(); + SMTPAccount."Client Secret Storage Id" := CreateGuid(); + SMTPAccount."Tenant Id" := CreateGuid(); + SMTPAccount."Redirect Uri" := 'https://example.com/redirect'; + SMTPAccount.Modify(); + + // [WHEN] Opening the page and setting CustomOAuth2Settings to false + SMTPAccountPage.OpenEdit(); + SMTPAccountPage.GoToRecord(SMTPAccount); + SMTPAccountPage.CustomOAuth2Settings.SetValue(false); + + SMTPAccountPage.Close(); + + // [THEN] All related GUIDs and redirect URI are cleared + SMTPAccount.Get(SMTPAccount.Id); + Assert.IsTrue(IsNullGuid(SMTPAccount."Client Id Storage Id"), 'Client Id Storage Id should be cleared when disabling Custom OAuth 2.0'); + Assert.IsTrue(IsNullGuid(SMTPAccount."Client Secret Storage Id"), 'Client Secret Storage Id should be cleared when disabling Custom OAuth 2.0'); + Assert.IsTrue(IsNullGuid(SMTPAccount."Tenant Id"), 'Tenant Id should be cleared when disabling Custom OAuth 2.0'); + Assert.AreEqual('', SMTPAccount."Redirect Uri", 'Redirect URI should be cleared when disabling Custom OAuth 2.0'); + end; + + [Test] + [HandlerFunctions('ConfirmCloseCustomOAuthHandler')] + procedure TestCustomOAuth2AuthenticateRequiresClientIdAndSecret() + begin + // [SCENARIO] "Authenticate with Customized OAuth 2.0" errors when Client Id or Secret is missing. + + // [GIVEN] OAuth 2.0 account using O365 server and Custom OAuth toggled on, but without ClientId/Secret + CreateSMTPAccount(); + SMTPAccount."Authentication Type" := SMTPAccount."Authentication Type"::"OAuth 2.0"; + SMTPAccount.Server := 'smtp.office365.com'; + SMTPAccount."Client Id Storage Id" := CreateGuid(); // Only ClientId is present to force partial configuration + SMTPAccount.Modify(); + + SMTPAccountPage.OpenEdit(); + SMTPAccountPage.GoToRecord(SMTPAccount); + + // Turn on Custom OAuth 2.0 (in case it isn't already) + if not SMTPAccountPage.CustomOAuth2Settings.AsBoolean() then + SMTPAccountPage.CustomOAuth2Settings.SetValue(true); + + // [THEN] Invoking authenticate should raise an error because Client Secret is missing + asserterror SMTPAccountPage."Authenticate with Customized OAuth 2.0".Invoke(); + Assert.ExpectedError('To use customized OAuth 2.0 settings, the Client ID, Client Secret and Tenant ID must be provided.'); + + SMTPAccountPage.Close(); + end; + + [Test] + [HandlerFunctions('ConfirmCloseCustomOAuthHandler')] + procedure TestClosePageWithIncompleteCustomOAuthRequiresConfirm() + begin + // [SCENARIO] When Custom OAuth 2.0 is enabled but required fields are missing, closing page asks for confirmation. + + // [GIVEN] OAuth 2.0 account with Custom OAuth enabled and incomplete configuration + CreateSMTPAccount(); + SMTPAccount."Authentication Type" := SMTPAccount."Authentication Type"::"OAuth 2.0"; + SMTPAccount."Client Id Storage Id" := CreateGuid(); // Only ClientId present + SMTPAccount.Modify(); + + SMTPAccountPage.OpenEdit(); + SMTPAccountPage.GoToRecord(SMTPAccount); + + // Ensure Custom OAuth 2.0 setting is true + if not SMTPAccountPage.CustomOAuth2Settings.AsBoolean() then + SMTPAccountPage.CustomOAuth2Settings.SetValue(true); + + // [WHEN] Closing the page + SMTPAccountPage.Close(); + + // [THEN] The ConfirmCloseCustomOAuthHandler confirms that the right question was asked + end; + + [ConfirmHandler] + procedure ConfirmCloseCustomOAuthHandler(Question: Text[1024]; var Reply: Boolean) + begin + Assert.AreEqual('To use customized OAuth 2.0 settings, the Client ID, Client Secret and Tenant ID must be provided. Do you want to exit without these information?', Question, 'Unexpected confirmation question when closing page with incomplete Custom OAuth settings.'); + Reply := true; + end; + #endregion #region Wizard page tests @@ -555,8 +770,168 @@ codeunit 139762 "SMTP Account Auth Tests" SMTPAccountWizardPage.EmailAddress.SetValue('test@example.com'); // [THEN] Next button should be enabled - if not SMTPAccountWizardPage.Next.Enabled() then - Error('Next button should be enabled with valid data'); + Assert.IsTrue(SMTPAccountWizardPage.Next.Enabled(), 'Next button should be enabled with valid data'); + + SMTPAccountWizardPage.Close(); + end; + + [Test] + procedure TestWizardNextDisabledUntilBasicFieldsValid() + begin + // [SCENARIO] In Step 1, Next is disabled until account is considered valid. + + // [WHEN] Opening the wizard + SMTPAccountWizardPage.OpenNew(); + + // [THEN] Next is initially disabled + Assert.IsFalse(SMTPAccountWizardPage.Next.Enabled(), 'Next should be disabled when required fields are empty'); + + // [WHEN] Filling the required fields (same pattern as in existing tests for a valid account) + SMTPAccountWizardPage.NameField.SetValue('Validation Test'); + SMTPAccountWizardPage.ServerUrl.SetValue('smtp.test.com'); + SMTPAccountWizardPage.SenderTypeField.SetValue("SMTP Connector Sender Type"::"Specific User"); + SMTPAccountWizardPage.EmailAddress.SetValue('valid@example.com'); + + // [THEN] Next becomes enabled + Assert.IsTrue(SMTPAccountWizardPage.Next.Enabled(), 'Next should be enabled when required fields are filled'); + + SMTPAccountWizardPage.Close(); + end; + + [Test] + [TransactionModel(TransactionModel::AutoRollback)] + procedure TestWizardOAuth2ShowsStep2() + var + EnvironmentInfoTestLibrary: Codeunit "Environment Info Test Library"; + begin + // [SCENARIO] When Authentication is OAuth 2.0, Next from Step 1 goes to Step 2 (custom OAuth question). + + // [GIVEN] Force SaaS environment so no "authenticate" message is shown + EnvironmentInfoTestLibrary.SetTestabilitySoftwareAsAService(true); + + // [WHEN] Opening wizard and filling basic valid data + SMTPAccountWizardPage.OpenNew(); + SMTPAccountWizardPage.NameField.SetValue('OAuth Step Test'); + SMTPAccountWizardPage.ServerUrl.SetValue('smtp.office365.com'); + SMTPAccountWizardPage.SenderTypeField.SetValue("SMTP Connector Sender Type"::"Specific User"); + SMTPAccountWizardPage.EmailAddress.SetValue('test@example.com'); + + // Set authentication to OAuth 2.0 (this is where the message would be shown in OnPrem) + SMTPAccountWizardPage.Authentication.SetValue("SMTP Authentication"::"OAuth 2.0"); + + // Move to Step 2 + SMTPAccountWizardPage.Next.Invoke(); + + // [THEN] Step 2 (Custom app registration question) is visible + Assert.IsTrue( + SMTPAccountWizardPage.Custom.Visible(), + 'Custom OAuth question should be visible in Step 2 for OAuth 2.0 flow' + ); + + SMTPAccountWizardPage.Close(); + end; + + [Test] + procedure TestWizardBackFromStep2ToStep1() + begin + // [SCENARIO] Back action navigates from Step 2 to Step 1. + + // [GIVEN] We are in Step 2 (OAuth 2.0 flow) + SMTPAccountWizardPage.OpenNew(); + SMTPAccountWizardPage.NameField.SetValue('Back Nav Test'); + SMTPAccountWizardPage.ServerUrl.SetValue('smtp.office365.com'); + SMTPAccountWizardPage.SenderTypeField.SetValue("SMTP Connector Sender Type"::"Specific User"); + SMTPAccountWizardPage.EmailAddress.SetValue('test@example.com'); + SMTPAccountWizardPage.Authentication.SetValue("SMTP Authentication"::"OAuth 2.0"); + SMTPAccountWizardPage.Next.Invoke(); + Assert.IsTrue(SMTPAccountWizardPage.Custom.Visible(), 'Custom OAuth question should be visible before pressing Back'); + + // [WHEN] Pressing Back + SMTPAccountWizardPage.Back.Invoke(); + + // [THEN] We are back on Step 1 (Name field is visible and Custom is not) + Assert.IsTrue(SMTPAccountWizardPage.NameField.Visible(), 'Name field should be visible again on Step 1'); + Assert.IsFalse(SMTPAccountWizardPage.Custom.Visible(), 'Custom OAuth question should not be visible on Step 1'); + + SMTPAccountWizardPage.Close(); + end; + + [Test] + procedure TestWizardCustomOAuthDisablesNextUntilOAuthFieldsValid() + begin + // [SCENARIO] When using Custom OAuth in the wizard, Next on Step 3 is disabled + // until Client Id, Client Secret, and Tenant ID are filled. + + // [GIVEN] OAuth 2.0 flow and Step 2 = Custom OAuth enabled + SMTPAccountWizardPage.OpenNew(); + SMTPAccountWizardPage.NameField.SetValue('Custom OAuth Wizard'); + SMTPAccountWizardPage.ServerUrl.SetValue('smtp.office365.com'); + SMTPAccountWizardPage.SenderTypeField.SetValue("SMTP Connector Sender Type"::"Specific User"); + SMTPAccountWizardPage.EmailAddress.SetValue('test@example.com'); + SMTPAccountWizardPage.Authentication.SetValue("SMTP Authentication"::"OAuth 2.0"); + + // Step 1 -> Step 2 + SMTPAccountWizardPage.Next.Invoke(); + + // Enable Custom OAuth + SMTPAccountWizardPage.Custom.SetValue(true); + + // Step 2 -> Step 3 + SMTPAccountWizardPage.Next.Invoke(); + + // [THEN] In Step 3, Next should be disabled because OAuth fields are not filled yet + Assert.IsFalse(SMTPAccountWizardPage.Next.Enabled(), 'Next should be disabled on Step 3 when OAuth fields are empty for Custom OAuth'); + + // [WHEN] Filling OAuth fields + SMTPAccountWizardPage.ClientId.SetValue('client-id-value'); + SMTPAccountWizardPage.ClientSecret.SetValue('client-secret-value'); + SMTPAccountWizardPage."Tenant Id".SetValue(Format(CreateGuid())); // valid GUID string + + // [THEN] Next is enabled after all OAuth fields are valid + Assert.IsTrue(SMTPAccountWizardPage.Next.Enabled(), 'Next should be enabled once all Custom OAuth fields are filled'); + + SMTPAccountWizardPage.Close(); + end; + + [Test] + procedure TestWizardEmailAddressAutoFillsUserName() + begin + // [SCENARIO] In the wizard, setting Email Address when User Name is empty fills User Name. + + SMTPAccountWizardPage.OpenNew(); + SMTPAccountWizardPage.NameField.SetValue('UserName AutoFill'); + SMTPAccountWizardPage.SenderTypeField.SetValue("SMTP Connector Sender Type"::"Specific User"); + SMTPAccountWizardPage.EmailAddress.SetValue('wizard-user@example.com'); + + // [THEN] User Name is auto-filled (same as page 4512 behavior) + Assert.AreEqual('wizard-user@example.com', SMTPAccountWizardPage.UserName.Value(), 'User Name should be auto-filled in wizard'); + + SMTPAccountWizardPage.Close(); + end; + + [Test] + [HandlerFunctions('OAuth2AuthenticationMessageHandler2')] + procedure TestWizardShowsAuthenticateMessageWhenSwitchingToO365WithOAuth() + var + EnvironmentInfoTestLibrary: Codeunit "Environment Info Test Library"; + begin + // [SCENARIO] When Authentication = OAuth 2.0 and Server is set to O365 on-prem, + // the wizard shows the "every user should authenticate" message. + + // [GIVEN] OnPrem environment + EnvironmentInfoTestLibrary.SetTestabilitySoftwareAsAService(false); + + SMTPAccountWizardPage.OpenNew(); + SMTPAccountWizardPage.NameField.SetValue('Auth Msg Wizard'); + SMTPAccountWizardPage.SenderTypeField.SetValue("SMTP Connector Sender Type"::"Specific User"); + SMTPAccountWizardPage.EmailAddress.SetValue('user@example.com'); + + SMTPAccountWizardPage.Authentication.SetValue("SMTP Authentication"::"OAuth 2.0"); + + // [WHEN] Setting server to O365 SMTP server triggers message in OnValidate(ServerUrl) + SMTPAccountWizardPage.ServerUrl.SetValue('smtp.office365.com'); + + // [THEN] OAuth2AuthenticationMessageHandler verifies the message text SMTPAccountWizardPage.Close(); end; @@ -634,9 +1009,15 @@ codeunit 139762 "SMTP Account Auth Tests" end; [MessageHandler] - procedure OAuth2AuthenticationMessageHandler(Message: Text[1024]) + procedure OAuth2AuthenticationMessageHandler1(Message: Text[1024]) + begin + Assert.ExpectedMessage('Before people can send email they must authenticate their email account. They can do that by choosing the Authenticate action on the SMTP Account page.', Message); + end; + + [MessageHandler] + procedure OAuth2AuthenticationMessageHandler2(Message: Text[1024]) begin - Assert.AreEqual(EveryUserShouldPressAuthenticateMsg, Message, 'Incorrect message is shown.'); + Assert.ExpectedMessage('Before people can send email they must authenticate their account.', Message); end; [EventSubscriber(ObjectType::Codeunit, Codeunit::"Azure AD Auth Flow", 'OnAcquireTokenFromCacheWithCredentials', '', false, false)] diff --git a/Apps/W1/Email - SMTP Connector/test/src/SMTPConnectorTest.Codeunit.al b/Apps/W1/Email - SMTP Connector/test/src/SMTPConnectorTest.Codeunit.al index c0e286cc98..bb6a37be35 100644 --- a/Apps/W1/Email - SMTP Connector/test/src/SMTPConnectorTest.Codeunit.al +++ b/Apps/W1/Email - SMTP Connector/test/src/SMTPConnectorTest.Codeunit.al @@ -206,6 +206,8 @@ codeunit 139760 "SMTP Connector Test" SMTPAccountWizard.Password.SetValue(SMTPAccountMock.Password()); SMTPAccountWizard.SecureConnection.SetValue(SMTPAccountMock.SecureConnection()); + // Need to clike two Next to complete the wizard + SMTPAccountWizard.Next.Invoke(); SMTPAccountWizard.Next.Invoke(); end; diff --git a/Apps/W1/EmailLogging/app/src/codeunits/EmailLoggingInvoke.Codeunit.al b/Apps/W1/EmailLogging/app/src/codeunits/EmailLoggingInvoke.Codeunit.al index c1cff5c149..2450496650 100644 --- a/Apps/W1/EmailLogging/app/src/codeunits/EmailLoggingInvoke.Codeunit.al +++ b/Apps/W1/EmailLogging/app/src/codeunits/EmailLoggingInvoke.Codeunit.al @@ -492,6 +492,7 @@ codeunit 1685 "Email Logging Invoke" local procedure GetInboundOutboundInteraction(var EmailLoggingMessage: Codeunit "Email Logging Message"; var SegmentLine: Record "Segment Line"): Boolean begin + OnBeforeGetInboundOutboundInteraction(EmailLoggingMessage, SegmentLine); // Check if in- or out-bound and store sender and recipients in segment line(s) if IsSalesperson(EmailLoggingMessage.GetSender(), SegmentLine) then begin SegmentLine."Information Flow" := SegmentLine."Information Flow"::Outbound; @@ -535,4 +536,9 @@ codeunit 1685 "Email Logging Invoke" begin ErrorContext := NewContext; end; + + [IntegrationEvent(false, false)] + local procedure OnBeforeGetInboundOutboundInteraction(var EmailLoggingMessage: Codeunit "Email Logging Message"; var SegmentLine: Record "Segment Line") + begin + end; } \ No newline at end of file diff --git a/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al b/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al index 5775bdfb52..e7ea17af90 100644 --- a/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al +++ b/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al @@ -19,6 +19,8 @@ using Microsoft.Foundation.Reporting; using Microsoft.Purchases.Document; using Microsoft.Purchases.History; using Microsoft.Purchases.Payables; +using Microsoft.Purchases.Setup; +using Microsoft.Purchases.Vendor; using Microsoft.Sales.Customer; using Microsoft.Sales.Document; using Microsoft.Sales.History; @@ -57,6 +59,7 @@ codeunit 139515 "Digital Vouchers Tests" LibraryService: Codeunit "Library - Service"; IsInitialized: Boolean; NotPossibleToPostWithoutVoucherErr: Label 'Not possible to post without attaching the digital voucher.'; + NotPossibleToPostWithoutVoucherOrNoteErr: Label 'Not possible to post without attaching the digital voucher or adding the note.'; DialogErrorCodeTok: Label 'Dialog', Locked = true; CannotRemoveReferenceRecordFromIncDocErr: Label 'Cannot remove the reference record from the incoming document because it is used for the enforced digital voucher functionality'; DetachQst: Label 'Do you want to remove the reference from this incoming document to posted document'; @@ -65,6 +68,8 @@ codeunit 139515 "Digital Vouchers Tests" PaymentLineAppliedMsg: Label '%1 payment lines out of 1 are applied.\\', Comment = '%1 - number'; DoYouWantTPostPmtQst: Label 'Do you want to post the payments?'; LinesPostedMsg: Label 'The journal lines were successfully posted.'; + DigitalVoucherGenerateErr: Label 'Digital voucher has been generated.'; + DigitalVoucherNotGenerateErr: Label 'Digital voucher has not been generated'; trigger OnRun() begin @@ -1107,6 +1112,430 @@ codeunit 139515 "Digital Vouchers Tests" UnbindSubscription(DigVouchersDisableEnforce); end; + [Test] + procedure DigitalVoucherIsGeneratedForSelfBillingPurchaseOrderAutoGenerateCheckTypeAttechment() + var + IncomingDocument: Record "Incoming Document"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + PurchInvHeader: Record "Purch. Inv. Header"; + DigVouchersDisableEnforce: Codeunit "Dig. Vouchers Disable Enforce"; + SelfBillingInvNo: Code[20]; + begin + // [SCENARIO 580348] Digital Voucher is generated for self-billing purchase order with "Attachment" check type. + Initialize(); + EnableDigitalVoucherFeature(); + BindSubscription(DigVouchersDisableEnforce); + + // [GIVEN] Set Report Selection for Purchase Invoice to use "Purchase - Invoice" report. + CreateInvoiceReportSelection(); + + // [GIVEN] Digital Voucher entry setup for Purchase Document is "Attachment", "Generate Automatically" option is enabled and "Consider Blank Doc. Type" option is disabled. + InitSetupGenerateAutomaticallyAndConsiderBlankDocType("Digital Voucher Entry Type"::"Purchase Document", "Digital Voucher Check Type"::Attachment, false); + + // [GIVEN] Purchases & Payables Setup "Posted Self-Billing Inv. Nos." is set to a No. Series. + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", LibraryERM.CreateNoSeriesCode()); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] Create Vendor with "Self-Billing Agreement" enabled. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Modify(true); + + // [GIVEN] Create Purchase Order with Item line. + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine( + PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), LibraryRandom.RandInt(10)); + + // [WHEN] Post Purchase Order as Self-Billing Invoice. + SelfBillingInvNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + + // [THEN] Digital voucher is generated for the posted Self-Billing Purchase Invoice. + PurchInvHeader.Get(SelfBillingInvNo); + Assert.IsTrue(IncomingDocument.FindByDocumentNoAndPostingDate( + IncomingDocument, PurchInvHeader."No.", Format(PurchInvHeader."Posting Date")), DigitalVoucherNotGenerateErr); + UnbindSubscription(DigVouchersDisableEnforce); + end; + + [Test] + procedure DigitalVoucherIsGeneratedForSelfBillingPurchaseOrderAutoGenerateCheckTypeAttechmentOrNote() + var + IncomingDocument: Record "Incoming Document"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + PurchInvHeader: Record "Purch. Inv. Header"; + DigVouchersDisableEnforce: Codeunit "Dig. Vouchers Disable Enforce"; + SelfBillingInvNo: Code[20]; + begin + // [SCENARIO 580348] Digital Voucher is generated for self-billing purchase order with "Attachment" check type. + Initialize(); + EnableDigitalVoucherFeature(); + BindSubscription(DigVouchersDisableEnforce); + + // [GIVEN] Set Report Selection for Purchase Invoice to use "Purchase - Invoice" report. + CreateInvoiceReportSelection(); + + // [GIVEN] Digital Voucher entry setup for Purchase Document is "Attachment Or Note", "Generate Automatically" option is enabled and "Consider Blank Doc. Type" option is disabled. + InitSetupGenerateAutomaticallyAndConsiderBlankDocType("Digital Voucher Entry Type"::"Purchase Document", "Digital Voucher Check Type"::"Attachment or Note", false); + + // [GIVEN] Purchases & Payables Setup "Posted Self-Billing Inv. Nos." is set to a No. Series. + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", LibraryERM.CreateNoSeriesCode()); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] Create Vendor with "Self-Billing Agreement" enabled. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Modify(true); + + // [GIVEN] Create Purchase Order with Item line. + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine( + PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), LibraryRandom.RandInt(10)); + + // [WHEN] Post Purchase Order as Self-Billing Invoice. + SelfBillingInvNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + + // [THEN] Digital Voucher is generated for the posted Self-Billing Purchase Invoice. + PurchInvHeader.Get(SelfBillingInvNo); + Assert.IsTrue(IncomingDocument.FindByDocumentNoAndPostingDate( + IncomingDocument, PurchInvHeader."No.", Format(PurchInvHeader."Posting Date")), DigitalVoucherNotGenerateErr); + UnbindSubscription(DigVouchersDisableEnforce); + end; + + [Test] + procedure DigitalVoucherNotGeneratedForSelfBillingPurchaseOrderAutoGenerateCheckTypeNoCheck() + var + IncomingDocument: Record "Incoming Document"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + PurchInvHeader: Record "Purch. Inv. Header"; + DigVouchersDisableEnforce: Codeunit "Dig. Vouchers Disable Enforce"; + SelfBillingInvNo: Code[20]; + begin + // [SCENARIO 580348] Digital Voucher is generated for self-billing purchase order with "Attachment" check type. + Initialize(); + EnableDigitalVoucherFeature(); + BindSubscription(DigVouchersDisableEnforce); + + // [GIVEN] Set Report Selection for Purchase Invoice to use "Purchase - Invoice" report. + CreateInvoiceReportSelection(); + + // [GIVEN] Digital Voucher entry setup for Purchase Document is "No Check", "Generate Automatically" option is enabled and "Consider Blank Doc. Type" option is disabled. + InitSetupGenerateAutomaticallyAndConsiderBlankDocType("Digital Voucher Entry Type"::"Purchase Document", "Digital Voucher Check Type"::"No Check", false); + + // [GIVEN] Purchases & Payables Setup "Posted Self-Billing Inv. Nos." is set to a No. Series. + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", LibraryERM.CreateNoSeriesCode()); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] Create Vendor with "Self-Billing Agreement" enabled. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Modify(true); + + // [GIVEN] Create Purchase Order with Item line. + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine( + PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), LibraryRandom.RandInt(10)); + + // [WHEN] Post Purchase Order as Self-Billing Invoice. + SelfBillingInvNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + + // [THEN] Digital Voucher is Not generated for the posted Self-Billing Purchase Invoice. + PurchInvHeader.Get(SelfBillingInvNo); + Assert.IsFalse(IncomingDocument.FindByDocumentNoAndPostingDate( + IncomingDocument, PurchInvHeader."No.", Format(PurchInvHeader."Posting Date")), DigitalVoucherGenerateErr); + UnbindSubscription(DigVouchersDisableEnforce); + end; + + [Test] + procedure DigitalVoucherNotGeneratedForSelfBillingPurchaseOrderCheckTypeNoCheckAndAutoGenerateFalse() + var + IncomingDocument: Record "Incoming Document"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + PurchInvHeader: Record "Purch. Inv. Header"; + DigVouchersDisableEnforce: Codeunit "Dig. Vouchers Disable Enforce"; + SelfBillingInvNo: Code[20]; + begin + // [SCENARIO 580348] Digital Voucher is generated for self-billing purchase order with "Attachment" check type. + Initialize(); + EnableDigitalVoucherFeature(); + BindSubscription(DigVouchersDisableEnforce); + + // [GIVEN] Set Report Selection for Purchase Invoice to use "Purchase - Invoice" report. + CreateInvoiceReportSelection(); + + // [GIVEN] Digital Voucher entry setup for Purchase Document is "No Check", "Generate Automatically" option is disabled and "Consider Blank Doc. Type" option is disabled. + InitSetupCheckWithConsiderBlankDocType("Digital Voucher Entry Type"::"Purchase Document", "Digital Voucher Check Type"::"No Check", false); + + // [GIVEN] Purchases & Payables Setup "Posted Self-Billing Inv. Nos." is set to a No. Series. + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", LibraryERM.CreateNoSeriesCode()); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] Create Vendor with "Self-Billing Agreement" enabled. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Modify(true); + + // [GIVEN] Create Purchase Order with Item line. + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine( + PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), LibraryRandom.RandInt(10)); + + // [WHEN] Post Purchase Order as Self-Billing Invoice. + SelfBillingInvNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + + // [THEN] Digital Voucher is Not generated for the posted Self-Billing Purchase Invoice. + PurchInvHeader.Get(SelfBillingInvNo); + Assert.IsFalse(IncomingDocument.FindByDocumentNoAndPostingDate( + IncomingDocument, PurchInvHeader."No.", Format(PurchInvHeader."Posting Date")), DigitalVoucherGenerateErr); + UnbindSubscription(DigVouchersDisableEnforce); + end; + + [Test] + procedure DigitalVoucherNotGeneratedForSelfBillingPurchaseOrderCheckTypeAttachmentAndAutoGenerateFalse() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + DigVouchersDisableEnforce: Codeunit "Dig. Vouchers Disable Enforce"; + begin + // [SCENARIO 580348] Digital Voucher is generated for self-billing purchase order with "Attachment" check type. + Initialize(); + EnableDigitalVoucherFeature(); + BindSubscription(DigVouchersDisableEnforce); + + // [GIVEN] Set Report Selection for Purchase Invoice to use "Purchase - Invoice" report. + CreateInvoiceReportSelection(); + + // [GIVEN] Digital Voucher entry setup for Purchase Document is "Attachment", "Generate Automatically" option is disabled and "Consider Blank Doc. Type" option is disabled. + InitSetupCheckWithConsiderBlankDocType("Digital Voucher Entry Type"::"Purchase Document", "Digital Voucher Check Type"::Attachment, false); + + // [GIVEN] Purchases & Payables Setup "Posted Self-Billing Inv. Nos." is set to a No. Series. + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", LibraryERM.CreateNoSeriesCode()); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] Create Vendor with "Self-Billing Agreement" enabled. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Modify(true); + + // [GIVEN] Create Purchase Order with Item line. + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine( + PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), LibraryRandom.RandInt(10)); + + // [WHEN] Post Purchase Order as Self-Billing Invoice. + asserterror LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + + // [THEN] While posting user receives an error "Not possible to post without attaching the digital voucher" + Assert.ExpectedErrorCode(DialogErrorCodeTok); + Assert.ExpectedError(NotPossibleToPostWithoutVoucherErr); + UnbindSubscription(DigVouchersDisableEnforce); + end; + + [Test] + procedure DigitalVoucherNotGeneratedForSelfBillingPurchaseOrderCheckTypeAttachmentORNoteAndAutoGenerateFalse() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + DigVouchersDisableEnforce: Codeunit "Dig. Vouchers Disable Enforce"; + begin + // [SCENARIO 580348] Digital Voucher is generated for self-billing purchase order with "Attachment" check type. + Initialize(); + EnableDigitalVoucherFeature(); + BindSubscription(DigVouchersDisableEnforce); + + // [GIVEN] Set Report Selection for Purchase Invoice to use "Purchase - Invoice" report. + CreateInvoiceReportSelection(); + + // [GIVEN] Digital Voucher entry setup for Purchase Document is "Attachment or Note", "Generate Automatically" option is disabled and "Consider Blank Doc. Type" option is disabled. + InitSetupCheckWithConsiderBlankDocType("Digital Voucher Entry Type"::"Purchase Document", "Digital Voucher Check Type"::"Attachment or Note", false); + + // [GIVEN] Purchases & Payables Setup "Posted Self-Billing Inv. Nos." is set to a No. Series. + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", LibraryERM.CreateNoSeriesCode()); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] Create Vendor with "Self-Billing Agreement" enabled. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Modify(true); + + // [GIVEN] Create Purchase Order with Item line. + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine( + PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), LibraryRandom.RandInt(10)); + + // [WHEN] Post Purchase Order as Self-Billing Invoice. + asserterror LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + + // [THEN] While posting user receives an error "Not possible to post without attaching the digital voucher or adding the note" + Assert.ExpectedErrorCode(DialogErrorCodeTok); + Assert.ExpectedError(NotPossibleToPostWithoutVoucherOrNoteErr); + UnbindSubscription(DigVouchersDisableEnforce); + end; + + [Test] + procedure DigitalVoucherNotGeneratedForSelfBillingPurchaseOrderAutoGenerateCheckTypeAttechmentSkipManual() + var + IncomingDocument: Record "Incoming Document"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + PurchInvHeader: Record "Purch. Inv. Header"; + DigVouchersDisableEnforce: Codeunit "Dig. Vouchers Disable Enforce"; + SelfBillingInvNo: Code[20]; + begin + // [SCENARIO 580348] Digital Voucher is not generated for self-billing purchase order with "Attachment" check type and manual added document. + Initialize(); + EnableDigitalVoucherFeature(); + BindSubscription(DigVouchersDisableEnforce); + + // [GIVEN] Set Report Selection for Purchase Invoice to use "Purchase - Invoice" report. + CreateInvoiceReportSelection(); + + // [GIVEN] Digital voucher entry setup for Purchase Document is "Attachment", "Generate Automatically" option is enabled and "Skip if Manually added" option is enabled. + InitSetupGenerateAutomaticallySkipIfManuallyAdded("Digital Voucher Entry Type"::"Purchase Document", "Digital Voucher Check Type"::Attachment); + + // [GIVEN] Purchases & Payables Setup "Posted Self-Billing Inv. Nos." is set to a No. Series. + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", LibraryERM.CreateNoSeriesCode()); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] Create Vendor with "Self-Billing Agreement" enabled. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Modify(true); + + // [GIVEN] Create Purchase Order with Item line. + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine( + PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), LibraryRandom.RandInt(10)); + + // [WHEN] Post Purchase Order as Self-Billing Invoice. + SelfBillingInvNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + + // [THEN] Digital voucher is generated for the posted Self-Billing Purchase Invoice. + PurchInvHeader.Get(SelfBillingInvNo); + Assert.IsTrue(IncomingDocument.FindByDocumentNoAndPostingDate( + IncomingDocument, PurchInvHeader."No.", Format(PurchInvHeader."Posting Date")), DigitalVoucherGenerateErr); + UnbindSubscription(DigVouchersDisableEnforce); + end; + + [Test] + procedure DigitalVoucherNotGeneratedForSelfBillingPurchaseOrderAutoGenerateCheckTypeAttechmentOrNoteSkipManual() + var + IncomingDocument: Record "Incoming Document"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + PurchInvHeader: Record "Purch. Inv. Header"; + DigVouchersDisableEnforce: Codeunit "Dig. Vouchers Disable Enforce"; + SelfBillingInvNo: Code[20]; + begin + // [SCENARIO 580348] Digital Voucher is not generated for self-billing purchase order with "Attachment or Note" check type and manual added document. + Initialize(); + EnableDigitalVoucherFeature(); + BindSubscription(DigVouchersDisableEnforce); + + // [GIVEN] Set Report Selection for Purchase Invoice to use "Purchase - Invoice" report. + CreateInvoiceReportSelection(); + + // [GIVEN] Digital Voucher entry setup for Purchase Document is "Attachment or Note", "Generate Automatically" option is enabled and "Skip if Manually added" option is enabled. + InitSetupGenerateAutomaticallySkipIfManuallyAdded("Digital Voucher Entry Type"::"Purchase Document", "Digital Voucher Check Type"::"Attachment or Note"); + + // [GIVEN] Purchases & Payables Setup "Posted Self-Billing Inv. Nos." is set to a No. Series. + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", LibraryERM.CreateNoSeriesCode()); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] Create Vendor with "Self-Billing Agreement" enabled. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Modify(true); + + // [GIVEN] Create Purchase Order with Item line. + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine( + PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), LibraryRandom.RandInt(10)); + + // [WHEN] Post Purchase Order as Self-Billing Invoice. + SelfBillingInvNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + + // [THEN] Digital voucher is generated for the posted Self-Billing Purchase Invoice. + PurchInvHeader.Get(SelfBillingInvNo); + Assert.IsTrue(IncomingDocument.FindByDocumentNoAndPostingDate( + IncomingDocument, PurchInvHeader."No.", Format(PurchInvHeader."Posting Date")), DigitalVoucherGenerateErr); + UnbindSubscription(DigVouchersDisableEnforce); + end; + + [Test] + procedure DigitalVoucherNotGeneratedForSelfBillingPurchaseOrderAutoGenerateCheckTypeNoCheckSkipManual() + var + IncomingDocument: Record "Incoming Document"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; + Vendor: Record Vendor; + PurchInvHeader: Record "Purch. Inv. Header"; + DigVouchersDisableEnforce: Codeunit "Dig. Vouchers Disable Enforce"; + SelfBillingInvNo: Code[20]; + begin + // [SCENARIO 580348] Digital Voucher is not generated for self-billing purchase order with "No Check" check type and manual added document. + Initialize(); + EnableDigitalVoucherFeature(); + BindSubscription(DigVouchersDisableEnforce); + + // [GIVEN] Set Report Selection for Purchase Invoice to use "Purchase - Invoice" report. + CreateInvoiceReportSelection(); + + // [GIVEN] Digital voucher entry setup for Purchase Document is "No Check", "Generate Automatically" option is enabled and "Skip if Manually Added" option is enabled. + InitSetupGenerateAutomaticallySkipIfManuallyAdded("Digital Voucher Entry Type"::"Purchase Document", "Digital Voucher Check Type"::"No Check"); + + // [GIVEN] Purchases & Payables Setup "Posted Self-Billing Inv. Nos." is set to a No. Series. + PurchasesPayablesSetup.Get(); + PurchasesPayablesSetup.Validate("Posted Self-Billing Inv. Nos.", LibraryERM.CreateNoSeriesCode()); + PurchasesPayablesSetup.Modify(true); + + // [GIVEN] Create Vendor with "Self-Billing Agreement" enabled. + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Self-Billing Agreement", true); + Vendor.Modify(true); + + // [GIVEN] Create Purchase Order with Item line. + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine( + PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, LibraryInventory.CreateItemNo(), LibraryRandom.RandInt(10)); + + // [WHEN] Post Purchase Order as Self-Billing Invoice. + SelfBillingInvNo := LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true); + + // [THEN] Digital voucher is Not generated for the posted Self-Billing Purchase Invoice. + PurchInvHeader.Get(SelfBillingInvNo); + Assert.IsFalse(IncomingDocument.FindByDocumentNoAndPostingDate( + IncomingDocument, PurchInvHeader."No.", Format(PurchInvHeader."Posting Date")), DigitalVoucherGenerateErr); + UnbindSubscription(DigVouchersDisableEnforce); + end; + local procedure Initialize() var CompanyInformation: Record "Company Information"; @@ -1516,6 +1945,20 @@ codeunit 139515 "Digital Vouchers Tests" Assert.RecordCount(IncomingDocumentAttachment, AttachmentsCount); end; + local procedure CreateInvoiceReportSelection() + var + CustomReportSelection: Record "Custom Report Selection"; + ReportSelections: Record "Report Selections"; + begin + ReportSelections.DeleteAll(); + CustomReportSelection.DeleteAll(); + + ReportSelections.Init(); + ReportSelections.Usage := ReportSelections.Usage::"P.Invoice"; + ReportSelections."Report ID" := REPORT::"Purchase - Invoice"; + if ReportSelections.Insert() then; + end; + [ConfirmHandler] procedure ConfirmHandler(Question: Text; var Reply: Boolean) begin diff --git a/Apps/W1/FieldServiceIntegration/app/src/Codeunits/FSInstall.Codeunit.al b/Apps/W1/FieldServiceIntegration/app/src/Codeunits/FSInstall.Codeunit.al index dad4a55041..0bbb14f1cc 100644 --- a/Apps/W1/FieldServiceIntegration/app/src/Codeunits/FSInstall.Codeunit.al +++ b/Apps/W1/FieldServiceIntegration/app/src/Codeunits/FSInstall.Codeunit.al @@ -97,11 +97,7 @@ codeunit 6616 "FS Install" if UpgradeTag.HasUpgradeTag(GetAssistedSetupUpgradeTag()) then exit; -#if not CLEAN25 - GuidedExperience.Remove("Guided Experience Type"::"Assisted Setup", ObjectType::Page, Page::Microsoft.Integration.FieldService."FS Connection Setup Wizard"); -#else GuidedExperience.Remove("Guided Experience Type"::"Assisted Setup", ObjectType::Page, 6421); // 6421 is the ID of the FS Connection Setup Wizard page in Base Application -#endif UpgradeTag.SetUpgradeTag(GetAssistedSetupUpgradeTag()); end; diff --git a/Apps/W1/FieldServiceIntegration/app/src/Codeunits/FSUpgrade.Codeunit.al b/Apps/W1/FieldServiceIntegration/app/src/Codeunits/FSUpgrade.Codeunit.al index 6920b418f1..9c4c65e3ca 100644 --- a/Apps/W1/FieldServiceIntegration/app/src/Codeunits/FSUpgrade.Codeunit.al +++ b/Apps/W1/FieldServiceIntegration/app/src/Codeunits/FSUpgrade.Codeunit.al @@ -24,11 +24,7 @@ codeunit 6617 "FS Upgrade" if UpgradeTag.HasUpgradeTag(GetAssistedSetupUpgradeTag()) then exit; -#if not CLEAN25 - GuidedExperience.Remove("Guided Experience Type"::"Assisted Setup", ObjectType::Page, Page::"FS Connection Setup Wizard"); -#else GuidedExperience.Remove("Guided Experience Type"::"Assisted Setup", ObjectType::Page, 6421); // 6421 is the ID of the FS Connection Setup Wizard page in Base Application -#endif UpgradeTag.SetUpgradeTag(GetAssistedSetupUpgradeTag()); end; diff --git a/Apps/W1/HybridBCLast/app/src/codeunits/W1Transformation.Codeunit.al b/Apps/W1/HybridBCLast/app/src/codeunits/W1Transformation.Codeunit.al deleted file mode 100644 index 408f89ee7d..0000000000 --- a/Apps/W1/HybridBCLast/app/src/codeunits/W1Transformation.Codeunit.al +++ /dev/null @@ -1,145 +0,0 @@ -namespace Microsoft.DataMigration.BC; - -codeunit 4027 "W1 Transformation" -{ - ObsoleteState = Pending; - ObsoleteReason = 'This functionality will be replaced by invoking the actual upgrade from each of the apps'; - ObsoleteTag = '17.0'; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Company Handler", 'OnTransformPerCompanyTableDataForVersion', '', false, false)] - local procedure TransformPerCompanyTableData_15x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 15.0 then - exit; - - OnAfterW1TransformationForVersion(CountryCode, TargetVersion); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Company Handler", 'OnTransformPerCompanyTableDataForVersion', '', false, false)] - local procedure TransformPerCompanyTableData_16x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 16.0 then - exit; - - OnAfterW1TransformationForVersion(CountryCode, TargetVersion); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Company Handler", 'OnTransformPerCompanyTableDataForVersion', '', false, false)] - local procedure TransformPerCompanyTableData_17x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 17.0 then - exit; - - OnAfterW1TransformationForVersion(CountryCode, TargetVersion); - end; - - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Company Handler", 'OnTransformPerCompanyTableDataForVersion', '', false, false)] - local procedure TransformPerCompanyTableData_18x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 18.0 then - exit; - - OnAfterW1TransformationForVersion(CountryCode, TargetVersion); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Company Handler", 'OnTransformPerCompanyTableDataForVersion', '', false, false)] - local procedure TransformPerCompanyTableData_19x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 19.0 then - exit; - - OnAfterW1TransformationForVersion(CountryCode, TargetVersion); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Company Handler", 'OnTransformPerCompanyTableDataForVersion', '', false, false)] - local procedure TransformPerCompanyTableData_20x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 20.0 then - exit; - - OnAfterW1TransformationForVersion(CountryCode, TargetVersion); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Company Handler", 'OnTransformPerCompanyTableDataForVersion', '', false, false)] - local procedure TransformPerCompanyTableData_21x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 21.0 then - exit; - - OnAfterW1TransformationForVersion(CountryCode, TargetVersion); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Management", 'OnTransformNonCompanyTableDataForVersion', '', false, false)] - local procedure TransformNonCompanyTableData_15x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 15.0 then - exit; - - OnAfterW1NonCompanyTransformationForVersion(CountryCode, TargetVersion); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Management", 'OnTransformNonCompanyTableDataForVersion', '', false, false)] - local procedure TransformNonCompanyTableData_16x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 16.0 then - exit; - - OnAfterW1NonCompanyTransformationForVersion(CountryCode, TargetVersion); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Management", 'OnTransformNonCompanyTableDataForVersion', '', false, false)] - local procedure TransformNonCompanyTableData_17x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 17.0 then - exit; - - OnAfterW1NonCompanyTransformationForVersion(CountryCode, TargetVersion); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Management", 'OnTransformNonCompanyTableDataForVersion', '', false, false)] - local procedure TransformNonCompanyTableData_18x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 18.0 then - exit; - - OnAfterW1NonCompanyTransformationForVersion(CountryCode, TargetVersion); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Management", 'OnTransformNonCompanyTableDataForVersion', '', false, false)] - local procedure TransformNonCompanyTableData_19x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 19.0 then - exit; - - OnAfterW1NonCompanyTransformationForVersion(CountryCode, TargetVersion); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Management", 'OnTransformNonCompanyTableDataForVersion', '', false, false)] - local procedure TransformNonCompanyTableData_20x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 20.0 then - exit; - - OnAfterW1NonCompanyTransformationForVersion(CountryCode, TargetVersion); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"W1 Management", 'OnTransformNonCompanyTableDataForVersion', '', false, false)] - local procedure TransformNonCompanyTableData_21x(CountryCode: Text; TargetVersion: Decimal) - begin - if TargetVersion <> 21.0 then - exit; - - OnAfterW1NonCompanyTransformationForVersion(CountryCode, TargetVersion); - end; - - [IntegrationEvent(false, false)] - local procedure OnAfterW1TransformationForVersion(CountryCode: Text; TargetVersion: Decimal) - begin - end; - - [IntegrationEvent(false, false)] - local procedure OnAfterW1NonCompanyTransformationForVersion(CountryCode: Text; TargetVersion: Decimal) - begin - end; -} diff --git a/Apps/W1/HybridBCLast/app/src/pages/TableFieldMappings.page.al b/Apps/W1/HybridBCLast/app/src/pages/TableFieldMappings.page.al index 30be239ccc..46795eee5b 100644 --- a/Apps/W1/HybridBCLast/app/src/pages/TableFieldMappings.page.al +++ b/Apps/W1/HybridBCLast/app/src/pages/TableFieldMappings.page.al @@ -6,7 +6,6 @@ page 40031 "Table Field Mappings" { PageType = List; ApplicationArea = All; - UsageCategory = Lists; SourceTable = "Table Field Mappings"; InherentPermissions = X; InherentEntitlements = X; diff --git a/Apps/W1/HybridGP/app/src/Migration/Items/GPItemMigrator.codeunit.al b/Apps/W1/HybridGP/app/src/Migration/Items/GPItemMigrator.codeunit.al index eb43dcdf57..c8b6580ed8 100644 --- a/Apps/W1/HybridGP/app/src/Migration/Items/GPItemMigrator.codeunit.al +++ b/Apps/W1/HybridGP/app/src/Migration/Items/GPItemMigrator.codeunit.al @@ -369,22 +369,14 @@ codeunit 4019 "GP Item Migrator" TempTrackingSpecification: Record "Tracking Specification" temporary; DataMigrationErrorLogging: Codeunit "Data Migration Error Logging"; CreateReserveEntry: Codeunit "Create Reserv. Entry"; -#if CLEAN25 ItemJnlLineReserve: Codeunit "Item Jnl. Line-Reserve"; -#endif ExpirationDate: Date; begin if GPItem.ItemTrackingCode = '' then exit; DataMigrationErrorLogging.SetLastRecordUnderProcessing(Format(GPItemTransactions.RecordId)); -#if not CLEAN25 -#pragma warning disable AL0432 - TempTrackingSpecification.InitFromItemJnlLine(ItemJnlLine); -#pragma warning restore AL0432 -#else ItemJnlLineReserve.InitFromItemJnlLine(TempTrackingSpecification, ItemJnlLine); -#endif if GPItemTransactions.ExpirationDate = DMY2Date(1, 1, 1900) then ExpirationDate := 0D else diff --git a/Apps/W1/HybridGP/app/src/Migration/Support/HelperFunctions.codeunit.al b/Apps/W1/HybridGP/app/src/Migration/Support/HelperFunctions.codeunit.al index f39e6ee911..b3da3e7b57 100644 --- a/Apps/W1/HybridGP/app/src/Migration/Support/HelperFunctions.codeunit.al +++ b/Apps/W1/HybridGP/app/src/Migration/Support/HelperFunctions.codeunit.al @@ -106,15 +106,9 @@ codeunit 4037 "Helper Functions" SavedJrnlLinesFoundMsg: Label 'Saved journal lines are found. In order to use the wizard, you will need to delete the journal lines before you migrate your data.'; MigrationNotSupportedErr: Label 'This migration does not support the "Specific" costing method. Verify your costing method in Inventory Setup.'; PostingGroupCodeTxt: Label 'GP', Locked = true; -#if not CLEAN25 - DocNoOutofBalanceMsg: Label 'Document No. %1 is out of balance by %2. Transactions will not be created. Please check the amount in the import file.', Comment = '%1 = Balance Amount', Locked = true; -#endif CustomerBatchNameTxt: Label 'GPCUST', Locked = true; VendorBatchNameTxt: Label 'GPVEND', Locked = true; BankBatchNameTxt: Label 'GPBANK', Locked = true; -#if not CLEAN25 - GlDocNoTxt: Label 'G00001', Locked = true; -#endif MigrationTypeTxt: Label 'Great Plains'; CloudMigrationTok: Label 'CloudMigration', Locked = true; GeneralTemplateNameTxt: Label 'GENERAL', Locked = true; @@ -1351,34 +1345,6 @@ codeunit 4037 "Helper Functions" Session.LogMessage('00007GK', StrSubstNo(FinishedTelemetryTxt, DurationAsInt), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', GetTelemetryCategory()); end; -#if not CLEAN25 - [Obsolete('This procedure will be soon removed.', '25.0')] - procedure PostGLBatch(JournalBatchName: Code[10]) - var - GenJournalLine: Record "Gen. Journal Line"; - TotalBalance: Decimal; - begin - GenJournalLine.Reset(); - GenJournalLine.SetRange("Journal Template Name", GeneralTemplateNameTxt); - GenJournalLine.SetRange("Journal Batch Name", JournalBatchName); - // Do not care about balances for Customer, Vendor, and Bank batches - if (JournalBatchName <> CustomerBatchNameTxt) and (JournalBatchName <> VendorBatchNameTxt) and (JournalBatchName <> BankBatchNameTxt) then begin - repeat - TotalBalance := TotalBalance + GenJournalLine.Amount; - until GenJournalLine.Next() = 0; - if TotalBalance = 0 then - if GenJournalLine.FindFirst() then - codeunit.Run(codeunit::"Gen. Jnl.-Post Batch", GenJournalLine) - else begin - Message(StrSubstNo(DocNoOutofBalanceMsg, GlDocNoTxt, FORMAT(TotalBalance))); - if GenJournalLine.FindFirst() then - GenJournalLine.DeleteAll(); - end; - end else - if GenJournalLine.FindFirst() then - codeunit.Run(codeunit::"Gen. Jnl.-Post Batch", GenJournalLine); - end; -#endif local procedure SafePostGLBatch(JournalBatchName: Code[10]) var @@ -1394,17 +1360,6 @@ codeunit 4037 "Helper Functions" end; end; -#if not CLEAN25 - [Obsolete('This procedure will be soon removed.', '25.0')] - procedure PostStatisticalAccBatch(JournalBatchName: Code[10]) - var - StatisticalAccJournalLine: Record "Statistical Acc. Journal Line"; - begin - StatisticalAccJournalLine.SetRange("Journal Batch Name", JournalBatchName); - if StatisticalAccJournalLine.FindFirst() then - Codeunit.Run(Codeunit::"Stat. Acc. Post. Batch", StatisticalAccJournalLine); - end; -#endif local procedure SafePostStatisticalAccBatch(JournalBatchName: Code[10]) var diff --git a/Apps/W1/HybridGP/app/src/pages/GPMigrationConfiguration.Page.al b/Apps/W1/HybridGP/app/src/pages/GPMigrationConfiguration.Page.al index 362072d5ab..9367fffc4b 100644 --- a/Apps/W1/HybridGP/app/src/pages/GPMigrationConfiguration.Page.al +++ b/Apps/W1/HybridGP/app/src/pages/GPMigrationConfiguration.Page.al @@ -326,15 +326,6 @@ page 4050 "GP Migration Configuration" } #pragma warning restore AA0219 -#if not CLEAN25 - group(Inactives) - { - Visible = false; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - ObsoleteReason = 'Group replaced by IncludeTheseRecords'; - } -#endif group(IncludeTheseRecords) { diff --git a/Apps/W1/INTaxEngine/app/TaxEngine-JsonExchange/src/AssistedSetup/TaxEngineSetupWizard.Page.al b/Apps/W1/INTaxEngine/app/TaxEngine-JsonExchange/src/AssistedSetup/TaxEngineSetupWizard.Page.al index bd6fc18432..35fe72fce1 100644 --- a/Apps/W1/INTaxEngine/app/TaxEngine-JsonExchange/src/AssistedSetup/TaxEngineSetupWizard.Page.al +++ b/Apps/W1/INTaxEngine/app/TaxEngine-JsonExchange/src/AssistedSetup/TaxEngineSetupWizard.Page.al @@ -120,7 +120,7 @@ page 20364 "Tax Engine Setup Wizard" { action(ActionBack) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Caption = 'Back'; Enabled = BackActionEnabled; Image = PreviousRecord; @@ -133,7 +133,7 @@ page 20364 "Tax Engine Setup Wizard" } action(ActionNext) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Caption = 'Next'; Enabled = NextActionEnabled; Image = NextRecord; @@ -146,7 +146,7 @@ page 20364 "Tax Engine Setup Wizard" } action(ExportModified) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Caption = 'Export Modified Use Cases'; Enabled = FinishActionEnabled; Image = ExportFile; @@ -157,13 +157,13 @@ page 20364 "Tax Engine Setup Wizard" i: Integer; begin i := 0; - //blank OnAction created as we have a subscriber of this action in Use Case Archival mgmt codeunit + //blank OnAction created as we have a subscriber of this action in Use Case Archival mgmt codeunit //and ruleset doesn't allow to create a action without the OnAction trigger end; } action(ActionFinish) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Caption = 'Finish'; Enabled = FinishActionEnabled; Image = Approve; diff --git a/Apps/W1/ImageAnalysis/app/src/Permissions/ImageAnalysisObjects.PermissionSet.al b/Apps/W1/ImageAnalysis/app/src/Permissions/ImageAnalysisObjects.PermissionSet.al index 9e4ad5b8f8..4ee4a29e39 100644 --- a/Apps/W1/ImageAnalysis/app/src/Permissions/ImageAnalysisObjects.PermissionSet.al +++ b/Apps/W1/ImageAnalysis/app/src/Permissions/ImageAnalysisObjects.PermissionSet.al @@ -8,9 +8,6 @@ permissionset 4211 "ImageAnalysis - Objects" Caption = 'Image Analyzer - Objects'; Permissions = codeunit "Image Analyzer Ext. Mgt." = X, -#if not CLEAN25 - codeunit "Contact Picture Analyze" = X, -#endif codeunit "Image Analysis Install" = X, codeunit "Item Attr Populate" = X, page "Image Analysis Blacklist" = X, diff --git a/Apps/W1/ImageAnalysis/app/src/codeunits/ContactPictureAnalyze.Codeunit.al b/Apps/W1/ImageAnalysis/app/src/codeunits/ContactPictureAnalyze.Codeunit.al deleted file mode 100644 index d4219afc20..0000000000 --- a/Apps/W1/ImageAnalysis/app/src/codeunits/ContactPictureAnalyze.Codeunit.al +++ /dev/null @@ -1,218 +0,0 @@ -#if not CLEAN25 -namespace Microsoft.Utility.ImageAnalysis; - -using Microsoft.CRM.Contact; -using System.AI; -using Microsoft.CRM.Profiling; -// ------------------------------------------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// ------------------------------------------------------------------------------------------------ - -codeunit 2028 "Contact Picture Analyze" -{ - ObsoleteReason = 'Image analyzer for contacts is being removed.'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - - var - ImageAnalyzerExtMgt: Codeunit "Image Analyzer Ext. Mgt."; - ImageAnalyzerContactQuestionnaireDescriptionTxt: Label 'Attributes detected by Image Analyzer.', Comment = 'Should be less than or equal to 50 characters.', MaxLength = 50; - GenderProfileQuestionTxt: Label 'Detected gender', MaxLength = 250; - AgeProfileQuestionTxt: Label 'Detected age', MaxLength = 250; - MaleTok: Label 'Male', MaxLength = 250; - FemaleTok: Label 'Female', MaxLength = 250; - ImageAnalyzerQuestionnaireCodeTxt: Label 'IMAGE ANALYZER', Comment = 'Should be less than or equal to 20 characters.', MaxLength = 20; - ProfileQuestionnairePopulatedTxt: Label 'Good work! You can view the results of the image analysis on the Profile Questionnaire FastTab.'; - - [EventSubscriber(ObjectType::Page, PAGE::"Contact Picture", 'OnAfterActionEvent', 'ImportPicture', false, false)] - procedure OnAfterImportPictureAnalyzePicture(var Rec: Record Contact) - begin - AnalyzePicture(Rec); - end; - - procedure AnalyzePicture(var ContactRec: Record Contact): Boolean - var - ImageAnalysisResult: Codeunit "Image Analysis Result"; - AnalysisType: Option Tags,Faces,Color; - begin - if ImageAnalyzerExtMgt.IsSaasAndCannotUseRelationshipMgmt() then - exit(false); - - if not (ContactRec.Type = ContactRec.Type::Person) then - exit(false); - - if not ContactRec.Image.HasValue() then - exit(false); - - if not ImageAnalyzerExtMgt.AnalyzePicture(ContactRec.Image.MediaId(), ImageAnalysisResult, AnalysisType::Faces) then - exit(false); - - PopulateContact(ContactRec, ImageAnalysisResult); - exit(true); - end; - - procedure PopulateContact(var Contact: Record Contact; ImageAnalysisResult: Codeunit "Image Analysis Result") - var - CortanaProfileQuestionnaireHeader: Record "Profile Questionnaire Header"; - ContactProfileAnswerToDelete: Record "Contact Profile Answer"; - begin - GetAndCreateCortanaQuestionnaireIfNeeded(CortanaProfileQuestionnaireHeader); - - //clear existing cortana answers for this contact - ContactProfileAnswerToDelete.SetRange("Contact No.", Contact."No."); - ContactProfileAnswerToDelete.SetRange("Profile Questionnaire Code", CortanaProfileQuestionnaireHeader.Code); - ContactProfileAnswerToDelete.DeleteAll(); - - if ImageAnalysisResult.FaceCount() <> 1 then - exit; // if 0, we have nothing to do, if more than 1 we don't know what face to use - - if PopulateContactGender(Contact, ImageAnalysisResult, CortanaProfileQuestionnaireHeader) or - PopulateContactAge(Contact, ImageAnalysisResult, CortanaProfileQuestionnaireHeader) - then - if ImageAnalyzerExtMgt.IsInformationNotificationEnabled(ImageAnalyzerExtMgt.GetContactQuestionnairePopulatedNotificationId()) then - ImageAnalyzerExtMgt.SendInformationNotification(ProfileQuestionnairePopulatedTxt, ImageAnalyzerExtMgt.GetContactQuestionnairePopulatedNotificationId()); - end; - - local procedure PopulateContactGender(var Contact: Record Contact; ImageAnalysisResult: Codeunit "Image Analysis Result"; CortanaProfileQuestionnaireHeader: Record "Profile Questionnaire Header"): Boolean - var - ProfileQuestionnaireLine: Record "Profile Questionnaire Line"; - Gender: Option " ",Male,Female; - begin - EVALUATE(Gender, ImageAnalysisResult.FaceGender(1)); - - // search for an answer that matches the gender - ProfileQuestionnaireLine.SetRange("Profile Questionnaire Code", CortanaProfileQuestionnaireHeader.Code); - ProfileQuestionnaireLine.SetRange(Type, ProfileQuestionnaireLine.Type::Answer); - - ProfileQuestionnaireLine.SetRange(Description, GetGenderText(Gender)); - if (ProfileQuestionnaireLine.FindFirst()) then begin - InsertAnswer(Contact, CortanaProfileQuestionnaireHeader, ProfileQuestionnaireLine."Line No."); - exit(true); - end; - end; - - local procedure GetGenderText(GenderOption: Option " ",Male,Female): Text[250] - begin - case GenderOption of - GenderOption::" ": - exit(''); - - GenderOption::Male: - exit(MaleTok); - - GenderOption::Female: - exit(FemaleTok); - end; - end; - - local procedure PopulateContactAge(var Contact: Record Contact; ImageAnalysisResult: Codeunit "Image Analysis Result"; CortanaProfileQuestionnaireHeader: Record "Profile Questionnaire Header"): Boolean - var - ProfileQuestionnaireLine: Record "Profile Questionnaire Line"; - Age: Integer; - begin - Age := ImageAnalysisResult.FaceAge(1); - - // search for an answer that matches the age - ProfileQuestionnaireLine.SetRange("Profile Questionnaire Code", CortanaProfileQuestionnaireHeader.Code); - ProfileQuestionnaireLine.SetRange(Type, ProfileQuestionnaireLine.Type::Answer); - ProfileQuestionnaireLine.SetRange("From Value", Age); - ProfileQuestionnaireLine.SetRange("To Value", Age); - - if (ProfileQuestionnaireLine.FindFirst()) then begin - InsertAnswer(Contact, CortanaProfileQuestionnaireHeader, ProfileQuestionnaireLine."Line No."); - exit(true); - end; - end; - - local procedure InsertAnswer(Contact: Record Contact; CortanaProfileQuestionnaireHeader: Record "Profile Questionnaire Header"; ProfileQuestionnaireLineNo: Integer) - var - ContactProfileAnswer: Record "Contact Profile Answer"; - begin - ContactProfileAnswer.Init(); - ContactProfileAnswer."Profile Questionnaire Code" := CortanaProfileQuestionnaireHeader.Code; - ContactProfileAnswer."Profile Questionnaire Priority" := CortanaProfileQuestionnaireHeader.Priority; - ContactProfileAnswer."Answer Priority" := ContactProfileAnswer."Answer Priority"::Normal; - ContactProfileAnswer."Contact Company No." := Contact."Company No."; - ContactProfileAnswer."Last Date Updated" := TODAY(); - ContactProfileAnswer."Line No." := ProfileQuestionnaireLineNo; - ContactProfileAnswer."Contact No." := Contact."No."; - - ContactProfileAnswer.Insert(true); - end; - - procedure GetImageAnalyzerQuestionnaireCode(): Code[20] - begin - exit(CopyStr(ImageAnalyzerQuestionnaireCodeTxt, 1, 20)); - end; - - procedure GetImageAnalyzerQuestionnaireDescription(): Text[50] - begin - exit(CopyStr(ImageAnalyzerContactQuestionnaireDescriptionTxt, 1, 50)); - end; - - procedure GetAgeProfileQuestionDescription(): Text[250] - begin - exit(CopyStr(AgeProfileQuestionTxt, 1, 250)); - end; - - procedure GetGenderProfileQuestionDescription(): Text[250] - begin - exit(CopyStr(GenderProfileQuestionTxt, 1, 250)); - end; - - local procedure GetAndCreateCortanaQuestionnaireIfNeeded(var ProfileQuestionnaireHeader: Record "Profile Questionnaire Header") - var - Age: Integer; - LineNumber: Integer; - begin - ProfileQuestionnaireHeader.Reset(); - ProfileQuestionnaireHeader.SetRange(Code, GetImageAnalyzerQuestionnaireCode()); - IF not ProfileQuestionnaireHeader.FindFirst() then begin - LineNumber := 10000; - ProfileQuestionnaireHeader.Code := GetImageAnalyzerQuestionnaireCode(); - ProfileQuestionnaireHeader.Description := GetImageAnalyzerQuestionnaireDescription(); - ProfileQuestionnaireHeader."Contact Type" := ProfileQuestionnaireHeader."Contact Type"::People; - ProfileQuestionnaireHeader.Priority := ProfileQuestionnaireHeader.Priority::Normal; - ProfileQuestionnaireHeader.Insert(); - - CreateQuestionnaireQuestionLine(LineNumber, GetGenderProfileQuestionDescription()); - CreateQuestionnaireAnswerLine(LineNumber, MaleTok, 0, 0); - CreateQuestionnaireAnswerLine(LineNumber, FemaleTok, 0, 0); - - CreateQuestionnaireQuestionLine(LineNumber, GetAgeProfileQuestionDescription()); - for Age := 16 to 150 do - CreateQuestionnaireAnswerLine(LineNumber, Format(Age), Age, Age); - end; - end; - - - local procedure CreateQuestionnaireQuestionLine(var LineNumber: Integer; QuestionDescription: Text[250]) - var - ProfileQuestionnaireLine: Record "Profile Questionnaire Line"; - begin - ProfileQuestionnaireLine.Init(); - ProfileQuestionnaireLine."Line No." := LineNumber; - ProfileQuestionnaireLine."Profile Questionnaire Code" := GetImageAnalyzerQuestionnaireCode(); - ProfileQuestionnaireLine.Type := ProfileQuestionnaireLine.Type::Question; - ProfileQuestionnaireLine.Description := QuestionDescription; - ProfileQuestionnaireLine.Insert(); - LineNumber += 10000; - end; - - local procedure CreateQuestionnaireAnswerLine(var LineNumber: Integer; AnswerDescription: Text[250]; FromValue: Integer; ToValue: Integer) - var - ProfileQuestionnaireLine: Record "Profile Questionnaire Line"; - begin - ProfileQuestionnaireLine.Init(); - ProfileQuestionnaireLine."Line No." := LineNumber; - ProfileQuestionnaireLine."Profile Questionnaire Code" := GetImageAnalyzerQuestionnaireCode(); - ProfileQuestionnaireLine.Type := ProfileQuestionnaireLine.Type::Answer; - ProfileQuestionnaireLine.Description := AnswerDescription; - ProfileQuestionnaireLine."From Value" := FromValue; - ProfileQuestionnaireLine."To Value" := ToValue; - ProfileQuestionnaireLine.Insert(); - LineNumber += 10000; - end; -} -#endif \ No newline at end of file diff --git a/Apps/W1/ImageAnalysis/app/src/pages/ImageAnalyzerWizard.Page.al b/Apps/W1/ImageAnalysis/app/src/pages/ImageAnalyzerWizard.Page.al index bf80c6e7ad..445a75729f 100644 --- a/Apps/W1/ImageAnalysis/app/src/pages/ImageAnalyzerWizard.Page.al +++ b/Apps/W1/ImageAnalysis/app/src/pages/ImageAnalyzerWizard.Page.al @@ -4,9 +4,6 @@ using System.Utilities; using System.Environment; using Microsoft.Inventory.Item; using System.Telemetry; -#if not CLEAN25 -using Microsoft.CRM.Contact; -#endif // ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. @@ -306,19 +303,12 @@ page 2029 "Image Analyzer Wizard" if IsSetItemToFill then HasPicture := ItemToFill.Picture.Count() = 1; -#if not CLEAN25 - if IsSetContactToFill then - HasPicture := (ContactToFill.Type = ContactToFill.Type::Person) and (ContactToFill.Image.HasValue()); -#endif end; var MediaRepositoryStandard: Record "Media Repository"; MediaResourcesStandard: Record "Media Resources"; ItemToFill: Record Item; -#if not CLEAN25 - ContactToFill: Record Contact; -#endif Step: Option Start,Second,Finish; TopBannerVisible: Boolean; FirstStepVisible: Boolean; @@ -343,9 +333,6 @@ page 2029 "Image Analyzer Wizard" CognitiveServicesLinkLinkTxt: Label 'http://go.microsoft.com/fwlink/?LinkID=829046', Locked = true; CognitiveServicesLinkTxt: Label 'Microsoft Cognitive Services'; WantToAnalyzeTheCurrentPictureQst: Label 'An image has been added to the chosen item or contact. Want to analyze the image, right after you enable Image Analyzer?'; -#if not CLEAN25 - IsSetContactToFill: Boolean; -#endif IsSetItemToFill: Boolean; AnalyzePictureOnFinishSwitch: Boolean; HasPicture: Boolean; @@ -382,9 +369,6 @@ page 2029 "Image Analyzer Wizard" var AuditLog: Codeunit "Audit Log"; ItemAttrPopulate: Codeunit "Item Attr Populate"; -#if not CLEAN25 - ContactPictureAnalyze: Codeunit "Contact Picture Analyze"; -#endif ItemAttrPopManagement: Codeunit "Image Analyzer Ext. Mgt."; ImageAnalyzerConsentProvidedLbl: Label 'Image Analyzer - consent provided by UserSecurityId %1.', Locked = true; begin @@ -398,11 +382,6 @@ page 2029 "Image Analyzer Wizard" if IsSetItemToFill then if ItemAttrPopulate.AnalyzePicture(ItemToFill) then CurrPage.Close(); -#if not CLEAN25 - if IsSetContactToFill then - if ContactPictureAnalyze.AnalyzePicture(ContactToFill) then - CurrPage.Close(); -#endif AuditLog.LogAuditMessage(StrSubstNo(ImageAnalyzerConsentProvidedLbl, UserSecurityId()), SecurityOperationResult::Success, AuditCategory::ApplicationManagement, 4, 0); end; @@ -451,13 +430,4 @@ page 2029 "Image Analyzer Wizard" IsSetItemToFill := true; end; -#if not CLEAN25 - [Obsolete('Image analyzer for contacts is being removed.', '25.0')] - procedure SetContact(Contact: Record Contact) - begin - ContactToFill := Contact; - IsSetContactToFill := true; - end; -#endif } - diff --git a/Apps/W1/ImageAnalysis/test/src/codeunits/ContactPicAnalyzerTest.Codeunit.al b/Apps/W1/ImageAnalysis/test/src/codeunits/ContactPicAnalyzerTest.Codeunit.al deleted file mode 100644 index e34b9b48bf..0000000000 --- a/Apps/W1/ImageAnalysis/test/src/codeunits/ContactPicAnalyzerTest.Codeunit.al +++ /dev/null @@ -1,187 +0,0 @@ -#if not CLEAN25 -namespace Microsoft.Utility.ImageAnalysis; - -using Microsoft.CRM.Contact; -using System.AI; -using Microsoft.CRM.Profiling; -using System.Text; -// ------------------------------------------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// ------------------------------------------------------------------------------------------------ - -codeunit 139593 "Contact Pic Analyzer Test" -{ - Subtype = Test; - TestType = IntegrationTest; - TestPermissions = Disabled; - ObsoleteReason = 'Image analyzer for contacts is being removed.'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - - var - Assert: Codeunit Assert; - - [Test] - [HandlerFunctions('NotificationHandler')] - procedure TestPopulateAgeAndGender() - var - Contact: Record Contact; - ImageAnalysisResult: Codeunit "Image Analysis Result"; - ContactPictureAnalyze: Codeunit "Contact Picture Analyze"; - JsonManagement: Codeunit "JSON Management"; - Gender: Option " ",Male,Female; - begin - // [Scenario] Check the contact is populated correctly in a success case - // [Given] A contact and an analysis result with age and gender - Initialize(); - CreateTestContact(Contact); - - JsonManagement.InitializeObject('{"requestId":"2c15a4c1-9271-4584-a30e-342d7fdf206b"' + - ',"metadata":{"width":500,"height":600,"format":"Jpeg"},"faces":[ { "age": 37, "gender": "Female",' + - '"faceRectangle": { "left": 1379, "top": 320, "width": 310, "height": 310 } } ] }'); - ImageAnalysisResult.SetResult(JsonManagement, Enum::"Image Analysis Type"::Faces); - - // [When] We try to populate the contact - ContactPictureAnalyze.PopulateContact(Contact, ImageAnalysisResult); - - // [Then] The contact is populated as expected - Contact.Get(Contact.RecordId()); - - Assert.IsTrue(GetContactAge(Contact) = 37, StrSubstNo('Age should have been 37, but was %1', GetContactAge(Contact))); - Assert.IsTrue(GetContactGender(Contact) = Gender::Female, 'Expected the gender to be female.'); - end; - - [Test] - procedure TestPopulate2Faces() - var - Contact: Record Contact; - ContactProfileAnswer: Record "Contact Profile Answer"; - ImageAnalysisResult: Codeunit "Image Analysis Result"; - ContactPictureAnalyze: Codeunit "Contact Picture Analyze"; - JsonManagement: Codeunit "JSON Management"; - begin - // [Scenario] Check the contact is not populated in a case where 2 faces are on a picture - // [Given] A contact and an analysis result with age and gender for 2 faces - Initialize(); - CreateTestContact(Contact); - - JsonManagement.InitializeObject('{"tags":[],"requestId":"2c15a4c1-9271-4584-a30e-342d7fdf206b"' + - ',"metadata":{"width":500,"height":600,"format":"Jpeg"},"faces":[ { "age": 37, "gender": "Female",' + - '"faceRectangle": { "left": 1379, "top": 320, "width": 310, "height": 310 } }, { "age": 45, "gender": "Male",' + - '"faceRectangle": { "left": 1379, "top": 320, "width": 310, "height": 310 } } ] }'); - ImageAnalysisResult.SetResult(JsonManagement, Enum::"Image Analysis Type"::Faces); - - // [When] We try to populate the contact - ContactPictureAnalyze.PopulateContact(Contact, ImageAnalysisResult); - - // [Then] The contact is not populated because of the 2 faces - Contact.Get(Contact.RecordId()); - Assert.IsFalse(GetContactAzureAIAnswers(Contact, ContactProfileAnswer), 'Expected the contact questionnaire answers not to be populated'); - end; - - local procedure Initialize() - var - ImageAnalysisSetup: Record "Image Analysis Setup"; - ProfileQuestionnaireLine: Record "Profile Questionnaire Line"; - ProfileQuestionnaireHeader: Record "Profile Questionnaire Header"; - ContactProfileAnswer: Record "Contact Profile Answer"; - ContactPictureAnalyze: Codeunit "Contact Picture Analyze"; - begin - ImageAnalysisSetup.GetSingleInstance(); - ImageAnalysisSetup."Image-Based Attribute Recognition Enabled" := true; - ImageAnalysisSetup.Modify(); - - ContactProfileAnswer.SetRange("Profile Questionnaire Code", ContactPictureAnalyze.GetImageAnalyzerQuestionnaireCode()); - ContactProfileAnswer.DeleteAll(); - - ProfileQuestionnaireLine.SetRange("Profile Questionnaire Code", ContactPictureAnalyze.GetImageAnalyzerQuestionnaireCode()); - ProfileQuestionnaireLine.DeleteAll(); - - ProfileQuestionnaireHeader.SetRange("Code", ContactPictureAnalyze.GetImageAnalyzerQuestionnaireCode()); - ProfileQuestionnaireHeader.DeleteAll(); - end; - - - local procedure GetContactAge(Contact: Record Contact): Integer - var - ProfileQuestionnaireLineAgeQuestion: Record "Profile Questionnaire Line"; - ProfileQuestionnaireLineAnswer: Record "Profile Questionnaire Line"; - ContactProfileAnswer: Record "Contact Profile Answer"; - ContactPictureAnalyze: Codeunit "Contact Picture Analyze"; - Age: Integer; - begin - ProfileQuestionnaireLineAgeQuestion.SetRange("Profile Questionnaire Code", ContactPictureAnalyze.GetImageAnalyzerQuestionnaireCode()); - ProfileQuestionnaireLineAgeQuestion.SetRange(Type, ProfileQuestionnaireLineAgeQuestion.Type::Question); - ProfileQuestionnaireLineAgeQuestion.SetRange(Description, ContactPictureAnalyze.GetAgeProfileQuestionDescription()); - ProfileQuestionnaireLineAgeQuestion.FindFirst(); - - if GetContactAzureAIAnswers(Contact, ContactProfileAnswer) then - repeat - ProfileQuestionnaireLineAnswer.SetRange("Profile Questionnaire Code", ContactPictureAnalyze.GetImageAnalyzerQuestionnaireCode()); - ProfileQuestionnaireLineAnswer.SetRange(Type, ProfileQuestionnaireLineAnswer.Type::Answer); - ProfileQuestionnaireLineAnswer.SetRange("Line No.", ContactProfileAnswer."Line No."); - ProfileQuestionnaireLineAnswer.FindFirst(); - if ProfileQuestionnaireLineAnswer.FindQuestionLine() = ProfileQuestionnaireLineAgeQuestion."Line No." then begin - Evaluate(Age, ProfileQuestionnaireLineAnswer.Description); - exit(Age); - end; - until ContactProfileAnswer.Next() = 0; - exit(0); - end; - - local procedure GetContactAzureAIAnswers(Contact: Record Contact; var ContactProfileAnswer: Record "Contact Profile Answer"): Boolean - var - ContactPictureAnalyze: Codeunit "Contact Picture Analyze"; - begin - ContactProfileAnswer.Reset(); - ContactProfileAnswer.SetRange("Profile Questionnaire Code", ContactPictureAnalyze.GetImageAnalyzerQuestionnaireCode()); - ContactProfileAnswer.SetRange("Contact No.", Contact."No."); - exit(ContactProfileAnswer.FindSet()); - end; - - local procedure GetContactGender(Contact: Record Contact): Option " ",Male,Female - var - ProfileQuestionnaireLineGenderQuestion: Record "Profile Questionnaire Line"; - ProfileQuestionnaireLineAnswer: Record "Profile Questionnaire Line"; - ContactProfileAnswer: Record "Contact Profile Answer"; - ContactPictureAnalyze: Codeunit "Contact Picture Analyze"; - Gender: Option " ",Male,Female; - begin - ProfileQuestionnaireLineGenderQuestion.SetRange("Profile Questionnaire Code", ContactPictureAnalyze.GetImageAnalyzerQuestionnaireCode()); - ProfileQuestionnaireLineGenderQuestion.SetRange(Type, ProfileQuestionnaireLineGenderQuestion.Type::Question); - ProfileQuestionnaireLineGenderQuestion.SetRange(Description, ContactPictureAnalyze.GetGenderProfileQuestionDescription()); - ProfileQuestionnaireLineGenderQuestion.FindFirst(); - - if GetContactAzureAIAnswers(Contact, ContactProfileAnswer) then - repeat - ProfileQuestionnaireLineAnswer.SetRange("Profile Questionnaire Code", ContactPictureAnalyze.GetImageAnalyzerQuestionnaireCode()); - ProfileQuestionnaireLineAnswer.SetRange(Type, ProfileQuestionnaireLineAnswer.Type::Answer); - ProfileQuestionnaireLineAnswer.SetRange("Line No.", ContactProfileAnswer."Line No."); - ProfileQuestionnaireLineAnswer.FindFirst(); - if ProfileQuestionnaireLineAnswer.FindQuestionLine() = ProfileQuestionnaireLineGenderQuestion."Line No." then begin - Evaluate(Gender, ProfileQuestionnaireLineAnswer.Description); - exit(Gender); - end; - until ContactProfileAnswer.Next() = 0; - exit(Gender::" "); - end; - - local procedure CreateTestContact(var Contact: Record Contact) - begin - Contact.Reset(); - Contact.SetFilter(Name, 'Test contact'); - Contact.DeleteAll(); - - Contact.Init(); - Contact.Name := 'Test contact'; - Contact.Insert(true); - end; - - [SendNotificationHandler] - procedure NotificationHandler(var Notification: Notification): Boolean - begin - exit(true); - end; -} -#endif diff --git a/Apps/W1/ImageAnalysis/test/src/codeunits/TestRunner.Codeunit.al b/Apps/W1/ImageAnalysis/test/src/codeunits/TestRunner.Codeunit.al index 371d0fab42..0601bb6784 100644 --- a/Apps/W1/ImageAnalysis/test/src/codeunits/TestRunner.Codeunit.al +++ b/Apps/W1/ImageAnalysis/test/src/codeunits/TestRunner.Codeunit.al @@ -10,14 +10,8 @@ codeunit 139590 TestRunner var ImgAnalyzerMgtTest: Codeunit "Img. Analyzer Mgt. Test"; ItemAttrPopulateTest: Codeunit "Item Attr Populate Test"; -#if not CLEAN25 - ContactPicAnalyzerTest: Codeunit "Contact Pic Analyzer Test"; -#endif begin ImgAnalyzerMgtTest.Run(); ItemAttrPopulateTest.Run(); -#if not CLEAN25 - ContactPicAnalyzerTest.Run(); -#endif end; } \ No newline at end of file diff --git a/Apps/W1/Intrastat/app/src/Processing/IntrastatReportManagement.Codeunit.al b/Apps/W1/Intrastat/app/src/Processing/IntrastatReportManagement.Codeunit.al index a0bb3b7870..b329a5b0d7 100644 --- a/Apps/W1/Intrastat/app/src/Processing/IntrastatReportManagement.Codeunit.al +++ b/Apps/W1/Intrastat/app/src/Processing/IntrastatReportManagement.Codeunit.al @@ -17,33 +17,14 @@ codeunit 4810 IntrastatReportManagement ReceptFileNameLbl: Label 'Receipt-%1.txt', Comment = '%1 - Statistics Period'; ShipmentFileNameLbl: Label 'Shipment-%1.txt', Comment = '%1 - Statistics Period'; ZipFileNameLbl: Label 'Intrastat-%1.zip', Comment = '%1 - Statistics Period'; -#if not CLEAN25 - FeatureNotEnabledMessageTxt: Label 'The %1 page is part of the new Intrastat Report feature, which is not yet enabled in your Business Central. An administrator can enable the feature on the Feature Management page.', Comment = '%1 - page caption'; - NewFeatureEnabledMessageTxt: Label 'The Intrastat Report extension is enabled, which means you can''t use the %1 page. You''ve been redirected to the %2 page for the extension.', Comment = '%1 - old page caption, %2 - new page caption'; -#endif DisableNotificationTxt: Label 'Disable this notification'; -#if not CLEAN25 - LearnMoreTxt: Label 'Learn more'; - IntrastatAwarenessNotificationNameTxt: Label 'Notify the user about the Intrastat Report extension.'; - IntrastatAwarenessNotificationDescriptionTxt: Label 'Alert users about the capabilities of the Intrastat Report extension.'; - IntrastatAwarenessNotificationTxt: Label 'This version of Intrastat will be deprecated. We recommend that you enable the Intrastat Report extension.'; -#endif SupplementaryUnitUpdateNotificationNameTxt: Label 'Notify the user about the %1 update.', Comment = '%1 - Supplementary Unit of Measure caption'; SupplementaryUnitUpdateNotificationDescriptionTxt: Label 'Alert users about the update of %1 during %2 change.', Comment = '%1 - Supplementary Unit of Measure caption, %2 - Tariff Number caption'; SupplementaryUnitUpdateNotificationTxt: Label '%1 was updated, due to change of %2.', Comment = '%1 - Supplementary Unit of Measure caption, %2 - Tariff Number caption'; ImportDefaultIntrastatDataExchDefConfirmQst: Label 'This will create the default Intrastat %1 . \\All existing default Intrastat %1 will be overwritten.\\Do you want to continue?', Comment = '%1 - Data Exchange Definition caption'; AssistedSetupTxt: Label 'Set up Intrastat reporting'; AssistedSetupDescriptionTxt: Label 'The Intrastat reporting makes it easy to export the Intrastat report in the format that the authorities in your country require.'; -#if not CLEAN25 - UserDisabledNotificationTxt: Label 'The user disabled notification %1.', Locked = true; - IntrastatFeatureKeyIdTok: Label 'ReplaceIntrastat', Locked = true; - IntrastatFeatureAwarenessNotificationIdTok: Label 'dcd4e71a-8c6a-44fc-9642-54f931e5e7d9', Locked = true; -#endif SupplementaryUnitUpdateNotificationIdTok: Label '52f2c034-1857-4922-99cb-448c09e01474', Locked = true; -#if not CLEAN25 - IntrastatCoreAppIdTok: Label '70912191-3c4c-49fc-a1de-bc6ea1ac9da6', Locked = true; - IntrastatTelemetryCategoryTok: Label 'AL Intrastat', Locked = true; -#endif LearnMoreLinkTok: Label 'https://go.microsoft.com/fwlink/?linkid=2283605', Locked = true; RangeCrossingErr: Label 'There is a conflict in checklist rules for ''%1'' in ''%2'' (field must be both blank and not blank). Please review filters in %3.', Comment = '%1=caption of a field, %2=key of record, %3=caption of report checklist page'; MaximumLinesErr: Label 'Split files functionality can only be used when the source record is using default sorting and fields are not grouped. Please contact the %1 administrator to adjust the settings in the related %2.', Comment = '%1=Data Exchange caption, %2=Data Exch Mapping Card caption'; @@ -1023,55 +1004,6 @@ codeunit 4810 IntrastatReportManagement ItemUOM.Modify(true); end; -#if not CLEAN25 - [Obsolete('Pending removal.', '25.0')] - procedure IsFeatureEnabled() IsEnabled: Boolean - begin - IsEnabled := true; -#pragma warning disable AL0432 - OnAfterCheckFeatureEnabled(IsEnabled); -#pragma warning restore AL0432 - end; - - [Obsolete('Pending removal.', '25.0')] - procedure NotifyUserAboutIntrastatFeature() - var - MyNotifications: Record "My Notifications"; - IntrastatFeatureAwarenessNotification: Notification; - begin -#pragma warning disable AL0432 - if IsInstalledByAppId(GetAppId()) then - if MyNotifications.IsEnabled(GetIntrastatFeatureAwarenessNotificationId()) then begin - IntrastatFeatureAwarenessNotification.Id(GetIntrastatFeatureAwarenessNotificationId()); - IntrastatFeatureAwarenessNotification.SetData('NotificationId', GetIntrastatFeatureAwarenessNotificationId()); - IntrastatFeatureAwarenessNotification.Message(IntrastatAwarenessNotificationTxt); -#pragma warning restore AL0432 - IntrastatFeatureAwarenessNotification.AddAction(LearnMoreTxt, Codeunit::IntrastatReportManagement, 'LearnMore'); - IntrastatFeatureAwarenessNotification.AddAction(DisableNotificationTxt, Codeunit::IntrastatReportManagement, 'DisableNotification'); - IntrastatFeatureAwarenessNotification.Send(); - end; - end; - - [Obsolete('Pending removal.', '25.0')] - procedure LearnMore(HostNotification: Notification) - begin - Hyperlink(LearnMoreLinkTok); - end; - - [Obsolete('Pending removal.', '25.0')] - procedure DisableNotification(HostNotification: Notification) - var - MyNotifications: Record "My Notifications"; - NotificationId: Text; - begin - NotificationId := HostNotification.GetData('NotificationId'); - if MyNotifications.Get(UserId(), NotificationId) then - MyNotifications.Disable(NotificationId) - else - MyNotifications.InsertDefault(NotificationId, IntrastatAwarenessNotificationNameTxt, IntrastatAwarenessNotificationDescriptionTxt, false); - Session.LogMessage('0000I9Q', StrSubstNo(UserDisabledNotificationTxt, HostNotification.GetData('NotificationId')), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', IntrastatTelemetryCategoryTok); - end; -#endif internal procedure NotifyUserAboutSupplementaryUnitUpdate() var Item: Record Item; @@ -1102,19 +1034,6 @@ codeunit 4810 IntrastatReportManagement StrSubstNo(SupplementaryUnitUpdateNotificationDescriptionTxt, Item.FieldCaption("Supplementary Unit of Measure"), Item.FieldCaption("Tariff No.")), false); end; -#if not CLEAN25 - [Obsolete('Pending removal.', '25.0')] - procedure ShowNotEnabledMessage(PageCaption: Text) - begin - Message(FeatureNotEnabledMessageTxt, PageCaption); - end; - - [Obsolete('Pending removal.', '25.0')] - procedure ShowFeatureEnabledMessage(OldPageCaption: Text; NewPageCaption: Text) - begin - Message(NewFeatureEnabledMessageTxt, OldPageCaption, NewPageCaption); - end; -#endif procedure IsCustomerPrivatePerson(Customer: Record Customer): Boolean; begin if Customer."Intrastat Partner Type" <> "Partner Type"::" " then @@ -1131,39 +1050,11 @@ codeunit 4810 IntrastatReportManagement exit(Vendor."Partner Type" = "Partner Type"::Person); end; -#if not CLEAN25 - [Obsolete('Pending removal.', '25.0')] - local procedure GetIntrastatFeatureKeyId(): Text[50] - begin - exit(IntrastatFeatureKeyIdTok); - end; - - [Obsolete('Pending removal.', '25.0')] - local procedure GetIntrastatFeatureAwarenessNotificationId(): Guid; - begin - exit(IntrastatFeatureAwarenessNotificationIdTok); - end; -#endif local procedure GetSupplementaryUnitUpdateNotificationId(): Guid; begin exit(SupplementaryUnitUpdateNotificationIdTok); end; -#if not CLEAN25 - [Obsolete('Pending removal.', '25.0')] - local procedure GetAppId(): Guid; - begin - exit(IntrastatCoreAppIdTok); - end; - - [Obsolete('Pending removal.', '25.0')] - local procedure IsInstalledByAppId(AppID: Guid): Boolean - var - NAVAppInstalledApp: Record "NAV App Installed App"; - begin - exit(NAVAppInstalledApp.Get(AppID)); - end; -#endif [EventSubscriber(ObjectType::Codeunit, Codeunit::"Guided Experience", 'OnRegisterAssistedSetup', '', true, true)] local procedure InsertIntoAssistedSetup() var @@ -1225,13 +1116,6 @@ codeunit 4810 IntrastatReportManagement begin end; -#if not CLEAN25 - [Obsolete('Pending removal.', '25.0')] - [IntegrationEvent(true, false)] - local procedure OnAfterCheckFeatureEnabled(var IsEnabled: Boolean) - begin - end; -#endif [IntegrationEvent(true, false)] local procedure OnBeforeDefineFileNames(var IntrastatReportHeader: Record "Intrastat Report Header"; var FileName: Text; var ReceptFileName: Text; var ShipmentFileName: Text; var ZipFileName: Text; var IsHandled: Boolean) begin @@ -1306,4 +1190,4 @@ codeunit 4810 IntrastatReportManagement local procedure OnRecalculateWeightAndSupplUOMQtyOnAfterCalculateNetWeight(var IntrastatReportLine: Record "Intrastat Report Line"; var NetWeight: Decimal) begin end; -} +} \ No newline at end of file diff --git a/Apps/W1/LibraryNoTransactions/.objidconfig b/Apps/W1/LibraryNoTransactions/app/.objidconfig similarity index 100% rename from Apps/W1/LibraryNoTransactions/.objidconfig rename to Apps/W1/LibraryNoTransactions/app/.objidconfig diff --git a/Apps/W1/LibraryNoTransactions/ExtensionLogo.png b/Apps/W1/LibraryNoTransactions/app/ExtensionLogo.png similarity index 100% rename from Apps/W1/LibraryNoTransactions/ExtensionLogo.png rename to Apps/W1/LibraryNoTransactions/app/ExtensionLogo.png diff --git a/Apps/W1/LibraryNoTransactions/NoTransactionsSubscriber.Codeunit.al b/Apps/W1/LibraryNoTransactions/app/NoTransactionsSubscriber.Codeunit.al similarity index 100% rename from Apps/W1/LibraryNoTransactions/NoTransactionsSubscriber.Codeunit.al rename to Apps/W1/LibraryNoTransactions/app/NoTransactionsSubscriber.Codeunit.al diff --git a/Apps/W1/LibraryNoTransactions/app.json b/Apps/W1/LibraryNoTransactions/app/app.json similarity index 100% rename from Apps/W1/LibraryNoTransactions/app.json rename to Apps/W1/LibraryNoTransactions/app/app.json diff --git a/Apps/W1/MicrosoftUniversalPrint/.objidconfig b/Apps/W1/MicrosoftUniversalPrint/app/.objidconfig similarity index 100% rename from Apps/W1/MicrosoftUniversalPrint/.objidconfig rename to Apps/W1/MicrosoftUniversalPrint/app/.objidconfig diff --git a/Apps/W1/MicrosoftUniversalPrint/ExtensionLogo.png b/Apps/W1/MicrosoftUniversalPrint/app/ExtensionLogo.png similarity index 100% rename from Apps/W1/MicrosoftUniversalPrint/ExtensionLogo.png rename to Apps/W1/MicrosoftUniversalPrint/app/ExtensionLogo.png diff --git a/Apps/W1/MicrosoftUniversalPrint/README.md b/Apps/W1/MicrosoftUniversalPrint/app/README.md similarity index 100% rename from Apps/W1/MicrosoftUniversalPrint/README.md rename to Apps/W1/MicrosoftUniversalPrint/app/README.md diff --git a/Apps/W1/MicrosoftUniversalPrint/app.json b/Apps/W1/MicrosoftUniversalPrint/app/app.json similarity index 100% rename from Apps/W1/MicrosoftUniversalPrint/app.json rename to Apps/W1/MicrosoftUniversalPrint/app/app.json diff --git a/Apps/W1/PayPalPaymentsStandard/app/src/pages/MSPayPalStandardSettings.Page.al b/Apps/W1/PayPalPaymentsStandard/app/src/pages/MSPayPalStandardSettings.Page.al index 42368cfbab..1e8b6e7f70 100644 --- a/Apps/W1/PayPalPaymentsStandard/app/src/pages/MSPayPalStandardSettings.Page.al +++ b/Apps/W1/PayPalPaymentsStandard/app/src/pages/MSPayPalStandardSettings.Page.al @@ -22,7 +22,7 @@ page 1074 "MS - PayPal Standard Settings" InstructionalText = 'Enter your email address for PayPal payments.'; field(AccountID; PayPalAccountID) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Caption = 'PayPal Email'; ExtendedDatatype = EMail; ToolTip = 'Specifies the PayPal email.'; @@ -37,7 +37,7 @@ page 1074 "MS - PayPal Standard Settings" } field("Terms of Service"; TermsOfServiceLbl) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Caption = 'PayPal Terms of Service'; Editable = false; ShowCaption = false; @@ -54,7 +54,7 @@ page 1074 "MS - PayPal Standard Settings" Visible = IsSandbox; field(SandboxControl; IsSandbox) { - ApplicationArea = Invoicing, Basic, Suite; + ApplicationArea = Basic, Suite; Editable = false; Caption = 'Sandbox active'; ToolTip = 'Specifies whether the Sandbox is active.'; @@ -95,6 +95,3 @@ page 1074 "MS - PayPal Standard Settings" IsSandbox: Boolean; TermsOfServiceLbl: Label 'Terms of service'; } - - - diff --git a/Apps/W1/QBMigration/app/src/Support/MSQBODataMigration.Page.al b/Apps/W1/QBMigration/app/src/Support/MSQBODataMigration.Page.al index a7a2f390b7..50140259cb 100644 --- a/Apps/W1/QBMigration/app/src/Support/MSQBODataMigration.Page.al +++ b/Apps/W1/QBMigration/app/src/Support/MSQBODataMigration.Page.al @@ -54,27 +54,6 @@ page 1830 "MS - QBO Data Migration" } } } -#if not CLEAN25 - group("2") - { - ObsoleteState = Pending; - ObsoleteReason = 'Not used anymore'; - ObsoleteTag = '17.0'; - - Visible = false; - ShowCaption = false; - field(Instructions1; '') - { - ApplicationArea = Basic, Suite; - Editable = false; - MultiLine = true; - ShowCaption = false; - ObsoleteState = Pending; - ObsoleteReason = 'Not used anymore'; - ObsoleteTag = '25.0'; - } - } -#endif group("3") { InstructionalText = 'Enter the accounts to use when you post sales and purchase transactions to the general ledger.'; @@ -663,4 +642,4 @@ page 1830 "MS - QBO Data Migration" begin Evaluate(GuidTest, StringToTest); end; -} +} \ No newline at end of file diff --git a/Apps/W1/QBMigration/app/src/Support/MigrationQBConfig.Table.al b/Apps/W1/QBMigration/app/src/Support/MigrationQBConfig.Table.al index 587e09c093..b60cb478dc 100644 --- a/Apps/W1/QBMigration/app/src/Support/MigrationQBConfig.Table.al +++ b/Apps/W1/QBMigration/app/src/Support/MigrationQBConfig.Table.al @@ -55,18 +55,6 @@ table 1917 "MigrationQB Config" Insert(); end; end; -#if not CLEAN25 - - [NonDebuggable] - [Obsolete('Replaced by InitializeOnlineConfig(AccessToken: SecretText; RealmId: Text)', '25.0')] - procedure InitializeOnlineConfig(AccessToken: Text; RealmId: Text) - var - AccessTokenAsSecretText: SecretText; - begin - AccessTokenAsSecretText := AccessToken; - InitializeOnlineConfig(AccessTokenAsSecretText, RealmId); - end; -#endif procedure InitializeOnlineConfig(AccessToken: SecretText; RealmId: Text) begin @@ -82,31 +70,6 @@ table 1917 "MigrationQB Config" IsolatedStorage.Set('Migration QB Access Token', AccessToken, DataScope::Company); end; -#if not CLEAN25 - [Obsolete('Do not use. Replaced with InitializeOnlineConfig() for OAuth 2.0 implementation.', '15.4')] - procedure InitializeOnlineSetup(TokenKey: Text; TokenSecret: Text; RealmId: Text) - var - CryptographyManagement: Codeunit "Cryptography Management"; - begin - if not Get() then begin - Init(); - Insert(); - end; - - Validate(Online, true); - Modify(); - - if CryptographyManagement.IsEncryptionEnabled() then begin - IsolatedStorage.SetEncrypted('Migration QB Realm Id', RealmId, DataScope::Company); - IsolatedStorage.SetEncrypted('Migration QB Token Key', TokenKey, DataScope::Company); - IsolatedStorage.SetEncrypted('Migration QB Token Secret', TokenSecret, DataScope::Company); - end else begin - IsolatedStorage.Set('Migration QB Realm Id', RealmId, DataScope::Company); - IsolatedStorage.Set('Migration QB Token Key', TokenKey, DataScope::Company); - IsolatedStorage.Set('Migration QB Token Secret', TokenSecret, DataScope::Company); - end; - end; -#endif procedure IsOnlineData(): Boolean begin @@ -149,4 +112,4 @@ table 1917 "MigrationQB Config" Validate("Total Vendors", TotalVendors); Modify(); end; -} +} \ No newline at end of file diff --git a/Apps/W1/QBMigration/app/src/Support/MigrationQBHelperFunctions.Codeunit.al b/Apps/W1/QBMigration/app/src/Support/MigrationQBHelperFunctions.Codeunit.al index a84af55639..e0ae924a0c 100644 --- a/Apps/W1/QBMigration/app/src/Support/MigrationQBHelperFunctions.Codeunit.al +++ b/Apps/W1/QBMigration/app/src/Support/MigrationQBHelperFunctions.Codeunit.al @@ -511,21 +511,6 @@ codeunit 1917 "MigrationQB Helper Functions" begin exit(LocalGetPropertyFromCode(CodeTxt, Property)); end; -#if not CLEAN25 - - [TryFunction] - [Scope('OnPrem')] - [NonDebuggable] - [Obsolete('Replaced by GetAuthRequestUrl(ClientId: SecretText; ClientSecret: SecretText; Scope: Text; Url: Text; CallBackUrl: Text; State: Text; var AuthRequestUrl: Text)', '25.0')] - procedure GetAuthRequestUrl(ClientId: Text; ClientSecret: Text; Scope: Text; Url: Text; CallBackUrl: Text; State: Text; var AuthRequestUrl: Text) - var - ClientIdAsSecretText, ClientSecretAsSecretText : SecretText; - begin - ClientIdAsSecretText := ClientId; - ClientSecretAsSecretText := ClientSecret; - GetAuthRequestUrl(ClientIdAsSecretText, ClientSecretAsSecretText, Scope, Url, CallBackUrl, State, AuthRequestUrl); - end; -#endif [TryFunction] [Scope('OnPrem')] @@ -533,23 +518,6 @@ codeunit 1917 "MigrationQB Helper Functions" begin GetAuthRequestUrlImp(ClientId, ClientSecret, Scope, Url, CallBackUrl, State, AuthRequestUrl); end; -#if not CLEAN25 - - [TryFunction] - [Scope('OnPrem')] - [NonDebuggable] - [Obsolete('Replaced by GetAccessToken(Url: Text; Callback: Text; AuthCode: SecretText; ClientId: SecretText; ClientSecret: SecretText; var AccessKey: SecretText)', '25.0')] - procedure GetAccessToken(Url: Text; Callback: Text; AuthCode: Text; ClientId: Text; ClientSecret: Text; var AccessKey: Text) - var - AuthCodeAsSecretText, ClientIdAsSecretText, ClientSecretAsSecretText, AccessKeyAsSecretText : SecretText; - begin - AuthCodeAsSecretText := AuthCode; - ClientIdAsSecretText := ClientId; - ClientSecretAsSecretText := ClientSecret; - GetAccessToken(Url, Callback, AuthCodeAsSecretText, ClientIdAsSecretText, ClientSecretAsSecretText, AccessKeyAsSecretText); - AccessKey := AccessKeyAsSecretText.Unwrap(); - end; -#endif [TryFunction] [Scope('OnPrem')] @@ -701,4 +669,4 @@ codeunit 1917 "MigrationQB Helper Functions" exit(''); end; -} +} \ No newline at end of file diff --git a/Apps/W1/ReviewGLEntries/app/src/pages/ReviewGLEntries.Page.al b/Apps/W1/ReviewGLEntries/app/src/pages/ReviewGLEntries.Page.al index 4dab8f6ee7..a9c6336bc1 100644 --- a/Apps/W1/ReviewGLEntries/app/src/pages/ReviewGLEntries.Page.al +++ b/Apps/W1/ReviewGLEntries/app/src/pages/ReviewGLEntries.Page.al @@ -342,6 +342,8 @@ page 22207 "Review G/L Entries" begin Rec.CalcFields("Reviewed Amount"); RemainingAmount := Rec.Amount - Rec."Reviewed Amount"; + if Rec."Amount to Review" = 0 then + Rec."Amount to Review" := RemainingAmount; end; trigger OnAfterGetCurrRecord() @@ -375,6 +377,7 @@ page 22207 "Review G/L Entries" GLEntry: Record "G/L Entry"; begin SelectedGLEntries(GLEntry); + GLEntry.SetLoadFields("Debit Amount", "Credit Amount"); GLEntry.CalcSums("Debit Amount", "Credit Amount"); Debit := GLEntry."Debit Amount"; Credit := GLEntry."Credit Amount"; @@ -390,6 +393,7 @@ page 22207 "Review G/L Entries" var GLAccount: record "G/L Account"; begin + GLAccount.SetLoadFields("No.", Name, "Review Policy"); if not GLAccount.Get(Rec."G/L Account No.") then if Rec.GetFilter(Rec."G/L Account No.") <> '' then GLAccount.Get(Rec.GetRangeMin(Rec."G/L Account No.")); @@ -400,13 +404,23 @@ page 22207 "Review G/L Entries" local procedure CalcBalance() var GLEntry: Record "G/L Entry"; + FeatureTelemetry: Codeunit "Feature Telemetry"; begin Balance := 0; GLEntry.Copy(Rec); - if GLEntry.FindSet() then - repeat - Balance += GLEntry."Amount to Review"; - until GLEntry.Next() = 0; + GLEntry.SetLoadFields("Amount to Review"); + GLEntry.SetFilter("Amount to Review", '<>0'); + if GLEntry.CalcSums("Amount to Review") then + Balance := GLEntry."Amount to Review" + else begin + FeatureTelemetry.LogUsage('0000QPE', 'Review G/L Entries', 'Adding up Amount to Review one by one'); + if GLEntry.FindSet() then + repeat + Balance += GLEntry."Amount to Review"; + until GLEntry.Next() = 0; + FeatureTelemetry.LogUsage('0000QPF', 'Review G/L Entries', 'Added up Amount to Review one by one'); + end; + end; local procedure AreOppositeSign(Amount1: Decimal; Amount2: Decimal): Boolean diff --git a/Apps/W1/SalesLinesSuggestions/app/BaseAppExtensions/SalesInvoiceSubFormExt.PageExt.al b/Apps/W1/SalesLinesSuggestions/app/BaseAppExtensions/SalesInvoiceSubFormExt.PageExt.al index 3f185be12b..0f657bb960 100644 --- a/Apps/W1/SalesLinesSuggestions/app/BaseAppExtensions/SalesInvoiceSubFormExt.PageExt.al +++ b/Apps/W1/SalesLinesSuggestions/app/BaseAppExtensions/SalesInvoiceSubFormExt.PageExt.al @@ -43,36 +43,6 @@ pageextension 7277 "Sales Invoice Sub Form Ext" extends "Sales Invoice Subform" end; } } -#if not CLEAN25 - addlast(processing) - { - group("Copilot") - { - Image = SparkleFilled; - ShowAs = SplitButton; - Visible = false; - ObsoleteReason = 'Replaced by Suggest Sales Line Prompting'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - action("Suggest Sales Lines") - { - ApplicationArea = All; - Caption = 'Suggest sales lines'; - Image = SparkleFilled; - ToolTip = 'Get sales lines suggestions from Copilot'; - Visible = false; - ObsoleteReason = 'Replaced by Suggest Sales Line Prompting'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - - trigger OnAction() - begin - SalesLineAISuggestionImp.GetLinesSuggestions(Rec); - end; - } - } - } -#endif } var diff --git a/Apps/W1/SalesLinesSuggestions/app/BaseAppExtensions/SalesOrderSubFormExt.PageExt.al b/Apps/W1/SalesLinesSuggestions/app/BaseAppExtensions/SalesOrderSubFormExt.PageExt.al index 7eb7751b43..aac1dffd82 100644 --- a/Apps/W1/SalesLinesSuggestions/app/BaseAppExtensions/SalesOrderSubFormExt.PageExt.al +++ b/Apps/W1/SalesLinesSuggestions/app/BaseAppExtensions/SalesOrderSubFormExt.PageExt.al @@ -43,37 +43,6 @@ pageextension 7278 "Sales Order Sub Form Ext" extends "Sales Order Subform" end; } } -#if not CLEAN25 - addlast(processing) - { - group("Copilot") - { - Image = SparkleFilled; - ShowAs = SplitButton; - Visible = false; - ObsoleteReason = 'Replaced by Suggest Sales Line Prompting'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - - action("Suggest Sales Lines") - { - ApplicationArea = All; - Caption = 'Suggest sales lines'; - Image = SparkleFilled; - ToolTip = 'Get sales lines suggestions from Copilot'; - Visible = false; - ObsoleteReason = 'Replaced by Suggest Sales Line Prompting'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - - trigger OnAction() - begin - SalesLineAISuggestionImp.GetLinesSuggestions(Rec); - end; - } - } - } -#endif } var diff --git a/Apps/W1/SalesLinesSuggestions/app/BaseAppExtensions/SalesQuoteSubFormExt.PageExt.al b/Apps/W1/SalesLinesSuggestions/app/BaseAppExtensions/SalesQuoteSubFormExt.PageExt.al index 95079435b6..7ad72ef970 100644 --- a/Apps/W1/SalesLinesSuggestions/app/BaseAppExtensions/SalesQuoteSubFormExt.PageExt.al +++ b/Apps/W1/SalesLinesSuggestions/app/BaseAppExtensions/SalesQuoteSubFormExt.PageExt.al @@ -43,37 +43,6 @@ pageextension 7279 "Sales Quote Sub Form Ext" extends "Sales Quote Subform" end; } } -#if not CLEAN25 - addlast(processing) - { - group("Copilot") - { - Image = SparkleFilled; - ShowAs = SplitButton; - Visible = false; - ObsoleteReason = 'Replaced by Suggest Sales Line Prompting'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - - action("Suggest Sales Lines") - { - ApplicationArea = All; - Caption = 'Suggest sales lines'; - Image = SparkleFilled; - ToolTip = 'Get sales lines suggestions from Copilot'; - Visible = false; - ObsoleteReason = 'Replaced by Suggest Sales Line Prompting'; - ObsoleteState = Pending; - ObsoleteTag = '25.0'; - - trigger OnAction() - begin - SalesLineAISuggestionImp.GetLinesSuggestions(Rec); - end; - } - } - } -#endif } var diff --git a/Apps/W1/SalesOrderAgent/app/src/Integration/SOAAnnotation.Codeunit.al b/Apps/W1/SalesOrderAgent/app/src/Integration/SOAAnnotation.Codeunit.al index dfabc9a853..a66240f5cf 100644 --- a/Apps/W1/SalesOrderAgent/app/src/Integration/SOAAnnotation.Codeunit.al +++ b/Apps/W1/SalesOrderAgent/app/src/Integration/SOAAnnotation.Codeunit.al @@ -35,7 +35,7 @@ codeunit 4399 "SOA Annotation" var SOASetup: Record "SOA Setup"; begin - SOASetup.SetRange("Agent User Security ID", AgentUserId); + SOASetup.SetRange("User Security ID", AgentUserId); if not SOASetup.FindFirst() then exit; diff --git a/Apps/W1/SalesOrderAgent/app/src/Integration/SOADispatcher.Codeunit.al b/Apps/W1/SalesOrderAgent/app/src/Integration/SOADispatcher.Codeunit.al index f094ce5e2e..b0cf7a648e 100644 --- a/Apps/W1/SalesOrderAgent/app/src/Integration/SOADispatcher.Codeunit.al +++ b/Apps/W1/SalesOrderAgent/app/src/Integration/SOADispatcher.Codeunit.al @@ -120,7 +120,7 @@ codeunit 4586 "SOA Dispatcher" end; // Check if the agent is enabled - if not Agent.IsActive(Setup."Agent User Security ID") then begin + if not Agent.IsActive(Setup."User Security ID") then begin FeatureTelemetry.LogError('0000NDL', SOASetupCU.GetFeatureName(), 'Agent enable check', TelemetryAgentNotEnabledLbl, GetLastErrorCallStack(), TelemetryDimensions); exit(false); end; diff --git a/Apps/W1/SalesOrderAgent/app/src/Integration/SOAImpl.Codeunit.al b/Apps/W1/SalesOrderAgent/app/src/Integration/SOAImpl.Codeunit.al index 86384ede97..c3f1c30214 100644 --- a/Apps/W1/SalesOrderAgent/app/src/Integration/SOAImpl.Codeunit.al +++ b/Apps/W1/SalesOrderAgent/app/src/Integration/SOAImpl.Codeunit.al @@ -74,7 +74,7 @@ codeunit 4587 "SOA Impl" exit(true); repeat - if User.Get(SOASetup."Agent User Security ID") then + if User.Get(SOASetup."User Security ID") then if User.State = User.State::Enabled then exit(true); until SOASetup.Next() = 0; diff --git a/Apps/W1/SalesOrderAgent/app/src/Integration/SOARecovery.Codeunit.al b/Apps/W1/SalesOrderAgent/app/src/Integration/SOARecovery.Codeunit.al index aa147cf23c..583a32e722 100644 --- a/Apps/W1/SalesOrderAgent/app/src/Integration/SOARecovery.Codeunit.al +++ b/Apps/W1/SalesOrderAgent/app/src/Integration/SOARecovery.Codeunit.al @@ -46,7 +46,7 @@ codeunit 4584 "SOA Recovery" end; // Check if the agent is enabled - if not Agent.IsActive(Setup."Agent User Security ID") then begin + if not Agent.IsActive(Setup."User Security ID") then begin FeatureTelemetry.LogError('0000NDW', SOASetupCU.GetFeatureName(), 'Sales order agent enable check', TelemetrySalesOrderAgentIsNotEnabledLbl, GetLastErrorCallStack(), TelemetryDimensions); exit; end; diff --git a/Apps/W1/SalesOrderAgent/app/src/Integration/SOARetrieveEmails.Codeunit.al b/Apps/W1/SalesOrderAgent/app/src/Integration/SOARetrieveEmails.Codeunit.al index c4d7d3dc43..caee5ef895 100644 --- a/Apps/W1/SalesOrderAgent/app/src/Integration/SOARetrieveEmails.Codeunit.al +++ b/Apps/W1/SalesOrderAgent/app/src/Integration/SOARetrieveEmails.Codeunit.al @@ -145,7 +145,7 @@ codeunit 4582 "SOA Retrieve Emails" exit; end; - if AgentTaskBuilder.TaskExists(SOASetup."Agent User Security ID", EmailInbox."Conversation Id") then + if AgentTaskBuilder.TaskExists(SOASetup."User Security ID", EmailInbox."Conversation Id") then AddEmailToExistingAgentTask(SOASetup, EmailInbox, SOAEmail) else AddEmailToNewAgentTask(SOASetup, EmailInbox, SOAEmail); @@ -202,7 +202,7 @@ codeunit 4582 "SOA Retrieve Emails" .SetRequiresReview(SOATaskMessage.MessageRequiresReview(SOASetup, EmailInbox, true)) .SetIgnoreAttachment(not SOASetup."Analyze Attachments"); - AgentTaskBuilder.Initialize(SOASetup."Agent User Security ID", AgentTaskTitle) + AgentTaskBuilder.Initialize(SOASetup."User Security ID", AgentTaskTitle) .SetExternalId(EmailInbox."Conversation Id") .AddTaskMessage(AgentMessageBuilder); diff --git a/Apps/W1/SalesOrderAgent/app/src/Integration/SOASendReplies.Codeunit.al b/Apps/W1/SalesOrderAgent/app/src/Integration/SOASendReplies.Codeunit.al index 367058dc07..59ffa942f9 100644 --- a/Apps/W1/SalesOrderAgent/app/src/Integration/SOASendReplies.Codeunit.al +++ b/Apps/W1/SalesOrderAgent/app/src/Integration/SOASendReplies.Codeunit.al @@ -47,7 +47,7 @@ codeunit 4581 "SOA Send Replies" OutputAgentTaskMessage.ReadIsolation(IsolationLevel::ReadCommitted); OutputAgentTaskMessage.SetRange(Status, OutputAgentTaskMessage.Status::Reviewed); OutputAgentTaskMessage.SetRange(Type, OutputAgentTaskMessage.Type::Output); - OutputAgentTaskMessage.SetRange("Agent User Security ID", SOASetup."Agent User Security ID"); + OutputAgentTaskMessage.SetRange("Agent User Security ID", SOASetup."User Security ID"); if not OutputAgentTaskMessage.FindSet() then exit; diff --git a/Apps/W1/SalesOrderAgent/app/src/Integration/SOAUpgrade.Codeunit.al b/Apps/W1/SalesOrderAgent/app/src/Integration/SOAUpgrade.Codeunit.al index 7e981acfae..b7871a4d78 100644 --- a/Apps/W1/SalesOrderAgent/app/src/Integration/SOAUpgrade.Codeunit.al +++ b/Apps/W1/SalesOrderAgent/app/src/Integration/SOAUpgrade.Codeunit.al @@ -30,6 +30,7 @@ codeunit 4589 "SOA Upgrade" trigger OnUpgradePerCompany() begin AddDailyEmailLimit(); + UpgradeUserSecurityIDField(); end; local procedure RegisterCapability() @@ -59,6 +60,21 @@ codeunit 4589 "SOA Upgrade" end; end; + local procedure UpgradeUserSecurityIDField() + var + DummySOASetup: Record "SOA Setup"; + UpgradeTag: Codeunit "Upgrade Tag"; + SOADataTransfer: DataTransfer; + begin + if UpgradeTag.HasUpgradeTag(GetUserSecurityIDUpgradeTag()) then + exit; + SOADataTransfer.SetTables(Database::"SOA Setup", Database::"SOA Setup"); + SOADataTransfer.AddFieldValue(DummySOASetup.FieldNo("Agent User Security ID"), DummySOASetup.FieldNo("User Security ID")); + SOADataTransfer.CopyFields(); + + UpgradeTag.SetUpgradeTag(GetUserSecurityIDUpgradeTag()); + end; + local procedure AddDailyEmailLimit() var SOASetup: Record "SOA Setup"; @@ -89,9 +105,20 @@ codeunit 4589 "SOA Upgrade" exit('MS-597734-DailyEmailLimit-20250822'); end; + local procedure GetUserSecurityIDUpgradeTag(): Code[250] + begin + exit('MS-597811-UserSecurityIDField-20251114'); + end; + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Upgrade Tag", OnGetPerDatabaseUpgradeTags, '', false, false)] local procedure RegisterPerDatabaseUpgradeTags(var PerDatabaseUpgradeTags: List of [Code[250]]) begin PerDatabaseUpgradeTags.Add(GetAddBillingTypeToSOACapabilityTag()); end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Upgrade Tag", OnGetPerCompanyUpgradeTags, '', false, false)] + local procedure RegisterPerCompanyUpgradeTags(var PerCompanyUpgradeTags: List of [Code[250]]) + begin + PerCompanyUpgradeTags.Add(GetSetDailyEmailLimitTag()); + end; } \ No newline at end of file diff --git a/Apps/W1/SalesOrderAgent/app/src/Profile/SalesOrderAgent.Profile.al b/Apps/W1/SalesOrderAgent/app/src/Profile/SalesOrderAgent.Profile.al index e89d4115da..56ec11921f 100644 --- a/Apps/W1/SalesOrderAgent/app/src/Profile/SalesOrderAgent.Profile.al +++ b/Apps/W1/SalesOrderAgent/app/src/Profile/SalesOrderAgent.Profile.al @@ -10,6 +10,7 @@ profile "Sales Order Agent" { Caption = 'Sales Order Agent (Copilot)'; Description = 'Page customizations for Sales Order Agent'; + ProfileDescription = 'Functionality for the Sales Order Agent to efficiently process sales orders and quotes.'; RoleCenter = "SOA Role Center"; Customizations = "SOA Customer Card", "SOA Customer List", diff --git a/Apps/W1/SalesOrderAgent/app/src/RoleCenter/SOAKPI.Page.al b/Apps/W1/SalesOrderAgent/app/src/RoleCenter/SOAKPI.Page.al index bfc48050a0..0da484ff6e 100644 --- a/Apps/W1/SalesOrderAgent/app/src/RoleCenter/SOAKPI.Page.al +++ b/Apps/W1/SalesOrderAgent/app/src/RoleCenter/SOAKPI.Page.al @@ -14,7 +14,7 @@ page 4402 "SOA KPI" { PageType = CardPart; ApplicationArea = All; - SourceTable = Agent; + SourceTable = "SOA KPI"; Permissions = tabledata "General Ledger Setup" = R; Caption = 'Sales Order Agent'; InherentEntitlements = X; @@ -27,13 +27,13 @@ page 4402 "SOA KPI" cuegroup(Summary) { ShowCaption = false; - field(ReceivedEmails; SOAgentKPI."Received Emails") + field(ReceivedEmails; Rec."Received Emails") { ApplicationArea = All; Caption = 'Received emails'; ToolTip = 'Specifies the total number of emails that the agent has received.'; } - field(Quotes; SOAgentKPI."Total Quotes Created") + field(Quotes; Rec."Total Quotes Created") { ApplicationArea = All; Caption = 'Quotes created'; @@ -48,7 +48,7 @@ page 4402 "SOA KPI" Page.Run(Page::"SOA KPI Entries", SOAKPIEntry); end; } - field(Orders; SOAgentKPI."Total Orders Created") + field(Orders; Rec."Total Orders Created") { ApplicationArea = All; Caption = 'Orders created'; @@ -92,6 +92,12 @@ page 4402 "SOA KPI" } } + trigger OnOpenPage() + begin + Rec.GetSafe(); + VerifyUserHasAccessToAgent(); + end; + trigger OnAfterGetCurrRecord() begin CalculateTotals(); @@ -100,9 +106,8 @@ page 4402 "SOA KPI" local procedure CalculateTotals() begin VerifyUserHasAccessToAgent(); - SOAgentKPI.GetSafe(); - SOAgentKPI.UpdateEmailKPIs(Rec."User Security ID"); - GetAmount(SOAgentKPI."Total Amount Orders", TotalAmountOrders, TotalAmountOrdersFormat); + Rec.UpdateEmailKPIs(Rec."User Security ID"); + GetAmount(Rec."Total Amount Orders", TotalAmountOrders, TotalAmountOrdersFormat); TimeSavedEmails := GetTimeSavedEmails(EmailTimeAutoFormatExpression); TimeSavedQuotes := GetTimeSavedQuotes(QuoteTimeAutoFormatExpression); end; @@ -184,12 +189,12 @@ page 4402 "SOA KPI" local procedure GetTimeSavedEmails(var ControlAutoFormatExpression: Text): Decimal begin - exit(ConvertDurationToText(SOAgentKPI."Total Emails" * 3, ControlAutoFormatExpression)); // Estimate is - 3 minutes per email + exit(ConvertDurationToText(Rec."Total Emails" * 3, ControlAutoFormatExpression)); // Estimate is - 3 minutes per email end; local procedure GetTimeSavedQuotes(var ControlAutoFormatExpression: Text): Decimal begin - exit(ConvertDurationToText(SOAgentKPI."Total Quotes Created" * 6, ControlAutoFormatExpression)); // Estimate is - 6 minutes per quote + exit(ConvertDurationToText(Rec."Total Quotes Created" * 6, ControlAutoFormatExpression)); // Estimate is - 6 minutes per quote end; local procedure ConvertDurationToText(MinutesSaved: Integer; var ControlAutoFormatExpression: Text): Decimal @@ -233,7 +238,6 @@ page 4402 "SOA KPI" end; var - SOAgentKPI: Record "SOA KPI"; TimeSavedEmails: Decimal; TimeSavedQuotes: Decimal; EmailTimeAutoFormatExpression: Text; diff --git a/Apps/W1/SalesOrderAgent/app/src/RoleCenter/SOAKPI.Table.al b/Apps/W1/SalesOrderAgent/app/src/RoleCenter/SOAKPI.Table.al index bda4a69517..ba54ba0f06 100644 --- a/Apps/W1/SalesOrderAgent/app/src/RoleCenter/SOAKPI.Table.al +++ b/Apps/W1/SalesOrderAgent/app/src/RoleCenter/SOAKPI.Table.al @@ -57,6 +57,11 @@ table 4593 "SOA KPI" Caption = 'Updated at'; ToolTip = 'Specifies the date and time when the KPI was last updated.'; } + field(5000; "User Security ID"; Guid) + { + Caption = 'User Security ID'; + ToolTip = 'Specifies the security identifier (SID) of the agent for whom the KPIs are tracked.'; + } } keys @@ -68,10 +73,18 @@ table 4593 "SOA KPI" } internal procedure GetSafe() + var + UserSecurityIDFilter: Text; begin Rec.ReadIsolation := IsolationLevel::ReadCommitted; if not Rec.Get() then Rec.Insert(); + + if IsNullGuid(Rec."User Security ID") then begin + UserSecurityIDFilter := Rec.GetFilter("User Security ID"); + if Evaluate(Rec."User Security ID", UserSecurityIDFilter) then + Rec.Modify(false); + end; end; internal procedure UpdateEntryKPIs(var SOAKPIEntry: Record "SOA KPI Entry"; PreviousAmount: Decimal; InsertedRecord: Boolean) @@ -118,7 +131,7 @@ table 4593 "SOA KPI" if IsNullGuid(AgentSecurityID) then exit; - SOASetup.SetRange("Agent User Security ID", AgentSecurityID); + SOASetup.SetRange("User Security ID", AgentSecurityID); if SOASetup.IsEmpty() then exit; diff --git a/Apps/W1/SalesOrderAgent/app/src/Setup/SOAAwarenessNotifications.Codeunit.al b/Apps/W1/SalesOrderAgent/app/src/Setup/SOAAwarenessNotifications.Codeunit.al new file mode 100644 index 0000000000..9a3b715974 --- /dev/null +++ b/Apps/W1/SalesOrderAgent/app/src/Setup/SOAAwarenessNotifications.Codeunit.al @@ -0,0 +1,101 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +#pragma warning disable AS0007 +namespace Microsoft.Agent.SalesOrderAgent; + +using Microsoft.Sales.Document; +using System.Agents; +using System.Environment.Configuration; + +codeunit 4323 "SOA Awareness Notifications" +{ + Access = Internal; + EventSubscriberInstance = Manual; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Page, Page::"Sales Order", 'OnNewRecordEvent', '', false, false)] + local procedure SalesOrderOnNewRecordEvent(var Rec: Record "Sales Header"; BelowxRec: Boolean; var xRec: Record "Sales Header") + begin + ProcessManualActionCounter(); + end; + + [EventSubscriber(ObjectType::Page, Page::"Sales Quote", 'OnNewRecordEvent', '', false, false)] + local procedure SalesQuoteOnNewRecordEvent(var Rec: Record "Sales Header"; BelowxRec: Boolean; var xRec: Record "Sales Header") + begin + ProcessManualActionCounter(); + end; + + internal procedure IsBindingNeeded(): Boolean + var + MyNotifications: Record "My Notifications"; + SOASetup: Record "SOA Setup"; + AgentSession: Codeunit "Agent Session"; + AgentMetadataProvider: Enum "Agent Metadata Provider"; + begin + if not MyNotifications.IsEnabled(GetSOAAwarenessNotificationId()) then + exit(false); + + if AgentSession.IsAgentSession(AgentMetadataProvider) then + exit(false); + + exit(SOASetup.IsEmpty()); + end; + + local procedure ProcessManualActionCounter() + begin + if SOARelatedManualActionCount < 4 then + SOARelatedManualActionCount += 1 + else + NotifyUserAboutSOA(); + end; + + local procedure NotifyUserAboutSOA() + var + MyNotifications: Record "My Notifications"; + SOAAwarenessNotification: Notification; + begin + if not MyNotifications.IsEnabled(GetSOAAwarenessNotificationId()) then + exit; + + SOAAwarenessNotification.Id(GetSOAAwarenessNotificationId()); + SOAAwarenessNotification.Message(SOAAwarenessNotificationTxt); + SOAAwarenessNotification.AddAction(LearnMoreLbl, Codeunit::"SOA Awareness Notifications", 'SOAAwarenessLearnMore'); + SOAAwarenessNotification.AddAction(DisableSOAAwarenessNotificationTxt, Codeunit::"SOA Awareness Notifications", 'DisableSOAAwarenessNotification'); + if SOAAwarenessNotification.Recall() then; + SOAAwarenessNotification.Send(); + end; + + internal procedure SOAAwarenessLearnMore(var AwarenessNotification: Notification) + begin + HyperLink(SOAAwarenessLinkLbl); + end; + + internal procedure DisableSOAAwarenessNotification(HostNotification: Notification) + var + MyNotifications: Record "My Notifications"; + begin + if MyNotifications.Get(UserId(), GetSOAAwarenessNotificationId()) then + MyNotifications.Disable(GetSOAAwarenessNotificationId()) + else + MyNotifications.InsertDefault(GetSOAAwarenessNotificationId(), CopyStr(SOAAwarenessNotificationNameTxt, 1, 128), + SOAAwarenessNotificationDescriptionTxt, false); + end; + + local procedure GetSOAAwarenessNotificationId(): Guid; + begin + exit('502dd03f-4552-49af-8dab-6799258b926c'); + end; + + var + SOAAwarenessNotificationNameTxt: Label 'Notify the user who creates quotes or orders manually that the Sales Order Agent can automate quote creation from customer emails'; + SOAAwarenessNotificationDescriptionTxt: Label 'Notification to users who manually create sales quotes or orders, informing them that they can enable the Sales Order Agent to automate creating quotes from customer email requests'; + SOAAwarenessNotificationTxt: Label 'You can activate the Sales Order Agent, which uses AI to automatically create and update quotes based on customer email requests.'; + DisableSOAAwarenessNotificationTxt: Label 'Don''t show again'; + LearnMoreLbl: Label 'Learn more'; + SOAAwarenessLinkLbl: Label 'https://go.microsoft.com/fwlink/?linkid=2344613', Locked = true; + SOARelatedManualActionCount: Integer; +} \ No newline at end of file diff --git a/Apps/W1/SalesOrderAgent/app/src/Setup/SOASetup.Codeunit.al b/Apps/W1/SalesOrderAgent/app/src/Setup/SOASetup.Codeunit.al index 7686b9525a..a4b0086a14 100644 --- a/Apps/W1/SalesOrderAgent/app/src/Setup/SOASetup.Codeunit.al +++ b/Apps/W1/SalesOrderAgent/app/src/Setup/SOASetup.Codeunit.al @@ -37,38 +37,45 @@ codeunit 4400 "SOA Setup" [Scope('OnPrem')] procedure CreateDefaultAgentNoEmail() var - TempAgentAccessControl: Record "Agent Access Control" temporary; + AgentSetupBuffer: Record "Agent Setup Buffer"; TempSOASetup: Record "SOA Setup" temporary; - TempAgent: Record Agent temporary; - DummyUserSettings: Record "User Settings"; - begin - GetAgent(TempAgent); - TempAgent.State := TempAgent.State::Enabled; - GetDefaultSOASetup(TempSOASetup, TempAgent); + AgentSetup: Codeunit "Agent Setup"; + SOASetup: Codeunit "SOA Setup"; + AgentUserSecurityID: Guid; + begin + Clear(TempSOASetup); + AgentSetup.GetSetupRecord(AgentSetupBuffer, + TempSOASetup."User Security ID", + "Agent Metadata Provider"::"SO Agent", + SOASetup.GetSOAUsername(), + SOASetup.GetSOAUserDisplayName(), + SOASetup.GetAgentSummary() + ); + + AgentSetupBuffer.State := AgentSetupBuffer.State::Enabled; + AgentUserSecurityID := AgentSetup.SaveChanges(AgentSetupBuffer); + GetSOASetup(TempSOASetup, AgentUserSecurityID); TempSOASetup."Email Monitoring" := false; - GetDefaultAgentAccessControl(TempAgent."User Security ID", TempAgentAccessControl); - UpdateAgent(TempAgent, TempAgentAccessControl, TempSOASetup, true, true, false, DummyUserSettings); + UpdateAgent(AgentSetupBuffer, TempSOASetup, true); end; - local procedure CreateAgent(var TempAgent: Record Agent; var TempAgentAccessControl: Record "Agent Access Control" temporary; var TempSOASetup: Record "SOA Setup" temporary; var UserSettings: Record "User Settings") + local procedure CreateAgent(var AgentSetupBuffer: Record "Agent Setup Buffer"; var TempSOASetup: Record "SOA Setup" temporary) + var + AgentSetup: Codeunit "Agent Setup"; begin - TempSOASetup."Agent User Security ID" := Agent.Create("Agent Metadata Provider"::"SO Agent", TempAgent."User Name", TempAgent."Display Name", TempAgentAccessControl); + TempSOASetup."User Security ID" := AgentSetup.SaveChanges(AgentSetupBuffer); UpdateInstructions(TempSOASetup); - Agent.UpdateLocalizationSettings(TempSOASetup."Agent User Security ID", UserSettings); - if TempAgent.State = TempAgent.State::Enabled then + if AgentSetupBuffer.State = AgentSetupBuffer.State::Enabled then UpdateSOASetupActivationDT(TempSOASetup); UpdateSOASetup(TempSOASetup); - if TempAgent.State = TempAgent.State::Enabled then begin + if AgentSetupBuffer.State = AgentSetupBuffer.State::Enabled then begin EnableItemSearch(); - Agent.Activate(TempSOASetup."Agent User Security ID"); if TempSOASetup."Email Monitoring" and TempSOASetup."Incoming Monitoring" and not IsNullGuid(TempSOASetup."Email Account ID") then SOAImpl.ScheduleSOAgent(TempSOASetup) - end - else - Agent.Deactivate(TempSOASetup."Agent User Security ID"); + end; end; internal procedure GetInitials(): Text[4] @@ -93,51 +100,43 @@ codeunit 4400 "SOA Setup" exit(SOASetup.IsEmpty()); end; - internal procedure UpdateAgent(var TempAgent: Record Agent; var TempAgentAccessControl: Record "Agent Access Control" temporary; var TempSOASetup: Record "SOA Setup" temporary; AccessUpdated: Boolean; Schedule: Boolean; LocalizationSettingsUpdated: Boolean; UserSettings: Record "User Settings") + internal procedure UpdateAgent(var AgentSetupBuffer: Record "Agent Setup Buffer"; var TempSOASetup: Record "SOA Setup" temporary; Schedule: Boolean) var AzureADGraphUser: Codeunit "Azure AD Graph User"; + AgentSetup: Codeunit "Agent Setup"; begin if AzureADGraphUser.IsUserDelegatedAdmin() or AzureADGraphUser.IsUserDelegatedHelpdesk() then Error(DelegateAdminErr); - if IsNullGuid(TempAgent."User Security ID") then - CreateAgent(TempAgent, TempAgentAccessControl, TempSOASetup, UserSettings) + if IsNullGuid(AgentSetupBuffer."User Security ID") then + CreateAgent(AgentSetupBuffer, TempSOASetup) else begin - - if TempAgent.State = TempAgent.State::Enabled then begin + AgentSetup.SaveChanges(AgentSetupBuffer); + if AgentSetupBuffer.State = AgentSetupBuffer.State::Enabled then begin UpdateSOASetupActivationDT(TempSOASetup); UpdateInstructions(TempSOASetup); end; - Agent.SetDisplayName(TempAgent."User Security ID", TempAgent."Display Name"); - if TempAgent.State = TempAgent.State::Enabled then begin - Agent.Activate(TempAgent."User Security ID"); + if AgentSetupBuffer.State = AgentSetupBuffer.State::Enabled then begin EnableItemSearch(); if TempSOASetup."Email Monitoring" and TempSOASetup."Incoming Monitoring" and not IsNullGuid(TempSOASetup."Email Account ID") and Schedule then SOAImpl.ScheduleSOAgent(TempSOASetup); end - else begin - Agent.Deactivate(TempAgent."User Security ID"); + else SOAImpl.RemoveScheduledTask(TempSOASetup); - end; - UpdateSOASetup(TempSOASetup); - - if AccessUpdated then - Agent.UpdateAccess(TempAgent."User Security ID", TempAgentAccessControl); - if LocalizationSettingsUpdated then - Agent.UpdateLocalizationSettings(TempAgent."User Security ID", UserSettings); + UpdateSOASetup(TempSOASetup); end; // Log SOA setup telemetry - LogTelemetry(TempAgent, TempSOASetup); + LogTelemetry(AgentSetupBuffer, TempSOASetup); end; local procedure UpdateSOASetup(var TempSOASetup: Record "SOA Setup" temporary) var SOASetup: Record "SOA Setup"; begin - if SOASetup.GetBasedOnAgentUserSecurityID(TempSOASetup."Agent User Security ID", false) then begin + if SOASetup.GetBasedOnAgentUserSecurityID(TempSOASetup."User Security ID", false) then begin SOASetup."Incoming Monitoring" := TempSOASetup."Incoming Monitoring"; SOASetup."Email Monitoring" := TempSOASetup."Email Monitoring"; if SOASetup."Email Monitoring" then begin @@ -177,7 +176,7 @@ codeunit 4400 "SOA Setup" end; end; - local procedure LogTelemetry(var TempAgent: Record Agent temporary; var TempSOASetup: Record "SOA Setup" temporary) + local procedure LogTelemetry(var AgentSetupBuffer: Record "Agent Setup Buffer"; var TempSOASetup: Record "SOA Setup" temporary) var UserSettings: Record "User Settings"; FeatureTelemetry: Codeunit "Feature Telemetry"; @@ -185,8 +184,8 @@ codeunit 4400 "SOA Setup" TelemetryCustomDimension: Dictionary of [Text, Text]; begin // SOA user settings - TelemetryCustomDimension.Add('AgentUserId', Format(TempSOASetup."Agent User Security ID")); - Agent.GetUserSettings(TempAgent."User Security ID", UserSettings); + TelemetryCustomDimension.Add('AgentUserId', Format(TempSOASetup."User Security ID")); + Agent.GetUserSettings(AgentSetupBuffer."User Security ID", UserSettings); if UserSettings."Language ID" <> 0 then TelemetryCustomDimension.Add('Language', Language.GetCultureName(UserSettings."Language ID")) else @@ -218,7 +217,7 @@ codeunit 4400 "SOA Setup" TelemetryCustomDimension.Add('HasEmailAccountId', 'false'); TelemetryCustomDimension.Add('EmailConnector', Format(TempSOASetup."Email Connector")); - if (TempAgent.State = TempAgent.State::Enabled) then + if (AgentSetupBuffer.State = AgentSetupBuffer.State::Enabled) then FeatureTelemetry.LogUptake('0000QB5', GetFeatureName(), Enum::"Feature Uptake Status"::"Set up", TelemetryCustomDimension) else FeatureTelemetry.LogUptake('0000QB6', GetFeatureName(), Enum::"Feature Uptake Status"::Undiscovered, TelemetryCustomDimension); @@ -266,7 +265,7 @@ codeunit 4400 "SOA Setup" InstructionsSecret: SecretText; begin SOAPromptBuilder.PrepareInstructions(InstructionsSecret, TempSOASetup); - Agent.SetInstructions(TempSOASetup."Agent User Security ID", InstructionsSecret); + Agent.SetInstructions(TempSOASetup."User Security ID", InstructionsSecret); TempSOASetup."Instructions Last Sync At" := CurrentDateTime(); end; @@ -363,17 +362,25 @@ codeunit 4400 "SOA Setup" end; end; - internal procedure GetDefaultSOASetup(var TempSOASetup: Record "SOA Setup" temporary; var TempSOAgent: Record Agent temporary) + local procedure SetAgentDefaults(var TempSOAgent: Record Agent temporary) + begin + TempSOAgent.Init(); + TempSOAgent."User Name" := GetSOAUsername(); + TempSOAgent."Display Name" := SalesOrderAgentDisplayNameLbl; + TempSOAgent.Insert(); + end; + + internal procedure GetSOASetup(var TempSOASetup: Record "SOA Setup" temporary; AgentUserSecurityID: Guid) var SOASetup: Record "SOA Setup"; begin - if IsNullGuid(TempSOAgent."User Security ID") then begin - SetSOASetupDefaults(TempSOASetup, TempSOAgent."User Security ID"); + if IsNullGuid(AgentUserSecurityID) then begin + SetSOASetupDefaults(TempSOASetup, AgentUserSecurityID); exit; end; - if IsNullGuid(TempSOASetup."Agent User Security ID") then begin - SOASetup.SetRange("Agent User Security ID", TempSOAgent."User Security ID"); + if IsNullGuid(TempSOASetup."User Security ID") then begin + SOASetup.SetRange("User Security ID", AgentUserSecurityID); if SOASetup.FindFirst() then begin SOASetup.CalcFields("Email Template"); TempSOASetup := SOASetup; @@ -381,16 +388,16 @@ codeunit 4400 "SOA Setup" exit; end; - SetSOASetupDefaults(TempSOASetup, TempSOAgent."User Security ID"); + SetSOASetupDefaults(TempSOASetup, AgentUserSecurityID); exit; end; - if SOASetup.GetBasedOnAgentUserSecurityID(TempSOASetup."Agent User Security ID", false) then begin + if SOASetup.GetBasedOnAgentUserSecurityID(TempSOASetup."User Security ID", false) then begin TempSOASetup := SOASetup; TempSOASetup.Insert(); end else - SetSOASetupDefaults(TempSOASetup, TempSOAgent."User Security ID"); + SetSOASetupDefaults(TempSOASetup, AgentUserSecurityID); end; internal procedure CheckSOASetupStillValid(var SOASetup: Record "SOA Setup"): Boolean @@ -600,20 +607,17 @@ codeunit 4400 "SOA Setup" TempSOASetup."Email Monitoring" := true; SetDefaultSalesDocConfig(TempSOASetup, true); TempSOASetup."Analyze Attachments" := true; - TempSOASetup."Agent User Security ID" := AgentUserSecurityID; + TempSOASetup."User Security ID" := AgentUserSecurityID; SetDefaultEmailSignature(TempSOASetup); TempSOASetup.Insert(); end; - local procedure SetAgentDefaults(var TempSOAgent: Record Agent temporary) + internal procedure GetSOAUserDisplayName(): Text[80] begin - TempSOAgent.Init(); - TempSOAgent."User Name" := GetSOAUsername(); - TempSOAgent."Display Name" := SalesOrderAgentDisplayNameLbl; - TempSOAgent.Insert(); + exit(SalesOrderAgentDisplayNameLbl); end; - local procedure GetSOAUsername(): Text[50] + internal procedure GetSOAUsername(): Text[50] begin exit(SalesOrderAgentNameLbl + ' - ' + CompanyName()); end; diff --git a/Apps/W1/SalesOrderAgent/app/src/Setup/SOASetup.Page.al b/Apps/W1/SalesOrderAgent/app/src/Setup/SOASetup.Page.al index eb221397e9..ad4b2aec98 100644 --- a/Apps/W1/SalesOrderAgent/app/src/Setup/SOASetup.Page.al +++ b/Apps/W1/SalesOrderAgent/app/src/Setup/SOASetup.Page.al @@ -9,8 +9,6 @@ namespace Microsoft.Agent.SalesOrderAgent; using System.Agents; using System.AI; using System.Email; -using System.Environment.Configuration; -using System.Globalization; using System.Security.AccessControl; using System.Telemetry; @@ -22,8 +20,9 @@ page 4400 "SOA Setup" Caption = 'Configure Sales Order Agent'; InstructionalText = 'Choose how the agent helps with inquiries, quotes, and orders.'; AdditionalSearchTerms = 'Sales order agent, Copilot agent, Agent, SOA'; - SourceTable = Agent; + SourceTable = "SOA Setup"; SourceTableTemporary = true; + RefreshOnActivate = true; InherentEntitlements = X; InherentPermissions = X; HelpLink = 'https://go.microsoft.com/fwlink/?linkid=2281481'; @@ -32,36 +31,44 @@ page 4400 "SOA Setup" { area(Content) { + part(AgentSetupPart; "Agent Setup Part") + { + ApplicationArea = All; + Visible = AgentSetupPartVisible; + UpdatePropagation = Both; + } group(StartCard) { + Visible = not AgentSetupPartVisible; group(Header) { - field(Badge; BadgeTxt) + field(Badge; AgentSetupBuffer.Initials) { ShowCaption = false; Editable = false; ToolTip = 'The badge of the sales order agent.'; } - field(Type; AgentType) + field(Type; AgentSetupBuffer."Agent Metadata Provider") { ShowCaption = false; Editable = false; ToolTip = 'Specifies the type of the sales order agent.'; } - field(Name; Rec."Display Name") + field(Name; AgentSetupBuffer."Display Name") { ShowCaption = false; Editable = false; ToolTip = 'Specifies the name of the sales order agent.'; } - field(State; Rec.State) + field(State; AgentSetupBuffer.State) { Caption = 'Active'; ToolTip = 'Specifies the state of the sales order agent, such as active or inactive.'; - trigger OnValidate() begin - IsConfigUpdated := true; + AgentSetupBuffer."State Updated" := true; + AgentSetupBuffer.Modify(); + ConfigUpdated(); end; } field(UserSettingsLink; ManageUserAccessLbl) @@ -71,23 +78,13 @@ page 4400 "SOA Setup" ToolTip = 'Specifies the user access control settings for the sales order agent.'; trigger OnDrillDown() - var - TempBackupAgentAccessControl: Record "Agent Access Control" temporary; begin - CopyTempAgentAccessControl(TempAgentAccessControl, TempBackupAgentAccessControl); - if (Page.RunModal(Page::"Select Agent Access Control", TempAgentAccessControl) in [Action::LookupOK, Action::OK]) then begin - AccessUpdated := true; - IsConfigUpdated := true; - exit; - end; - - CopyTempAgentAccessControl(TempBackupAgentAccessControl, TempAgentAccessControl); + AgentSetup.UpdateUserAccessControl(AgentSetupBuffer); + IsConfigUpdated := IsConfigUpdated or AgentSetup.GetChangesMade(AgentSetupBuffer); end; } } - - - field(Summary; AgentSummary) + field(Summary; AgentSummaryTxt) { Caption = 'Summary'; MultiLine = true; @@ -95,13 +92,12 @@ page 4400 "SOA Setup" ToolTip = 'Specifies a brief description of the sales order agent.'; } } - group(MonitorIncomingCard) { Caption = 'Monitor incoming information'; InstructionalText = 'The agent will read messages in these channels:'; - field("Monitor incoming inquiries"; TempSOASetup."Incoming Monitoring") + field("Monitor incoming inquiries"; Rec."Incoming Monitoring") { ShowCaption = false; ToolTip = 'Specifies if the sales order agent should monitor incoming inquiries.'; @@ -110,11 +106,10 @@ page 4400 "SOA Setup" ConfigUpdated(); end; } - group(MailboxGroup) { Caption = 'Mailbox'; - field(MailEnabled; TempSOASetup."Email Monitoring") + field(MailEnabled; Rec."Email Monitoring") { ShowCaption = false; ToolTip = 'Specifies if the sales order agent should monitor incoming mail.'; @@ -152,8 +147,9 @@ page 4400 "SOA Setup" { Caption = 'Default language'; InstructionalText = 'Used for task details and outgoing messages unless the recipient has a language set.'; + Visible = not AgentSetupPartVisible; - field(LanguageAndRegion; SelectedLanguageTxt) + field(LanguageAndRegion; AgentSetupBuffer."Language Used") { ShowCaption = false; Editable = false; @@ -161,17 +157,9 @@ page 4400 "SOA Setup" ApplicationArea = All; trigger OnDrillDown() - var - Language: Codeunit Language; - AgentUserSettings: Page "Agent User Settings"; begin - AgentUserSettings.InitializeTemp(UserSettings); - if AgentUserSettings.RunModal() in [Action::LookupOK, Action::OK] then begin - AgentUserSettings.GetRecord(UserSettings); - IsConfigUpdated := true; - UserSettingsUpdated := true; - SelectedLanguageTxt := Language.GetWindowsLanguageName(UserSettings."Language ID"); - end; + AgentSetup.SetupLanguageAndRegion(AgentSetupBuffer); + IsConfigUpdated := IsConfigUpdated or AgentSetup.GetChangesMade(AgentSetupBuffer); end; } } @@ -191,7 +179,6 @@ page 4400 "SOA Setup" end; } } - group(BillingInformationSecondSetup) { Visible = not FirstConfig; @@ -209,7 +196,6 @@ page 4400 "SOA Setup" } } } - group(RespondToInquiriesCard) { Caption = 'Respond to inquiries'; @@ -218,7 +204,7 @@ page 4400 "SOA Setup" group(RegisteredSenderMessages) { Caption = 'Messages from already registered senders'; - field(RegisteredSenderInputMessageReview; TempSOASetup."Known Sender In. Msg. Review") + field(RegisteredSenderInputMessageReview; Rec."Known Sender In. Msg. Review") { Caption = 'Review'; ToolTip = 'Specifies the type of review required for incoming messages from already registered senders.'; @@ -228,11 +214,10 @@ page 4400 "SOA Setup" end; } } - group(UnregisteredSenderMessages) { Caption = 'Messages from unregistered senders'; - field(UnregisteredSenderInputMessageReview; TempSOASetup."Unknown Sender In. Msg. Review") + field(UnregisteredSenderInputMessageReview; Rec."Unknown Sender In. Msg. Review") { Caption = 'Review'; ToolTip = 'Specifies the type of review required for incoming messages from unregistered senders.'; @@ -242,7 +227,6 @@ page 4400 "SOA Setup" end; } } - group(ItemSearch) { Caption = 'Search for requested items'; @@ -252,19 +236,19 @@ page 4400 "SOA Setup" Caption = 'Select only available items'; InstructionalText = 'The agent checks availability of requested quantity'; - field(SearchOnlyAvailableItems; TempSOASetup."Search Only Available Items") + field(SearchOnlyAvailableItems; Rec."Search Only Available Items") { ShowCaption = false; ToolTip = 'Specifies if the agent takes item availability into account when searching for matches to the requested items.'; trigger OnValidate() begin - if not TempSOASetup."Search Only Available Items" then - TempSOASetup."Incl. Capable to Promise" := false; + if not Rec."Search Only Available Items" then + Rec."Incl. Capable to Promise" := false; ConfigUpdated(); end; } - field(IncludeCapableToPromise; TempSOASetup."Incl. Capable to Promise") + field(IncludeCapableToPromise; Rec."Incl. Capable to Promise") { Caption = 'Include capable to promise'; ToolTip = 'Specifies whether the agent includes in the search results items that are currently unavailable but can be ordered for a later shipment date.'; @@ -277,7 +261,6 @@ page 4400 "SOA Setup" } } } - group(SOASalesDocConfigCard) { Caption = 'Create sales documents'; @@ -286,7 +269,7 @@ page 4400 "SOA Setup" group(QuoteSetup) { ShowCaption = false; - field(RequestQuoteReview; TempSOASetup."Quote Review") + field(RequestQuoteReview; Rec."Quote Review") { Caption = 'Review quotes when created and updated'; ToolTip = 'Specifies if the agent requests review when a quote is created and updated.'; @@ -296,7 +279,7 @@ page 4400 "SOA Setup" ConfigUpdated(); end; } - field(SendSalesQuote; TempSOASetup."Send Sales Quote") + field(SendSalesQuote; Rec."Send Sales Quote") { Caption = 'Send quotes for confirmation'; ToolTip = 'Specifies if the agent sends sales quotes for confirmation.'; @@ -307,7 +290,6 @@ page 4400 "SOA Setup" end; } } - group(OrderSetup) { ShowCaption = false; @@ -316,7 +298,7 @@ page 4400 "SOA Setup" Caption = 'Make orders from quotes'; InstructionalText = 'The agent turns accepted quotes into orders'; - field(CreateOrderFromQuote; TempSOASetup."Create Order from Quote") + field(CreateOrderFromQuote; Rec."Create Order from Quote") { Caption = 'Make orders from quotes'; ToolTip = 'Specifies if the agent makes orders from quotes.'; @@ -324,12 +306,12 @@ page 4400 "SOA Setup" trigger OnValidate() begin - if not TempSOASetup."Create Order from Quote" then - TempSOASetup."Order Review" := false; + if not Rec."Create Order from Quote" then + Rec."Order Review" := false; ConfigUpdated(); end; } - field(RequestOrderReview; TempSOASetup."Order Review") + field(RequestOrderReview; Rec."Order Review") { Caption = 'Review orders when created and updated'; ToolTip = 'Specifies if the agent requests review when an order is created and updated.'; @@ -343,7 +325,6 @@ page 4400 "SOA Setup" } } } - group(SOAManageMailboxConfigCard) { Caption = 'Manage mailbox'; @@ -379,21 +360,17 @@ page 4400 "SOA Setup" EmailFolders: Page "Email Account Folders"; begin EmailFolders.LookupMode(true); - EmailFolders.SetEmailAccount(TempSOASetup."Email Account ID", TempSOASetup."Email Connector"); + EmailFolders.SetEmailAccount(Rec."Email Account ID", Rec."Email Connector"); if EmailFolders.RunModal() = Action::LookupOK then begin EmailFolders.GetRecord(TempEmailFolder); - TempSOASetup."Email Folder" := TempEmailFolder."Folder Name"; - TempSOASetup."Email Folder Id" := TempEmailFolder."Id"; + Rec."Email Folder" := TempEmailFolder."Folder Name"; + Rec."Email Folder Id" := TempEmailFolder."Id"; MailboxFolder := TempEmailFolder."Folder Name"; + ConfigUpdated(); end; end; - trigger OnValidate() - begin - ConfigUpdated(); - end; } - group(IncomingMail) { Caption = 'Incoming mail'; @@ -404,7 +381,7 @@ page 4400 "SOA Setup" Caption = 'Analyze attachments'; InstructionalText = 'Includes attachments when analyzing intent. Supported formats: PDF, PNG, JPG.'; - field(AnalyzeAttachments; TempSOASetup."Analyze Attachments") + field(AnalyzeAttachments; Rec."Analyze Attachments") { Caption = 'Analyze attachments'; ToolTip = 'Includes attachments when analyzing intent. Supported formats: PDF, PNG, JPG.'; @@ -417,7 +394,6 @@ page 4400 "SOA Setup" } } } - group(ProcessingLimits) { Caption = 'Processing Limits'; @@ -431,14 +407,13 @@ page 4400 "SOA Setup" trigger OnValidate() begin - TempSOASetup."Message Limit" := DailyEmailLimit; + Rec."Message Limit" := DailyEmailLimit; ConfigUpdated(); end; } } } - group(OutputMailGroup) { Caption = 'Format outgoing messages'; @@ -451,7 +426,7 @@ page 4400 "SOA Setup" { Caption = 'Include a custom signature in the replies'; - field(ConfigureEmailSignature; TempSOASetup."Configure Email Template") + field(ConfigureEmailSignature; Rec."Configure Email Template") { ShowCaption = false; ToolTip = 'Specifies if the agent includes a custom mail signature below the message body when preparing outgoing mails.'; @@ -459,7 +434,7 @@ page 4400 "SOA Setup" trigger OnValidate() begin IsConfigUpdated := true; - MailTemplateEditable := TempSOASetup."Configure Email Template"; + MailTemplateEditable := Rec."Configure Email Template"; end; } field(EmailTemplate; EmailSignatureModifyLbl) @@ -475,7 +450,6 @@ page 4400 "SOA Setup" } } } - } } actions @@ -488,7 +462,6 @@ page 4400 "SOA Setup" Enabled = IsConfigUpdated; ToolTip = 'Apply the changes to the agent setup.'; } - systemaction(Cancel) { Caption = 'Cancel'; @@ -501,24 +474,47 @@ page 4400 "SOA Setup" var FeatureTelemetry: Codeunit "Feature Telemetry"; SOASetupCU: Codeunit "SOA Setup"; + UserSecurityIDFilter: Text; + UserSecurityID: Guid; begin if not AzureOpenAI.IsEnabled(Enum::"Copilot Capability"::"Sales Order Agent") then Error(''); IsConfigUpdated := false; FirstConfig := IsFirstConfig(); + UserSecurityIDFilter := Rec.GetFilter("User Security ID"); + if not Evaluate(UserSecurityID, UserSecurityIDFilter) then + Clear(UserSecurityID); + + if not AgentSetupPartVisible then begin + AgentSetup.GetSetupRecord(AgentSetupBuffer, + UserSecurityID, + "Agent Metadata Provider"::"SO Agent", + SOASetupCU.GetSOAUsername(), + SOASetupCU.GetSOAUserDisplayName(), + SOASetupCU.GetAgentSummary() + ); + AgentSummaryTxt := SOASetupCU.GetAgentSummary(); + end else begin + CurrPage.AgentSetupPart.Page.Initialize(UserSecurityID, + "Agent Metadata Provider"::"SO Agent", + SOASetupCU.GetSOAUsername(), + SOASetupCU.GetSOAUserDisplayName(), + SOASetupCU.GetAgentSummary()); + UpdateAgentSetupBuffer(); + end; + + InitialState := AgentSetupBuffer.State; UpdateControls(); FeatureTelemetry.LogUptake('0000QIK', SOASetupCU.GetFeatureName(), Enum::"Feature Uptake Status"::Discovered); end; - trigger OnAfterGetRecord() - var - Agent: Codeunit Agent; - Language: Codeunit Language; + trigger OnAfterGetCurrRecord() begin - UpdateControls(); - Agent.GetUserSettings(Rec."User Security ID", UserSettings); - SelectedLanguageTxt := Language.GetWindowsLanguageName(UserSettings."Language ID"); + if AgentSetupPartVisible then begin + UpdateAgentSetupBuffer(); + IsConfigUpdated := IsConfigUpdated or AgentSetup.GetChangesMade(AgentSetupBuffer); + end; end; trigger OnQueryClosePage(CloseAction: Action): Boolean @@ -538,26 +534,27 @@ page 4400 "SOA Setup" if Confirm(ReadyToActivateLbl) then Rec.State := Rec.State::Enabled; - if (Rec.State = Rec.State::Enabled) and MailboxChanged and StateChanged() then + UpdateAgentSetupBuffer(); + if (AgentSetupBuffer.State = AgentSetupBuffer.State::Enabled) and MailboxChanged and StateChanged() then if CheckIsValidConfig() then begin SOASessionEvents.BindUserEvents(); - SOASetupCU.ValidateEmailConnection(StateChanged(), TempSOASetup); + SOASetupCU.ValidateEmailConnection(StateChanged(), Rec); end else begin SOASessionEvents.BindUserEvents(); - if TempSOASetup."Incoming Monitoring" and TempSOASetup."Email Monitoring" and (MailboxName = '') then + if Rec."Incoming Monitoring" and Rec."Email Monitoring" and (MailboxName = '') then Error(ActivateWithoutMailboxNameErr); - if TempSOASetup."Incoming Monitoring" and not TempSOASetup."Email Monitoring" then + if Rec."Incoming Monitoring" and not Rec."Email Monitoring" then if not Confirm(ActivateWithoutMailboxLbl) then exit(false); - if not TempSOASetup."Incoming Monitoring" then + if not Rec."Incoming Monitoring" then if not Confirm(ActivateWithoutMonitoringLbl) then exit(false); end; - if (TempSOASetup."Message Limit" <= 0) then + if (Rec."Message Limit" <= 0) then Error(DailyEmailLimitErr); if ShowDeactivateAgentEmailPermissionsWarning() then @@ -565,28 +562,35 @@ page 4400 "SOA Setup" exit(false); if StateChanged() then - SOASetupCU.UpdateSOASetupActivationDT(TempSOASetup); + SOASetupCU.UpdateSOASetupActivationDT(Rec); - SOASetupCU.UpdateAgent(Rec, TempAgentAccessControl, TempSOASetup, AccessUpdated, ShouldScheduleTask(), UserSettingsUpdated, UserSettings); + SOASetupCU.UpdateAgent(AgentSetupBuffer, Rec, ShouldScheduleTask()); exit(true); end; + local procedure UpdateAgentSetupBuffer() + begin + if AgentSetupPartVisible then + CurrPage.AgentSetupPart.Page.GetAgentSetupBuffer(AgentSetupBuffer); + end; + local procedure StateChanged(): Boolean begin - exit((Rec.State <> InitialState) or IsFirstConfig()); + exit((AgentSetupBuffer.State <> InitialState) or IsFirstConfig()); end; local procedure ShouldScheduleTask(): Boolean begin - exit((Rec.State = Rec.State::Enabled) and (StateChanged() or MailboxChanged)); + exit((AgentSetupBuffer.State = AgentSetupBuffer.State::Enabled) and (StateChanged() or MailboxChanged)); end; local procedure ShowDeactivateAgentEmailPermissionsWarning(): Boolean var SOASetupCU: Codeunit "SOA Setup"; begin - if (Rec.State = Rec.State::Disabled) and StateChanged() and not IsFirstConfig() then - if not SOASetupCU.ValidateEmailConnectionStatus(TempSOASetup) then + UpdateAgentSetupBuffer(); + if (AgentSetupBuffer.State = AgentSetupBuffer.State::Disabled) and StateChanged() and not IsFirstConfig() then + if not SOASetupCU.ValidateEmailConnectionStatus(Rec) then exit(true); end; @@ -595,43 +599,27 @@ page 4400 "SOA Setup" User: Record User; SOASetupCU: Codeunit "SOA Setup"; begin - BadgeTxt := SOASetupCU.GetInitials(); - AgentType := SOASetupCU.GetAgentType(); - AgentSummary := SOASetupCU.GetAgentSummary(); - - if Rec.IsEmpty() then begin - SOASetupCU.GetAgent(Rec); - if not IsNullGuid(Rec."User Security ID") then begin - Rec.Insert(); - InitialState := Rec.State; - end else - InitialState := Rec.State::Disabled; - end; - - if TempSOASetup.IsEmpty() or (TempSOASetup."Agent User Security ID" <> Rec."User Security ID") then begin - SOASetupCU.GetDefaultSOASetup(TempSOASetup, Rec); - MailboxName := TempSOASetup."Email Address"; - if TempSOASetup."Email Folder" <> '' then - MailboxFolder := TempSOASetup."Email Folder" + if Rec.IsEmpty() or (Rec."User Security ID" <> AgentSetupBuffer."User Security ID") then begin + SOASetupCU.GetSOASetup(Rec, AgentSetupBuffer."User Security ID"); + MailboxName := Rec."Email Address"; + if Rec."Email Folder" <> '' then + MailboxFolder := Rec."Email Folder" else MailboxFolder := OptionalMailboxLbl; - ShowLastSync := CheckIsValidConfig() and (TempSOASetup."Last Sync At" <> 0DT); - LastSync := Format(TempSOASetup."Last Sync At"); + ShowLastSync := CheckIsValidConfig() and (Rec."Last Sync At" <> 0DT); + LastSync := Format(Rec."Last Sync At"); end; - MailTemplateEditable := TempSOASetup."Configure Email Template"; - - if TempAgentAccessControl.IsEmpty() then - SOASetupCU.GetDefaultAgentAccessControl(Rec."User Security ID", TempAgentAccessControl); + MailTemplateEditable := Rec."Configure Email Template"; - CreateOrderFromQuoteActive := TempSOASetup."Create Order from Quote"; - OnlyAvailableItemsActive := TempSOASetup."Search Only Available Items"; + CreateOrderFromQuoteActive := Rec."Create Order from Quote"; + OnlyAvailableItemsActive := Rec."Search Only Available Items"; - DailyEmailLimit := TempSOASetup."Message Limit"; + DailyEmailLimit := Rec."Message Limit"; if DailyEmailLimit = 0 then - DailyEmailLimit := TempSOASetup.GetDefaultMessageLimit(); + DailyEmailLimit := Rec.GetDefaultMessageLimit(); - if User.Get(Rec.SystemModifiedBy) then + if User.Get(AgentSetupBuffer."Configured By") then ConfiguredBy := User."Full Name"; CheckIsValidConfig(); @@ -641,26 +629,26 @@ page 4400 "SOA Setup" begin IsConfigUpdated := true; CheckIsValidConfig(); - CreateOrderFromQuoteActive := TempSOASetup."Create Order from Quote"; - OnlyAvailableItemsActive := TempSOASetup."Search Only Available Items"; + CreateOrderFromQuoteActive := Rec."Create Order from Quote"; + OnlyAvailableItemsActive := Rec."Search Only Available Items"; if EnabledAgentFirstConfig() then - Rec.State := Rec.State::Enabled; + AgentSetupBuffer.State := AgentSetupBuffer.State::Enabled; end; local procedure EnabledAgentFirstConfig(): Boolean begin - exit((Rec.State = Rec.State::Disabled) and IsFirstConfig() and CheckIsValidConfig()); + exit((AgentSetupBuffer.State = AgentSetupBuffer.State::Disabled) and IsFirstConfig() and CheckIsValidConfig()); end; local procedure CheckIsValidConfig(): Boolean begin - exit(TempSOASetup."Incoming Monitoring" and TempSOASetup."Email Monitoring" and (MailboxName <> '')); + exit(Rec."Incoming Monitoring" and Rec."Email Monitoring" and (MailboxName <> '')); end; local procedure IsFirstConfig(): Boolean begin - exit(IsNullGuid(TempSOASetup."Agent User Security ID")); + exit(IsNullGuid(Rec."User Security ID")); end; local procedure CheckMailboxExists(): Boolean @@ -701,78 +689,60 @@ page 4400 "SOA Setup" EmailAccounts.FilterConnectorV4Accounts(true); if EmailAccounts.RunModal() = Action::LookupOK then begin EmailAccounts.GetAccount(TempEmailAccount); - TempSOASetup."Email Account ID" := TempEmailAccount."Account Id"; - TempSOASetup."Email Connector" := TempEmailAccount.Connector; - TempSOASetup."Email Address" := TempEmailAccount."Email Address"; + Rec."Email Account ID" := TempEmailAccount."Account Id"; + Rec."Email Connector" := TempEmailAccount.Connector; + Rec."Email Address" := TempEmailAccount."Email Address"; end; - if MailboxName <> TempSOASetup."Email Address" then begin + if MailboxName <> Rec."Email Address" then begin MailboxChanged := true; - MailboxName := TempSOASetup."Email Address"; + MailboxName := Rec."Email Address"; ConfigUpdated(); MailboxFolder := OptionalMailboxLbl; - Clear(TempSOASetup."Email Folder"); - Clear(TempSOASetup."Email Folder Id"); + Clear(Rec."Email Folder"); + Clear(Rec."Email Folder Id"); end; end; - local procedure CopyTempAgentAccessControl(var SourceTempAgentAccessControl: Record "Agent Access Control" temporary; var TargetTempAgentAccessControl: Record "Agent Access Control" temporary) - begin - TargetTempAgentAccessControl.Reset(); - TargetTempAgentAccessControl.DeleteAll(); - if not SourceTempAgentAccessControl.FindSet() then - exit; - - repeat - TargetTempAgentAccessControl.TransferFields(SourceTempAgentAccessControl, true); - TargetTempAgentAccessControl.Insert() - until SourceTempAgentAccessControl.Next() = 0; - end; - local procedure UpdateEmailSignature() var EmailTemplatePage: Page "SOA Email Template"; begin - if not TempSOASetup."Configure Email Template" then + if not Rec."Configure Email Template" then exit; - EmailTemplatePage.SetCurrentSignatureAsTxt(TempSOASetup.GetEmailSignatureAsTxt()); + EmailTemplatePage.SetCurrentSignatureAsTxt(Rec.GetEmailSignatureAsTxt()); EmailTemplatePage.RunModal(); if EmailTemplatePage.IsValueUpdated() then begin - TempSOASetup.SetEmailSignature(EmailTemplatePage.GetNewSignatureAsTxt()); - TempSOASetup.Modify(); + Rec.SetEmailSignature(EmailTemplatePage.GetNewSignatureAsTxt()); + Rec.Modify(); IsConfigUpdated := true; end; end; var - UserSettings: Record "User Settings"; - TempAgentAccessControl: Record "Agent Access Control" temporary; + AgentSetupBuffer: Record "Agent Setup Buffer"; TempEmailAccount: Record "Email Account" temporary; - TempSOASetup: Record "SOA Setup" temporary; AzureOpenAI: Codeunit "Azure OpenAI"; + AgentSetup: Codeunit "Agent Setup"; MailboxName, MailboxFolder : Text; + InitialState: Option; LastSync: Text; - BadgeTxt: Text[4]; - AgentType: Text; - AgentSummary: Text; ShowLastSync: Boolean; - IsConfigUpdated: Boolean; - AccessUpdated: Boolean; - UserSettingsUpdated: Boolean; FirstConfig: Boolean; MailTemplateEditable: Boolean; CreateOrderFromQuoteActive: Boolean; OnlyAvailableItemsActive: Boolean; MailboxChanged: Boolean; DailyEmailLimit: Integer; - ConfiguredBy: Text; - InitialState: Option Enabled,Disabled; LearnMoreTxt: Label 'Learn more'; LearnMoreBillingDocumentationLinkTxt: Label 'https://go.microsoft.com/fwlink/?linkid=2333517'; ManageUserAccessLbl: Label 'Manage user access'; DailyEmailLimitErr: Label 'The daily email limit must be greater than zero.'; EmailSignatureModifyLbl: Label 'Edit signature'; - SelectedLanguageTxt: Text; + ConfiguredBy: Text[80]; + AgentSummaryTxt: Text; OptionalMailboxLbl: Label '(optional)'; + IsConfigUpdated: Boolean; + AgentSetupPartVisible: Boolean; } \ No newline at end of file diff --git a/Apps/W1/SalesOrderAgent/app/src/Setup/SOASetup.Table.al b/Apps/W1/SalesOrderAgent/app/src/Setup/SOASetup.Table.al index 630b23b52d..6b28a52d72 100644 --- a/Apps/W1/SalesOrderAgent/app/src/Setup/SOASetup.Table.al +++ b/Apps/W1/SalesOrderAgent/app/src/Setup/SOASetup.Table.al @@ -25,9 +25,19 @@ table 4325 "SOA Setup" DataClassification = SystemMetadata; AutoIncrement = true; } +#if not CLEANSCHEMA28 field(2; "Agent User Security ID"; Guid) { DataClassification = SystemMetadata; + ObsoleteReason = 'Replaced by "User Security ID" field.'; +#if not CLEAN28 + ObsoleteState = Pending; + ObsoleteTag = '28.0'; +#else + ObsoleteState = Removed; + ObsoleteTag = '31.0'; +#endif +#endif } field(3; "Email Account ID"; Guid) { @@ -49,7 +59,7 @@ table 4325 "SOA Setup" { Caption = 'Exists'; FieldClass = FlowField; - CalcFormula = exist(Agent where("User Security ID" = field("Agent User Security Id"))); + CalcFormula = exist(Agent where("User Security ID" = field("User Security ID"))); } field(8; State; Option) { @@ -58,7 +68,7 @@ table 4325 "SOA Setup" OptionCaption = 'Enabled,Disabled'; OptionMembers = Enabled,Disabled; FieldClass = FlowField; - CalcFormula = lookup(Agent.State where("User Security ID" = field("Agent User Security Id"))); + CalcFormula = lookup(Agent.State where("User Security ID" = field("User Security ID"))); } field(9; "Agent Scheduled Task ID"; Guid) { @@ -189,6 +199,10 @@ table 4325 "SOA Setup" Caption = 'Email Folder Id'; ToolTip = 'Specifies the unique identifier of the email folder that the agent monitors.'; } + field(50; "User Security ID"; Guid) + { + DataClassification = SystemMetadata; + } } keys @@ -197,7 +211,14 @@ table 4325 "SOA Setup" { Clustered = true; } +#if not CLEAN28 +#pragma warning disable AL0432 key(Key2; "Agent User Security ID") +#pragma warning restore AL0432 + { + } +#endif + key(Key3; "User Security ID") { } } @@ -207,7 +228,7 @@ table 4325 "SOA Setup" NotFoundErr: Label 'Sales Order Agent Setup not found.'; begin Rec.Reset(); - Rec.SetRange("Agent User Security ID", AgentUserSecurityID); + Rec.SetRange("User Security ID", AgentUserSecurityID); if Rec.FindFirst() then exit(true); diff --git a/Apps/W1/SalesOrderAgent/app/src/Validation/SOASessionEvents.Codeunit.al b/Apps/W1/SalesOrderAgent/app/src/Validation/SOASessionEvents.Codeunit.al index 29b93026aa..23e1d035fb 100644 --- a/Apps/W1/SalesOrderAgent/app/src/Validation/SOASessionEvents.Codeunit.al +++ b/Apps/W1/SalesOrderAgent/app/src/Validation/SOASessionEvents.Codeunit.al @@ -51,6 +51,9 @@ codeunit 4304 "SOA Session Events" if GlobalSOAKPITrackAll.IsOrderTakerAgentSession(AgentTaskID) then exit; + if GlobalSOAAwarenessNotifications.IsBindingNeeded() then + if BindSubscription(GlobalSOAAwarenessNotifications) then; + // Cover a case when a regular session is updating the work Agent did, if there is any work to track TrackChanges := GlobalSOAKPITrackAll.TrackChanges(); if not TrackChanges then @@ -117,6 +120,7 @@ codeunit 4304 "SOA Session Events" GlobalSOAKPITrackAgents: Codeunit "SOA - KPI Track Agents"; GlobalSOAKPITrackAll: Codeunit "SOA - KPI Track All"; GlobalSOAUserNotifications: Codeunit "SOA User Notifications"; + GlobalSOAAwarenessNotifications: Codeunit "SOA Awareness Notifications"; FeatureTelemetry: Codeunit "Feature Telemetry"; ContactFilteringDisabledAgentTxt: Label 'Contact and customer filtering is disabled for this agent through an event.', Locked = true; FailedToBindUserKPISubscriptionErr: Label 'Failed to bind subscription for User Agent KPI changes.', Locked = true; diff --git a/Apps/W1/SmartList/.objidconfig b/Apps/W1/SmartList/app/.objidconfig similarity index 100% rename from Apps/W1/SmartList/.objidconfig rename to Apps/W1/SmartList/app/.objidconfig diff --git a/Apps/W1/SmartList/ExtensionLogo.png b/Apps/W1/SmartList/app/ExtensionLogo.png similarity index 100% rename from Apps/W1/SmartList/ExtensionLogo.png rename to Apps/W1/SmartList/app/ExtensionLogo.png diff --git a/Apps/W1/SmartList/app.json b/Apps/W1/SmartList/app/app.json similarity index 100% rename from Apps/W1/SmartList/app.json rename to Apps/W1/SmartList/app/app.json diff --git a/Apps/W1/SmartList/src/CodeUnits/SmartListInstall.Codeunit.al b/Apps/W1/SmartList/app/src/CodeUnits/SmartListInstall.Codeunit.al similarity index 100% rename from Apps/W1/SmartList/src/CodeUnits/SmartListInstall.Codeunit.al rename to Apps/W1/SmartList/app/src/CodeUnits/SmartListInstall.Codeunit.al diff --git a/Apps/W1/SmartList/src/CodeUnits/SmartListUpgrade.Codeunit.al b/Apps/W1/SmartList/app/src/CodeUnits/SmartListUpgrade.Codeunit.al similarity index 100% rename from Apps/W1/SmartList/src/CodeUnits/SmartListUpgrade.Codeunit.al rename to Apps/W1/SmartList/app/src/CodeUnits/SmartListUpgrade.Codeunit.al diff --git a/Apps/W1/SmartList/src/Queries/AccountSummary.Query.al b/Apps/W1/SmartList/app/src/Queries/AccountSummary.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/AccountSummary.Query.al rename to Apps/W1/SmartList/app/src/Queries/AccountSummary.Query.al diff --git a/Apps/W1/SmartList/src/Queries/BankAcctLedgerEntries.Query.al b/Apps/W1/SmartList/app/src/Queries/BankAcctLedgerEntries.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/BankAcctLedgerEntries.Query.al rename to Apps/W1/SmartList/app/src/Queries/BankAcctLedgerEntries.Query.al diff --git a/Apps/W1/SmartList/src/Queries/BlanketPurchaseOrderLines.Query.al b/Apps/W1/SmartList/app/src/Queries/BlanketPurchaseOrderLines.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/BlanketPurchaseOrderLines.Query.al rename to Apps/W1/SmartList/app/src/Queries/BlanketPurchaseOrderLines.Query.al diff --git a/Apps/W1/SmartList/src/Queries/BlanketPurchaseOrders.Query.al b/Apps/W1/SmartList/app/src/Queries/BlanketPurchaseOrders.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/BlanketPurchaseOrders.Query.al rename to Apps/W1/SmartList/app/src/Queries/BlanketPurchaseOrders.Query.al diff --git a/Apps/W1/SmartList/src/Queries/BlockedCustomers.Query.al b/Apps/W1/SmartList/app/src/Queries/BlockedCustomers.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/BlockedCustomers.Query.al rename to Apps/W1/SmartList/app/src/Queries/BlockedCustomers.Query.al diff --git a/Apps/W1/SmartList/src/Queries/BlockedVendors.Query.al b/Apps/W1/SmartList/app/src/Queries/BlockedVendors.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/BlockedVendors.Query.al rename to Apps/W1/SmartList/app/src/Queries/BlockedVendors.Query.al diff --git a/Apps/W1/SmartList/src/Queries/CustomerAndContact.Query.al b/Apps/W1/SmartList/app/src/Queries/CustomerAndContact.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/CustomerAndContact.Query.al rename to Apps/W1/SmartList/app/src/Queries/CustomerAndContact.Query.al diff --git a/Apps/W1/SmartList/src/Queries/CustomerAndSalesperson.Query.al b/Apps/W1/SmartList/app/src/Queries/CustomerAndSalesperson.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/CustomerAndSalesperson.Query.al rename to Apps/W1/SmartList/app/src/Queries/CustomerAndSalesperson.Query.al diff --git a/Apps/W1/SmartList/src/Queries/CustomerShipToAddresses.Query.al b/Apps/W1/SmartList/app/src/Queries/CustomerShipToAddresses.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/CustomerShipToAddresses.Query.al rename to Apps/W1/SmartList/app/src/Queries/CustomerShipToAddresses.Query.al diff --git a/Apps/W1/SmartList/src/Queries/CustomersWithCreditLimit.Query.al b/Apps/W1/SmartList/app/src/Queries/CustomersWithCreditLimit.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/CustomersWithCreditLimit.Query.al rename to Apps/W1/SmartList/app/src/Queries/CustomersWithCreditLimit.Query.al diff --git a/Apps/W1/SmartList/src/Queries/GLEntrieswithDimensions.Query.al b/Apps/W1/SmartList/app/src/Queries/GLEntrieswithDimensions.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/GLEntrieswithDimensions.Query.al rename to Apps/W1/SmartList/app/src/Queries/GLEntrieswithDimensions.Query.al diff --git a/Apps/W1/SmartList/src/Queries/GeneralLedgerEntries.Query.al b/Apps/W1/SmartList/app/src/Queries/GeneralLedgerEntries.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/GeneralLedgerEntries.Query.al rename to Apps/W1/SmartList/app/src/Queries/GeneralLedgerEntries.Query.al diff --git a/Apps/W1/SmartList/src/Queries/ItemPurchaseReceipts.Query.al b/Apps/W1/SmartList/app/src/Queries/ItemPurchaseReceipts.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/ItemPurchaseReceipts.Query.al rename to Apps/W1/SmartList/app/src/Queries/ItemPurchaseReceipts.Query.al diff --git a/Apps/W1/SmartList/src/Queries/ItemQuantities.Query.al b/Apps/W1/SmartList/app/src/Queries/ItemQuantities.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/ItemQuantities.Query.al rename to Apps/W1/SmartList/app/src/Queries/ItemQuantities.Query.al diff --git a/Apps/W1/SmartList/src/Queries/Items.Query.al b/Apps/W1/SmartList/app/src/Queries/Items.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/Items.Query.al rename to Apps/W1/SmartList/app/src/Queries/Items.Query.al diff --git a/Apps/W1/SmartList/src/Queries/ItemsByLocation.Query.al b/Apps/W1/SmartList/app/src/Queries/ItemsByLocation.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/ItemsByLocation.Query.al rename to Apps/W1/SmartList/app/src/Queries/ItemsByLocation.Query.al diff --git a/Apps/W1/SmartList/src/Queries/ItemsDueForCount.Query.al b/Apps/W1/SmartList/app/src/Queries/ItemsDueForCount.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/ItemsDueForCount.Query.al rename to Apps/W1/SmartList/app/src/Queries/ItemsDueForCount.Query.al diff --git a/Apps/W1/SmartList/src/Queries/ItemsOverdueForCount.Query.al b/Apps/W1/SmartList/app/src/Queries/ItemsOverdueForCount.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/ItemsOverdueForCount.Query.al rename to Apps/W1/SmartList/app/src/Queries/ItemsOverdueForCount.Query.al diff --git a/Apps/W1/SmartList/src/Queries/NegativeQuantityItems.Query.al b/Apps/W1/SmartList/app/src/Queries/NegativeQuantityItems.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/NegativeQuantityItems.Query.al rename to Apps/W1/SmartList/app/src/Queries/NegativeQuantityItems.Query.al diff --git a/Apps/W1/SmartList/src/Queries/PostedSalesCMemoLineItem.Query.al b/Apps/W1/SmartList/app/src/Queries/PostedSalesCMemoLineItem.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/PostedSalesCMemoLineItem.Query.al rename to Apps/W1/SmartList/app/src/Queries/PostedSalesCMemoLineItem.Query.al diff --git a/Apps/W1/SmartList/src/Queries/PostedSalesCreditMemos.Query.al b/Apps/W1/SmartList/app/src/Queries/PostedSalesCreditMemos.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/PostedSalesCreditMemos.Query.al rename to Apps/W1/SmartList/app/src/Queries/PostedSalesCreditMemos.Query.al diff --git a/Apps/W1/SmartList/src/Queries/PostedSalesILineItem.Query.al b/Apps/W1/SmartList/app/src/Queries/PostedSalesILineItem.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/PostedSalesILineItem.Query.al rename to Apps/W1/SmartList/app/src/Queries/PostedSalesILineItem.Query.al diff --git a/Apps/W1/SmartList/src/Queries/PostedSalesInvoices.Query.al b/Apps/W1/SmartList/app/src/Queries/PostedSalesInvoices.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/PostedSalesInvoices.Query.al rename to Apps/W1/SmartList/app/src/Queries/PostedSalesInvoices.Query.al diff --git a/Apps/W1/SmartList/src/Queries/PurchaseOrderLineItems.Query.al b/Apps/W1/SmartList/app/src/Queries/PurchaseOrderLineItems.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/PurchaseOrderLineItems.Query.al rename to Apps/W1/SmartList/app/src/Queries/PurchaseOrderLineItems.Query.al diff --git a/Apps/W1/SmartList/src/Queries/PurchaseOrders.Query.al b/Apps/W1/SmartList/app/src/Queries/PurchaseOrders.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/PurchaseOrders.Query.al rename to Apps/W1/SmartList/app/src/Queries/PurchaseOrders.Query.al diff --git a/Apps/W1/SmartList/src/Queries/PurchasingCrMemoLineItems.Query.al b/Apps/W1/SmartList/app/src/Queries/PurchasingCrMemoLineItems.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/PurchasingCrMemoLineItems.Query.al rename to Apps/W1/SmartList/app/src/Queries/PurchasingCrMemoLineItems.Query.al diff --git a/Apps/W1/SmartList/src/Queries/PurchasingInvLineItems.Query.al b/Apps/W1/SmartList/app/src/Queries/PurchasingInvLineItems.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/PurchasingInvLineItems.Query.al rename to Apps/W1/SmartList/app/src/Queries/PurchasingInvLineItems.Query.al diff --git a/Apps/W1/SmartList/src/Queries/PurchasingRcptLineItems.Query.al b/Apps/W1/SmartList/app/src/Queries/PurchasingRcptLineItems.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/PurchasingRcptLineItems.Query.al rename to Apps/W1/SmartList/app/src/Queries/PurchasingRcptLineItems.Query.al diff --git a/Apps/W1/SmartList/src/Queries/PurchasingTrxCrdtMemos.Query.al b/Apps/W1/SmartList/app/src/Queries/PurchasingTrxCrdtMemos.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/PurchasingTrxCrdtMemos.Query.al rename to Apps/W1/SmartList/app/src/Queries/PurchasingTrxCrdtMemos.Query.al diff --git a/Apps/W1/SmartList/src/Queries/PurchasingTrxInvoices.Query.al b/Apps/W1/SmartList/app/src/Queries/PurchasingTrxInvoices.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/PurchasingTrxInvoices.Query.al rename to Apps/W1/SmartList/app/src/Queries/PurchasingTrxInvoices.Query.al diff --git a/Apps/W1/SmartList/src/Queries/UnpostedSalesLineBlktOrdr.Query.al b/Apps/W1/SmartList/app/src/Queries/UnpostedSalesLineBlktOrdr.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/UnpostedSalesLineBlktOrdr.Query.al rename to Apps/W1/SmartList/app/src/Queries/UnpostedSalesLineBlktOrdr.Query.al diff --git a/Apps/W1/SmartList/src/Queries/UnpostedSalesLineCrdtMemo.Query.al b/Apps/W1/SmartList/app/src/Queries/UnpostedSalesLineCrdtMemo.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/UnpostedSalesLineCrdtMemo.Query.al rename to Apps/W1/SmartList/app/src/Queries/UnpostedSalesLineCrdtMemo.Query.al diff --git a/Apps/W1/SmartList/src/Queries/UnpostedSalesLineInvoices.Query.al b/Apps/W1/SmartList/app/src/Queries/UnpostedSalesLineInvoices.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/UnpostedSalesLineInvoices.Query.al rename to Apps/W1/SmartList/app/src/Queries/UnpostedSalesLineInvoices.Query.al diff --git a/Apps/W1/SmartList/src/Queries/UnpostedSalesLineOrders.Query.al b/Apps/W1/SmartList/app/src/Queries/UnpostedSalesLineOrders.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/UnpostedSalesLineOrders.Query.al rename to Apps/W1/SmartList/app/src/Queries/UnpostedSalesLineOrders.Query.al diff --git a/Apps/W1/SmartList/src/Queries/UnpostedSalesLineQuotes.Query.al b/Apps/W1/SmartList/app/src/Queries/UnpostedSalesLineQuotes.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/UnpostedSalesLineQuotes.Query.al rename to Apps/W1/SmartList/app/src/Queries/UnpostedSalesLineQuotes.Query.al diff --git a/Apps/W1/SmartList/src/Queries/UnpostedSalesLineReturns.Query.al b/Apps/W1/SmartList/app/src/Queries/UnpostedSalesLineReturns.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/UnpostedSalesLineReturns.Query.al rename to Apps/W1/SmartList/app/src/Queries/UnpostedSalesLineReturns.Query.al diff --git a/Apps/W1/SmartList/src/Queries/UnpostedSalesTrxBlnktOrdr.Query.al b/Apps/W1/SmartList/app/src/Queries/UnpostedSalesTrxBlnktOrdr.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/UnpostedSalesTrxBlnktOrdr.Query.al rename to Apps/W1/SmartList/app/src/Queries/UnpostedSalesTrxBlnktOrdr.Query.al diff --git a/Apps/W1/SmartList/src/Queries/UnpostedSalesTrxCreditMemo.Query.al b/Apps/W1/SmartList/app/src/Queries/UnpostedSalesTrxCreditMemo.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/UnpostedSalesTrxCreditMemo.Query.al rename to Apps/W1/SmartList/app/src/Queries/UnpostedSalesTrxCreditMemo.Query.al diff --git a/Apps/W1/SmartList/src/Queries/UnpostedSalesTrxInvoices.Query.al b/Apps/W1/SmartList/app/src/Queries/UnpostedSalesTrxInvoices.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/UnpostedSalesTrxInvoices.Query.al rename to Apps/W1/SmartList/app/src/Queries/UnpostedSalesTrxInvoices.Query.al diff --git a/Apps/W1/SmartList/src/Queries/UnpostedSalesTrxOrders.Query.al b/Apps/W1/SmartList/app/src/Queries/UnpostedSalesTrxOrders.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/UnpostedSalesTrxOrders.Query.al rename to Apps/W1/SmartList/app/src/Queries/UnpostedSalesTrxOrders.Query.al diff --git a/Apps/W1/SmartList/src/Queries/UnpostedSalesTrxQuotes.Query.al b/Apps/W1/SmartList/app/src/Queries/UnpostedSalesTrxQuotes.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/UnpostedSalesTrxQuotes.Query.al rename to Apps/W1/SmartList/app/src/Queries/UnpostedSalesTrxQuotes.Query.al diff --git a/Apps/W1/SmartList/src/Queries/UnpostedSalesTrxReturns.Query.al b/Apps/W1/SmartList/app/src/Queries/UnpostedSalesTrxReturns.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/UnpostedSalesTrxReturns.Query.al rename to Apps/W1/SmartList/app/src/Queries/UnpostedSalesTrxReturns.Query.al diff --git a/Apps/W1/SmartList/src/Queries/VendorAndPurchaser.Query.al b/Apps/W1/SmartList/app/src/Queries/VendorAndPurchaser.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/VendorAndPurchaser.Query.al rename to Apps/W1/SmartList/app/src/Queries/VendorAndPurchaser.Query.al diff --git a/Apps/W1/SmartList/src/Queries/VendorBalance.Query.al b/Apps/W1/SmartList/app/src/Queries/VendorBalance.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/VendorBalance.Query.al rename to Apps/W1/SmartList/app/src/Queries/VendorBalance.Query.al diff --git a/Apps/W1/SmartList/src/Queries/VendorOrderAddresses.Query.al b/Apps/W1/SmartList/app/src/Queries/VendorOrderAddresses.Query.al similarity index 100% rename from Apps/W1/SmartList/src/Queries/VendorOrderAddresses.Query.al rename to Apps/W1/SmartList/app/src/Queries/VendorOrderAddresses.Query.al diff --git a/Apps/W1/Sustainability/app/src/Journal/SustainabilityJnlLine.Table.al b/Apps/W1/Sustainability/app/src/Journal/SustainabilityJnlLine.Table.al index 07e362c9d1..1ec3f4a789 100644 --- a/Apps/W1/Sustainability/app/src/Journal/SustainabilityJnlLine.Table.al +++ b/Apps/W1/Sustainability/app/src/Journal/SustainabilityJnlLine.Table.al @@ -410,6 +410,10 @@ table 6214 "Sustainability Jnl. Line" { Caption = 'Renewable Energy'; } + field(5817; Correction; Boolean) + { + Caption = 'Correction'; + } } keys diff --git a/Apps/W1/Sustainability/app/src/Ledger/SustainabilityLedgerEntry.Table.al b/Apps/W1/Sustainability/app/src/Ledger/SustainabilityLedgerEntry.Table.al index 61014c2766..7d55707fc3 100644 --- a/Apps/W1/Sustainability/app/src/Ledger/SustainabilityLedgerEntry.Table.al +++ b/Apps/W1/Sustainability/app/src/Ledger/SustainabilityLedgerEntry.Table.al @@ -328,6 +328,10 @@ table 6216 "Sustainability Ledger Entry" DataClassification = EndUserIdentifiableInformation; ValidateTableRelation = false; } + field(5817; Correction; Boolean) + { + Caption = 'Correction'; + } } keys diff --git a/Apps/W1/Sustainability/app/src/Ledger/SustainabilityValueEntry.Table.al b/Apps/W1/Sustainability/app/src/Ledger/SustainabilityValueEntry.Table.al index 3cfe6d1e14..bbbc1abc69 100644 --- a/Apps/W1/Sustainability/app/src/Ledger/SustainabilityValueEntry.Table.al +++ b/Apps/W1/Sustainability/app/src/Ledger/SustainabilityValueEntry.Table.al @@ -11,6 +11,7 @@ using Microsoft.Manufacturing.MachineCenter; using Microsoft.Manufacturing.WorkCenter; using Microsoft.Projects.Project.Job; using Microsoft.Projects.Project.Ledger; +using Microsoft.Projects.Resources.Ledger; using Microsoft.Projects.Resources.Resource; using Microsoft.Sustainability.Account; using Microsoft.Sustainability.Journal; @@ -332,6 +333,34 @@ table 6227 "Sustainability Value Entry" end; end; + procedure CopyFromResourceLedgerEntry(ResourceLedgerEntry: Record "Res. Ledger Entry") + begin + "Posting Date" := ResourceLedgerEntry."Posting Date"; + "Document No." := ResourceLedgerEntry."Document No."; + + if ResourceLedgerEntry."Entry Type" = ResourceLedgerEntry."Entry Type"::Usage then begin + "Valued Quantity" := -ResourceLedgerEntry.Quantity; + "Invoiced Quantity" := -ResourceLedgerEntry.Quantity; + end else begin + "Valued Quantity" := ResourceLedgerEntry.Quantity; + "Invoiced Quantity" := ResourceLedgerEntry.Quantity; + end; + + "User ID" := ResourceLedgerEntry."User ID"; + "Source Code" := ResourceLedgerEntry."Source Code"; + "Global Dimension 1 Code" := ResourceLedgerEntry."Global Dimension 1 Code"; + "Global Dimension 2 Code" := ResourceLedgerEntry."Global Dimension 2 Code"; + "Journal Batch Name" := ResourceLedgerEntry."Journal Batch Name"; + "Document Date" := ResourceLedgerEntry."Document Date"; + "External Document No." := ResourceLedgerEntry."External Document No."; + "Document Line No." := ResourceLedgerEntry."Order Line No."; + "Entry Type" := "Entry Type"::"Direct Cost"; + "Dimension Set ID" := ResourceLedgerEntry."Dimension Set ID"; + Type := Type::Resource; + "No." := ResourceLedgerEntry."Resource No."; + "Item Ledger Entry Type" := "Item Ledger Entry Type"::" "; + end; + procedure CopyFromJobLedgerEntry(JobLedgerEntry: Record "Job Ledger Entry") begin "No." := JobLedgerEntry."No."; diff --git a/Apps/W1/Sustainability/app/src/Posting/SustItemPostSubscriber.Codeunit.al b/Apps/W1/Sustainability/app/src/Posting/SustItemPostSubscriber.Codeunit.al index 312f4b59aa..fd5845ec8a 100644 --- a/Apps/W1/Sustainability/app/src/Posting/SustItemPostSubscriber.Codeunit.al +++ b/Apps/W1/Sustainability/app/src/Posting/SustItemPostSubscriber.Codeunit.al @@ -24,6 +24,13 @@ codeunit 6256 "Sust. Item Post Subscriber" PostSustainabilityValueEntry(ItemJnlLine, ValueEntry, ItemLedgerEntry); end; + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Item Jnl.-Post Line", 'OnAfterInsertCorrValueEntry', '', false, false)] + local procedure OnAfterInsertCorrValueEntry(ItemJournalLine: Record "Item Journal Line"; var NewValueEntry: Record "Value Entry"; var ItemLedgerEntry: Record "Item Ledger Entry") + begin + if CanCreateSustValueEntry(ItemJournalLine, NewValueEntry) then + PostSustainabilityValueEntry(ItemJournalLine, NewValueEntry, ItemLedgerEntry); + end; + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Item Jnl.-Post Line", 'OnBeforeInsertItemLedgEntry', '', false, false)] local procedure OnBeforeInsertItemLedgEntry(ItemJournalLine: Record "Item Journal Line"; var ItemLedgerEntry: Record "Item Ledger Entry") begin @@ -78,6 +85,7 @@ codeunit 6256 "Sust. Item Post Subscriber" SustainabilityJnlLine.Validate("Emission CO2", ItemJournalLine."Emission CO2"); SustainabilityJnlLine.Validate("Emission CH4", ItemJournalLine."Emission CH4"); SustainabilityJnlLine.Validate("Emission N2O", ItemJournalLine."Emission N2O"); + SustainabilityJnlLine.Validate(Correction, ItemJournalLine.Correction); SustainabilityJnlLine.Validate("Country/Region Code", ItemJournalLine."Country/Region Code"); SustainabilityPostMgt.InsertValueEntry(SustainabilityJnlLine, ValueEntry, ItemLedgerEntry); end; diff --git a/Apps/W1/Sustainability/app/src/Posting/SustResourcePostSubscriber.Codeunit.al b/Apps/W1/Sustainability/app/src/Posting/SustResourcePostSubscriber.Codeunit.al new file mode 100644 index 0000000000..77d217be4d --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Posting/SustResourcePostSubscriber.Codeunit.al @@ -0,0 +1,55 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Posting; + +using Microsoft.Projects.Resources.Journal; +using Microsoft.Projects.Resources.Ledger; +using Microsoft.Sustainability.Journal; +using Microsoft.Sustainability.Setup; + +codeunit 6286 "Sust. Resource Post Subscriber" +{ + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Res. Jnl.-Post Line", 'OnAfterResLedgEntryInsert', '', false, false)] + local procedure OnAfterResLedgEntryInsert(ResJournalLine: Record "Res. Journal Line"; var ResLedgerEntry: Record "Res. Ledger Entry") + begin + if CanCreateSustValueEntry(ResJournalLine) then + PostSustainabilityValueEntry(ResJournalLine, ResLedgerEntry); + end; + + local procedure CanCreateSustValueEntry(ResJournalLine: Record "Res. Journal Line"): Boolean + begin + if not SustainabilitySetup.IsValueChainTrackingEnabled() then + exit(false); + + exit(ResJournalLine."Sust. Account No." <> ''); + end; + + local procedure PostSustainabilityValueEntry(var ResJournalLine: Record "Res. Journal Line"; var ResLedgerEntry: Record "Res. Ledger Entry") + var + SustainabilityJnlLine: Record "Sustainability Jnl. Line"; + SustainabilityPostMgt: Codeunit "Sustainability Post Mgt"; + begin + SustainabilityJnlLine.Init(); + SustainabilityJnlLine."Journal Template Name" := ''; + SustainabilityJnlLine."Journal Batch Name" := ''; + SustainabilityJnlLine."Source Code" := ResJournalLine."Source Code"; + SustainabilityJnlLine.Validate("Posting Date", ResJournalLine."Posting Date"); + SustainabilityJnlLine.Validate("Document No.", ResJournalLine."Document No."); + SustainabilityJnlLine.Validate("Account No.", ResJournalLine."Sust. Account No."); + SustainabilityJnlLine.Validate("Reason Code", ResJournalLine."Reason Code"); + SustainabilityJnlLine.Validate("Account Category", ResJournalLine."Sust. Account Category"); + SustainabilityJnlLine.Validate("Account Subcategory", ResJournalLine."Sust. Account Subcategory"); + SustainabilityJnlLine.Validate("Unit of Measure", SustainabilitySetup."Emission Unit of Measure Code"); + SustainabilityJnlLine."Dimension Set ID" := ResLedgerEntry."Dimension Set ID"; + SustainabilityJnlLine."Shortcut Dimension 1 Code" := ResLedgerEntry."Global Dimension 1 Code"; + SustainabilityJnlLine."Shortcut Dimension 2 Code" := ResLedgerEntry."Global Dimension 2 Code"; + SustainabilityJnlLine.Validate("CO2e Emission", ResJournalLine."Total CO2e"); + SustainabilityPostMgt.InsertValueEntry(SustainabilityJnlLine, ResLedgerEntry); + end; + + var + SustainabilitySetup: Record "Sustainability Setup"; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Posting/SustainabilityPostMgt.Codeunit.al b/Apps/W1/Sustainability/app/src/Posting/SustainabilityPostMgt.Codeunit.al index e5eaf45e86..237862b5a4 100644 --- a/Apps/W1/Sustainability/app/src/Posting/SustainabilityPostMgt.Codeunit.al +++ b/Apps/W1/Sustainability/app/src/Posting/SustainabilityPostMgt.Codeunit.al @@ -3,6 +3,7 @@ namespace Microsoft.Sustainability.Posting; using Microsoft.Inventory.Item; using Microsoft.Inventory.Ledger; using Microsoft.Projects.Project.Ledger; +using Microsoft.Projects.Resources.Ledger; using Microsoft.Sustainability.Account; using Microsoft.Sustainability.Emission; using Microsoft.Sustainability.Journal; @@ -87,6 +88,9 @@ codeunit 6212 "Sustainability Post Mgt" SustainabilityValueEntry."CO2e Amount (Expected)", ItemLedgerEntry.Quantity = ItemLedgerEntry."Invoiced Quantity"); + if (SustainabilityJnlLine.Correction) and (not SustainabilityValueEntry."Expected Emission") then + SustainabilityValueEntry.Validate("CO2e Amount (Actual)", -SustainabilityValueEntry."CO2e Amount (Expected)"); + SustainabilityValueEntry.Insert(true); UpdateCO2ePerUnit(SustainabilityValueEntry); @@ -113,6 +117,27 @@ codeunit 6212 "Sustainability Post Mgt" UpdateCO2ePerUnit(SustainabilityValueEntry); end; + procedure InsertValueEntry(SustainabilityJnlLine: Record "Sustainability Jnl. Line"; ResourceLedgerEntry: Record "Res. Ledger Entry") + var + SustainabilityValueEntry: Record "Sustainability Value Entry"; + FeatureTelemetry: Codeunit "Feature Telemetry"; + begin + SustainabilityValueEntry.Init(); + FeatureTelemetry.LogUsage('0000QOZ', SustainabilityLbl, SustainabilityValueEntryAddedLbl); + FeatureTelemetry.LogUptake('0000QOY', SustainabilityLbl, Enum::"Feature Uptake Status"::"Used"); + + SustainabilityValueEntry."Entry No." := SustainabilityValueEntry.GetLastEntryNo() + 1; + SustainabilityValueEntry.CopyFromResourceLedgerEntry(ResourceLedgerEntry); + SustainabilityValueEntry.CopyFromSustainabilityJnlLine(SustainabilityJnlLine); + SustainabilityValueEntry.Validate("User ID", CopyStr(UserId(), 1, 50)); + + SkipUpdateCarbonEmissionValue := true; + UpdateCarbonFeeEmissionForValueEntry(SustainabilityValueEntry, SustainabilityJnlLine); + SustainabilityValueEntry.Insert(true); + + UpdateCO2ePerUnit(SustainabilityValueEntry); + end; + procedure UpdateCO2ePerUnit(SustValueEntry: Record "Sustainability Value Entry") var Item: Record Item; diff --git a/Apps/W1/Sustainability/app/src/Service/SustPstdServCrMemoSub.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustPstdServCrMemoSub.PageExt.al new file mode 100644 index 0000000000..d7b7e9ac77 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustPstdServCrMemoSub.PageExt.al @@ -0,0 +1,49 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.History; +using Microsoft.Sustainability.Setup; + +pageextension 6300 "Sust. Pstd Serv. Cr. Memo. Sub" extends "Posted Service Cr. Memo Lines" +{ + layout + { + addafter(Description) + { + field("Sust. Account No."; Rec."Sust. Account No.") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Sustainability Account No. field.'; + } + } + addafter("Line Discount Amount") + { + field("Total CO2e"; Rec."Total CO2e") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Total CO2e field.'; + } + } + } + + trigger OnOpenPage() + begin + VisibleSustainabilityControls(); + end; + + local procedure VisibleSustainabilityControls() + begin + SustainabilitySetup.GetRecordOnce(); + + SustainabilityVisible := SustainabilitySetup."Enable Value Chain Tracking"; + end; + + var + SustainabilitySetup: Record "Sustainability Setup"; + SustainabilityVisible: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustPstdServCrSubfm.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustPstdServCrSubfm.PageExt.al new file mode 100644 index 0000000000..89d9649ed8 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustPstdServCrSubfm.PageExt.al @@ -0,0 +1,49 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.History; +using Microsoft.Sustainability.Setup; + +pageextension 6313 "Sust. Pstd. Serv. Cr. Subfm." extends "Posted Serv. Cr. Memo Subform" +{ + layout + { + addafter("Bin Code") + { + field("Sust. Account No."; Rec."Sust. Account No.") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Sustainability Account No. field.'; + } + } + addafter("Line Discount Amount") + { + field("Total CO2e"; Rec."Total CO2e") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Total CO2e field.'; + } + } + } + + trigger OnOpenPage() + begin + VisibleSustainabilityControls(); + end; + + local procedure VisibleSustainabilityControls() + begin + SustainabilitySetup.GetRecordOnce(); + + SustainabilityVisible := SustainabilitySetup."Enable Value Chain Tracking"; + end; + + var + SustainabilitySetup: Record "Sustainability Setup"; + SustainabilityVisible: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustPstdServInvSubform.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustPstdServInvSubform.PageExt.al new file mode 100644 index 0000000000..80af87454a --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustPstdServInvSubform.PageExt.al @@ -0,0 +1,49 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.History; +using Microsoft.Sustainability.Setup; + +pageextension 6301 "Sust. Pstd Serv. Inv. Subform" extends "Posted Service Invoice Subform" +{ + layout + { + addafter(Description) + { + field("Sust. Account No."; Rec."Sust. Account No.") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Sustainability Account No. field.'; + } + } + addafter("Line Discount Amount") + { + field("Total CO2e"; Rec."Total CO2e") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Total CO2e field.'; + } + } + } + + trigger OnOpenPage() + begin + VisibleSustainabilityControls(); + end; + + local procedure VisibleSustainabilityControls() + begin + SustainabilitySetup.GetRecordOnce(); + + SustainabilityVisible := SustainabilitySetup."Enable Value Chain Tracking"; + end; + + var + SustainabilitySetup: Record "Sustainability Setup"; + SustainabilityVisible: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustPstdServShptSubfm.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustPstdServShptSubfm.PageExt.al new file mode 100644 index 0000000000..4b9491a87c --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustPstdServShptSubfm.PageExt.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.Sustainability.Service; + +using Microsoft.Service.History; +using Microsoft.Sustainability.Setup; + +pageextension 6311 "Sust. Pstd. Serv. Shpt. Subfm." extends "Posted Service Shpt. Subform" +{ + layout + { + addafter("Resolution Code") + { + field("Total CO2e"; Rec."Total CO2e") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Total CO2e field.'; + } + } + } + + trigger OnOpenPage() + begin + VisibleSustainabilityControls(); + end; + + local procedure VisibleSustainabilityControls() + begin + SustainabilitySetup.GetRecordOnce(); + + SustainabilityVisible := SustainabilitySetup."Enable Value Chain Tracking"; + end; + + var + SustainabilitySetup: Record "Sustainability Setup"; + SustainabilityVisible: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustResourceJournalLine.TableExt.al b/Apps/W1/Sustainability/app/src/Service/SustResourceJournalLine.TableExt.al new file mode 100644 index 0000000000..42f6322669 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustResourceJournalLine.TableExt.al @@ -0,0 +1,58 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Projects.Resources.Journal; +using Microsoft.Sustainability.Account; +using Microsoft.Sustainability.Setup; + +tableextension 6279 "Sust. Resource Journal Line" extends "Res. Journal Line" +{ + fields + { + field(6210; "Sust. Account No."; Code[20]) + { + Caption = 'Sustainability Account No.'; + TableRelation = "Sustainability Account" where("Account Type" = const(Posting), Blocked = const(false)); + DataClassification = CustomerContent; + } + field(6211; "Sust. Account Name"; Text[100]) + { + Caption = 'Sustainability Account Name'; + DataClassification = CustomerContent; + } + field(6212; "Sust. Account Category"; Code[20]) + { + Caption = 'Sustainability Account Category'; + Editable = false; + TableRelation = "Sustain. Account Category"; + DataClassification = CustomerContent; + } + field(6213; "Sust. Account Subcategory"; Code[20]) + { + Caption = 'Sustainability Account Subcategory'; + Editable = false; + TableRelation = "Sustain. Account Subcategory".Code where("Category Code" = field("Sust. Account Category")); + DataClassification = CustomerContent; + } + field(6217; "CO2e per Unit"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + Caption = 'CO2e per Unit'; + DataClassification = CustomerContent; + } + field(6218; "Total CO2e"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + Caption = 'Total CO2e'; + DataClassification = CustomerContent; + } + } + + var + SustainabilitySetup: Record "Sustainability Setup"; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServShipmentItemLine.TableExt.al b/Apps/W1/Sustainability/app/src/Service/SustServShipmentItemLine.TableExt.al new file mode 100644 index 0000000000..278b9824a8 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServShipmentItemLine.TableExt.al @@ -0,0 +1,28 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.History; +using Microsoft.Sustainability.Setup; + +tableextension 6278 "Sust. Serv. Shipment Item Line" extends "Service Shipment Item Line" +{ + fields + { + field(6210; "Total CO2e"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + CalcFormula = sum("Service Shipment Line"."Total CO2e" where("Document No." = field("No."), + "Service Item Line No." = field("Line No."))); + Caption = 'Total CO2e'; + Editable = false; + FieldClass = FlowField; + } + } + + var + SustainabilitySetup: Record "Sustainability Setup"; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoHeader.TableExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoHeader.TableExt.al new file mode 100644 index 0000000000..dadebd9afa --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoHeader.TableExt.al @@ -0,0 +1,37 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.History; +using Microsoft.Sustainability.Ledger; +using Microsoft.Sustainability.Setup; + +tableextension 6272 "Sust. Service Cr. Memo Header" extends "Service Cr.Memo Header" +{ + fields + { + field(6210; "Sustainability Lines Exist"; Boolean) + { + Caption = 'Sustainability Lines Exist'; + Editable = false; + FieldClass = FlowField; + CalcFormula = exist("Service Cr.Memo Line" where("Sust. Account No." = filter('<>'''''), "Document No." = field("No."))); + } +#pragma warning disable AA0232 + field(6211; "Total CO2e"; Decimal) +#pragma warning restore AA0232 + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + CalcFormula = sum("Sustainability Value Entry"."CO2e Amount (Actual)" where("Document No." = field("No."))); + Caption = 'Total CO2e'; + Editable = false; + FieldClass = FlowField; + } + } + + var + SustainabilitySetup: Record "Sustainability Setup"; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoLine.TableExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoLine.TableExt.al new file mode 100644 index 0000000000..cf63de5122 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoLine.TableExt.al @@ -0,0 +1,58 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.History; +using Microsoft.Sustainability.Account; +using Microsoft.Sustainability.Setup; + +tableextension 6273 "Sust. Service Cr. Memo Line" extends "Service Cr.Memo Line" +{ + fields + { + field(6210; "Sust. Account No."; Code[20]) + { + Caption = 'Sustainability Account No.'; + TableRelation = "Sustainability Account" where("Account Type" = const(Posting), Blocked = const(false)); + DataClassification = CustomerContent; + } + field(6211; "Sust. Account Name"; Text[100]) + { + Caption = 'Sustainability Account Name'; + DataClassification = CustomerContent; + } + field(6212; "Sust. Account Category"; Code[20]) + { + Caption = 'Sustainability Account Category'; + Editable = false; + TableRelation = "Sustain. Account Category"; + DataClassification = CustomerContent; + } + field(6213; "Sust. Account Subcategory"; Code[20]) + { + Caption = 'Sustainability Account Subcategory'; + Editable = false; + TableRelation = "Sustain. Account Subcategory".Code where("Category Code" = field("Sust. Account Category")); + DataClassification = CustomerContent; + } + field(6214; "CO2e per Unit"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + Caption = 'CO2e per Unit'; + DataClassification = CustomerContent; + } + field(6215; "Total CO2e"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + Caption = 'Total CO2e'; + DataClassification = CustomerContent; + } + } + + var + SustainabilitySetup: Record "Sustainability Setup"; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoStats.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoStats.PageExt.al new file mode 100644 index 0000000000..c2b3e5d04f --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoStats.PageExt.al @@ -0,0 +1,52 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.History; + +pageextension 6304 "Sust. Service Cr. Memo. Stats." extends "Service Credit Memo Statistics" +{ + layout + { + addafter(Customer) + { + group(Sustainability) + { + Visible = EnableSustainability; + Caption = 'Sustainability'; + field("Total CO2e"; Rec."Total CO2e") + { + ApplicationArea = Basic, Suite; + Caption = 'Total CO2e'; + ToolTip = 'Specifies the total CO2e emissions.'; + } + } + } + } + + trigger OnOpenPage() + begin + EnableSustainabilityControl(); + end; + + trigger OnAfterGetCurrRecord() + begin + EnableSustainabilityControl(); + end; + + trigger OnAfterGetRecord() + begin + EnableSustainabilityControl(); + end; + + local procedure EnableSustainabilityControl() + begin + Rec.CalcFields("Sustainability Lines Exist"); + EnableSustainability := Rec."Sustainability Lines Exist"; + end; + + var + EnableSustainability: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoSubform.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoSubform.PageExt.al new file mode 100644 index 0000000000..9ca1d3b77e --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceCrMemoSubform.PageExt.al @@ -0,0 +1,49 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.Document; +using Microsoft.Sustainability.Setup; + +pageextension 6302 "Sust. Service Cr. Memo Subform" extends "Service Credit Memo Subform" +{ + layout + { + addafter("Bin Code") + { + field("Sust. Account No."; Rec."Sust. Account No.") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Sustainability Account No. field.'; + } + } + addafter("Line Discount Amount") + { + field("Total CO2e"; Rec."Total CO2e") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Total CO2e field.'; + } + } + } + + trigger OnOpenPage() + begin + VisibleSustainabilityControls(); + end; + + local procedure VisibleSustainabilityControls() + begin + SustainabilitySetup.GetRecordOnce(); + + SustainabilityVisible := SustainabilitySetup."Enable Value Chain Tracking"; + end; + + var + SustainabilitySetup: Record "Sustainability Setup"; + SustainabilityVisible: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceHeader.TableExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceHeader.TableExt.al new file mode 100644 index 0000000000..531eb0c25c --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceHeader.TableExt.al @@ -0,0 +1,37 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.History; +using Microsoft.Sustainability.Setup; +using Microsoft.Sustainability.Ledger; + +tableextension 6274 "Sust. Service Invoice Header" extends "Service Invoice Header" +{ + fields + { + field(6210; "Sustainability Lines Exist"; Boolean) + { + Caption = 'Sustainability Lines Exist'; + Editable = false; + FieldClass = FlowField; + CalcFormula = exist("Service Invoice Line" where("Sust. Account No." = filter('<>'''''), "Document No." = field("No."))); + } +#pragma warning disable AA0232 + field(6211; "Total CO2e"; Decimal) +#pragma warning restore AA0232 + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + CalcFormula = sum("Sustainability Value Entry"."CO2e Amount (Actual)" where("Document No." = field("No."))); + Caption = 'Total CO2e'; + Editable = false; + FieldClass = FlowField; + } + } + + var + SustainabilitySetup: Record "Sustainability Setup"; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceLine.TableExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceLine.TableExt.al new file mode 100644 index 0000000000..9a2d91e2c3 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceLine.TableExt.al @@ -0,0 +1,58 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.History; +using Microsoft.Sustainability.Account; +using Microsoft.Sustainability.Setup; + +tableextension 6275 "Sust. Service Invoice Line" extends "Service Invoice Line" +{ + fields + { + field(6210; "Sust. Account No."; Code[20]) + { + Caption = 'Sustainability Account No.'; + TableRelation = "Sustainability Account" where("Account Type" = const(Posting), Blocked = const(false)); + DataClassification = CustomerContent; + } + field(6211; "Sust. Account Name"; Text[100]) + { + Caption = 'Sustainability Account Name'; + DataClassification = CustomerContent; + } + field(6212; "Sust. Account Category"; Code[20]) + { + Caption = 'Sustainability Account Category'; + Editable = false; + TableRelation = "Sustain. Account Category"; + DataClassification = CustomerContent; + } + field(6213; "Sust. Account Subcategory"; Code[20]) + { + Caption = 'Sustainability Account Subcategory'; + Editable = false; + TableRelation = "Sustain. Account Subcategory".Code where("Category Code" = field("Sust. Account Category")); + DataClassification = CustomerContent; + } + field(6214; "CO2e per Unit"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + Caption = 'CO2e per Unit'; + DataClassification = CustomerContent; + } + field(6215; "Total CO2e"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + Caption = 'Total CO2e'; + DataClassification = CustomerContent; + } + } + + var + SustainabilitySetup: Record "Sustainability Setup"; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceStats.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceStats.PageExt.al new file mode 100644 index 0000000000..bdcdf327b9 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceStats.PageExt.al @@ -0,0 +1,52 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.History; + +pageextension 6305 "Sust. Service Invoice Stats." extends "Service Invoice Statistics" +{ + layout + { + addafter(Customer) + { + group(Sustainability) + { + Visible = EnableSustainability; + Caption = 'Sustainability'; + field("Total CO2e"; Rec."Total CO2e") + { + ApplicationArea = Basic, Suite; + Caption = 'Total CO2e'; + ToolTip = 'Specifies the total CO2e emissions.'; + } + } + } + } + + trigger OnOpenPage() + begin + EnableSustainabilityControl(); + end; + + trigger OnAfterGetCurrRecord() + begin + EnableSustainabilityControl(); + end; + + trigger OnAfterGetRecord() + begin + EnableSustainabilityControl(); + end; + + local procedure EnableSustainabilityControl() + begin + Rec.CalcFields("Sustainability Lines Exist"); + EnableSustainability := Rec."Sustainability Lines Exist"; + end; + + var + EnableSustainability: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceSubform.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceSubform.PageExt.al new file mode 100644 index 0000000000..42fb3a3434 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceInvoiceSubform.PageExt.al @@ -0,0 +1,49 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.Document; +using Microsoft.Sustainability.Setup; + +pageextension 6303 "Sust. Service Invoice Subform" extends "Service Invoice Subform" +{ + layout + { + addafter("Bin Code") + { + field("Sust. Account No."; Rec."Sust. Account No.") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Sustainability Account No. field.'; + } + } + addafter("Line Discount Amount") + { + field("Total CO2e"; Rec."Total CO2e") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Total CO2e field.'; + } + } + } + + trigger OnOpenPage() + begin + VisibleSustainabilityControls(); + end; + + local procedure VisibleSustainabilityControls() + begin + SustainabilitySetup.GetRecordOnce(); + + SustainabilityVisible := SustainabilitySetup."Enable Value Chain Tracking"; + end; + + var + SustainabilitySetup: Record "Sustainability Setup"; + SustainabilityVisible: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceItemLine.TableExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceItemLine.TableExt.al new file mode 100644 index 0000000000..613b95a6c9 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceItemLine.TableExt.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.Document; +using Microsoft.Sustainability.Setup; + +tableextension 6277 "Sust. Service Item Line" extends "Service Item Line" +{ + fields + { + field(6210; "Total CO2e"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + CalcFormula = sum("Service Line"."Total CO2e" where("Document Type" = field("Document Type"), + "Document No." = field("Document No."), + "Service Item Line No." = field("Line No."))); + Caption = 'Total CO2e'; + Editable = false; + FieldClass = FlowField; + } + } + + var + SustainabilitySetup: Record "Sustainability Setup"; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceLines.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceLines.PageExt.al new file mode 100644 index 0000000000..fc4f3bcbe1 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceLines.PageExt.al @@ -0,0 +1,49 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.Document; +using Microsoft.Sustainability.Setup; + +pageextension 6308 "Sust. Service Lines" extends "Service Lines" +{ + layout + { + addafter("Bin Code") + { + field("Sust. Account No."; Rec."Sust. Account No.") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Sustainability Account No. field.'; + } + } + addafter("Line Discount Amount") + { + field("Total CO2e"; Rec."Total CO2e") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Total CO2e field.'; + } + } + } + + trigger OnOpenPage() + begin + VisibleSustainabilityControls(); + end; + + local procedure VisibleSustainabilityControls() + begin + SustainabilitySetup.GetRecordOnce(); + + SustainabilityVisible := SustainabilitySetup."Enable Value Chain Tracking"; + end; + + var + SustainabilitySetup: Record "Sustainability Setup"; + SustainabilityVisible: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceOrderStats.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceOrderStats.PageExt.al new file mode 100644 index 0000000000..913fd3f0d4 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceOrderStats.PageExt.al @@ -0,0 +1,59 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.Document; + +pageextension 6306 "Sust. Service Order Stats." extends "Service Order Statistics" +{ + layout + { + addafter(Customer) + { + group(Sustainability) + { + Visible = EnableSustainability; + Caption = 'Sustainability'; + + field("Total CO2e"; Rec."Total CO2e") + { + ApplicationArea = Basic, Suite; + Caption = 'Total CO2e'; + ToolTip = 'Specifies the Total CO2e for Purchase Order'; + } + field("Posted Total CO2e"; Rec."Posted Total CO2e") + { + ApplicationArea = Basic, Suite; + Caption = 'Posted Total CO2e'; + ToolTip = 'Specifies the Posted Total CO2e for Purchase Order'; + } + } + } + } + + trigger OnOpenPage() + begin + EnableSustainabilityControl(); + end; + + trigger OnAfterGetCurrRecord() + begin + EnableSustainabilityControl(); + end; + + trigger OnAfterGetRecord() + begin + EnableSustainabilityControl(); + end; + + local procedure EnableSustainabilityControl() + begin + Rec.CalcFields("Sustainability Lines Exist"); + EnableSustainability := Rec."Sustainability Lines Exist"; + end; + + var + EnableSustainability: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceOrderSubform.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceOrderSubform.PageExt.al new file mode 100644 index 0000000000..6832fbda91 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceOrderSubform.PageExt.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.Sustainability.Service; + +using Microsoft.Service.Document; +using Microsoft.Sustainability.Setup; + +pageextension 6310 "Sust. Service Order Subform" extends "Service Order Subform" +{ + layout + { + addafter("Resolution Code") + { + field("Total CO2e"; Rec."Total CO2e") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Total CO2e field.'; + } + } + } + + trigger OnOpenPage() + begin + VisibleSustainabilityControls(); + end; + + local procedure VisibleSustainabilityControls() + begin + SustainabilitySetup.GetRecordOnce(); + + SustainabilityVisible := SustainabilitySetup."Enable Value Chain Tracking"; + end; + + var + SustainabilitySetup: Record "Sustainability Setup"; + SustainabilityVisible: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceQuoteLines.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceQuoteLines.PageExt.al new file mode 100644 index 0000000000..30e7b12725 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceQuoteLines.PageExt.al @@ -0,0 +1,49 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.Document; +using Microsoft.Sustainability.Setup; + +pageextension 6309 "Sust. Service Quote Lines" extends "Service Quote Lines" +{ + layout + { + addafter("Location Code") + { + field("Sust. Account No."; Rec."Sust. Account No.") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Sustainability Account No. field.'; + } + } + addafter("Line Discount Amount") + { + field("Total CO2e"; Rec."Total CO2e") + { + Visible = SustainabilityVisible; + ApplicationArea = Basic, Suite; + ToolTip = 'Specifies the value of the Total CO2e field.'; + } + } + } + + trigger OnOpenPage() + begin + VisibleSustainabilityControls(); + end; + + local procedure VisibleSustainabilityControls() + begin + SustainabilitySetup.GetRecordOnce(); + + SustainabilityVisible := SustainabilitySetup."Enable Value Chain Tracking"; + end; + + var + SustainabilitySetup: Record "Sustainability Setup"; + SustainabilityVisible: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceShipmentLine.TableExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceShipmentLine.TableExt.al new file mode 100644 index 0000000000..559423390c --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceShipmentLine.TableExt.al @@ -0,0 +1,58 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.History; +using Microsoft.Sustainability.Account; +using Microsoft.Sustainability.Setup; + +tableextension 6276 "Sust. Service Shipment Line" extends "Service Shipment Line" +{ + fields + { + field(6210; "Sust. Account No."; Code[20]) + { + Caption = 'Sustainability Account No.'; + TableRelation = "Sustainability Account" where("Account Type" = const(Posting), Blocked = const(false)); + DataClassification = CustomerContent; + } + field(6211; "Sust. Account Name"; Text[100]) + { + Caption = 'Sustainability Account Name'; + DataClassification = CustomerContent; + } + field(6212; "Sust. Account Category"; Code[20]) + { + Caption = 'Sustainability Account Category'; + Editable = false; + TableRelation = "Sustain. Account Category"; + DataClassification = CustomerContent; + } + field(6213; "Sust. Account Subcategory"; Code[20]) + { + Caption = 'Sustainability Account Subcategory'; + Editable = false; + TableRelation = "Sustain. Account Subcategory".Code where("Category Code" = field("Sust. Account Category")); + DataClassification = CustomerContent; + } + field(6214; "CO2e per Unit"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + Caption = 'CO2e per Unit'; + DataClassification = CustomerContent; + } + field(6215; "Total CO2e"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + Caption = 'Total CO2e'; + DataClassification = CustomerContent; + } + } + + var + SustainabilitySetup: Record "Sustainability Setup"; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceStatistics.PageExt.al b/Apps/W1/Sustainability/app/src/Service/SustServiceStatistics.PageExt.al new file mode 100644 index 0000000000..1b19fc06f7 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceStatistics.PageExt.al @@ -0,0 +1,58 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.Document; + +pageextension 6307 "Sust. Service Statistics" extends "Service Statistics" +{ + layout + { + addafter(Customer) + { + group(Sustainability) + { + Visible = EnableSustainability; + Caption = 'Sustainability'; + field("Total CO2e"; Rec."Total CO2e") + { + ApplicationArea = Basic, Suite; + Caption = 'Total CO2e'; + ToolTip = 'Specifies the total CO2e emissions.'; + } + field("Posted Total CO2e"; Rec."Posted Total CO2e") + { + ApplicationArea = Basic, Suite; + Caption = 'Posted Total CO2e'; + ToolTip = 'Specifies the posted total CO2e emissions.'; + } + } + } + } + + trigger OnOpenPage() + begin + EnableSustainabilityControl(); + end; + + trigger OnAfterGetCurrRecord() + begin + EnableSustainabilityControl(); + end; + + trigger OnAfterGetRecord() + begin + EnableSustainabilityControl(); + end; + + local procedure EnableSustainabilityControl() + begin + Rec.CalcFields("Sustainability Lines Exist"); + EnableSustainability := Rec."Sustainability Lines Exist"; + end; + + var + EnableSustainability: Boolean; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustServiceSubscriber.Codeunit.al b/Apps/W1/Sustainability/app/src/Service/SustServiceSubscriber.Codeunit.al new file mode 100644 index 0000000000..6f38aad333 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustServiceSubscriber.Codeunit.al @@ -0,0 +1,371 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Inventory; +using Microsoft.Inventory.Item; +using Microsoft.Inventory.Journal; +using Microsoft.Projects.Project.Journal; +using Microsoft.Projects.Resources.Journal; +using Microsoft.Projects.Resources.Resource; +using Microsoft.Service.Document; +using Microsoft.Service.History; +using Microsoft.Service.Posting; +using Microsoft.Sustainability.Account; +using Microsoft.Sustainability.Setup; + +codeunit 6285 "Sust. Service Subscriber" +{ + [EventSubscriber(ObjectType::Table, Database::"Service Line", 'OnAfterAssignItemValues', '', false, false)] + local procedure OnAfterAssignItemValues(var ServiceLine: Record "Service Line"; Item: Record Item) + begin + if SustainabilitySetup.IsValueChainTrackingEnabled() then + ServiceLine.Validate("Sust. Account No.", Item."Default Sust. Account"); + end; + + [EventSubscriber(ObjectType::Table, Database::"Service Line", 'OnAfterAssignResourceValues', '', false, false)] + local procedure OnAfterAssignResourceValues(var ServiceLine: Record "Service Line"; Resource: Record Resource) + begin + if SustainabilitySetup.IsValueChainTrackingEnabled() then + ServiceLine.Validate("Sust. Account No.", Resource."Default Sust. Account"); + end; + + [EventSubscriber(ObjectType::Table, Database::"Service Line", 'OnValidateQuantityOnBeforeResetAmounts', '', false, false)] + local procedure OnValidateQuantityOnBeforeResetAmounts(var ServiceLine: Record "Service Line") + begin + ServiceLine.UpdateSustainabilityEmission(ServiceLine); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Serv-Documents Mgt.", 'OnUpdateServLinesOnPostOrderOnBeforeServLineLoop', '', false, false)] + local procedure OnUpdateServLinesOnPostOrderOnBeforeServLineLoop(var ServiceLine: Record "Service Line"; Invoice: Boolean; Consume: Boolean) + begin + if Invoice or Consume then + UpdatePostedSustainabilityEmissionOrderLine(ServiceLine, Invoice, Consume); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Serv. Undo Posting Mgt.", 'OnUpdateServLineCnsmOnBeforeServLineModify', '', false, false)] + local procedure OnUpdateServLineCnsmOnBeforeServLineModify(var ServiceLine: Record "Service Line"; UndoQty: Decimal) + begin + UpdatePostedSustainabilityEmissionOrderLine(ServiceLine, UndoQty); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Serv-Documents Mgt.", 'OnBeforeServShptLineInsert', '', false, false)] + local procedure OnBeforeServShptLineInsert(ServiceLine: Record "Service Line"; var ServiceShipmentLine: Record "Service Shipment Line") + begin + UpdatePostedSustainabilityEmission(ServiceLine, ServiceShipmentLine.Quantity, 1, ServiceShipmentLine."Total CO2e"); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Undo Service Shipment Line", 'OnBeforeNewServiceShptLineInsert', '', false, false)] + local procedure OnBeforeNewServiceShptLineInsertForUndoServiceShipment(OldServiceShipmentLine: Record "Service Shipment Line"; var NewServiceShipmentLine: Record "Service Shipment Line") + begin + UpdatePostedSustainabilityEmission(OldServiceShipmentLine, NewServiceShipmentLine.Quantity, -1, NewServiceShipmentLine."Total CO2e"); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Undo Service Consumption Line", 'OnInsertCorrectiveShipmentLineOnBeforeInsert', '', false, false)] + local procedure OnInsertCorrectiveShipmentLineOnBeforeInsertForUndoServiceConsumption(OldServiceShipmentLine: Record "Service Shipment Line"; var NewServiceShipmentLine: Record "Service Shipment Line") + begin + UpdatePostedSustainabilityEmission(OldServiceShipmentLine, NewServiceShipmentLine.Quantity, -1, NewServiceShipmentLine."Total CO2e"); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Serv-Documents Mgt.", 'OnBeforeServInvLineInsert', '', false, false)] + local procedure OnBeforeServInvLineInsert(ServiceLine: Record "Service Line"; var ServiceInvoiceLine: Record "Service Invoice Line") + begin + UpdatePostedSustainabilityEmission(ServiceLine, ServiceInvoiceLine.Quantity, 1, ServiceInvoiceLine."Total CO2e"); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Serv-Documents Mgt.", 'OnBeforeServCrMemoLineInsert', '', false, false)] + local procedure OnBeforeServCrMemoLineInsert(ServiceLine: Record "Service Line"; var ServiceCrMemoLine: Record "Service Cr.Memo Line") + begin + UpdatePostedSustainabilityEmission(ServiceLine, ServiceCrMemoLine.Quantity, 1, ServiceCrMemoLine."Total CO2e"); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Serv-Documents Mgt.", 'OnPostDocumentLinesOnAfterFillInvPostingBuffer', '', false, false)] + local procedure OnPostDocumentLinesOnAfterFillInvPostingBuffer(var TempServiceLine: Record "Service Line" temporary) + begin + TempServiceLine.UpdateSustainabilityEmission(TempServiceLine); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Serv-Posting Journals Mgt.", 'OnBeforePostItemJnlLine', '', false, false)] + local procedure OnBeforePostItemJnlLine(var ItemJournalLine: Record "Item Journal Line"; ServiceLine: Record "Service Line") + begin + if (ItemJournalLine.Quantity <> 0) or (ItemJournalLine."Invoiced Quantity" <> 0) then + UpdateSustainabilityItemJournalLine(ItemJournalLine, ServiceLine); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Serv-Posting Journals Mgt.", 'OnBeforeResJnlPostLine', '', false, false)] + local procedure OnBeforeResJnlPostLine(var ResJnlLine: Record "Res. Journal Line"; ServiceLine: Record "Service Line") + begin + if (ServiceLine."Qty. to Consume" <> 0) or ((ServiceLine."Qty. to Invoice" <> 0) and (ResJnlLine."Entry Type" = ResJnlLine."Entry Type"::Sale)) then + UpdateSustainabilityResourceJournalLine(ResJnlLine, ServiceLine); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Serv-Posting Journals Mgt.", 'OnAfterTransferValuesToJobJnlLine', '', false, false)] + local procedure OnAfterTransferValuesToJobJnlLine(var JobJournalLine: Record "Job Journal Line"; ServiceLine: Record "Service Line") + begin + JobJournalLine."Sust. Account No." := ServiceLine."Sust. Account No."; + JobJournalLine."Sust. Account Name" := ServiceLine."Sust. Account Name"; + JobJournalLine."Sust. Account Category" := ServiceLine."Sust. Account Category"; + JobJournalLine."Sust. Account Subcategory" := ServiceLine."Sust. Account Subcategory"; + JobJournalLine."CO2e per Unit" := ServiceLine."CO2e per Unit"; + JobJournalLine."Total CO2e" := ServiceLine."Total CO2e"; + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Undo Service Shipment Line", 'OnAfterCopyItemJnlLineFromServShpt', '', false, false)] + local procedure OnAfterCopyItemJnlLineFromServShptForUndoServiceShipment(var ItemJournalLine: Record "Item Journal Line"; ServiceShipmentLine: Record "Service Shipment Line") + begin + if (ItemJournalLine.Quantity <> 0) or (ItemJournalLine."Invoiced Quantity" <> 0) then + UpdateSustainabilityItemJournalLine(ItemJournalLine, ServiceShipmentLine); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Undo Service Consumption Line", 'OnAfterCopyItemJnlLineFromServShpt', '', false, false)] + local procedure OnAfterCopyItemJnlLineFromServShptForUndoServiceConsumption(var ItemJournalLine: Record "Item Journal Line"; ServiceShipmentLine: Record "Service Shipment Line") + begin + if (ItemJournalLine.Quantity <> 0) or (ItemJournalLine."Invoiced Quantity" <> 0) then + UpdateSustainabilityItemJournalLine(ItemJournalLine, ServiceShipmentLine); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Undo Service Consumption Line", 'OnPostResourceJnlLineOnBeforeResJnlPostLine', '', false, false)] + local procedure OnPostResourceJnlLineOnBeforeResJnlPostLine(var ResJournalLine: Record "Res. Journal Line"; ServiceShipmentLine: Record "Service Shipment Line") + begin + if (ResJournalLine.Quantity <> 0) then + UpdateSustainabilityResourceJournalLine(ResJournalLine, ServiceShipmentLine); + end; + + local procedure UpdateSustainabilityItemJournalLine(var ItemJournalLine: Record "Item Journal Line"; var ServiceLine: Record "Service Line") + var + ServiceHeader: Record "Service Header"; + GHGCredit: Boolean; + Sign: Integer; + CO2eToPost: Decimal; + begin + ServiceHeader := ServiceLine.GetServHeader(); + GHGCredit := IsGHGCreditLine(ServiceLine); + + Sign := GetPostingSign(ServiceHeader, GHGCredit); + + if ItemJournalLine."Invoiced Quantity" <> 0 then + CO2eToPost := ServiceLine."CO2e per Unit" * Abs(ItemJournalLine."Invoiced Quantity") * ServiceLine."Qty. per Unit of Measure" + else + CO2eToPost := ServiceLine."CO2e per Unit" * Abs(ItemJournalLine.Quantity) * ServiceLine."Qty. per Unit of Measure"; + + CO2eToPost := CO2eToPost * Sign; + + if not CanPostSustainabilityJnlLine(ServiceLine."Sust. Account No.", ServiceLine."Sust. Account Category", ServiceLine."Sust. Account Subcategory", CO2eToPost) then + exit; + + ItemJournalLine."Sust. Account No." := ServiceLine."Sust. Account No."; + ItemJournalLine."Sust. Account Name" := ServiceLine."Sust. Account Name"; + ItemJournalLine."Sust. Account Category" := ServiceLine."Sust. Account Category"; + ItemJournalLine."Sust. Account Subcategory" := ServiceLine."Sust. Account Subcategory"; + ItemJournalLine."CO2e per Unit" := ServiceLine."CO2e per Unit"; + ItemJournalLine."Total CO2e" := CO2eToPost; + end; + + local procedure UpdateSustainabilityItemJournalLine(var ItemJournalLine: Record "Item Journal Line"; ServiceShipmentLine: Record "Service Shipment Line") + var + GHGCredit: Boolean; + Sign: Integer; + CO2eToPost: Decimal; + begin + Sign := 1; + GHGCredit := IsGHGCreditLine(ServiceShipmentLine); + if GHGCredit then + Sign := -1; + + if ItemJournalLine."Invoiced Quantity" <> 0 then + CO2eToPost := ServiceShipmentLine."CO2e per Unit" * Abs(ItemJournalLine."Invoiced Quantity") * ServiceShipmentLine."Qty. per Unit of Measure" + else + CO2eToPost := ServiceShipmentLine."CO2e per Unit" * Abs(ItemJournalLine.Quantity) * ServiceShipmentLine."Qty. per Unit of Measure"; + + CO2eToPost := CO2eToPost * Sign; + + if not CanPostSustainabilityJnlLine(ServiceShipmentLine."Sust. Account No.", ServiceShipmentLine."Sust. Account Category", ServiceShipmentLine."Sust. Account Subcategory", CO2eToPost) then + exit; + + ItemJournalLine."Sust. Account No." := ServiceShipmentLine."Sust. Account No."; + ItemJournalLine."Sust. Account Name" := ServiceShipmentLine."Sust. Account Name"; + ItemJournalLine."Sust. Account Category" := ServiceShipmentLine."Sust. Account Category"; + ItemJournalLine."Sust. Account Subcategory" := ServiceShipmentLine."Sust. Account Subcategory"; + ItemJournalLine."CO2e per Unit" := ServiceShipmentLine."CO2e per Unit"; + ItemJournalLine."Total CO2e" := CO2eToPost; + end; + + local procedure UpdateSustainabilityResourceJournalLine(var ResJournalLine: Record "Res. Journal Line"; ServiceShipmentLine: Record "Service Shipment Line") + var + GHGCredit: Boolean; + Sign: Integer; + CO2eToPost: Decimal; + begin + Sign := 1; + GHGCredit := IsGHGCreditLine(ServiceShipmentLine); + if GHGCredit then + Sign := -1; + + CO2eToPost := ServiceShipmentLine."CO2e per Unit" * Abs(ResJournalLine.Quantity) * ServiceShipmentLine."Qty. per Unit of Measure"; + + CO2eToPost := CO2eToPost * Sign; + + if not CanPostSustainabilityJnlLine(ServiceShipmentLine."Sust. Account No.", ServiceShipmentLine."Sust. Account Category", ServiceShipmentLine."Sust. Account Subcategory", CO2eToPost) then + exit; + + ResJournalLine."Sust. Account No." := ServiceShipmentLine."Sust. Account No."; + ResJournalLine."Sust. Account Name" := ServiceShipmentLine."Sust. Account Name"; + ResJournalLine."Sust. Account Category" := ServiceShipmentLine."Sust. Account Category"; + ResJournalLine."Sust. Account Subcategory" := ServiceShipmentLine."Sust. Account Subcategory"; + ResJournalLine."CO2e per Unit" := ServiceShipmentLine."CO2e per Unit"; + ResJournalLine."Total CO2e" := CO2eToPost; + end; + + local procedure UpdateSustainabilityResourceJournalLine(var ResJnlLine: Record "Res. Journal Line"; var ServiceLine: Record "Service Line") + var + ServiceHeader: Record "Service Header"; + GHGCredit: Boolean; + Sign: Integer; + CO2eToPost: Decimal; + begin + ServiceHeader := ServiceLine.GetServHeader(); + GHGCredit := IsGHGCreditLine(ServiceLine); + + Sign := GetPostingSign(ServiceHeader, GHGCredit); + + CO2eToPost := ServiceLine."CO2e per Unit" * Abs(ResJnlLine.Quantity) * ServiceLine."Qty. per Unit of Measure"; + CO2eToPost := CO2eToPost * Sign; + + if not CanPostSustainabilityJnlLine(ServiceLine."Sust. Account No.", ServiceLine."Sust. Account Category", ServiceLine."Sust. Account Subcategory", CO2eToPost) then + exit; + + ResJnlLine."Sust. Account No." := ServiceLine."Sust. Account No."; + ResJnlLine."Sust. Account Name" := ServiceLine."Sust. Account Name"; + ResJnlLine."Sust. Account Category" := ServiceLine."Sust. Account Category"; + ResJnlLine."Sust. Account Subcategory" := ServiceLine."Sust. Account Subcategory"; + ResJnlLine."CO2e per Unit" := ServiceLine."CO2e per Unit"; + ResJnlLine."Total CO2e" := CO2eToPost; + end; + + local procedure UpdatePostedSustainabilityEmissionOrderLine(var ServiceLine: Record "Service Line"; Invoice: Boolean; Consume: Boolean) + var + ServiceHeader: Record "Service Header"; + PostedEmissionCO2e: Decimal; + GHGCredit: Boolean; + Sign: Integer; + begin + ServiceHeader := ServiceLine.GetServHeader(); + + GHGCredit := IsGHGCreditLine(ServiceLine); + Sign := GetPostingSign(ServiceHeader, GHGCredit); + + if Invoice then + UpdatePostedSustainabilityEmission(ServiceLine, ServiceLine."Qty. to Invoice", Sign, PostedEmissionCO2e); + + if Consume then + UpdatePostedSustainabilityEmission(ServiceLine, ServiceLine."Qty. to Consume", Sign, PostedEmissionCO2e); + + ServiceLine."Posted Total CO2e" += PostedEmissionCO2e; + end; + + local procedure UpdatePostedSustainabilityEmissionOrderLine(var ServiceLine: Record "Service Line"; UndoQty: Decimal) + var + ServiceHeader: Record "Service Header"; + PostedEmissionCO2e: Decimal; + GHGCredit: Boolean; + Sign: Integer; + begin + ServiceHeader := ServiceLine.GetServHeader(); + + GHGCredit := IsGHGCreditLine(ServiceLine); + Sign := GetPostingSign(ServiceHeader, GHGCredit); + + UpdatePostedSustainabilityEmission(ServiceLine, UndoQty, -Sign, PostedEmissionCO2e); + + ServiceLine."Posted Total CO2e" += PostedEmissionCO2e; + end; + + local procedure UpdatePostedSustainabilityEmission(ServiceLine: Record "Service Line"; Quantity: Decimal; Sign: Integer; var PostedEmissionCO2e: Decimal) + begin + PostedEmissionCO2e := (ServiceLine."CO2e per Unit" * Abs(Quantity) * ServiceLine."Qty. per Unit of Measure") * Sign; + end; + + local procedure UpdatePostedSustainabilityEmission(ServiceShipmentLine: Record "Service Shipment Line"; Quantity: Decimal; Sign: Integer; var PostedEmissionCO2e: Decimal) + begin + PostedEmissionCO2e := (ServiceShipmentLine."CO2e per Unit" * Abs(Quantity) * ServiceShipmentLine."Qty. per Unit of Measure") * Sign; + end; + + local procedure GetPostingSign(ServiceHeader: Record "Service Header"; GHGCredit: Boolean): Integer + var + Sign: Integer; + begin + Sign := 1; + + case ServiceHeader."Document Type" of + ServiceHeader."Document Type"::Invoice, ServiceHeader."Document Type"::Order: + if not GHGCredit then + Sign := -1; + else + if GHGCredit then + Sign := -1; + end; + + exit(Sign); + end; + + local procedure IsGHGCreditLine(ServiceLine: Record "Service Line"): Boolean + var + Item: Record Item; + begin + if ServiceLine.Type <> ServiceLine.Type::Item then + exit(false); + + if ServiceLine."No." = '' then + exit(false); + + Item.Get(ServiceLine."No."); + + exit(Item."GHG Credit"); + end; + + local procedure IsGHGCreditLine(ServiceShipmentLine: Record "Service Shipment Line"): Boolean + var + Item: Record Item; + begin + if ServiceShipmentLine.Type <> ServiceShipmentLine.Type::Item then + exit(false); + + if ServiceShipmentLine."No." = '' then + exit(false); + + Item.Get(ServiceShipmentLine."No."); + + exit(Item."GHG Credit"); + end; + + local procedure CanPostSustainabilityJnlLine(AccountNo: Code[20]; AccountCategory: Code[20]; AccountSubCategory: Code[20]; CO2eToPost: Decimal): Boolean + var + SustAccountCategory: Record "Sustain. Account Category"; + SustainAccountSubcategory: Record "Sustain. Account Subcategory"; + begin + if AccountNo = '' then + exit(false); + + if not SustainabilitySetup.IsValueChainTrackingEnabled() then + exit(false); + + if SustAccountCategory.Get(AccountCategory) then + if SustAccountCategory."Water Intensity" or SustAccountCategory."Waste Intensity" or SustAccountCategory."Discharged Into Water" then + Error(NotAllowedToPostSustLedEntryForWaterOrWasteErr, AccountNo); + + if SustainAccountSubcategory.Get(AccountCategory, AccountSubCategory) then + if not SustainAccountSubcategory."Renewable Energy" then + if (CO2eToPost = 0) then + Error(CO2eMustNotBeZeroErr); + + if (CO2eToPost <> 0) then + exit(true); + end; + + var + SustainabilitySetup: Record "Sustainability Setup"; + CO2eMustNotBeZeroErr: Label 'The CO2e fields must have a value that is not 0.'; + NotAllowedToPostSustLedEntryForWaterOrWasteErr: Label 'It is not allowed to post Sustainability Ledger Entry for water or waste in sales document for Account No. %1', Comment = '%1 = Sustainability Account No.'; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustainabilityServiceHeader.TableExt.al b/Apps/W1/Sustainability/app/src/Service/SustainabilityServiceHeader.TableExt.al new file mode 100644 index 0000000000..aace29a5c7 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustainabilityServiceHeader.TableExt.al @@ -0,0 +1,47 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Service.Document; +using Microsoft.Sustainability.Setup; + +tableextension 6270 "Sustainability Service Header" extends "Service Header" +{ + fields + { + field(6210; "Sustainability Lines Exist"; Boolean) + { + Caption = 'Sustainability Lines Exist'; + Editable = false; + FieldClass = FlowField; + CalcFormula = exist("Service Line" where("Document Type" = field("Document Type"), + "Document No." = field("No."), + "Sust. Account No." = filter('<>'''''))); + } + field(6211; "Total CO2e"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + CalcFormula = sum("Service Line"."Total CO2e" where("Document Type" = field("Document Type"), + "Document No." = field("No."))); + Caption = 'Total CO2e'; + Editable = false; + FieldClass = FlowField; + } + field(6212; "Posted Total CO2e"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + CalcFormula = sum("Service Line"."Posted Total CO2e" where("Document Type" = field("Document Type"), + "Document No." = field("No."))); + Caption = 'Posted Total CO2e'; + Editable = false; + FieldClass = FlowField; + } + } + + var + SustainabilitySetup: Record "Sustainability Setup"; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Service/SustainabilityServiceLine.TableExt.al b/Apps/W1/Sustainability/app/src/Service/SustainabilityServiceLine.TableExt.al new file mode 100644 index 0000000000..a258f0893b --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Service/SustainabilityServiceLine.TableExt.al @@ -0,0 +1,201 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Service; + +using Microsoft.Inventory.Item; +using Microsoft.Projects.Resources.Resource; +using Microsoft.Service.Document; +using Microsoft.Sustainability.Account; +using Microsoft.Sustainability.Setup; + +tableextension 6271 "Sustainability Service Line" extends "Service Line" +{ + fields + { + field(6210; "Sust. Account No."; Code[20]) + { + Caption = 'Sustainability Account No.'; + TableRelation = "Sustainability Account" where("Account Type" = const(Posting), Blocked = const(false)); + DataClassification = CustomerContent; + + trigger OnValidate() + var + SustainabilityAccount: Record "Sustainability Account"; + begin + Rec.TestStatusOpen(); + if Rec."Sust. Account No." <> xRec."Sust. Account No." then + ClearEmissionInformation(Rec); + + if Rec."Sust. Account No." = '' then begin + Rec.Validate("Sust. Account Category", ''); + "Sust. Account Name" := ''; + end else begin + ValidateEmissionPrerequisite(Rec, Rec.FieldNo("Sust. Account No.")); + + SustainabilityAccount.Get(Rec."Sust. Account No."); + SustainabilityAccount.CheckAccountReadyForPosting(); + SustainabilityAccount.TestField("Direct Posting", true); + + Rec.Validate("Sust. Account Name", SustainabilityAccount.Name); + Rec.Validate("Sust. Account Category", SustainabilityAccount.Category); + Rec.Validate("Sust. Account Subcategory", SustainabilityAccount.Subcategory); + + UpdateCO2eInformation(); + end; + + CreateDimFromDefaultDim(FieldNo(Rec."Sust. Account No.")); + end; + } + field(6211; "Sust. Account Name"; Text[100]) + { + Caption = 'Sustainability Account Name'; + DataClassification = CustomerContent; + } + field(6212; "Sust. Account Category"; Code[20]) + { + Caption = 'Sustainability Account Category'; + Editable = false; + TableRelation = "Sustain. Account Category"; + DataClassification = CustomerContent; + + trigger OnValidate() + begin + if Rec."Sust. Account Category" <> '' then + ValidateEmissionPrerequisite(Rec, Rec.FieldNo("Sust. Account Category")) + else + Rec.Validate("Sust. Account Subcategory", ''); + + if "Sust. Account Category" <> xRec."Sust. Account Category" then + Rec.Validate("Shortcut Dimension 1 Code", ''); + end; + } + field(6213; "Sust. Account Subcategory"; Code[20]) + { + Caption = 'Sustainability Account Subcategory'; + Editable = false; + TableRelation = "Sustain. Account Subcategory".Code where("Category Code" = field("Sust. Account Category")); + DataClassification = CustomerContent; + + trigger OnValidate() + begin + if Rec."Sust. Account Subcategory" <> '' then + ValidateEmissionPrerequisite(Rec, Rec.FieldNo("Sust. Account Subcategory")); + end; + } + field(6214; "CO2e per Unit"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + Caption = 'CO2e per Unit'; + DataClassification = CustomerContent; + + trigger OnValidate() + begin + if Rec."CO2e per Unit" <> 0 then + ValidateEmissionPrerequisite(Rec, Rec.FieldNo("CO2e per Unit")); + + UpdateSustainabilityEmission(Rec); + end; + } + field(6215; "Total CO2e"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + Caption = 'Total CO2e'; + DataClassification = CustomerContent; + + trigger OnValidate() + begin + if Rec."Total CO2e" <> 0 then + ValidateEmissionPrerequisite(Rec, Rec.FieldNo("Total CO2e")); + + UpdateEmissionPerUnit(Rec); + end; + } + field(6216; "Posted Total CO2e"; Decimal) + { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); + Caption = 'Posted Total CO2e'; + Editable = false; + DataClassification = CustomerContent; + } + } + + procedure UpdateSustainabilityEmission(var ServiceLine: Record "Service Line") + begin + ServiceLine."Total CO2e" := ServiceLine."CO2e per Unit" * ServiceLine."Qty. per Unit of Measure" * ServiceLine.Quantity; + end; + + procedure UpdateEmissionPerUnit(var ServiceLine: Record "Service Line") + var + Denominator: Decimal; + begin + ServiceLine."CO2e Per Unit" := 0; + + if (ServiceLine."Qty. per Unit of Measure" = 0) or (ServiceLine.Quantity = 0) then + exit; + + Denominator := ServiceLine."Qty. per Unit of Measure" * ServiceLine.Quantity; + if ServiceLine."Total CO2e" <> 0 then + ServiceLine."CO2e per Unit" := ServiceLine."Total CO2e" / Denominator; + end; + + local procedure ClearEmissionInformation(var ServiceLine: Record "Service Line") + begin + ServiceLine.Validate("CO2e per Unit", 0); + end; + + local procedure ValidateEmissionPrerequisite(ServiceLine: Record "Service Line"; CurrentFieldNo: Integer) + var + SustAccountCategory: Record "Sustain. Account Category"; + begin + case CurrentFieldNo of + ServiceLine.FieldNo("CO2e per Unit"), + ServiceLine.FieldNo("Total CO2e"): + begin + ServiceLine.TestStatusOpen(); + ServiceLine.TestField("Sust. Account No."); + end; + ServiceLine.FieldNo("Sust. Account No."), + ServiceLine.FieldNo("Sust. Account Category"), + ServiceLine.FieldNo("Sust. Account Subcategory"), + ServiceLine.FieldNo("Sust. Account Name"): + begin + ServiceLine.TestField("No."); + if not (ServiceLine.Type in [ServiceLine.Type::Item, ServiceLine.Type::Resource]) then + Error(InvalidTypeForSustErr, ServiceLine.Type::Item, ServiceLine.Type::Resource); + + if SustAccountCategory.Get(ServiceLine."Sust. Account Category") then + if SustAccountCategory."Water Intensity" or SustAccountCategory."Waste Intensity" or SustAccountCategory."Discharged Into Water" then + Error(NotAllowedToUseSustAccountForWaterOrWasteErr, ServiceLine."Sust. Account No."); + end; + end; + end; + + local procedure UpdateCO2eInformation() + var + Item: Record Item; + Resource: Record Resource; + begin + case Rec.Type of + Rec.Type::Item: + begin + Item.Get(Rec."No."); + Rec.Validate("CO2e per Unit", Item."CO2e per Unit"); + end; + Rec.Type::Resource: + begin + Resource.Get(Rec."No."); + Rec.Validate("CO2e per Unit", Resource."CO2e per Unit"); + end; + end; + end; + + var + SustainabilitySetup: Record "Sustainability Setup"; + InvalidTypeForSustErr: Label 'Sustainability is only applicable for Type: %1 and %2.', Comment = '%1 - Sales Line Type Item, %2 - Sales Line Type Resource'; + NotAllowedToUseSustAccountForWaterOrWasteErr: Label 'It is not allowed to use Sustainability Account %1 for water or waste in Sales document.', Comment = '%1 = Sust. Account No.'; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/test/src/SustCertificateTest.Codeunit.al b/Apps/W1/Sustainability/test/src/SustCertificateTest.Codeunit.al index 09b2d451a9..65183a6e87 100644 --- a/Apps/W1/Sustainability/test/src/SustCertificateTest.Codeunit.al +++ b/Apps/W1/Sustainability/test/src/SustCertificateTest.Codeunit.al @@ -1,40 +1,42 @@ namespace Microsoft.Test.Sustainability; -using System.TestLibraries.Utilities; -using Microsoft.Sustainability.Certificate; -using Microsoft.Inventory.Item; -using Microsoft.Foundation.UOM; -using Microsoft.Purchases.Vendor; -using Microsoft.Purchases.Document; -using Microsoft.Sustainability.Account; -using Microsoft.Sustainability.Ledger; -using Microsoft.Foundation.NoSeries; -using Microsoft.Purchases.Setup; -using Microsoft.Finance.GeneralLedger.Account; -using Microsoft.Sustainability.Setup; -using Microsoft.Manufacturing.ProductionBOM; -using Microsoft.Manufacturing.Routing; -using Microsoft.Manufacturing.WorkCenter; -using Microsoft.Projects.Resources.Resource; -using Microsoft.Manufacturing.MachineCenter; using Microsoft.Assembly.Document; using Microsoft.Assembly.History; -using Microsoft.Sales.Document; -using Microsoft.Sales.History; +using Microsoft.Assembly.Setup; +using Microsoft.Finance.GeneralLedger.Account; +using Microsoft.Finance.GeneralLedger.Journal; +using Microsoft.Foundation.AuditCodes; +using Microsoft.Foundation.NoSeries; +using Microsoft.Foundation.UOM; +using Microsoft.Inventory.BOM; +using Microsoft.Inventory.Item; +using Microsoft.Inventory.Journal; using Microsoft.Inventory.Location; using Microsoft.Inventory.Transfer; +using Microsoft.Manufacturing.Capacity; using Microsoft.Manufacturing.Document; using Microsoft.Manufacturing.Journal; -using Microsoft.Manufacturing.Capacity; -using Microsoft.Inventory.Journal; -using Microsoft.Foundation.AuditCodes; -using Microsoft.Purchases.History; -using Microsoft.Inventory.BOM; -using Microsoft.Assembly.Setup; -using Microsoft.Finance.GeneralLedger.Journal; +using Microsoft.Manufacturing.MachineCenter; +using Microsoft.Manufacturing.ProductionBOM; +using Microsoft.Manufacturing.Routing; +using Microsoft.Manufacturing.WorkCenter; using Microsoft.Projects.Project.Job; using Microsoft.Projects.Project.Journal; using Microsoft.Projects.Project.Planning; +using Microsoft.Projects.Resources.Resource; +using Microsoft.Purchases.Document; +using Microsoft.Purchases.History; +using Microsoft.Purchases.Setup; +using Microsoft.Purchases.Vendor; +using Microsoft.Sales.Document; +using Microsoft.Sales.History; +using Microsoft.Service.Document; +using Microsoft.Service.History; +using Microsoft.Sustainability.Account; +using Microsoft.Sustainability.Certificate; +using Microsoft.Sustainability.Ledger; +using Microsoft.Sustainability.Setup; +using System.TestLibraries.Utilities; codeunit 148187 "Sust. Certificate Test" { @@ -6806,6 +6808,454 @@ codeunit 148187 "Sust. Certificate Test" Assert.ExpectedTestFieldError(SustainabilitySetup.FieldCaption("Use Formulas In Purch. Docs"), Format(false)); end; + [Test] + procedure VerifySustFieldsAreVisibleOnPostedServCrMemoSubformIsEnableValueChainTrackingIsTrue() + var + PostedServiceCrMemoLines: TestPage "Posted Service Cr. Memo Lines"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are Visible on "Posted Service Cr. Memo Lines" + // if Enable Value Chain Tracking is true in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [WHEN] Open "Posted Service Cr. Memo Lines". + PostedServiceCrMemoLines.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" is Visible on "Posted Service Cr. Memo Lines". + Assert.IsTrue( + PostedServiceCrMemoLines."Total CO2e".Visible(), + StrSubstNo( + FieldShouldBeVisibleErr, + PostedServiceCrMemoLines."Total CO2e".Caption(), + PostedServiceCrMemoLines.Caption())); + + Assert.IsTrue( + PostedServiceCrMemoLines."Sust. Account No.".Visible(), + StrSubstNo( + FieldShouldBeVisibleErr, + PostedServiceCrMemoLines."Sust. Account No.".Caption(), + PostedServiceCrMemoLines.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreNotVisibleOnPostedServCrMemoSubformIsEnableValueChainTrackingIsFalse() + var + PostedServiceCrMemoLines: TestPage "Posted Service Cr. Memo Lines"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are not Visible on "Posted Service Cr. Memo Lines" + // if Enable Value Chain Tracking is false in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [WHEN] Open "Posted Service Cr. Memo Lines". + PostedServiceCrMemoLines.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" are not Visible on "Posted Service Cr. Memo Lines". + Assert.IsTrue( + PostedServiceCrMemoLines."Total CO2e".Visible(), + StrSubstNo( + FieldShouldNotBeVisibleErr, + PostedServiceCrMemoLines."Total CO2e".Caption(), + PostedServiceCrMemoLines.Caption())); + + Assert.IsTrue( + PostedServiceCrMemoLines."Sust. Account No.".Visible(), + StrSubstNo( + FieldShouldNotBeVisibleErr, + PostedServiceCrMemoLines."Sust. Account No.".Caption(), + PostedServiceCrMemoLines.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreVisibleOnPostedServInvoiceSubformIsEnableValueChainTrackingIsTrue() + var + PostedServiceInvoiceSubform: TestPage "Posted Service Invoice Subform"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are Visible on "Posted Service Invoice Subform" + // if Enable Value Chain Tracking is true in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [WHEN] Open "Posted Service Invoice Subform". + PostedServiceInvoiceSubform.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" is Visible on "Posted Service Invoice Subform". + Assert.IsTrue( + PostedServiceInvoiceSubform."Total CO2e".Visible(), + StrSubstNo( + FieldShouldBeVisibleErr, + PostedServiceInvoiceSubform."Total CO2e".Caption(), + PostedServiceInvoiceSubform.Caption())); + + Assert.IsTrue( + PostedServiceInvoiceSubform."Sust. Account No.".Visible(), + StrSubstNo( + FieldShouldBeVisibleErr, + PostedServiceInvoiceSubform."Sust. Account No.".Caption(), + PostedServiceInvoiceSubform.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreNotVisibleOnPostedServInvoiceSubformIsEnableValueChainTrackingIsFalse() + var + PostedServiceInvoiceSubform: TestPage "Posted Service Invoice Subform"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are not Visible on "Posted Service Invoice Subform" + // if Enable Value Chain Tracking is false in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [WHEN] Open "Posted Service Invoice Subform". + PostedServiceInvoiceSubform.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" are not Visible on "Posted Service Invoice Subform". + Assert.IsTrue( + PostedServiceInvoiceSubform."Total CO2e".Visible(), + StrSubstNo( + FieldShouldNotBeVisibleErr, + PostedServiceInvoiceSubform."Total CO2e".Caption(), + PostedServiceInvoiceSubform.Caption())); + + Assert.IsTrue( + PostedServiceInvoiceSubform."Sust. Account No.".Visible(), + StrSubstNo( + FieldShouldNotBeVisibleErr, + PostedServiceInvoiceSubform."Sust. Account No.".Caption(), + PostedServiceInvoiceSubform.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreVisibleOnServiceInvoiceSubformIsEnableValueChainTrackingIsTrue() + var + ServiceInvoiceSubform: TestPage "Service Invoice Subform"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are Visible on "Service Invoice Subform" + // if Enable Value Chain Tracking is true in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [WHEN] Open "Service Invoice Subform". + ServiceInvoiceSubform.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" is Visible on "Service Invoice Subform". + Assert.IsTrue( + ServiceInvoiceSubform."Total CO2e".Visible(), + StrSubstNo(FieldShouldBeVisibleErr, ServiceInvoiceSubform."Total CO2e".Caption(), ServiceInvoiceSubform.Caption())); + Assert.IsTrue( + ServiceInvoiceSubform."Sust. Account No.".Visible(), + StrSubstNo(FieldShouldBeVisibleErr, ServiceInvoiceSubform."Sust. Account No.".Caption(), ServiceInvoiceSubform.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreNotVisibleOnServiceInvoiceSubformIsEnableValueChainTrackingIsFalse() + var + ServiceInvoiceSubform: TestPage "Service Invoice Subform"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are not Visible on "Service Invoice Subform" + // if Enable Value Chain Tracking is false in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(false); + + // [WHEN] Open "Service Invoice Subform". + ServiceInvoiceSubform.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" are not Visible on "Service Invoice Subform". + Assert.IsFalse( + ServiceInvoiceSubform."Total CO2e".Visible(), + StrSubstNo(FieldShouldNotBeVisibleErr, ServiceInvoiceSubform."Total CO2e".Caption(), ServiceInvoiceSubform.Caption())); + Assert.IsFalse( + ServiceInvoiceSubform."Sust. Account No.".Visible(), + StrSubstNo(FieldShouldNotBeVisibleErr, ServiceInvoiceSubform."Sust. Account No.".Caption(), ServiceInvoiceSubform.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreVisibleOnServiceCrMemoSubformIsEnableValueChainTrackingIsTrue() + var + ServiceCrMemoSubform: TestPage "Service Credit Memo Subform"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are Visible on "Service Cr. Memo Subform" + // if Enable Value Chain Tracking is true in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [WHEN] Open "Service Cr. Memo Subform". + ServiceCrMemoSubform.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" is Visible on "Service Cr. Memo Subform". + Assert.IsTrue( + ServiceCrMemoSubform."Total CO2e".Visible(), + StrSubstNo(FieldShouldBeVisibleErr, ServiceCrMemoSubform."Total CO2e".Caption(), ServiceCrMemoSubform.Caption())); + Assert.IsTrue( + ServiceCrMemoSubform."Sust. Account No.".Visible(), + StrSubstNo(FieldShouldBeVisibleErr, ServiceCrMemoSubform."Sust. Account No.".Caption(), ServiceCrMemoSubform.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreNotVisibleOnServiceCrMemoSubformIsEnableValueChainTrackingIsFalse() + var + ServiceCrMemoSubform: TestPage "Service Credit Memo Subform"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are not Visible on "Service Cr. Memo Subform" + // if Enable Value Chain Tracking is false in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(false); + + // [WHEN] Open "Service Cr. Memo Subform". + ServiceCrMemoSubform.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" are not Visible on "Service Cr. Memo Subform". + Assert.IsFalse( + ServiceCrMemoSubform."Total CO2e".Visible(), + StrSubstNo(FieldShouldNotBeVisibleErr, ServiceCrMemoSubform."Total CO2e".Caption(), ServiceCrMemoSubform.Caption())); + Assert.IsFalse( + ServiceCrMemoSubform."Sust. Account No.".Visible(), + StrSubstNo(FieldShouldNotBeVisibleErr, ServiceCrMemoSubform."Sust. Account No.".Caption(), ServiceCrMemoSubform.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreVisibleOnServiceLinesIsEnableValueChainTrackingIsTrue() + var + ServiceLines: TestPage "Service Lines"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are Visible on "Service Lines" + // if Enable Value Chain Tracking is true in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [WHEN] Open "Service Lines". + ServiceLines.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" is Visible on "Service Lines". + Assert.IsTrue( + ServiceLines."Total CO2e".Visible(), + StrSubstNo(FieldShouldBeVisibleErr, ServiceLines."Total CO2e".Caption(), ServiceLines.Caption())); + Assert.IsTrue( + ServiceLines."Sust. Account No.".Visible(), + StrSubstNo(FieldShouldBeVisibleErr, ServiceLines."Sust. Account No.".Caption(), ServiceLines.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreNotVisibleOnServiceLinesIsEnableValueChainTrackingIsFalse() + var + ServiceLines: TestPage "Service Lines"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are not Visible on "Service Lines" + // if Enable Value Chain Tracking is false in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(false); + + // [WHEN] Open "Service Lines". + ServiceLines.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" are not Visible on "Service Lines". + Assert.IsFalse( + ServiceLines."Total CO2e".Visible(), + StrSubstNo(FieldShouldNotBeVisibleErr, ServiceLines."Total CO2e".Caption(), ServiceLines.Caption())); + Assert.IsFalse( + ServiceLines."Sust. Account No.".Visible(), + StrSubstNo(FieldShouldNotBeVisibleErr, ServiceLines."Sust. Account No.".Caption(), ServiceLines.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreVisibleOnServiceQuoteLinesIsEnableValueChainTrackingIsTrue() + var + ServiceQuoteLines: TestPage "Service Quote Lines"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are Visible on "Service Quote Lines" + // if Enable Value Chain Tracking is true in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [WHEN] Open "Service Quote Lines". + ServiceQuoteLines.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" is Visible on "Service Quote Lines". + Assert.IsTrue( + ServiceQuoteLines."Total CO2e".Visible(), + StrSubstNo(FieldShouldBeVisibleErr, ServiceQuoteLines."Total CO2e".Caption(), ServiceQuoteLines.Caption())); + Assert.IsTrue( + ServiceQuoteLines."Sust. Account No.".Visible(), + StrSubstNo(FieldShouldBeVisibleErr, ServiceQuoteLines."Sust. Account No.".Caption(), ServiceQuoteLines.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreNotVisibleOnServiceQuoteLinesIsEnableValueChainTrackingIsFalse() + var + ServiceQuoteLines: TestPage "Service Quote Lines"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are not Visible on "Service Quote Lines" + // if Enable Value Chain Tracking is false in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(false); + + // [WHEN] Open "Service Quote Lines". + ServiceQuoteLines.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" are not Visible on "Service Quote Lines". + Assert.IsFalse( + ServiceQuoteLines."Total CO2e".Visible(), + StrSubstNo(FieldShouldNotBeVisibleErr, ServiceQuoteLines."Total CO2e".Caption(), ServiceQuoteLines.Caption())); + Assert.IsFalse( + ServiceQuoteLines."Sust. Account No.".Visible(), + StrSubstNo(FieldShouldNotBeVisibleErr, ServiceQuoteLines."Sust. Account No.".Caption(), ServiceQuoteLines.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreVisibleOnPostedServiceCrMemoSubformIsEnableValueChainTrackingIsTrue() + var + PostedServiceCrMemoSubform: TestPage "Posted Serv. Cr. Memo Subform"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are Visible on "Posted Service Cr. Memo Subform" + // if Enable Value Chain Tracking is true in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [WHEN] Open "Posted Serv. Cr. Memo Subform". + PostedServiceCrMemoSubform.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" is Visible on "Posted Serv. Cr. Memo Subform". + Assert.IsTrue( + PostedServiceCrMemoSubform."Total CO2e".Visible(), + StrSubstNo(FieldShouldBeVisibleErr, PostedServiceCrMemoSubform."Total CO2e".Caption(), PostedServiceCrMemoSubform.Caption())); + Assert.IsTrue( + PostedServiceCrMemoSubform."Sust. Account No.".Visible(), + StrSubstNo(FieldShouldBeVisibleErr, PostedServiceCrMemoSubform."Sust. Account No.".Caption(), PostedServiceCrMemoSubform.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreNotVisibleOnPostedServiceCrMemoSubformIsEnableValueChainTrackingIsFalse() + var + PostedServiceCrMemoSubform: TestPage "Posted Serv. Cr. Memo Subform"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are not Visible on "Posted Service Cr. Memo Subform" + // if Enable Value Chain Tracking is false in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(false); + + // [WHEN] Open "Posted Serv. Cr. Memo Subform". + PostedServiceCrMemoSubform.OpenEdit(); + + // [THEN] "Sust. Account No.","Total CO2e" are not Visible on "Posted Serv. Cr. Memo Subform". + Assert.IsFalse( + PostedServiceCrMemoSubform."Total CO2e".Visible(), + StrSubstNo(FieldShouldNotBeVisibleErr, PostedServiceCrMemoSubform."Total CO2e".Caption(), PostedServiceCrMemoSubform.Caption())); + Assert.IsFalse( + PostedServiceCrMemoSubform."Sust. Account No.".Visible(), + StrSubstNo(FieldShouldNotBeVisibleErr, PostedServiceCrMemoSubform."Sust. Account No.".Caption(), PostedServiceCrMemoSubform.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreVisibleOnPostedServiceShptSubformIsEnableValueChainTrackingIsTrue() + var + PostedServiceShipmentSubform: TestPage "Posted Service Shpt. Subform"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are Visible on "Posted Service Shpt. Subform" + // if Enable Value Chain Tracking is true in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [WHEN] Open "Posted Service Shpt. Subform". + PostedServiceShipmentSubform.OpenEdit(); + + // [THEN] "Total CO2e" is Visible on "Posted Service Shpt. Subform". + Assert.IsTrue( + PostedServiceShipmentSubform."Total CO2e".Visible(), + StrSubstNo(FieldShouldBeVisibleErr, PostedServiceShipmentSubform."Total CO2e".Caption(), PostedServiceShipmentSubform.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreNotVisibleOnPostedServiceShptSubformIsEnableValueChainTrackingIsFalse() + var + PostedServiceShipmentSubform: TestPage "Posted Service Shpt. Subform"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are not Visible on "Posted Service Shpt. Subform" + // if Enable Value Chain Tracking is false in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(false); + + // [WHEN] Open "Posted Service Shpt. Subform". + PostedServiceShipmentSubform.OpenEdit(); + + // [THEN] "Total CO2e" are not Visible on "Posted Service Shpt. Subform". + Assert.IsFalse( + PostedServiceShipmentSubform."Total CO2e".Visible(), + StrSubstNo(FieldShouldNotBeVisibleErr, PostedServiceShipmentSubform."Total CO2e".Caption(), PostedServiceShipmentSubform.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreVisibleOnServiceOrderSubformIsEnableValueChainTrackingIsTrue() + var + ServiceOrderSubform: TestPage "Service Order Subform"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are Visible on "Service Order Subform" + // if Enable Value Chain Tracking is true in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [WHEN] Open "Service Order Subform". + ServiceOrderSubform.OpenEdit(); + + // [THEN] "Total CO2e" is Visible on "Service Order Subform". + Assert.IsTrue( + ServiceOrderSubform."Total CO2e".Visible(), + StrSubstNo(FieldShouldBeVisibleErr, ServiceOrderSubform."Total CO2e".Caption(), ServiceOrderSubform.Caption())); + end; + + [Test] + procedure VerifySustFieldsAreNotVisibleOnServiceOrderSubformIsEnableValueChainTrackingIsFalse() + var + ServiceOrderSubform: TestPage "Service Order Subform"; + begin + // [SCENARIO 580158] Verify Sustainability Fields are not Visible on "Service Order Subform" + // if Enable Value Chain Tracking is false in Sustainability Setup. + LibrarySustainability.CleanUpBeforeTesting(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(false); + + // [WHEN] Open "Service Order Subform". + ServiceOrderSubform.OpenEdit(); + + // [THEN] "Total CO2e" are not Visible on "Service Order Subform". + Assert.IsFalse( + ServiceOrderSubform."Total CO2e".Visible(), + StrSubstNo(FieldShouldNotBeVisibleErr, ServiceOrderSubform."Total CO2e".Caption(), ServiceOrderSubform.Caption())); + end; + local procedure CreateSustainabilityAccount(var AccountCode: Code[20]; var CategoryCode: Code[20]; var SubcategoryCode: Code[20]; i: Integer): Record "Sustainability Account" begin CreateSustainabilitySubcategory(CategoryCode, SubcategoryCode, i); diff --git a/Apps/W1/Sustainability/test/src/SustainabilityServiceTests.Codeunit.al b/Apps/W1/Sustainability/test/src/SustainabilityServiceTests.Codeunit.al new file mode 100644 index 0000000000..d67e41a3ca --- /dev/null +++ b/Apps/W1/Sustainability/test/src/SustainabilityServiceTests.Codeunit.al @@ -0,0 +1,2690 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Sustainability.Tests; + +using Microsoft.Foundation.Address; +using Microsoft.Inventory.Item; +using Microsoft.Projects.Project.Job; +using Microsoft.Projects.Resources.Resource; +using Microsoft.Purchases.Document; +using Microsoft.Service.Document; +using Microsoft.Service.History; +using Microsoft.Service.Item; +using Microsoft.Service.Test; +using Microsoft.Sustainability.Account; +using Microsoft.Sustainability.Emission; +using Microsoft.Sustainability.Ledger; +using Microsoft.Test.Sustainability; + +codeunit 148218 "Sustainability Service Tests" +{ + Subtype = Test; + TestType = Uncategorized; + TestPermissions = Disabled; + + var + Assert: Codeunit "Assert"; + LibraryJob: Codeunit "Library - Job"; + LibraryERM: Codeunit "Library - ERM"; + LibrarySales: Codeunit "Library - Sales"; + LibraryRandom: Codeunit "Library - Random"; + LibraryService: Codeunit "Library - Service"; + LibraryResource: Codeunit "Library - Resource"; + LibraryPurchase: Codeunit "Library - Purchase"; + LibraryInventory: Codeunit "Library - Inventory"; + LibrarySustainability: Codeunit "Library - Sustainability"; + LibraryTestInitialize: Codeunit "Library - Test Initialize"; + IsInitialized: Boolean; + AccountCodeLbl: Label 'AccountCode%1', Comment = '%1 = Number'; + CategoryCodeLbl: Label 'CategoryCode%1', Comment = '%1 = Number'; + SubcategoryCodeLbl: Label 'SubcategoryCode%1', Comment = '%1 = Number'; + ValueMustBeEqualErr: Label '%1 must be equal to %2 in the %3.', Comment = '%1 = Field Caption , %2 = Expected Value, %3 = Table Caption'; + CO2eMustNotBeZeroErr: Label 'The CO2e fields must have a value that is not 0.'; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceDocumentIsPostedWithShipAndInvoiceForItem() + var + SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + CO2ePerUnit: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Service document is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e Per Unit". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 200); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Item."No.", LibraryRandom.RandIntInRange(10, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e Per Unit", CO2ePerUnit); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Invoice. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceInvoiceHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * ServiceLine.Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * ServiceLine.Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + SustainabilityLedgerEntry.SetRange("Document No.", FindServiceInvoiceHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityLedgerEntry, 0); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceDocumentIsPostedWithShipAndInvoiceForResource() + var + SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + CO2ePerUnit: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Service document is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e Per Unit". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 200); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Resource."No.", LibraryRandom.RandInt(20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e Per Unit", CO2ePerUnit); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Invoice. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceInvoiceHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * ServiceLine.Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * ServiceLine.Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + SustainabilityLedgerEntry.SetRange("Document No.", FindServiceInvoiceHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityLedgerEntry, 0); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceDocumentIsPostedWithShipAndConsume() + var + SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + CO2ePerUnit: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value Entry should be created when the Service document is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e Per Unit". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 200); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Item."No.", LibraryRandom.RandInt(20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e Per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Consume", ServiceLine.Quantity); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Consume. + LibraryService.PostServiceOrder(ServiceHeader, true, true, false); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * ServiceLine.Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * ServiceLine.Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + SustainabilityLedgerEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityLedgerEntry, 0); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceDocumentIsPostedWithShipAndConsumeForResource() + var + SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + CO2ePerUnit: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value Entry should be created when the Service document is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e Per Unit". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 200); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Resource."No.", LibraryRandom.RandInt(20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e Per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Consume", ServiceLine.Quantity); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Consume. + LibraryService.PostServiceOrder(ServiceHeader, true, true, false); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * ServiceLine.Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * ServiceLine.Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + SustainabilityLedgerEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityLedgerEntry, 0); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceDocumentIsPartiallyPostedWithShipAndInvoice() + var + SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + CO2ePerUnit: Decimal; + Quantity: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Service document is partially posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e Per Unit". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 500); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Item."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e Per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Invoice", Quantity); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Invoice. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceInvoiceHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + SustainabilityLedgerEntry.SetRange("Document No.", FindServiceInvoiceHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityLedgerEntry, 0); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), -CO2ePerUnit * Quantity, ServiceLine.TableCaption())); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceDocumentIsPartiallyPostedWithShipAndInvoiceForResource() + var + SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + CO2ePerUnit: Decimal; + Quantity: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Service document is partially posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e per Unit". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 500); + + // [GIVEN] Generate "Quantity". + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Resource."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Invoice", Quantity); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Invoice. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceInvoiceHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + SustainabilityLedgerEntry.SetRange("Document No.", FindServiceInvoiceHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityLedgerEntry, 0); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), -CO2ePerUnit * Quantity, ServiceLine.TableCaption())); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceDocumentIsPartiallyPostedWithShipAndConsume() + var + SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + CO2ePerUnit: Decimal; + Quantity: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Service document is partially posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e per Unit". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 500); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Item."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Consume", Quantity); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Consume. + LibraryService.PostServiceOrder(ServiceHeader, true, true, false); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + SustainabilityLedgerEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityLedgerEntry, 0); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), -CO2ePerUnit * Quantity, ServiceLine.TableCaption())); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceDocumentIsPartiallyPostedWithShipAndConsumeForResource() + var + SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + CO2ePerUnit: Decimal; + Quantity: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Service document is partially posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e" and "Quantity". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 500); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Resource."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Consume", Quantity); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Consume. + LibraryService.PostServiceOrder(ServiceHeader, true, true, false); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + SustainabilityLedgerEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityLedgerEntry, 0); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), -CO2ePerUnit * Quantity, ServiceLine.TableCaption())); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceDocumentIsPartiallyPostedWithShip() + var + SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + CO2ePerUnit: Decimal; + Quantity: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Service document is partially posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e per Unit" and Quantity. + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 500); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Item."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Ship", Quantity); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship. + LibraryService.PostServiceOrder(ServiceHeader, true, false, false); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), -CO2ePerUnit * Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), 0, SustainabilityValueEntry.TableCaption())); + + SustainabilityLedgerEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityLedgerEntry, 0); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + 0, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), 0, ServiceLine.TableCaption())); + + // [WHEN] Post the Service Order with Invoice. + LibraryService.PostServiceOrder(ServiceHeader, false, false, true); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceInvoiceHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + CO2ePerUnit * Quantity, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), CO2ePerUnit * Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * Quantity, SustainabilityValueEntry.TableCaption())); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), -CO2ePerUnit * Quantity, ServiceLine.TableCaption())); + end; + + [Test] + procedure SustainabilityValueEntryShouldNotBeCreatedWhenServiceDocumentIsPartiallyPostedWithShipForResource() + var + SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + CO2ePerUnit: Decimal; + Quantity: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should not be created when the Service document is partially posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e per Unit" and "Quantity". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 500); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Resource."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Ship", Quantity); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship. + LibraryService.PostServiceOrder(ServiceHeader, true, false, false); + + // [THEN] Verify Sustainability Value entry must not be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityValueEntry, 0); + + SustainabilityLedgerEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityLedgerEntry, 0); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + 0, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), 0, ServiceLine.TableCaption())); + + // [WHEN] Post the Service Order with Invoice. + LibraryService.PostServiceOrder(ServiceHeader, false, false, true); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceInvoiceHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + 0, + 0, + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * Quantity, SustainabilityValueEntry.TableCaption())); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), -CO2ePerUnit * Quantity, ServiceLine.TableCaption())); + end; + + [Test] + [HandlerFunctions('ConfirmHandler')] + procedure SustainabilityValueEntryShouldBeCreatedWhenUndoConsumptionIsPosted() + var + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + CO2ePerUnit: Decimal; + Quantity: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Undo Consumption is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e per Unit" and "Quantity". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 500); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Item."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Consume", Quantity); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Consume. + LibraryService.PostServiceOrder(ServiceHeader, true, true, false); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), -CO2ePerUnit * Quantity, ServiceLine.TableCaption())); + + // [WHEN] Undo Consumption Lines. + LibraryService.UndoConsumptionLinesByServiceOrderNo(ServiceHeader."No."); + + // [THEN] Verify Sustainability Value entry must be created When Undo Consumption is posted. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityValueEntry, 2); + + SustainabilityValueEntry.CalcSums("CO2e Amount (Expected)", "CO2e Amount (Actual)"); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), 0, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + 0, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), 0, ServiceLine.TableCaption())); + end; + + [Test] + [HandlerFunctions('ConfirmHandler')] + procedure SustainabilityValueEntryShouldBeCreatedWhenUndoConsumptionIsPostedForResource() + var + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + CO2ePerUnit: Decimal; + Quantity: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Undo Consumption is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e per Unit" and "Quantity". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 500); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Resource."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Consume", Quantity); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Consume. + LibraryService.PostServiceOrder(ServiceHeader, true, true, false); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), -CO2ePerUnit * Quantity, ServiceLine.TableCaption())); + + // [WHEN] Undo Consumption Lines. + LibraryService.UndoConsumptionLinesByServiceOrderNo(ServiceHeader."No."); + + // [THEN] Verify Sustainability Value entry must be created When Undo Consumption is posted. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityValueEntry, 2); + + SustainabilityValueEntry.CalcSums("CO2e Amount (Expected)", "CO2e Amount (Actual)"); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), 0, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + 0, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), 0, ServiceLine.TableCaption())); + end; + + [Test] + [HandlerFunctions('ConfirmHandler')] + procedure SustainabilityValueEntryShouldBeCreatedWhenUndoShipmentIsPosted() + var + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + CO2ePerUnit: Decimal; + Quantity: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Undo Shipment is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e per Unit" and "Quantity". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 500); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Item."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Ship", Quantity); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship. + LibraryService.PostServiceOrder(ServiceHeader, true, false, false); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), -CO2ePerUnit * Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), 0, SustainabilityValueEntry.TableCaption())); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + 0, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), 0, ServiceLine.TableCaption())); + + // [WHEN] Undo Consumption Lines. + LibraryService.UndoShipmentLinesByServiceOrderNo(ServiceHeader."No."); + + // [THEN] Verify Sustainability Value entry must be created When Undo Consumption is posted. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityValueEntry, 4); + + SustainabilityValueEntry.CalcSums("CO2e Amount (Expected)", "CO2e Amount (Actual)"); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), 0, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + 0, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), 0, ServiceLine.TableCaption())); + end; + + [Test] + [HandlerFunctions('ConfirmHandler')] + procedure SustainabilityValueEntryShouldNotBeCreatedWhenUndoShipmentIsPostedForResource() + var + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + CO2ePerUnit: Decimal; + Quantity: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should not be created when the Undo Shipment is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e per Unit" and "Quantity". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 500); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Resource."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Ship", Quantity); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship. + LibraryService.PostServiceOrder(ServiceHeader, true, false, false); + + // [THEN] Verify Sustainability Value entry must not be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityValueEntry, 0); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + 0, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), 0, ServiceLine.TableCaption())); + + // [WHEN] Undo Consumption Lines. + LibraryService.UndoShipmentLinesByServiceOrderNo(ServiceHeader."No."); + + // [THEN] Verify Sustainability Value entry must not be created When Undo Consumption is posted. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityValueEntry, 0); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + 0, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), 0, ServiceLine.TableCaption())); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceInvoiceIsPosted() + var + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceInvoiceHeader: Record "Service Invoice Header"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + CO2ePerUnit: Decimal; + Quantity: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Service Invoice is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e per Unit" and "Quantity". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 500); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Invoice. + CreateServiceInvoiceWithServiceLine(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), Item."No."); + ServiceLine.Validate(Quantity, Quantity); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e per Unit", CO2ePerUnit); + ServiceLine.Modify(); + + // [WHEN] Post the Service Invoice. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [THEN] Verify Sustainability Value entry must be created. + FindServiceInvoiceHeader(ServiceInvoiceHeader, ServiceHeader."No."); + SustainabilityValueEntry.SetRange("Document No.", ServiceInvoiceHeader."No."); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + -CO2ePerUnit * Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * Quantity, SustainabilityValueEntry.TableCaption())); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceInvoiceIsPostedForResource() + var + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceInvoiceHeader: Record "Service Invoice Header"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + CO2ePerUnit: Decimal; + Quantity: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Service Invoice is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e per Unit" and "Quantity". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 500); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Invoice. + CreateServiceInvoiceWithServiceLineForResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), Resource."No."); + ServiceLine.Validate(Quantity, Quantity); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e per Unit", CO2ePerUnit); + ServiceLine.Modify(); + + // [WHEN] Post the Service Invoice. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [THEN] Verify Sustainability Value entry must be created. + FindServiceInvoiceHeader(ServiceInvoiceHeader, ServiceHeader."No."); + SustainabilityValueEntry.SetRange("Document No.", ServiceInvoiceHeader."No."); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + -Quantity * CO2ePerUnit, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -Quantity * CO2ePerUnit, SustainabilityValueEntry.TableCaption())); + end; + + [Test] + procedure TotalCO2eEmissionMustBeAutoFlowFromItem() + var + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceInvoiceHeader: Record "Service Invoice Header"; + PurchaseHeader: Record "Purchase Header"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + CountryRegion: Record "Country/Region"; + EmissionFee: array[3] of Record "Emission Fee"; + Item: Record Item; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + ExpectedCO2eEmission: Decimal; + EmissionCO2: Decimal; + EmissionCH4: Decimal; + EmissionN2O: Decimal; + Quantity: Decimal; + begin + // [SCENARIO 580158] Verify Total CO2e Emission must be auto flow from Item. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Generate Emission and Quantity. + EmissionCO2 := LibraryRandom.RandInt(100); + EmissionCH4 := LibraryRandom.RandInt(100); + EmissionN2O := LibraryRandom.RandInt(100); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Create Country/Region. + LibraryERM.CreateCountryRegion(CountryRegion); + + // [GIVEN] Create Emission Fee. + CreateEmissionFeeWithEmissionScope(EmissionFee, SustainabilityAccount."Emission Scope", CountryRegion.Code); + + // [GIVEN] Save Expected CO2e Emission. + ExpectedCO2eEmission := + (EmissionCH4 * EmissionFee[1]."Carbon Equivalent Factor" + EmissionCO2 * EmissionFee[2]."Carbon Equivalent Factor" + EmissionN2O * EmissionFee[3]."Carbon Equivalent Factor") / Quantity; + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post Purchase Document. + CreateAndPostPurchaseDocument(PurchaseHeader, Item."No.", Quantity, EmissionFee[1]."Country/Region Code", AccountCode, EmissionCO2, EmissionCH4, EmissionN2O); + + // [GIVEN] Create a Service Invoice. + CreateServiceInvoiceWithServiceLine(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), Item."No."); + ServiceLine.Validate(Quantity, Quantity); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Modify(); + + // [WHEN] Post the Service Invoice. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [THEN] Verify Sustainability Value entry must be created. + FindServiceInvoiceHeader(ServiceInvoiceHeader, ServiceHeader."No."); + SustainabilityValueEntry.SetRange("Document No.", ServiceInvoiceHeader."No."); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + -ExpectedCO2eEmission * Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -ExpectedCO2eEmission * Quantity, SustainabilityValueEntry.TableCaption())); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceCreditMemoIsPosted() + var + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceCreditMemoHeader: Record "Service Cr.Memo Header"; + PurchaseHeader: Record "Purchase Header"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + CountryRegion: Record "Country/Region"; + EmissionFee: array[3] of Record "Emission Fee"; + Item: Record Item; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + ExpectedCO2eEmission: Decimal; + EmissionCO2: Decimal; + EmissionCH4: Decimal; + EmissionN2O: Decimal; + Quantity: Decimal; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Service Credit Memo is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Generate Emission and Quantity. + EmissionCO2 := LibraryRandom.RandInt(100); + EmissionCH4 := LibraryRandom.RandInt(100); + EmissionN2O := LibraryRandom.RandInt(100); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Create Country/Region. + LibraryERM.CreateCountryRegion(CountryRegion); + + // [GIVEN] Create Emission Fee. + CreateEmissionFeeWithEmissionScope(EmissionFee, SustainabilityAccount."Emission Scope", CountryRegion.Code); + + // [GIVEN] Save Expected CO2e Emission. + ExpectedCO2eEmission := + (EmissionCH4 * EmissionFee[1]."Carbon Equivalent Factor" + EmissionCO2 * EmissionFee[2]."Carbon Equivalent Factor" + EmissionN2O * EmissionFee[3]."Carbon Equivalent Factor") / Quantity; + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post Purchase Document. + CreateAndPostPurchaseDocument(PurchaseHeader, Item."No.", Quantity, EmissionFee[1]."Country/Region Code", AccountCode, EmissionCO2, EmissionCH4, EmissionN2O); + + // [GIVEN] Create a Service Credit Memo. + CreateServiceCrMemoWithServiceLine(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), Item."No."); + ServiceLine.Validate(Quantity, Quantity); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Modify(); + + // [WHEN] Post the Service Credit Memo. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [THEN] Verify Sustainability Value entry must be created. + FindServiceCreditMemoHeader(ServiceCreditMemoHeader, ServiceHeader."No."); + SustainabilityValueEntry.SetRange("Document No.", ServiceCreditMemoHeader."No."); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + ExpectedCO2eEmission * Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), ExpectedCO2eEmission * Quantity, SustainabilityValueEntry.TableCaption())); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceCreditMemoIsPostedForResource() + var + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceCreditMemoHeader: Record "Service Cr.Memo Header"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + Quantity: Decimal; + begin + // [SCENARIO 580158] Verify Sustainability Value entry should be created when the Service Credit Memo is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Generate Quantity. + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Credit Memo. + CreateServiceCrMemoWithServiceLineForResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), Resource."No."); + ServiceLine.Validate(Quantity, Quantity); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", LibraryRandom.RandInt(100)); + ServiceLine.Modify(); + + // [WHEN] Post the Service Credit Memo. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [THEN] Verify Sustainability Value entry must be created. + FindServiceCreditMemoHeader(ServiceCreditMemoHeader, ServiceHeader."No."); + SustainabilityValueEntry.SetRange("Document No.", ServiceCreditMemoHeader."No."); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + Quantity, + SustainabilityValueEntry."Valued Quantity", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + Quantity, + SustainabilityValueEntry."Invoiced Quantity", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + ServiceLine."Total CO2e", + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), ServiceLine."Total CO2e", SustainabilityValueEntry.TableCaption())); + end; + + [Test] + procedure ServiceShipmentHeaderAndServiceInvoiceHeaderIsCreatedWithSustainabilityAccount() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + TotalCO2e: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Service Shipment Header and Service Invoice Header is created with Sustainability Account. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e". + TotalCO2e := LibraryRandom.RandIntInRange(100, 500); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Item."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", TotalCO2e); + ServiceLine.Validate("Qty. to Ship", LibraryRandom.RandIntInRange(10, 10)); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship. + LibraryService.PostServiceOrder(ServiceHeader, true, false, false); + + // [THEN] Verify Service Shipment Line must be created with Sustainability Account. + VerifyServiceShipmentLine(ServiceHeader, ServiceLine, TotalCO2e); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + 0, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), 0, ServiceLine.TableCaption())); + + // [WHEN] Post the Service Order with Invoice. + LibraryService.PostServiceOrder(ServiceHeader, false, false, true); + + // [THEN] Verify Service Invoice Line must be created with Sustainability Account. + VerifyServiceInvoiceLine(ServiceHeader, ServiceLine, TotalCO2e); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + -TotalCO2e / 2, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), -TotalCO2e / 2, ServiceLine.TableCaption())); + end; + + [Test] + procedure ServiceShipmentHeaderAndServiceInvoiceHeaderIsCreatedWithSustainabilityAccountForResource() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + TotalCO2e: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Service Shipment Header and Service Invoice Header is created with Sustainability Account. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e". + TotalCO2e := LibraryRandom.RandIntInRange(100, 500); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Resource."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", TotalCO2e); + ServiceLine.Validate("Qty. to Ship", LibraryRandom.RandIntInRange(10, 10)); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship. + LibraryService.PostServiceOrder(ServiceHeader, true, false, false); + + // [THEN] Verify Service Shipment Line must be created with Sustainability Account. + VerifyServiceShipmentLine(ServiceHeader, ServiceLine, TotalCO2e); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + 0, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), 0, ServiceLine.TableCaption())); + + // [WHEN] Post the Service Order with Invoice. + LibraryService.PostServiceOrder(ServiceHeader, false, false, true); + + // [THEN] Verify Service Invoice Line must be created with Sustainability Account. + VerifyServiceInvoiceLine(ServiceHeader, ServiceLine, TotalCO2e); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + -TotalCO2e / 2, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), -TotalCO2e / 2, ServiceLine.TableCaption())); + end; + + [Test] + procedure ServiceShipmentHeaderIsCreatedWithSustainabilityAccountForConsumption() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + TotalCO2e: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Service Shipment Header is created with Sustainability Account For Consumption. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e". + TotalCO2e := LibraryRandom.RandIntInRange(100, 500); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Item."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", TotalCO2e); + ServiceLine.Validate("Qty. to Consume", LibraryRandom.RandIntInRange(10, 10)); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Consume. + LibraryService.PostServiceOrder(ServiceHeader, true, true, false); + + // [THEN] Verify Service Shipment Line must be created with Sustainability Account. + VerifyServiceShipmentLine(ServiceHeader, ServiceLine, TotalCO2e); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + -TotalCO2e / 2, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), -TotalCO2e / 2, ServiceLine.TableCaption())); + end; + + [Test] + procedure ServiceShipmentHeaderIsCreatedWithSustainabilityAccountForConsumptionForResource() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + TotalCO2e: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Service Shipment Header is created with Sustainability Account For Consumption. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e". + TotalCO2e := LibraryRandom.RandIntInRange(100, 500); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Resource."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", TotalCO2e); + ServiceLine.Validate("Qty. to Consume", LibraryRandom.RandIntInRange(10, 10)); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Consume. + LibraryService.PostServiceOrder(ServiceHeader, true, true, false); + + // [THEN] Verify Service Shipment Line must be created with Sustainability Account. + VerifyServiceShipmentLine(ServiceHeader, ServiceLine, TotalCO2e); + + // [THEN] Verify Posted Total CO2e in Service Line. + ServiceLine.Get(ServiceLine."Document Type", ServiceHeader."No.", ServiceLine."Line No."); + Assert.AreEqual( + -TotalCO2e / 2, + ServiceLine."Posted Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceLine.FieldCaption("Posted Total CO2e"), -TotalCO2e / 2, ServiceLine.TableCaption())); + end; + + [Test] + [HandlerFunctions('ConfirmHandler')] + procedure ReverseServiceShipmentLineIsCreatedWhenUndoConsumptionIsPosted() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + TotalCO2e: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Reverse Service Shipment Line is created when Undo Consumption is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e". + TotalCO2e := LibraryRandom.RandIntInRange(100, 500); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Item."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", TotalCO2e); + ServiceLine.Validate("Qty. to Consume", LibraryRandom.RandIntInRange(10, 10)); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Consume. + LibraryService.PostServiceOrder(ServiceHeader, true, true, false); + + // [THEN] Verify Service Shipment Line must be created with Sustainability Account. + VerifyServiceShipmentLine(ServiceHeader, ServiceLine, TotalCO2e); + + // [WHEN] Undo Consumption Lines. + LibraryService.UndoConsumptionLinesByServiceOrderNo(ServiceHeader."No."); + + // [THEN] Verify Reverse Service Shipment Line is created When Undo Consumption is posted. + VerifyServiceShipmentLine(ServiceHeader, ServiceLine, -TotalCO2e); + end; + + [Test] + [HandlerFunctions('ConfirmHandler')] + procedure ReverseServiceShipmentLineIsCreatedWhenUndoConsumptionIsPostedForResource() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + TotalCO2e: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Reverse Service Shipment Line is created when Undo Consumption is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e". + TotalCO2e := LibraryRandom.RandIntInRange(100, 500); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Resource."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", TotalCO2e); + ServiceLine.Validate("Qty. to Consume", LibraryRandom.RandIntInRange(10, 10)); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Consume. + LibraryService.PostServiceOrder(ServiceHeader, true, true, false); + + // [THEN] Verify Service Shipment Line must be created with Sustainability Account. + VerifyServiceShipmentLine(ServiceHeader, ServiceLine, TotalCO2e); + + // [WHEN] Undo Consumption Lines. + LibraryService.UndoConsumptionLinesByServiceOrderNo(ServiceHeader."No."); + + // [THEN] Verify Reverse Service Shipment Line is created When Undo Consumption is posted. + VerifyServiceShipmentLine(ServiceHeader, ServiceLine, -TotalCO2e); + end; + + [Test] + [HandlerFunctions('ConfirmHandler')] + procedure ReverseServiceShipmentLineIsCreatedWhenUndoShipmentIsPosted() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + TotalCO2e: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Reverse Service Shipment Line is created when Undo Shipment is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e". + TotalCO2e := LibraryRandom.RandIntInRange(100, 500); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Item."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", TotalCO2e); + ServiceLine.Validate("Qty. to Ship", LibraryRandom.RandIntInRange(10, 10)); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship. + LibraryService.PostServiceOrder(ServiceHeader, true, false, false); + + // [THEN] Verify Service Shipment Line must be created with Sustainability Account. + VerifyServiceShipmentLine(ServiceHeader, ServiceLine, TotalCO2e); + + // [WHEN] Undo Shipment Lines. + LibraryService.UndoShipmentLinesByServiceOrderNo(ServiceHeader."No."); + + // [THEN] Verify Reverse Service Shipment Line is created When Undo Shipment is posted. + VerifyServiceShipmentLine(ServiceHeader, ServiceLine, -TotalCO2e); + end; + + [Test] + [HandlerFunctions('ConfirmHandler')] + procedure ReverseServiceShipmentLineIsCreatedWhenUndoShipmentIsPostedForResource() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + TotalCO2e: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Reverse Service Shipment Line is created when Undo Shipment is posted. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e". + TotalCO2e := LibraryRandom.RandIntInRange(100, 500); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Resource."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", TotalCO2e); + ServiceLine.Validate("Qty. to Ship", LibraryRandom.RandIntInRange(10, 10)); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship. + LibraryService.PostServiceOrder(ServiceHeader, true, false, false); + + // [THEN] Verify Service Shipment Line must be created with Sustainability Account. + VerifyServiceShipmentLine(ServiceHeader, ServiceLine, TotalCO2e); + + // [WHEN] Undo Shipment Lines. + LibraryService.UndoShipmentLinesByServiceOrderNo(ServiceHeader."No."); + + // [THEN] Verify Reverse Service Shipment Line is created When Undo Shipment is posted. + VerifyServiceShipmentLine(ServiceHeader, ServiceLine, -TotalCO2e); + end; + + [Test] + procedure PostedServiceCrMemoIsPostedWithSustainabilityAccount() + var + SustainabilityAccount: Record "Sustainability Account"; + PurchaseHeader: Record "Purchase Header"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + CountryRegion: Record "Country/Region"; + EmissionFee: array[3] of Record "Emission Fee"; + Item: Record Item; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + ExpectedCO2eEmission: Decimal; + EmissionCO2: Decimal; + EmissionCH4: Decimal; + EmissionN2O: Decimal; + Quantity: Decimal; + begin + // [SCENARIO 580158] Verify Posted Service Cr.Memo is posted with Sustainability Account. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Generate Emission and Quantity. + EmissionCO2 := LibraryRandom.RandInt(100); + EmissionCH4 := LibraryRandom.RandInt(100); + EmissionN2O := LibraryRandom.RandInt(100); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Create Country/Region. + LibraryERM.CreateCountryRegion(CountryRegion); + + // [GIVEN] Create Emission Fee. + CreateEmissionFeeWithEmissionScope(EmissionFee, SustainabilityAccount."Emission Scope", CountryRegion.Code); + + // [GIVEN] Save Expected CO2e Emission. + ExpectedCO2eEmission := + (EmissionCH4 * EmissionFee[1]."Carbon Equivalent Factor" + EmissionCO2 * EmissionFee[2]."Carbon Equivalent Factor" + EmissionN2O * EmissionFee[3]."Carbon Equivalent Factor") / Quantity; + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post Purchase Document. + CreateAndPostPurchaseDocument(PurchaseHeader, Item."No.", Quantity, EmissionFee[1]."Country/Region Code", AccountCode, EmissionCO2, EmissionCH4, EmissionN2O); + + // [GIVEN] Create a Service Credit Memo. + CreateServiceCrMemoWithServiceLine(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), Item."No."); + ServiceLine.Validate(Quantity, Quantity); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Modify(); + + // [WHEN] Post the Service Credit Memo. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [THEN] Verify Service Credit Memo Line must be created with Sustainability Account. + VerifyServiceCreditMemoLine(ServiceHeader, ServiceLine, ExpectedCO2eEmission * Quantity); + end; + + [Test] + procedure PostedServiceCrMemoIsPostedWithSustainabilityAccountForResource() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Resource: Record Resource; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + Quantity: Decimal; + begin + // [SCENARIO 580158] Verify Posted Service Cr.Memo is posted with Sustainability Account. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Generate Quantity. + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Credit Memo. + CreateServiceCrMemoWithServiceLineForResource(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), Resource."No."); + ServiceLine.Validate(Quantity, Quantity); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", LibraryRandom.RandInt(100)); + ServiceLine.Modify(); + + // [WHEN] Post the Service Credit Memo. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [THEN] Verify Service Credit Memo Line must be created with Sustainability Account. + VerifyServiceCreditMemoLine(ServiceHeader, ServiceLine, ServiceLine."Total CO2e"); + end; + + [Test] + procedure VerifyTotalCO2eInPostedServiceCreditMemoStatistics() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceCreditMemoHeader: Record "Service Cr.Memo Header"; + PurchaseHeader: Record "Purchase Header"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + CountryRegion: Record "Country/Region"; + EmissionFee: array[3] of Record "Emission Fee"; + Item: Record Item; + PostedServiceCreditMemo: TestPage "Posted Service Credit Memo"; + ServiceCreditMemoStatistics: TestPage "Service Credit Memo Statistics"; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + ExpectedCO2eEmission: Decimal; + EmissionCO2: Decimal; + EmissionCH4: Decimal; + EmissionN2O: Decimal; + Quantity: Decimal; + begin + // [SCENARIO 580158] Verify Total CO2e in Posted Service Credit Memo Statistics. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Generate Emission and Quantity. + EmissionCO2 := LibraryRandom.RandInt(100); + EmissionCH4 := LibraryRandom.RandInt(100); + EmissionN2O := LibraryRandom.RandInt(100); + Quantity := LibraryRandom.RandIntInRange(10, 10); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Create Country/Region. + LibraryERM.CreateCountryRegion(CountryRegion); + + // [GIVEN] Create Emission Fee. + CreateEmissionFeeWithEmissionScope(EmissionFee, SustainabilityAccount."Emission Scope", CountryRegion.Code); + + // [GIVEN] Save Expected CO2e Emission. + ExpectedCO2eEmission := + (EmissionCH4 * EmissionFee[1]."Carbon Equivalent Factor" + EmissionCO2 * EmissionFee[2]."Carbon Equivalent Factor" + EmissionN2O * EmissionFee[3]."Carbon Equivalent Factor") / Quantity; + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post Purchase Document. + CreateAndPostPurchaseDocument(PurchaseHeader, Item."No.", Quantity, EmissionFee[1]."Country/Region Code", AccountCode, EmissionCO2, EmissionCH4, EmissionN2O); + + // [GIVEN] Create a Service Credit Memo. + CreateServiceCrMemoWithServiceLine(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), Item."No."); + ServiceLine.Validate(Quantity, Quantity); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Modify(); + + // [GIVEN] Post the Service Credit Memo. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [GIVEN] Find the Service Credit Memo Header. + FindServiceCreditMemoHeader(ServiceCreditMemoHeader, ServiceHeader."No."); + + // [WHEN] Open Posted Service Credit Memo Page and Go to Service Statistics. + ServiceCreditMemoStatistics.Trap(); + PostedServiceCreditMemo.OpenEdit(); + PostedServiceCreditMemo.GoToRecord(ServiceCreditMemoHeader); + PostedServiceCreditMemo.ServiceStatistics.Invoke(); + + // [THEN] Verify Total CO2e in "Service Credit Memo Statistics". + ServiceCreditMemoStatistics."Total CO2e".AssertEquals(Quantity * ExpectedCO2eEmission); + end; + + [Test] + procedure VerifyTotalCO2eInPostedServiceInvoiceStatistics() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceInvoiceHeader: Record "Service Invoice Header"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + PostedServiceInvoice: TestPage "Posted Service Invoice"; + ServiceInvoiceStatistics: TestPage "Service Invoice Statistics"; + TotalCO2e: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Total CO2e in Posted Service Invoice Statistics. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e". + TotalCO2e := LibraryRandom.RandIntInRange(100, 500); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Invoice. + CreateServiceInvoiceWithServiceLine(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), Item."No."); + ServiceLine.Validate(Quantity, LibraryRandom.RandIntInRange(10, 10)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", TotalCO2e); + ServiceLine.Modify(); + + // [GIVEN] Post the Service Invoice. + LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [GIVEN] Find the Service Invoice Header. + FindServiceInvoiceHeader(ServiceInvoiceHeader, ServiceHeader."No."); + + // [WHEN] Open Posted Service Invoice Page and Go to Service Statistics. + ServiceInvoiceStatistics.Trap(); + PostedServiceInvoice.OpenEdit(); + PostedServiceInvoice.GoToRecord(ServiceInvoiceHeader); + PostedServiceInvoice.ServiceStatistics.Invoke(); + + // [THEN] Verify Total CO2e in "Service Invoice Statistics". + ServiceInvoiceStatistics."Total CO2e".AssertEquals(-TotalCO2e); + end; + + [Test] + procedure VerifyTotalCO2eAndPostedTotalCO2eInServiceOrderStatistics() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + ServiceOrder: TestPage "Service Order"; + ServiceOrderStatistics: TestPage "Service Order Statistics"; + TotalCO2e: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify "Total CO2e" and "Posted Total CO2e" in Service Order Statistics. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e". + TotalCO2e := LibraryRandom.RandIntInRange(100, 500); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), '', Item."No.", LibraryRandom.RandIntInRange(20, 20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", TotalCO2e); + ServiceLine.Validate("Qty. to Ship", LibraryRandom.RandIntInRange(10, 10)); + ServiceLine.Modify(); + + // [GIVEN] Post the Service Order with Ship. + LibraryService.PostServiceOrder(ServiceHeader, true, false, false); + + // [WHEN] Open Service Order Page and Go to Service Order Statistics. + ServiceOrderStatistics.Trap(); + ServiceOrder.OpenEdit(); + ServiceOrder.GoToRecord(ServiceHeader); + ServiceOrder.ServiceOrderStatistics.Invoke(); + + // [THEN] Verify Total CO2e in "Service Order Statistics". + ServiceOrderStatistics."Total CO2e".AssertEquals(TotalCO2e); + ServiceOrderStatistics."Posted Total CO2e".AssertEquals(0); + ServiceOrderStatistics.Close(); + ServiceOrder.Close(); + + // [GIVEN] Post the Service Order with Invoice. + LibraryService.PostServiceOrder(ServiceHeader, false, false, true); + + // [WHEN] Open Service Order Page and Go to Service Order Statistics. + ServiceOrderStatistics.Trap(); + ServiceOrder.OpenEdit(); + ServiceOrder.GoToRecord(ServiceHeader); + ServiceOrder.ServiceOrderStatistics.Invoke(); + + // [THEN] Verify Total CO2e in "Service Order Statistics". + ServiceOrderStatistics."Total CO2e".AssertEquals(TotalCO2e); + ServiceOrderStatistics."Posted Total CO2e".AssertEquals(-TotalCO2e / 2); + ServiceOrderStatistics.Close(); + ServiceOrder.Close(); + end; + + [Test] + procedure VerifyTotalCO2eInServiceInvoiceStatistics() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + ServiceInvoice: TestPage "Service Invoice"; + ServiceStatistics: TestPage "Service Statistics"; + TotalCO2e: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Total CO2e in Service Invoice Statistics. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e". + TotalCO2e := LibraryRandom.RandIntInRange(100, 500); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Invoice. + CreateServiceInvoiceWithServiceLine(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), Item."No."); + ServiceLine.Validate(Quantity, LibraryRandom.RandIntInRange(10, 10)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", TotalCO2e); + ServiceLine.Modify(); + + // [WHEN] Open Service Invoice Page and Go to Service Statistics. + ServiceStatistics.Trap(); + ServiceInvoice.OpenEdit(); + ServiceInvoice.GoToRecord(ServiceHeader); + ServiceInvoice.ServiceStatistics.Invoke(); + + // [THEN] Verify Total CO2e in "Service Invoice Statistics". + ServiceStatistics."Total CO2e".AssertEquals(TotalCO2e); + ServiceStatistics."Posted Total CO2e".AssertEquals(0); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceDocumentIsPostedWithShipAndConsumeForJob() + var + SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Job: Record Job; + JobTask: Record "Job Task"; + Item: Record Item; + CO2ePerUnit: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value Entry should be created when the Service document is posted with Ship and Consume for Job. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e Per Unit". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 200); + + // [GIVEN] Create a Job with Job Task. + CreateJobWithJobTask(JobTask); + Job.Get(JobTask."Job No."); + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithItem(ServiceHeader, ServiceLine, Job."Sell-to Customer No.", '', Item."No.", LibraryRandom.RandInt(20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e Per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Consume", ServiceLine.Quantity); + ServiceLine.Validate("Job No.", JobTask."Job No."); + ServiceLine.Validate("Job Task No.", JobTask."Job Task No."); + ServiceLine.Validate("Job Line Type", ServiceLine."Job Line Type"::Billable); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Consume. + LibraryService.PostServiceOrder(ServiceHeader, true, true, false); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * ServiceLine.Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * ServiceLine.Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + SustainabilityLedgerEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityLedgerEntry, 0); + end; + + [Test] + procedure SustainabilityValueEntryShouldBeCreatedWhenServiceDocumentIsPostedWithShipAndConsumeForResourceForJob() + var + SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; + SustainabilityValueEntry: Record "Sustainability Value Entry"; + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Job: Record Job; + JobTask: Record "Job Task"; + Resource: Record Resource; + CO2ePerUnit: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify Sustainability Value Entry should be created when the Service document is posted with Ship and Consume for Resource for Job. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "CO2e Per Unit". + CO2ePerUnit := LibraryRandom.RandIntInRange(100, 200); + + // [GIVEN] Create a Job with Job Task. + CreateJobWithJobTask(JobTask); + Job.Get(JobTask."Job No."); + + // [GIVEN] Create a Resource. + LibraryResource.CreateResourceNew(Resource); + + // [GIVEN] Create a Service Header. + CreateServiceOrderWithResource(ServiceHeader, ServiceLine, Job."Sell-to Customer No.", '', Resource."No.", LibraryRandom.RandInt(20)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("CO2e Per Unit", CO2ePerUnit); + ServiceLine.Validate("Qty. to Consume", ServiceLine.Quantity); + ServiceLine.Validate("Job No.", JobTask."Job No."); + ServiceLine.Validate("Job Task No.", JobTask."Job Task No."); + ServiceLine.Validate("Job Line Type", ServiceLine."Job Line Type"::Billable); + ServiceLine.Modify(); + + // [WHEN] Post the Service Order with Ship and Consume. + LibraryService.PostServiceOrder(ServiceHeader, true, true, false); + + // [THEN] Verify Sustainability Value entry must be created. + SustainabilityValueEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + SustainabilityValueEntry.FindFirst(); + Assert.RecordCount(SustainabilityValueEntry, 1); + Assert.AreEqual( + -CO2ePerUnit * ServiceLine.Quantity, + SustainabilityValueEntry."CO2e Amount (Actual)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Actual)"), -CO2ePerUnit * ServiceLine.Quantity, SustainabilityValueEntry.TableCaption())); + Assert.AreEqual( + 0, + SustainabilityValueEntry."CO2e Amount (Expected)", + StrSubstNo(ValueMustBeEqualErr, SustainabilityValueEntry.FieldCaption("CO2e Amount (Expected)"), 0, SustainabilityValueEntry.TableCaption())); + + SustainabilityLedgerEntry.SetRange("Document No.", FindServiceShipmentHeader(ServiceHeader."No.")); + Assert.RecordCount(SustainabilityLedgerEntry, 0); + end; + + [Test] + procedure VerifySystemMustThrowAnErrorIfTotalCO2eIsZero() + var + SustainabilityAccount: Record "Sustainability Account"; + ServiceHeader: Record "Service Header"; + ServiceLine: Record "Service Line"; + Item: Record Item; + TotalCO2e: Decimal; + CategoryCode: Code[20]; + SubcategoryCode: Code[20]; + AccountCode: Code[20]; + begin + // [SCENARIO 580158] Verify System must throw an error if Total CO2e is zero. + Initialize(); + + // [GIVEN] Update "Enable Value Chain Tracking" in Sustainability Setup. + LibrarySustainability.UpdateValueChainTrackingInSustainabilitySetup(true); + + // [GIVEN] Create a Sustainability Account. + CreateSustainabilityAccount(AccountCode, CategoryCode, SubcategoryCode, LibraryRandom.RandInt(10)); + SustainabilityAccount.Get(AccountCode); + + // [GIVEN] Generate "Total CO2e". + TotalCO2e := 0; + + // [GIVEN] Create an Item. + LibraryInventory.CreateItem(Item); + + // [GIVEN] Post a Positive Adjustment. + LibraryInventory.PostPositiveAdjustment(Item, '', '', '', LibraryRandom.RandIntInRange(200, 300), WorkDate(), LibraryRandom.RandInt(10)); + + // [GIVEN] Create a Service Invoice. + CreateServiceInvoiceWithServiceLine(ServiceHeader, ServiceLine, LibrarySales.CreateCustomerNo(), Item."No."); + ServiceLine.Validate(Quantity, LibraryRandom.RandIntInRange(10, 10)); + ServiceLine.Validate("Sust. Account No.", AccountCode); + ServiceLine.Validate("Total CO2e", TotalCO2e); + ServiceLine.Modify(); + + // [WHEN] Post the Service Invoice. + asserterror LibraryService.PostServiceOrder(ServiceHeader, true, false, true); + + // [THEN] Verify System must throw an error if Total CO2e is zero. + Assert.ExpectedError(CO2eMustNotBeZeroErr); + end; + + local procedure Initialize() + var + LibraryERMCountryData: Codeunit "Library - ERM Country Data"; + begin + LibraryTestInitialize.OnTestInitialize(Codeunit::"Sustainability Service Tests"); + LibrarySustainability.CleanUpBeforeTesting(); + if IsInitialized then + exit; + + LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"Sustainability Service Tests"); + + LibrarySales.SetCreditWarningsToNoWarnings(); + LibraryERMCountryData.CreateVATData(); + LibraryERMCountryData.UpdateGeneralLedgerSetup(); + LibraryERMCountryData.UpdateSalesReceivablesSetup(); + LibraryERMCountryData.CreateGeneralPostingSetupData(); + LibraryERMCountryData.UpdateVATPostingSetup(); + LibraryERMCountryData.UpdateGeneralPostingSetup(); + LibraryERMCountryData.UpdateLocalData(); + LibrarySales.SetExtDocNo(false); + + LibraryERMCountryData.CompanyInfoSetVATRegistrationNo(); + IsInitialized := true; + + LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"Sustainability Service Tests"); + end; + + local procedure CreateSustainabilityAccount(var AccountCode: Code[20]; var CategoryCode: Code[20]; var SubcategoryCode: Code[20]; i: Integer): Record "Sustainability Account" + begin + CreateSustainabilitySubcategory(CategoryCode, SubcategoryCode, i); + AccountCode := StrSubstNo(AccountCodeLbl, i); + exit(LibrarySustainability.InsertSustainabilityAccount( + AccountCode, '', CategoryCode, SubcategoryCode, Enum::"Sustainability Account Type"::Posting, '', true)); + end; + + local procedure CreateSustainabilitySubcategory(var CategoryCode: Code[20]; var SubcategoryCode: Code[20]; i: Integer) + begin + CategoryCode := StrSubstNo(CategoryCodeLbl, i); + CreateSustainabilityCategory(CategoryCode, i); + + SubcategoryCode := StrSubstNo(SubcategoryCodeLbl, i); + LibrarySustainability.InsertAccountSubcategory(CategoryCode, SubcategoryCode, SubcategoryCode, 1, 2, 3, false); + end; + + local procedure CreateSustainabilityCategory(var CategoryCode: Code[20]; i: Integer) + begin + CategoryCode := StrSubstNo(CategoryCodeLbl, i); + LibrarySustainability.InsertAccountCategory( + CategoryCode, CategoryCode, Enum::"Emission Scope"::"Scope 1", Enum::"Calculation Foundation"::"Fuel/Electricity", + true, true, true, '', false); + end; + + local procedure CreateAndPostPurchaseDocument(var PurchaseHeader: Record "Purchase Header"; ItemNo: Code[20]; Quantity: Decimal; CountryRegionCode: Code[10]; AccountCode: Code[20]; EmissionCO2: Decimal; EmissionCH4: Decimal; EmissionN2O: Decimal): Code[20] + var + PurchaseLine: Record "Purchase Line"; + begin + LibraryPurchase.CreatePurchHeader(PurchaseHeader, "Purchase Document Type"::Order, LibraryPurchase.CreateVendorNo()); + PurchaseHeader."Buy-from Country/Region Code" := CountryRegionCode; + PurchaseHeader.Modify(); + + LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, "Purchase Line Type"::Item, ItemNo, Quantity); + PurchaseLine.Validate("Direct Unit Cost", LibraryRandom.RandIntInRange(10, 200)); + PurchaseLine.Validate("Sust. Account No.", AccountCode); + PurchaseLine.Validate("Emission CO2", EmissionCO2); + PurchaseLine.Validate("Emission CH4", EmissionCH4); + PurchaseLine.Validate("Emission N2O", EmissionN2O); + PurchaseLine.Modify(); + + exit(LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, true)); + end; + + local procedure CreateEmissionFeeWithEmissionScope(var EmissionFee: array[3] of Record "Emission Fee"; EmissionScope: Enum "Emission Scope"; CountryRegionCode: Code[10]) + begin + LibrarySustainability.InsertEmissionFee( + EmissionFee[1], + "Emission Type"::CH4, + EmissionScope, + CalcDate('<-CM>', WorkDate()), + CalcDate('', WorkDate()), + CountryRegionCode, + LibraryRandom.RandDecInDecimalRange(0.5, 1, 1)); + + LibrarySustainability.InsertEmissionFee( + EmissionFee[2], + "Emission Type"::CO2, + EmissionScope, + CalcDate('<-CM>', WorkDate()), + CalcDate('', WorkDate()), + CountryRegionCode, + LibraryRandom.RandDecInDecimalRange(0.5, 1, 1)); + EmissionFee[2].Validate("Carbon Fee", LibraryRandom.RandDecInDecimalRange(0.5, 2, 1)); + EmissionFee[2].Modify(); + + LibrarySustainability.InsertEmissionFee( + EmissionFee[3], + "Emission Type"::N2O, + EmissionScope, + CalcDate('<-CM>', WorkDate()), + CalcDate('', WorkDate()), + CountryRegionCode, + LibraryRandom.RandDecInDecimalRange(0.5, 1, 1)); + end; + + local procedure CreateServiceOrderWithItem(var ServiceHeader: Record "Service Header"; var ServiceLine: Record "Service Line"; CustomerNo: Code[20]; LocationCode: Code[10]; ItemNo: Code[20]; Quantity: Decimal) + var + ServiceItemLine: Record "Service Item Line"; + ServiceItem: Record "Service Item"; + begin + LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader."Document Type"::Order, CustomerNo); + ServiceHeader.Validate("Location Code", LocationCode); + ServiceHeader.Modify(true); + + LibraryService.CreateServiceItem(ServiceItem, ServiceHeader."Customer No."); + LibraryService.CreateServiceItemLine(ServiceItemLine, ServiceHeader, ServiceItem."No."); + + LibraryService.CreateServiceLine(ServiceLine, ServiceHeader, ServiceLine.Type::Item, ItemNo); + UpdateServiceLine(ServiceLine, ServiceItemLine."Line No.", Quantity, LibraryRandom.RandDecInRange(1000, 2000, 2)); + end; + + local procedure CreateServiceOrderWithResource(var ServiceHeader: Record "Service Header"; var ServiceLine: Record "Service Line"; CustomerNo: Code[20]; LocationCode: Code[10]; ResourceNo: Code[20]; Quantity: Decimal) + var + ServiceItemLine: Record "Service Item Line"; + ServiceItem: Record "Service Item"; + begin + LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader."Document Type"::Order, CustomerNo); + ServiceHeader.Validate("Location Code", LocationCode); + ServiceHeader.Modify(true); + + LibraryService.CreateServiceItem(ServiceItem, ServiceHeader."Customer No."); + LibraryService.CreateServiceItemLine(ServiceItemLine, ServiceHeader, ServiceItem."No."); + + LibraryService.CreateServiceLine(ServiceLine, ServiceHeader, ServiceLine.Type::Resource, ResourceNo); + UpdateServiceLine(ServiceLine, ServiceItemLine."Line No.", Quantity, LibraryRandom.RandDecInRange(1000, 2000, 2)); + end; + + local procedure CreateServiceInvoiceWithServiceLine(var ServiceHeader: Record "Service Header"; var ServiceLine: Record "Service Line"; CustomerNo: Code[20]; ItemNo: Code[20]) + begin + LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader."Document Type"::Invoice, CustomerNo); + LibraryService.CreateServiceLine(ServiceLine, ServiceHeader, ServiceLine.Type::Item, ItemNo); + end; + + local procedure CreateServiceInvoiceWithServiceLineForResource(var ServiceHeader: Record "Service Header"; var ServiceLine: Record "Service Line"; CustomerNo: Code[20]; ResourceNo: Code[20]) + begin + LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader."Document Type"::Invoice, CustomerNo); + LibraryService.CreateServiceLine(ServiceLine, ServiceHeader, ServiceLine.Type::Resource, ResourceNo); + end; + + local procedure CreateServiceCrMemoWithServiceLine(var ServiceHeader: Record "Service Header"; var ServiceLine: Record "Service Line"; CustomerNo: Code[20]; ItemNo: Code[20]) + begin + LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader."Document Type"::"Credit Memo", CustomerNo); + LibraryService.CreateServiceLine(ServiceLine, ServiceHeader, ServiceLine.Type::Item, ItemNo); + end; + + local procedure CreateServiceCrMemoWithServiceLineForResource(var ServiceHeader: Record "Service Header"; var ServiceLine: Record "Service Line"; CustomerNo: Code[20]; ResourceNo: Code[20]) + begin + LibraryService.CreateServiceHeader(ServiceHeader, ServiceHeader."Document Type"::"Credit Memo", CustomerNo); + LibraryService.CreateServiceLine(ServiceLine, ServiceHeader, ServiceLine.Type::Resource, ResourceNo); + end; + + local procedure UpdateServiceLine(var ServiceLine: Record "Service Line"; ServiceItemLineNo: Integer; Quantity: Decimal; UnitPrice: Decimal) + begin + ServiceLine.Validate("Service Item Line No.", ServiceItemLineNo); + ServiceLine.Validate(Quantity, Quantity); + ServiceLine.Validate("Unit Price", UnitPrice); + ServiceLine.Modify(true); + end; + + local procedure FindServiceShipmentHeader(OrderNo: Code[20]): Code[20] + var + ServiceShipmentHeader: Record "Service Shipment Header"; + begin + ServiceShipmentHeader.SetRange("Order No.", OrderNo); + ServiceShipmentHeader.FindLast(); + + exit(ServiceShipmentHeader."No."); + end; + + local procedure FindServiceShipmentLine(var ServiceShipmentLine: Record "Service Shipment Line"; DocumentNo: Code[20]) + begin + ServiceShipmentLine.SetRange("Document No.", DocumentNo); + ServiceShipmentLine.FindLast(); + end; + + local procedure FindServiceInvoiceHeader(OrderNo: Code[20]): Code[20] + var + ServiceInvoiceHeader: Record "Service Invoice Header"; + begin + ServiceInvoiceHeader.SetRange("Order No.", OrderNo); + ServiceInvoiceHeader.FindLast(); + + exit(ServiceInvoiceHeader."No."); + end; + + local procedure FindServiceInvoiceLine(var ServiceInvoiceLine: Record "Service Invoice Line"; DocumentNo: Code[20]) + begin + ServiceInvoiceLine.SetRange("Document No.", DocumentNo); + ServiceInvoiceLine.FindLast(); + end; + + local procedure FindServiceInvoiceHeader(var ServiceInvoiceHeader: Record "Service Invoice Header"; PreAssignedNo: Code[20]) + begin + ServiceInvoiceHeader.SetRange("Pre-Assigned No.", PreAssignedNo); + ServiceInvoiceHeader.FindFirst(); + end; + + local procedure FindServiceCreditMemoHeader(var ServiceCreditMemoHeader: Record "Service Cr.Memo Header"; PreAssignedNo: Code[20]) + begin + ServiceCreditMemoHeader.SetRange("Pre-Assigned No.", PreAssignedNo); + ServiceCreditMemoHeader.FindFirst(); + end; + + local procedure FindServiceCreditMemoLine(var ServiceCreditMemoLine: Record "Service Cr.Memo Line"; DocumentNo: Code[20]) + begin + ServiceCreditMemoLine.SetRange("Document No.", DocumentNo); + ServiceCreditMemoLine.FindLast(); + end; + + local procedure CreateJobWithJobTask(var JobTask: Record "Job Task") + var + Job: Record Job; + begin + LibraryJob.CreateJob(Job); + LibraryJob.CreateJobTask(Job, JobTask); + end; + + local procedure VerifyServiceShipmentLine(ServiceHeader: Record "Service Header"; ServiceLine: Record "Service Line"; TotalCO2e: Decimal) + var + ServiceShipmentLine: Record "Service Shipment Line"; + begin + FindServiceShipmentLine(ServiceShipmentLine, FindServiceShipmentHeader(ServiceHeader."No.")); + + Assert.AreEqual( + ServiceLine."Sust. Account No.", + ServiceShipmentLine."Sust. Account No.", + StrSubstNo(ValueMustBeEqualErr, ServiceShipmentLine.FieldCaption("Sust. Account No."), ServiceLine."Sust. Account No.", ServiceShipmentLine.TableCaption())); + Assert.AreEqual( + ServiceLine."Sust. Account Name", + ServiceShipmentLine."Sust. Account Name", + StrSubstNo(ValueMustBeEqualErr, ServiceShipmentLine.FieldCaption("Sust. Account Name"), ServiceLine."Sust. Account Name", ServiceShipmentLine.TableCaption())); + Assert.AreEqual( + ServiceLine."Sust. Account Category", + ServiceShipmentLine."Sust. Account Category", + StrSubstNo(ValueMustBeEqualErr, ServiceShipmentLine.FieldCaption("Sust. Account Category"), ServiceLine."Sust. Account Category", ServiceShipmentLine.TableCaption())); + Assert.AreEqual( + ServiceLine."Sust. Account Subcategory", + ServiceShipmentLine."Sust. Account Subcategory", + StrSubstNo(ValueMustBeEqualErr, ServiceShipmentLine.FieldCaption("Sust. Account Subcategory"), ServiceLine."Sust. Account Subcategory", ServiceShipmentLine.TableCaption())); + Assert.AreEqual( + ServiceLine."CO2e per Unit", + ServiceShipmentLine."CO2e per Unit", + StrSubstNo(ValueMustBeEqualErr, ServiceShipmentLine.FieldCaption("CO2e per Unit"), ServiceLine."CO2e per Unit", ServiceShipmentLine.TableCaption())); + Assert.AreEqual( + TotalCO2e / 2, + ServiceShipmentLine."Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceShipmentLine.FieldCaption("Total CO2e"), TotalCO2e / 2, ServiceShipmentLine.TableCaption())); + end; + + local procedure VerifyServiceInvoiceLine(ServiceHeader: Record "Service Header"; ServiceLine: Record "Service Line"; TotalCO2e: Decimal) + var + ServiceInvoiceLine: Record "Service Invoice Line"; + begin + FindServiceInvoiceLine(ServiceInvoiceLine, FindServiceInvoiceHeader(ServiceHeader."No.")); + + Assert.AreEqual( + ServiceLine."Sust. Account No.", + ServiceInvoiceLine."Sust. Account No.", + StrSubstNo(ValueMustBeEqualErr, ServiceInvoiceLine.FieldCaption("Sust. Account No."), ServiceLine."Sust. Account No.", ServiceInvoiceLine.TableCaption())); + Assert.AreEqual( + ServiceLine."Sust. Account Name", + ServiceInvoiceLine."Sust. Account Name", + StrSubstNo(ValueMustBeEqualErr, ServiceInvoiceLine.FieldCaption("Sust. Account Name"), ServiceLine."Sust. Account Name", ServiceInvoiceLine.TableCaption())); + Assert.AreEqual( + ServiceLine."Sust. Account Category", + ServiceInvoiceLine."Sust. Account Category", + StrSubstNo(ValueMustBeEqualErr, ServiceInvoiceLine.FieldCaption("Sust. Account Category"), ServiceLine."Sust. Account Category", ServiceInvoiceLine.TableCaption())); + Assert.AreEqual( + ServiceLine."Sust. Account Subcategory", + ServiceInvoiceLine."Sust. Account Subcategory", + StrSubstNo(ValueMustBeEqualErr, ServiceInvoiceLine.FieldCaption("Sust. Account Subcategory"), ServiceLine."Sust. Account Subcategory", ServiceInvoiceLine.TableCaption())); + Assert.AreEqual( + ServiceLine."CO2e per Unit", + ServiceInvoiceLine."CO2e per Unit", + StrSubstNo(ValueMustBeEqualErr, ServiceInvoiceLine.FieldCaption("CO2e per Unit"), ServiceLine."CO2e per Unit", ServiceInvoiceLine.TableCaption())); + Assert.AreEqual( + TotalCO2e / 2, + ServiceInvoiceLine."Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceInvoiceLine.FieldCaption("Total CO2e"), TotalCO2e / 2, ServiceInvoiceLine.TableCaption())); + end; + + local procedure VerifyServiceCreditMemoLine(ServiceHeader: Record "Service Header"; ServiceLine: Record "Service Line"; TotalCO2e: Decimal) + var + ServiceCreditMemoHeader: Record "Service Cr.Memo Header"; + ServiceCreditMemoLine: Record "Service Cr.Memo Line"; + begin + FindServiceCreditMemoHeader(ServiceCreditMemoHeader, ServiceHeader."No."); + FindServiceCreditMemoLine(ServiceCreditMemoLine, ServiceCreditMemoHeader."No."); + + Assert.AreEqual( + ServiceLine."Sust. Account No.", + ServiceCreditMemoLine."Sust. Account No.", + StrSubstNo(ValueMustBeEqualErr, ServiceCreditMemoLine.FieldCaption("Sust. Account No."), ServiceLine."Sust. Account No.", ServiceCreditMemoLine.TableCaption())); + Assert.AreEqual( + ServiceLine."Sust. Account Name", + ServiceCreditMemoLine."Sust. Account Name", + StrSubstNo(ValueMustBeEqualErr, ServiceCreditMemoLine.FieldCaption("Sust. Account Name"), ServiceLine."Sust. Account Name", ServiceCreditMemoLine.TableCaption())); + Assert.AreEqual( + ServiceLine."Sust. Account Category", + ServiceCreditMemoLine."Sust. Account Category", + StrSubstNo(ValueMustBeEqualErr, ServiceCreditMemoLine.FieldCaption("Sust. Account Category"), ServiceLine."Sust. Account Category", ServiceCreditMemoLine.TableCaption())); + Assert.AreEqual( + ServiceLine."Sust. Account Subcategory", + ServiceCreditMemoLine."Sust. Account Subcategory", + StrSubstNo(ValueMustBeEqualErr, ServiceCreditMemoLine.FieldCaption("Sust. Account Subcategory"), ServiceLine."Sust. Account Subcategory", ServiceCreditMemoLine.TableCaption())); + Assert.AreEqual( + ServiceLine."CO2e per Unit", + ServiceCreditMemoLine."CO2e per Unit", + StrSubstNo(ValueMustBeEqualErr, ServiceCreditMemoLine.FieldCaption("CO2e per Unit"), ServiceLine."CO2e per Unit", ServiceCreditMemoLine.TableCaption())); + Assert.AreEqual( + TotalCO2e, + ServiceCreditMemoLine."Total CO2e", + StrSubstNo(ValueMustBeEqualErr, ServiceCreditMemoLine.FieldCaption("Total CO2e"), TotalCO2e, ServiceCreditMemoLine.TableCaption())); + end; + + [ConfirmHandler] + procedure ConfirmHandler(Question: Text[1024]; var Reply: Boolean) + begin + Reply := true; + end; +} \ No newline at end of file diff --git a/Apps/W1/SyncBase/.objidconfig b/Apps/W1/SyncBase/app/.objidconfig similarity index 100% rename from Apps/W1/SyncBase/.objidconfig rename to Apps/W1/SyncBase/app/.objidconfig diff --git a/Apps/W1/SyncBase/ExtensionLogo.png b/Apps/W1/SyncBase/app/ExtensionLogo.png similarity index 100% rename from Apps/W1/SyncBase/ExtensionLogo.png rename to Apps/W1/SyncBase/app/ExtensionLogo.png diff --git a/Apps/W1/SyncBase/app.json b/Apps/W1/SyncBase/app/app.json similarity index 100% rename from Apps/W1/SyncBase/app.json rename to Apps/W1/SyncBase/app/app.json diff --git a/Apps/W1/SyncBase/src/tables/SyncChange.Table.al b/Apps/W1/SyncBase/app/src/tables/SyncChange.Table.al similarity index 100% rename from Apps/W1/SyncBase/src/tables/SyncChange.Table.al rename to Apps/W1/SyncBase/app/src/tables/SyncChange.Table.al diff --git a/Apps/W1/SyncBase/src/tables/SyncMapping.Table.al b/Apps/W1/SyncBase/app/src/tables/SyncMapping.Table.al similarity index 100% rename from Apps/W1/SyncBase/src/tables/SyncMapping.Table.al rename to Apps/W1/SyncBase/app/src/tables/SyncMapping.Table.al diff --git a/Apps/W1/SyncBase/src/tables/SyncSetup.Table.al b/Apps/W1/SyncBase/app/src/tables/SyncSetup.Table.al similarity index 100% rename from Apps/W1/SyncBase/src/tables/SyncSetup.Table.al rename to Apps/W1/SyncBase/app/src/tables/SyncSetup.Table.al diff --git a/Apps/W1/VATGroupManagement/app/src/Codeunits/VATGroupCommunication.Codeunit.al b/Apps/W1/VATGroupManagement/app/src/Codeunits/VATGroupCommunication.Codeunit.al index 803decb00b..1f86e1b58c 100644 --- a/Apps/W1/VATGroupManagement/app/src/Codeunits/VATGroupCommunication.Codeunit.al +++ b/Apps/W1/VATGroupManagement/app/src/Codeunits/VATGroupCommunication.Codeunit.al @@ -8,10 +8,8 @@ using Microsoft.Finance.VAT.Reporting; using System.Azure.KeyVault; using System.Environment; using System.Security.Authentication; +using System.Reflection; using System.Telemetry; -#if not CLEAN25 -using System.Text; -#endif codeunit 4700 "VAT Group Communication" { @@ -79,12 +77,6 @@ codeunit 4700 "VAT Group Communication" PrepareHeaders(HttpRequestMessage, IsBatch); PrepareContent(HttpRequestMessage, Content); -#if not CLEAN25 -#pragma warning disable AL0432 - if VATReportSetup."VAT Group Authentication Type" = VATReportSetup."VAT Group Authentication Type"::WindowsAuthentication then - HttpClient.UseDefaultNetworkWindowsAuthentication(); -#pragma warning restore -#endif HttpClient.Send(HttpRequestMessage, HttpResponseMessage); HttpResponseMessage.Content().ReadAs(HttpResponseBodyText); HandleHttpResponse(HttpResponseMessage); @@ -289,13 +281,7 @@ codeunit 4700 "VAT Group Communication" local procedure PrepareHeaders(HttpRequestMessage: HttpRequestMessage; IsBatch: Boolean) var FeatureTelemetry: Codeunit "Feature Telemetry"; -#if not CLEAN25 - Base64Convert: Codeunit "Base64 Convert"; -#endif HttpRequestHeaders: HttpHeaders; -#if not CLEAN25 - Base64AuthHeader: SecretText; -#endif begin FeatureTelemetry.LogUptake('0000NG8', FeatureName(), Enum::"Feature Uptake Status"::Used); FeatureTelemetry.LogUsage('0000NG9', FeatureName(), 'Submitting VAT return to group representative.'); @@ -303,14 +289,6 @@ codeunit 4700 "VAT Group Communication" HttpRequestHeaders.Add('Accept', 'application/json'); -#if not CLEAN25 -#pragma warning disable AL0432 - if VATReportSetup."VAT Group Authentication Type" = VATReportSetup."VAT Group Authentication Type"::WebServiceAccessKey then begin - Base64AuthHeader := Base64Convert.ToBase64(VATReportSetup.GetSecretAsSecretText(VATReportSetup."User Name Key").Unwrap() + ':' + VATReportSetup.GetSecretAsSecretText(VATReportSetup."Web Service Access Key Key").Unwrap()); - HttpRequestHeaders.Add('Authorization', SecretStrSubstNo('Basic %1', GetBearerTokenFromCache())); - end; -#pragma warning restore -#endif if VATReportSetup."VAT Group Authentication Type" = VATReportSetup."VAT Group Authentication Type"::OAuth2 then HttpRequestHeaders.Add('Authorization', SecretStrSubstNo('Bearer %1', GetBearerTokenFromCache())); @@ -346,16 +324,20 @@ codeunit 4700 "VAT Group Communication" end; internal procedure PrepareURI(Endpoint: Text) Result: Text + var + TypeHelper: Codeunit "Type Helper"; + GroupRepCompanyName: Text; begin CheckLoadVATReportSetup(); Result := VATReportSetup."Group Representative API URL"; + GroupRepCompanyName := VATReportSetup."Group Representative Company"; case VATReportSetup."VAT Group BC Version" of VATReportSetup."VAT Group BC Version"::BC: - Result += StrSubstNo(URLAppendixCompanyLbl, VATReportSetup."Group Representative Company"); + Result += StrSubstNo(URLAppendixCompanyLbl, TypeHelper.UriEscapeDataString(GroupRepCompanyName)); VATReportSetup."VAT Group BC Version"::NAV2018: - Result += StrSubstNo(URLAppendixCompany2018Lbl, VATReportSetup."Group Representative Company"); + Result += StrSubstNo(URLAppendixCompany2018Lbl, TypeHelper.UriEscapeDataString(GroupRepCompanyName)); VATReportSetup."VAT Group BC Version"::NAV2017: - Result += StrSubstNo(URLAppendixCompany2017Lbl, VATReportSetup."Group Representative Company"); + Result += StrSubstNo(URLAppendixCompany2017Lbl, TypeHelper.UriEscapeDataString(GroupRepCompanyName)); end; Result += Endpoint; end; diff --git a/Apps/W1/VATGroupManagement/app/src/Enums/VATGroupAuthTypeOnPrem.Enum.al b/Apps/W1/VATGroupManagement/app/src/Enums/VATGroupAuthTypeOnPrem.Enum.al index 6a03ceab90..f507dc515c 100644 --- a/Apps/W1/VATGroupManagement/app/src/Enums/VATGroupAuthTypeOnPrem.Enum.al +++ b/Apps/W1/VATGroupManagement/app/src/Enums/VATGroupAuthTypeOnPrem.Enum.al @@ -6,26 +6,8 @@ namespace Microsoft.Finance.VAT.Group; enum 4704 "VAT Group Auth Type OnPrem" { -#if not CLEAN25 - value(0; WebServiceAccessKey) - { - Caption = 'Web Service Access Key'; - ObsoleteState = Pending; - ObsoleteReason = 'OAuth2 is the only authentication option for making a Business Central API call.'; - ObsoleteTag = '25.0'; - } -#endif value(1; OAuth2) { Caption = 'OAuth2'; } -#if not CLEAN25 - value(2; WindowsAuthentication) - { - Caption = 'Windows Authentication'; - ObsoleteState = Pending; - ObsoleteReason = 'OAuth2 is the only authentication option for making a Business Central API call.'; - ObsoleteTag = '25.0'; - } -#endif } \ No newline at end of file diff --git a/Apps/W1/VATGroupManagement/app/src/Enums/VATGroupAuthTypeSaas.Enum.al b/Apps/W1/VATGroupManagement/app/src/Enums/VATGroupAuthTypeSaas.Enum.al index 007f3c6db3..3c8f1c9684 100644 --- a/Apps/W1/VATGroupManagement/app/src/Enums/VATGroupAuthTypeSaas.Enum.al +++ b/Apps/W1/VATGroupManagement/app/src/Enums/VATGroupAuthTypeSaas.Enum.al @@ -6,15 +6,6 @@ namespace Microsoft.Finance.VAT.Group; enum 4705 "VAT Group Auth Type Saas" { -#if not CLEAN25 - value(0; WebServiceAccessKey) - { - Caption = 'Web Service Access Key'; - ObsoleteState = Pending; - ObsoleteReason = 'OAuth2 is the only authentication option for making a Business Central API call.'; - ObsoleteTag = '25.0'; - } -#endif value(1; OAuth2) { Caption = 'OAuth2'; diff --git a/Apps/W1/VATGroupManagement/app/src/Pages/VATGroupSetupGuide.Page.al b/Apps/W1/VATGroupManagement/app/src/Pages/VATGroupSetupGuide.Page.al index be906180de..e0e4d57b0f 100644 --- a/Apps/W1/VATGroupManagement/app/src/Pages/VATGroupSetupGuide.Page.al +++ b/Apps/W1/VATGroupManagement/app/src/Pages/VATGroupSetupGuide.Page.al @@ -257,12 +257,6 @@ page 4705 "VAT Group Setup Guide" trigger OnValidate() begin case VATGroupAuthenticationTypeSaas of -#if not CLEAN25 -#pragma warning disable AL0432 - VATGroupAuthenticationTypeSaas::WebServiceAccessKey: - VATGroupAuthenticationType := VATGroupAuthenticationType::WebServiceAccessKey; -#pragma warning restore -#endif VATGroupAuthenticationTypeSaas::OAuth2: VATGroupAuthenticationType := VATGroupAuthenticationType::OAuth2; end; @@ -618,12 +612,6 @@ page 4705 "VAT Group Setup Guide" Step -= 1; if (Step = Step::"Setup Representative") and (VATGroupRole = VATGroupRole::Member) then Step -= 1; -#if not CLEAN25 -#pragma warning disable AL0432 - if (Step = Step::"Setup Member WSAK") and (VATGroupAuthenticationType <> VATGroupAuthenticationType::WebServiceAccessKey) then - Step -= 1; -#pragma warning restore -#endif if (Step = Step::"Setup Member OAuth2") and (VATGroupAuthenticationType <> VATGroupAuthenticationType::OAuth2) then Step -= 2; end else begin @@ -632,20 +620,8 @@ page 4705 "VAT Group Setup Guide" Step += 1; if (Step = Step::"Setup Member") and (VATGroupRole = VATGroupRole::Representative) then Step += 3; -#if not CLEAN25 -#pragma warning disable AL0432 - if (Step = Step::"Setup Member WSAK") and (VATGroupAuthenticationType = VATGroupAuthenticationType::WindowsAuthentication) then - Step += 2; -#pragma warning restore -#endif if (Step = Step::"Setup Member WSAK") and (VATGroupAuthenticationType = VATGroupAuthenticationType::OAuth2) then Step += 1; -#if not CLEAN25 -#pragma warning disable AL0432 - if (Step = Step::"Setup Member OAuth2") and (VATGroupAuthenticationType = VATGroupAuthenticationType::WebServiceAccessKey) then - Step += 1; -#pragma warning restore -#endif if (Step = Step::"Setup VAT Report") and (VATGroupRole = VATGroupRole::Representative) then Step += 1; end; @@ -835,12 +811,6 @@ page 4705 "VAT Group Setup Guide" local procedure IsNextEnabled(): Boolean begin -#if not CLEAN25 -#pragma warning disable AL0432 - if VATGroupAuthenticationType = VATGroupAuthenticationType::WebServiceAccessKey then - exit((APIURL <> '') and (GroupRepresentativeCompany <> '') and (WebServiceAccessKey <> '') and (Username <> '')); -#pragma warning restore -#endif if VATGroupAuthenticationType = VATGroupAuthenticationType::OAuth2 then exit((APIURL <> '') and (GroupRepresentativeCompany <> '') and (ClientId <> '') and (ClientSecret <> '') and (RedirectURL <> '') and (ResourceURL <> '') and (OAuthAuthorityUrl <> '')); end; diff --git a/Apps/W1/VATGroupManagement/app/src/Pages/VATReportSetupExtension.PageExt.al b/Apps/W1/VATGroupManagement/app/src/Pages/VATReportSetupExtension.PageExt.al index dbb7600f37..960dab1f03 100644 --- a/Apps/W1/VATGroupManagement/app/src/Pages/VATReportSetupExtension.PageExt.al +++ b/Apps/W1/VATGroupManagement/app/src/Pages/VATReportSetupExtension.PageExt.al @@ -48,12 +48,6 @@ pageextension 4703 "VAT Report Setup Extension" extends "VAT Report Setup" trigger OnValidate() begin case AuthenticationTypeSaas of -#if not CLEAN25 -#pragma warning disable AL0432 - AuthenticationTypeSaas::WebServiceAccessKey: - Rec."VAT Group Authentication Type" := Rec."VAT Group Authentication Type"::WebServiceAccessKey; -#pragma warning restore -#endif AuthenticationTypeSaas::OAuth2: Rec."VAT Group Authentication Type" := Rec."VAT Group Authentication Type"::OAuth2; end; @@ -321,13 +315,6 @@ pageextension 4703 "VAT Report Setup Extension" extends "VAT Report Setup" case AuthenticationType of AuthenticationType::OAuth2: AuthenticationTypeSaaS := AuthenticationTypeSaaS::OAuth2; -#if not CLEAN25 -#pragma warning disable AL0432 - - AuthenticationType::WebServiceAccessKey: - AuthenticationTypeSaaS := AuthenticationTypeSaaS::WebServiceAccessKey; -#pragma warning restore -#endif end; end; diff --git a/Apps/W1/VATGroupManagement/test/.resources/200_blanked.json b/Apps/W1/VATGroupManagement/test/.resources/200_blanked.json new file mode 100644 index 0000000000..0519ecba6e --- /dev/null +++ b/Apps/W1/VATGroupManagement/test/.resources/200_blanked.json @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Apps/W1/VATGroupManagement/test/.resources/status_batch_released.json b/Apps/W1/VATGroupManagement/test/.resources/status_batch_released.json new file mode 100644 index 0000000000..a7cda5a2fb --- /dev/null +++ b/Apps/W1/VATGroupManagement/test/.resources/status_batch_released.json @@ -0,0 +1,28 @@ +{ + "responses": [ + { + "id": 1, + "status": 200, + "body" : { + "value": [ + { + "no": "VAT-RETURN-1", + "status": "Released" + } + ] + } + }, + { + "id": 2, + "status": 200, + "body": { + "value": [ + { + "no": "VAT-RETURN-2", + "status": "Released" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/Apps/W1/VATGroupManagement/test/.resources/status_single_released.json b/Apps/W1/VATGroupManagement/test/.resources/status_single_released.json new file mode 100644 index 0000000000..86db3d4383 --- /dev/null +++ b/Apps/W1/VATGroupManagement/test/.resources/status_single_released.json @@ -0,0 +1,7 @@ +{ + "value": [ + { + "status": "Released" + } + ] +} \ No newline at end of file diff --git a/Apps/W1/VATGroupManagement/test/app.json b/Apps/W1/VATGroupManagement/test/app.json index 05fd29b4d9..abb21e6563 100644 --- a/Apps/W1/VATGroupManagement/test/app.json +++ b/Apps/W1/VATGroupManagement/test/app.json @@ -54,5 +54,8 @@ "allowDownloadingSource": true, "includeSourceInSymbolFile": true }, - "target": "OnPrem" + "target": "OnPrem", + "resourceFolders": [ + ".resources" + ] } diff --git a/Apps/W1/VATGroupManagement/test/src/LibraryVATGroup.Codeunit.al b/Apps/W1/VATGroupManagement/test/src/LibraryVATGroup.Codeunit.al index 00fad394a1..da5d6d63de 100644 --- a/Apps/W1/VATGroupManagement/test/src/LibraryVATGroup.Codeunit.al +++ b/Apps/W1/VATGroupManagement/test/src/LibraryVATGroup.Codeunit.al @@ -228,9 +228,6 @@ codeunit 139525 "Library - VAT Group" VATReportSetup."Group Representative API URL" := CopyStr(GetRepresentativeURL(), 1, MaxStrLen(VATReportSetup."Group Representative API URL")); VATReportSetup."Group Representative Company" := CopyStr(CompanyName(), 1, MaxStrLen(VATReportSetup."Group Representative Company")); -#if not CLEAN25 - VATReportSetup."VAT Group Authentication Type" := VATReportSetup."VAT Group Authentication Type"::WindowsAuthentication; -#endif VATReportSetup."Group Member ID" := CreateGuid(); VATReportSetup."Manual Receive Period CU ID" := 0; VATReportSetup.Modify(); @@ -320,4 +317,4 @@ codeunit 139525 "Library - VAT Group" VATReport."Include VAT Group".Invoke(); VATReport.Close(); end; -} +} \ No newline at end of file diff --git a/Apps/W1/VATGroupManagement/test/src/VATGroupMockServiceTest.Codeunit.al b/Apps/W1/VATGroupManagement/test/src/VATGroupMockServiceTest.Codeunit.al index 16ae4adc5f..9d9dda9932 100644 --- a/Apps/W1/VATGroupManagement/test/src/VATGroupMockServiceTest.Codeunit.al +++ b/Apps/W1/VATGroupManagement/test/src/VATGroupMockServiceTest.Codeunit.al @@ -9,7 +9,7 @@ codeunit 139526 "VAT Group Mock Service Test" LibraryVATGroup: Codeunit "Library - VAT Group"; IsInitialized: Boolean; BCVersion: Enum "VAT Group BC Version"; - URLTxt: Label 'https://localhost:8080/vatgroup-mockservice', Locked = true; + URLTxt: Label 'https://vatgroup-mockservice', Locked = true; GuidBCTxt: Label 'A98C93EE-BC95-4C34-A34A-E6D289F768AA', Locked = true; Guid2018Txt: Label '4F35940F-FEB9-4370-897E-0A86B8270B95', Locked = true; Guid2017Txt: Label '417EB2A7-D8B3-4CA2-A285-57262BD64A65', Locked = true; @@ -17,6 +17,7 @@ codeunit 139526 "VAT Group Mock Service Test" VATReturn2Txt: Label 'VAT-RETURN-2', Locked = true; [Test] + [HandlerFunctions('VATGroupHttpClientHandler')] procedure SingleStatus_BC() begin // [SCENARIO 374187] Update single VAT Return Group Status (Business Central representer mode) @@ -32,6 +33,7 @@ codeunit 139526 "VAT Group Mock Service Test" end; [Test] + [HandlerFunctions('VATGroupHttpClientHandler')] procedure SingleStatus_2018() begin // [SCENARIO 374187] Update single VAT Return Group Status (NAV2018 representer mode) @@ -47,6 +49,7 @@ codeunit 139526 "VAT Group Mock Service Test" end; [Test] + [HandlerFunctions('VATGroupHttpClientHandler')] procedure SingleStatus_2017() begin // [SCENARIO 374187] Update single VAT Return Group Status (NAV2017 representer mode) @@ -62,6 +65,7 @@ codeunit 139526 "VAT Group Mock Service Test" end; [Test] + [HandlerFunctions('VATGroupHttpClientHandler')] procedure BatchStatus_BC() begin // [SCENARIO 374187] Update several VAT Returns Group Status via batch URL request (Business Central representer mode) @@ -78,6 +82,7 @@ codeunit 139526 "VAT Group Mock Service Test" end; [Test] + [HandlerFunctions('VATGroupHttpClientHandler')] procedure BatchStatus_2018() begin // [SCENARIO 374187] Update several VAT Returns Group Status via batch URL request (NAV2018 representer mode) @@ -94,6 +99,7 @@ codeunit 139526 "VAT Group Mock Service Test" end; [Test] + [HandlerFunctions('VATGroupHttpClientHandler')] procedure BatchStatus_2017() begin // [SCENARIO 374187] Update several VAT Returns Group Status via batch URL request (NAV2017 representer mode) @@ -110,6 +116,7 @@ codeunit 139526 "VAT Group Mock Service Test" end; [Test] + [HandlerFunctions('VATGroupHttpClientHandler')] procedure Submit_BC() var VATReportHeader: Record "VAT Report Header"; @@ -127,6 +134,7 @@ codeunit 139526 "VAT Group Mock Service Test" end; [Test] + [HandlerFunctions('VATGroupHttpClientHandler')] procedure Submit_2018() var VATReportHeader: Record "VAT Report Header"; @@ -144,6 +152,7 @@ codeunit 139526 "VAT Group Mock Service Test" end; [Test] + [HandlerFunctions('VATGroupHttpClientHandler')] procedure Submit_2017() var VATReportHeader: Record "VAT Report Header"; @@ -205,4 +214,36 @@ codeunit 139526 "VAT Group Mock Service Test" VATReportHeader.TestField("VAT Group Status", ExpectedStatus); UNTIL VATReportHeader.Next() = 0; end; + + + [HttpClientHandler] + procedure VATGroupHttpClientHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean + var + InStream: InStream; + ResourceName: Text; + begin + case Request.Path of + URLTxt + '/api/microsoft/vatgroup/v1.0/companies(name=''VAT%20Group%20Repr%20Test%20Company'')/vatGroupSubmissionStatus', + URLTxt + '/api/v1.0/companies(name=''VAT%20Group%20Repr%20Test%20Company'')/vatGroupSubmissionStatus', + URLTxt + '/OData/Company(''VAT%20Group%20Repr%20Test%20Company'')/vatGroupSubmissionStatus': + if Request.RequestType = HttpRequestType::Get then + ResourceName := 'status_single_released.json'; + + URLTxt + '/api/v1.0/$batch', + URLTxt + '/api/microsoft/vatgroup/v1.0/$batch', + URLTxt + '/OData/$batch': + if Request.RequestType = HttpRequestType::Post then + ResourceName := 'status_batch_released.json'; + URLTxt + '/api/microsoft/vatgroup/v1.0/companies(name=''VAT%20Group%20Repr%20Test%20Company'')/vatGroupSubmissions', + URLTxt + '/api/v1.0/companies(name=''VAT%20Group%20Repr%20Test%20Company'')/vatGroupSubmissions', + URLTxt + '/OData/Company(''VAT%20Group%20Repr%20Test%20Company'')/vatGroupSubmissions': + if Request.RequestType = HttpRequestType::Post then + ResourceName := '200_blanked.json'; + end; + + NavApp.GetResource(ResourceName, InStream); + Response.Content.WriteFrom(InStream); + Response.HttpStatusCode := 200; + exit(false); + end; } diff --git a/Apps/W1/VATGroupManagement/test/src/VATGroupSetupPageTest.Codeunit.al b/Apps/W1/VATGroupManagement/test/src/VATGroupSetupPageTest.Codeunit.al index b0c3d1cb13..61f7e5acfa 100644 --- a/Apps/W1/VATGroupManagement/test/src/VATGroupSetupPageTest.Codeunit.al +++ b/Apps/W1/VATGroupManagement/test/src/VATGroupSetupPageTest.Codeunit.al @@ -144,4 +144,64 @@ codeunit 139524 "VAT Group Setup Page Test" Assert.AreNotEqual(ClientIdTxt, TestPageVATReportSetup.ClientId.Value(), ValueShouldBeMaskedTxt); Assert.AreNotEqual(ClientSecretTxt, TestPageVATReportSetup.ClientSecret.Value(), ValueShouldBeMaskedTxt); end; + + [Test] + procedure PrepareURIEncodesCompanyNameWithSpecialCharacters() + var + VATReportSetup: Record "VAT Report Setup"; + VATGroupCommunication: Codeunit "VAT Group Communication"; + TypeHelper: Codeunit "Type Helper"; + ResultURI: Text; + CompanyNameWithSpecialChars: Text; + ExpectedEncodedCompany: Text; + begin + // [SCENARIO 613572] PrepareURI URL encodes company name with special characters + + // [GIVEN] VAT Report Setup with company name "Test (Company) Name" + CompanyNameWithSpecialChars := 'Test (Company) Name'; + LibraryVATGroup.DeleteVATReportSetup(); + VATReportSetup.Init(); + VATReportSetup."VAT Group Role" := VATReportSetup."VAT Group Role"::Member; + VATReportSetup."VAT Group BC Version" := VATReportSetup."VAT Group BC Version"::BC; + VATReportSetup."Group Representative API URL" := 'https://api.test.com'; + VATReportSetup."Group Representative Company" := CopyStr(CompanyNameWithSpecialChars, 1, MaxStrLen(VATReportSetup."Group Representative Company")); + VATReportSetup."Group Member ID" := CreateGuid(); + VATReportSetup.Insert(); + + // [WHEN] PrepareURI is called with endpoint + ResultURI := VATGroupCommunication.PrepareURI('/testendpoint'); + + // [THEN] Company name is URL encoded in the result + ExpectedEncodedCompany := TypeHelper.UriEscapeDataString(CompanyNameWithSpecialChars); + Assert.IsTrue(StrPos(ResultURI, ExpectedEncodedCompany) > 0, 'URI should contain URL encoded company name'); + Assert.IsFalse(StrPos(ResultURI, '(Company)') > 0, 'URI should not contain unencoded parentheses'); + end; + + [Test] + procedure PrepareURIKeepsPlainCompanyNameUnchanged() + var + VATReportSetup: Record "VAT Report Setup"; + VATGroupCommunication: Codeunit "VAT Group Communication"; + ResultURI: Text; + PlainCompanyName: Text; + begin + // [SCENARIO 613572] PrepareURI keeps plain company name unchanged in URL + + // [GIVEN] VAT Report Setup with plain company name "TestCompany" + PlainCompanyName := 'TestCompany'; + LibraryVATGroup.DeleteVATReportSetup(); + VATReportSetup.Init(); + VATReportSetup."VAT Group Role" := VATReportSetup."VAT Group Role"::Member; + VATReportSetup."VAT Group BC Version" := VATReportSetup."VAT Group BC Version"::BC; + VATReportSetup."Group Representative API URL" := 'https://api.test.com'; + VATReportSetup."Group Representative Company" := CopyStr(PlainCompanyName, 1, MaxStrLen(VATReportSetup."Group Representative Company")); + VATReportSetup."Group Member ID" := CreateGuid(); + VATReportSetup.Insert(); + + // [WHEN] PrepareURI is called with endpoint + ResultURI := VATGroupCommunication.PrepareURI('/testendpoint'); + + // [THEN] Company name appears unchanged in the result + Assert.IsTrue(StrPos(ResultURI, 'name=''' + PlainCompanyName + '''') > 0, 'URI should contain plain company name unchanged'); + end; } diff --git a/Build/Packages.json b/Build/Packages.json index 239ee40609..08b2c3aacc 100644 --- a/Build/Packages.json +++ b/Build/Packages.json @@ -4,7 +4,7 @@ "Source": "NuGet.org" }, "AppBaselines-BCArtifacts": { - "Version": "27.1.41148", + "Version": "27.3.43157", "Source": "BCArtifacts", "_comment": "Used to fetch app baselines from BC artifacts" } diff --git a/Build/rulesets/AppSourceCop.ruleset.json b/Build/rulesets/AppSourceCop.ruleset.json index 8d17650818..06c781aa85 100644 --- a/Build/rulesets/AppSourceCop.ruleset.json +++ b/Build/rulesets/AppSourceCop.ruleset.json @@ -212,15 +212,18 @@ }, { "id": "AS0053", - "action": "Error" + "action": "None", + "justification": "The compilation target of an application must be a value that is allowed in a multi-tenant SaaS environment" }, { "id": "AS0054", - "action": "Error" + "action": "None", + "justification": "The AppSourceCop configuration must specify the set of affixes used by the application" }, { "id": "AS0055", - "action": "Error" + "action": "None", + "justification": "The AppSourceCop configuration must specify the list of countries/regions targeted by the application" }, { "id": "AS0056", @@ -240,7 +243,8 @@ }, { "id": "AS0060", - "action": "Error" + "action": "None", + "justification": "Unsafe methods cannot be invoked in an AppSource application" }, { "id": "AS0061", @@ -324,7 +328,8 @@ }, { "id": "AS0081", - "action": "Error" + "action": "None", + "justification": "InternalsVisibleTo should not be used as a security feature." }, { "id": "AS0082", @@ -336,11 +341,13 @@ }, { "id": "AS0084", - "action": "Error" + "action": "None", + "justification": "The ID range assigned to the extension must be within the allowed range" }, { "id": "AS0085", - "action": "Error" + "action": "None", + "justification": "Use the 'application' property instead of specifying explicit dependencies." }, { "id": "AS0086", @@ -368,7 +375,8 @@ }, { "id": "AS0092", - "action": "Error" + "action": "None", + "justification": "The app.json file must specify an Azure Application Insights resource." }, { "id": "AS0093", @@ -400,7 +408,8 @@ }, { "id": "AS0100", - "action": "Error" + "action": "None", + "justification": "The 'application' property must be specified in the app.json file." }, { "id": "AS0101", @@ -464,7 +473,8 @@ }, { "id": "AS0116", - "action": "Error" + "action": "None", + "justification": "Cannot be an error. Validates table moves." }, { "id": "AS0117", diff --git a/Build/rulesets/Compiler.ruleset.json b/Build/rulesets/Compiler.ruleset.json index c804b760fe..77a230d0b2 100644 --- a/Build/rulesets/Compiler.ruleset.json +++ b/Build/rulesets/Compiler.ruleset.json @@ -2711,7 +2711,8 @@ }, { "id": "AL0678", - "action": "Error" + "action": "None", + "justification": "Information diagnostic reported on obsolete symbols contributing to metadata name conflicts, ex: 'My Page' and 'My_Page'." }, { "id": "AL0679", @@ -3187,7 +3188,8 @@ }, { "id": "AL0797", - "action": "Error" + "action": "None", + "justification": "Tables are moved from BaseApp to BCApps." }, { "id": "AL0798", diff --git a/Build/rulesets/PTECop.ruleset.json b/Build/rulesets/PTECop.ruleset.json index 6ce33a2a99..cbb1880198 100644 --- a/Build/rulesets/PTECop.ruleset.json +++ b/Build/rulesets/PTECop.ruleset.json @@ -3,11 +3,13 @@ "rules": [ { "id": "PTE0001", - "action": "Error" + "action": "None", + "justification": "Object ID must be in free range." }, { "id": "PTE0002", - "action": "Error" + "action": "None", + "justification": "PTE ID ranges do not apply to 1st party apps" }, { "id": "PTE0003", @@ -19,11 +21,13 @@ }, { "id": "PTE0005", - "action": "Error" + "action": "None", + "justification": "The compilation target of an application must be a value that is allowed in a multi-tenant SaaS environment" }, { "id": "PTE0006", - "action": "Error" + "action": "None", + "justification": "Encryption key functions must not be invoked." }, { "id": "PTE0007", @@ -48,11 +52,13 @@ }, { "id": "PTE0012", - "action": "Error" + "action": "None", + "justification": "Test assertion functions are not allowed in a non-test context." }, { "id": "PTE0013", - "action": "Error" + "action": "None", + "justification": "Entitlements cannot be defined in an extension." }, { "id": "PTE0014", @@ -97,7 +103,8 @@ }, { "id": "PTE0024", - "action": "Error" + "action": "None", + "justification": "We allow moved symbols for Microsoft apps because we run PTECop on the entire codebase which includes global apps." }, { "id": "PTE0025", diff --git a/Build/rulesets/UICop.ruleset.json b/Build/rulesets/UICop.ruleset.json index 35efe68403..ae53739e41 100644 --- a/Build/rulesets/UICop.ruleset.json +++ b/Build/rulesets/UICop.ruleset.json @@ -23,7 +23,8 @@ }, { "id": "AW0006", - "action": "Error" + "action": "None", + "justification": "Pages and reports should use the UsageCategory and ApplicationArea properties to be searchable." }, { "id": "AW0007", @@ -31,7 +32,8 @@ }, { "id": "AW0008", - "action": "Error" + "action": "None", + "justification": "The Web client only supports displaying Repeater controls in pages of type List, ListPart, and Worksheet." }, { "id": "AW0009", diff --git a/Build/rulesets/base.ruleset.json b/Build/rulesets/base.ruleset.json index c72038c6e1..6f697780e5 100644 --- a/Build/rulesets/base.ruleset.json +++ b/Build/rulesets/base.ruleset.json @@ -44,18 +44,10 @@ "id": "AL0547", "action": "Warning" }, - { - "id": "AL0551", - "action": "Warning" - }, { "id": "AL0589", "action": "Warning" }, - { - "id": "AL0602", - "action": "Warning" - }, { "id": "AA0247", "action": "Error" @@ -250,10 +242,6 @@ "action": "Warning", "justification": "The FindSet() or Find() method on the record must be used only in connection with the Next() method." }, - { - "id": "AA0189", - "action": "Warning" - }, { "id": "AA0194", "action": "Warning", diff --git a/Build/rulesets/ruleset.json b/Build/rulesets/ruleset.json index b1e550139e..6da850c7ad 100644 --- a/Build/rulesets/ruleset.json +++ b/Build/rulesets/ruleset.json @@ -29,135 +29,30 @@ } ], "rules": [ - { - "id": "AL0797", - "action": "None", - "justification": "Tables are moved from BaseApp to BCApps." - }, { "id": "AL0897", "action": "None", "justification": "TODO(#611991) - Temporarily downgraded to unblock compiler uptake." }, - { - "id": "AS0116", - "action": "None", - "justification": "Cannot be an error. Validates table moves." - }, - { - "id": "AS0053", - "action": "None", - "justification": "The compilation target of an application must be a value that is allowed in a multi-tenant SaaS environment" - }, - { - "id": "AS0054", - "action": "None", - "justification": "The AppSourceCop configuration must specify the set of affixes used by the application" - }, - { - "id": "AS0055", - "action": "None", - "justification": "The AppSourceCop configuration must specify the list of countries/regions targeted by the application" - }, - { - "id": "AS0060", - "action": "None", - "justification": "Unsafe methods cannot be invoked in an AppSource application" - }, { "id": "AS0077", "action": "None", "justification": "Adding a var modifier in events should be allowed in main, as it only will break the runtime behavior of extensions subscribing to it when used in hotfix scenarios." }, - { - "id": "AS0081", - "action": "None", - "justification": "InternalsVisibleTo should not be used as a security feature." - }, - { - "id": "AS0084", - "action": "None", - "justification": "The ID range assigned to the extension must be within the allowed range" - }, - { - "id": "AS0085", - "action": "None", - "justification": "Use the 'application' property instead of specifying explicit dependencies." - }, - { - "id": "AS0092", - "action": "None", - "justification": "The app.json file must specify an Azure Application Insights resource." - }, - { - "id": "AS0100", - "action": "None", - "justification": "The 'application' property must be specified in the app.json file." - }, { "id": "AS0138", "action": "None", - "justification": "TODO(#572306) - This will require a multi-release effort." + "justification": "TODO(#572306) - (see PTE0026) This will require a multi-release effort." }, { "id": "AS0139", "action": "None", "justification": "TODO(#595767) - This will be enabled after branching to BC 27." }, - { - "id": "PTE0001", - "action": "None", - "justification": "Object ID must be in free range." - }, - { - "id": "PTE0002", - "action": "None", - "justification": "PTE ID ranges do not apply to 1st party apps" - }, - { - "id": "PTE0005", - "action": "None", - "justification": "The compilation target of an application must be a value that is allowed in a multi-tenant SaaS environment" - }, - { - "id": "PTE0006", - "action": "None", - "justification": "Encryption key functions must not be invoked." - }, - { - "id": "PTE0012", - "action": "None", - "justification": "Test assertion functions are not allowed in a non-test context." - }, - { - "id": "PTE0013", - "action": "None", - "justification": "Entitlements cannot be defined in an extension." - }, - { - "id": "PTE0024", - "action": "None", - "justification": "We allow moved symbols for Microsoft apps because we run PTECop on the entire codebase which includes global apps." - }, { "id": "PTE0026", "action": "None", - "justification": "A similar rule (i.e. AS0138) is defined in AppSourceCop." - }, - { - "id": "AW0006", - "action": "None", - "justification": "Pages and reports should use the UsageCategory and ApplicationArea properties to be searchable." - }, - { - "id": "AW0008", - "action": "None", - "justification": "The Web client only supports displaying Repeater controls in pages of type List, ListPart, and Worksheet." - }, - { - "id": "AL0678", - "action": "None", - "justification": "Information diagnostic reported on obsolete symbols contributing to metadata name conflicts, ex: 'My Page' and 'My_Page'." + "justification": "TODO(#572306) - (see AS0138) This will require a multi-release effort." } ] }