From 238f71d84c266642e1f59659caf1e19db68c7270 Mon Sep 17 00:00:00 2001 From: aholstrup1 Date: Thu, 8 Feb 2024 08:51:48 +0100 Subject: [PATCH 1/5] Update code with latest changes (February 8th) --- .github/AL-Go-Settings.json | 122 +- .../app/src/core/SwissQRBillMgt.Codeunit.al | 2 +- .../SwissQRBillPurchases.Codeunit.al | 9 +- .../DocumentTypeHandlerCZZ.Codeunit.al | 1 + .../PurchAdvLetterManagementCZZ.Codeunit.al | 7 +- .../SalesAdvLetterManagementCZZ.Codeunit.al | 7 +- .../UpgradeApplicationCZZ.Codeunit.al | 16 - .../UpgradeTagDefinitionsCZZ.Codeunit.al | 6 - .../Pages/AdvanceLetterTemplatesCZZ.Page.al | 5 - .../app/Src/Pages/VATDocumentCZZ.Page.al | 13 +- .../Tables/AdvanceLetterTemplateCZZ.Table.al | 6 - .../Tables/PurchAdvLetterHeaderCZZ.Table.al | 18 +- .../Tables/SalesAdvLetterHeaderCZZ.Table.al | 17 +- .../PurchaseAdvancePaymentsCZZ.Codeunit.al | 31 - .../Src/SalesAdvancePaymentsCZZ.Codeunit.al | 36 - .../GLEntryPostApplicationCZA.Codeunit.al | 37 +- .../app/Src/Pages/ApplyGLEntriesCZA.Page.al | 6 +- .../TableExtensions/GLEntryCZA.TableExt.al | 1 + .../GenJournalLineHandlerCZB.Codeunit.al | 6 +- .../IssueBankStatCreateJnlCZB.Codeunit.al | 41 + .../IssuePaymentOrderExportCZB.Codeunit.al | 41 + .../app/Src/Pages/BankStatementCZB.Page.al | 22 +- .../app/Src/Pages/BankStatementsCZB.Page.al | 20 +- .../app/Src/Pages/PaymentOrderCZB.Page.al | 22 +- .../app/Src/Pages/PaymentOrdersCZB.Page.al | 20 +- .../CZBankDocumentsObjCZB.PermissionSet.al | 2 + .../Tables/BankStatementHeaderCZB.Table.al | 25 +- .../Src/Tables/PaymentOrderHeaderCZB.Table.al | 25 +- .../InstallApplicationCZP.Codeunit.al | 2 +- .../app/Src/Pages/CashDeskCardCZP.Page.al | 2 - .../app/Src/Tables/CashDeskCZP.Table.al | 25 +- .../Src/Tables/CashDocumentHeaderCZP.Table.al | 32 +- .../app/Src/Pages/CompensationCardCZC.Page.al | 2 - .../Src/Tables/CompensationHeaderCZC.Table.al | 26 +- .../RegistrationLogMgtCZL.Codeunit.al | 16 +- .../PurchasesPayablesSetupCZL.PageExt.al | 2 + .../Src/Pages/CompanyOfficialCardCZL.Page.al | 2 - .../Src/Pages/VATCtrlReportCardCZL.Page.al | 2 - .../app/Src/Pages/VIESDeclarationCZL.Page.al | 2 - .../Reports/CloseBalanceSheetCZL.Report.al | 11 +- .../IntrastatJnlBatchCZL.TableExt.al | 2 + .../IntrastatJnlLineCZL.TableExt.al | 2 + .../PurchasesPayablesSetupCZL.TableExt.al | 2 + .../SalesReceivablesSetupCZL.TableExt.al | 2 + .../ServiceMgtSetupCZL.TableExt.al | 2 + .../Src/Tables/CompanyOfficialCZL.Table.al | 25 +- .../Src/Tables/RegNoServiceConfigCZL.Table.al | 5 + .../StatutoryReportingSetupCZL.Table.al | 6 + .../Tables/VATCtrlReportHeaderCZL.Table.al | 30 +- .../Tables/VIESDeclarationHeaderCZL.Table.al | 32 +- .../IntrastatReportManagementCZ.Codeunit.al | 45 + .../src/Tables/SalesVATAdvanceNotif.Table.al | 29 +- .../src/CompaniesNemhandelStatus.PageExt.al | 13 +- .../src/CompanyInfoNemhandelStatus.PageExt.al | 19 +- .../CompanyInfoNemhandelStatus.TableExt.al | 7 +- .../app/src/NemhandelStatusMgt.Codeunit.al | 87 +- .../NemhandelStatusPageBckgrnd.Codeunit.al | 30 +- .../AccountantActivitNemhandel.PageExt.al | 30 +- .../O365ActivitiesNemhandel.PageExt.al | 30 +- .../SOProcessorActivNemhandel.PageExt.al | 30 +- .../SalesMgrActivitNemhandel.PageExt.al | 30 +- .../UserSecurityActivNemhandel.PageExt.al | 30 +- .../UpdRegisteredWithNemhandel.Codeunit.al | 8 +- .../test/src/NemhandelTests.Codeunit.al | 9 - .../OIOUBLCheckSalesandService.Codeunit.al | 4 +- .../GSTDistributionSubcsribers.codeunit.al | 4 +- .../src/table/ServiceTransferHeader.table.al | 29 +- .../GSTTransferOrderReceipt.Codeunit.al | 33 +- .../SubcontractingSubscribers.Codeunit.al | 22 + .../src/Table/DeliveryChallanHeader.Table.al | 29 +- .../Table/MultipleSubconOrderDetails.Table.al | 6 +- .../src/Table/SubCompRcptHeader.Table.al | 32 +- .../GSTSales/src/GSTServiceTests.Codeunit.al | 22 +- .../src/GSTSubcontracting.Codeunit.al | 63 + .../codeunit/GateEntrySubscribers.Codeunit.al | 32 +- .../app/src/table/GateEntryHeader.Table.al | 33 +- .../page/TCSAdjustmentJournal.page.al | 8 +- .../TDS-Journal/TDSAdjustmentJournal.Page.al | 8 +- .../app/src/page/BankPaymentVoucher.page.al | 6 +- .../app/src/page/BankReceiptVoucher.page.al | 6 +- .../app/src/page/CashPaymentVoucher.page.al | 6 +- .../app/src/page/CashReceiptVoucher.page.al | 6 +- .../app/src/page/ContraVoucher.page.al | 6 +- .../app/src/page/JournalVoucher.page.al | 6 +- .../test/src/IntrastatITTest.Codeunit.al | 11 +- .../test/src/ServDeclITTests.Codeunit.al | 13 +- Apps/NA/EnvestnetYodleeBankFeeds/app/app.json | 1 - .../app/src/MSYodleeAccessConsent.Page.al | 4 +- .../app/src/MSYodleeAccountLinking.Page.al | 4 +- .../app/src/MSYodleeEditAccount.Page.al | 4 +- .../app/src/MSYodleeGetLatestStmt.Page.al | 4 +- .../test/src/CDTransfer.Codeunit.al | 4 +- .../src/Processing/IRS1096FormHeader.Table.al | 23 +- .../app/src/BankRecAIMatchingImpl.Codeunit.al | 2 +- .../SetupBankDepositReports.Codeunit.al | 10 +- .../app/src/tables/BankDepositHeader.Table.al | 18 +- .../ConnectivityAppDefinitions.Codeunit.al | 4 +- .../CreateCommonNoSeries.Codeunit.al | 9 +- .../CreateCommonUnitOfMeasure.Codeunit.al | 15 + .../1.Setup Data/CreateFANoSeries.Codeunit.al | 10 +- .../CreateEmployeeNoSeries.Codeunit.al | 2 +- .../CreateJobNoSeries.Codeunit.al | 2 +- .../CreateMfgNoSeries.Codeunit.al | 16 +- .../CreateSvcNoSeries.Codeunit.al | 16 +- .../CreateSustainJnlSetup.Codeunit.al | 109 + .../CreateSustainNoSeries.Codeunit.al | 33 + .../CreateSustainSubcategory.Codeunit.al | 389 +++ .../CreateSustainabilityAccount.Codeunit.al | 506 +++ .../CreateSustainabilityCategory.Codeunit.al | 150 + .../CreateSustainabilitySetup.Codeunit.al | 44 + .../CreateSustainabilityJournal.Codeunit.al | 69 + .../CreateSustainabilityEntry.Codeunit.al | 71 + .../SustainabilityModule.Codeunit.al | 39 + .../CreateWhseNoSeries.Codeunit.al | 40 +- .../ContosoAuditCode.Codeunit.al | 36 + .../ContosoNoSeries.Codeunit.al | 52 + .../ContosoSustainability.Codeunit.al | 201 ++ .../DemoTool/ContosoDemoDataModule.Enum.al | 4 + Apps/W1/ContosoCoffeeDemoDataset/app/app.json | 9 +- .../EDocCoreBasic.PermissionSet.al | 5 +- .../Permissions/EDocCoreEdit.PermissionSet.al | 5 +- .../EDocCoreObjects.PermissionSet.al | 9 + .../Permissions/EDocCoreRead.PermissionSet.al | 5 +- .../EDocDataExchangeImpl.Codeunit.al | 5 + .../src/EDocDEDPEPPOLPreMapping.Codeunit.al | 22 +- .../src/EDocDEDPEPPOLSubscribers.Codeunit.al | 8 +- .../app/src/Document/EDocument.Page.al | 239 +- .../Document/EDocumentServiceStatus.Enum.al | 22 +- .../app/src/Document/EDocuments.Page.al | 5 +- .../app/src/EDocumentInstall.Codeunit.al | 3 +- .../Extensions/EDocBusManagerRC.PageExt.al | 13 + .../Extensions/EDocInvManagerRC.PageExt.al | 13 + .../Extensions/EDocOrderMapActivities.Page.al | 54 + .../Extensions/EDocPurchaseHeader.TableExt.al | 26 + .../Extensions/EDocPurchaseLine.TableExt.al | 50 + .../Extensions/EDocPurchaseOrder.PageExt.al | 34 + .../EDocPurchaseOrderList.PageExt.al | 70 + .../Extensions/EDocShipRecWmsRC.PageExt.al | 13 + .../src/Extensions/EDocVendorPage.PageExt.al | 17 + .../Extensions/EDocumentActivities.Page.al | 25 + .../Extensions/EDocumentVendor.TableExt.al | 12 + .../EDocIntegrationManagement.Codeunit.al | 8 - .../app/src/Log/EDocumentLog.Codeunit.al | 3 +- .../app/src/Processing/EDocImport.Codeunit.al | 484 ++- .../EDocumentCreateJnlLine.Codeunit.al | 9 +- .../EDocumentCreatePurchDoc.Codeunit.al | 6 +- .../EDocumentProcessing.Codeunit.al | 38 + .../EDocumentSubscription.Codeunit.al | 140 +- .../OrderMatching/EDocImportedLine.Table.al | 154 + .../OrderMatching/EDocImportedLineSub.Page.al | 146 + .../EDocLineMatching.Codeunit.al | 459 +++ .../EDocOrderLineMatching.Page.al | 328 ++ .../OrderMatching/EDocOrderMatch.Page.al | 44 + .../OrderMatching/EDocOrderMatch.Table.al | 82 + .../EDocPurchaseOrderSub.Page.al | 179 ++ .../app/src/Service/EDocumentService.Table.al | 6 +- .../Service/EDocumentServiceStatus.Page.al | 26 + .../app/src/Service/EdocumentService.Page.al | 25 +- .../Matching/EDocLineMatchingTest.Codeunit.al | 242 ++ .../src/Processing/EDocE2ETest.Codeunit.al | 4 +- .../src/Receive/EDocReceiveTest.Codeunit.al | 20 + .../src/E3Party/EDocExtEDocument.PageExt.al | 4 +- .../DigitalVoucherImpl.Codeunit.al | 2 + Apps/W1/EnforcedDigitalVouchers/test/app.json | 6 + .../test/src/DigitalVouchersTests.Codeunit.al | 75 + .../src/codeunits/CloudMigUpgrade.codeunit.al | 4 +- .../HybridCloudManagement.Codeunit.al | 27 +- .../codeunits/GPCloudMigration.codeunit.al | 11 + .../test/src/GPForecastingTests.codeunit.al | 9 +- .../Lookup/Table/LookupTableFilter.Table.al | 10 + .../app/src/IntrastatReportGetLines.Report.al | 21 +- .../app/src/IntrastatReportHeader.Table.al | 23 +- .../src/IntrastatReportManagement.Codeunit.al | 10 +- .../app/src/LPInvoicesAtRisk.Page.al | 2 +- .../app/src/LPMachineLearningSetup.Page.al | 37 +- .../app/src/LPMachineLearningSetup.Table.al | 51 +- .../app/src/LPModelManagement.Codeunit.al | 4 +- .../app/src/LPPredictionMgt.Codeunit.al | 19 +- .../MasterDataMgtSetupDefault.Codeunit.al | 5 + .../MasterDataMgtSubscribers.Codeunit.al | 12 + .../src/AzureADPlanModuleTest.codeunit.al | 9 + .../src/Support/MSQBODataMigration.Page.al | 2 +- .../app/src/enums/ReviewPolicyType.Enum.al | 6 +- .../SalesForecastHandler.Codeunit.al | 5 +- .../app/src/pages/SalesForecast.Page.al | 5 +- .../src/pages/SalesForecastSetupCard.Page.al | 22 +- .../src/tables/MSSalesForecastSetup.Table.al | 64 +- .../test/src/SalesForecastLib.Codeunit.al | 5 +- .../test/src/SalesForecastTests.Codeunit.al | 21 +- .../ServiceDeclarationHeader.Table.al | 27 +- .../ServiceDeclarationMgt.Codeunit.al | 2 +- Apps/W1/Shopify/app/app.json | 5 +- .../Codeunits/ShpfyUpgradeMgt.Codeunit.al | 36 + .../src/Base/Enums/ShpfyLoggingMode.Enum.al | 1 - .../app/src/Base/Pages/ShpfyShopCard.Page.al | 44 + .../app/src/Base/Tables/ShpfyShop.Table.al | 42 + .../Codeunits/ShpfyUpdateCustomer.Codeunit.al | 2 +- .../Pages/ShpfyAuthentication.Page.al | 2 +- .../ShpfyFulfillmentOrdersAPI.Codeunit.al | 12 +- .../Codeunits/ShpfyRefundsAPI.Codeunit.al | 39 +- .../Order Refunds/Pages/ShpfyRefund.Page.al | 2 + .../Order Refunds/Pages/ShpfyRefunds.Page.al | 2 + .../Tables/ShpfyRefundLine.Table.al | 6 + .../ShpfyRetRefProcCrMemo.Codeunit.al | 5 + .../Codeunits/ShpfyImportOrder.Codeunit.al | 154 +- .../Codeunits/ShpfyOrdersAPI.Codeunit.al | 30 +- .../Codeunits/ShpfyProcessOrder.Codeunit.al | 1 + .../Enums/ShpfyTrackingCompanies.Enum.al | 3 +- .../Pages/ShpfyOrderAttributes.Page.al | 28 +- .../Enums/ShpfyPaymentTransType.Enum.al | 3 +- .../Payments/Enums/ShpfyPayoutStatus.Enum.al | 5 +- .../ShpfyShippingCharges.Codeunit.al | 1 + .../Queries/ShpfyShipmentLocation.Query.al | 1 - .../Tables/ShpfyOrderShippingCharges.Table.al | 7 +- .../Enums/ShpfyTransactionStatus.Enum.al | 3 +- .../Enums/ShpfyTransactionType.Enum.al | 3 +- .../Tables/ShpfyOrderTransaction.Table.al | 4 +- .../ShpfyOrderRefundsHelper.Codeunit.al | 1 + Apps/W1/Sustainability/app/app.json | 8 +- .../src/Account/CalculationFoundation.Enum.al | 1 - .../Account/ChartOfSustainAccounts.Page.al | 27 +- .../app/src/Account/EmissionScope.Enum.al | 1 - .../Account/SustainAccountCategory.Table.al | 2 +- .../SustainAccountSubcategory.Table.al | 13 +- .../Account/SustainabilityAccount.Table.al | 28 +- .../Account/SustainabilityAccountList.Page.al | 5 + .../SustainabilityAccountMgt.Codeunit.al | 36 +- .../SustainabilityCalcMgt.Codeunit.al | 26 +- .../SustainabilityCalculation.Codeunit.al | 32 +- .../Journal/SustainabilityJnlLine.Table.al | 38 +- .../src/Journal/SustainabilityJournal.Page.al | 49 +- .../SustainabilityJournalMgt.Codeunit.al | 53 +- .../Ledger/SustainabilityLedgerEntry.Table.al | 16 +- .../SustainabilityAdmin.permissionset.al | 18 + .../SustainabilityEdit.permissionset.al | 9 +- .../SustainabilityObjects.permissionset.al | 6 +- ...365BasicSustainability.PermissionsetExt.al | 8 +- ...llaccessSustainability.permissionsetExt.al | 8 + ...d365ReadSustainability.PermissionsetExt.al | 4 + ...amMemberSustainability.PermissionsetExt.al | 8 +- .../SustainabilityJnlCheck.Codeunit.al | 62 +- .../Posting/SustainabilityJnlPost.Codeunit.al | 81 +- .../Posting/SustainabilityPostMgt.Codeunit.al | 46 +- .../SustainabilityRecurJnlPost.Codeunit.al | 37 +- .../src/Reports/EmissionByCategory.Report.al | 125 + .../app/src/Reports/EmissionByCategory.rdlc | 2300 ++++++++++++++ .../app/src/Reports/EmissionByCategory.xlsx | Bin 0 -> 110035 bytes .../src/Reports/EmissionPerFacility.Report.al | 112 + .../app/src/Reports/EmissionPerFacility.rdlc | 2021 ++++++++++++ .../app/src/Reports/EmissionPerFacility.xlsx | Bin 0 -> 77744 bytes .../app/src/Reports/TotalEmissions.Report.al | 130 + .../app/src/Reports/TotalEmissions.rdlc | 2757 +++++++++++++++++ .../app/src/Reports/TotalEmissions.xlsx | Bin 0 -> 99237 bytes .../InstallSustainabilitySetup.Codeunit.al | 26 + .../app/src/Setup/SustainabilitySetup.Page.al | 10 +- .../src/Setup/SustainabilitySetup.Table.al | 36 +- Apps/W1/Sustainability/test/app.json | 4 +- .../src/LibrarySustainability.Codeunit.al | 97 + .../src/SustainabilityCheckTest.Codeunit.al | 134 + .../SustainabilityFoundationTest.Codeunit.al | 31 + .../src/SustainabilityJournalTest.Codeunit.al | 103 + .../src/SustainabilityPostingTest.Codeunit.al | 62 + Apps/W1/TransactionStorage/app/app.json | 6 +- 263 files changed, 14723 insertions(+), 1331 deletions(-) create mode 100644 Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/IssueBankStatCreateJnlCZB.Codeunit.al create mode 100644 Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/IssuePaymentOrderExportCZB.Codeunit.al create mode 100644 Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainJnlSetup.Codeunit.al create mode 100644 Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainNoSeries.Codeunit.al create mode 100644 Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainSubcategory.Codeunit.al create mode 100644 Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainabilityAccount.Codeunit.al create mode 100644 Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainabilityCategory.Codeunit.al create mode 100644 Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainabilitySetup.Codeunit.al create mode 100644 Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/3. Transactions/CreateSustainabilityJournal.Codeunit.al create mode 100644 Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/4. Historical/CreateSustainabilityEntry.Codeunit.al create mode 100644 Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/SustainabilityModule.Codeunit.al create mode 100644 Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoAuditCode.Codeunit.al create mode 100644 Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoSustainability.Codeunit.al create mode 100644 Apps/W1/EDocument/app/src/Extensions/EDocBusManagerRC.PageExt.al create mode 100644 Apps/W1/EDocument/app/src/Extensions/EDocInvManagerRC.PageExt.al create mode 100644 Apps/W1/EDocument/app/src/Extensions/EDocOrderMapActivities.Page.al create mode 100644 Apps/W1/EDocument/app/src/Extensions/EDocPurchaseHeader.TableExt.al create mode 100644 Apps/W1/EDocument/app/src/Extensions/EDocPurchaseLine.TableExt.al create mode 100644 Apps/W1/EDocument/app/src/Extensions/EDocPurchaseOrderList.PageExt.al create mode 100644 Apps/W1/EDocument/app/src/Extensions/EDocShipRecWmsRC.PageExt.al create mode 100644 Apps/W1/EDocument/app/src/Extensions/EDocVendorPage.PageExt.al create mode 100644 Apps/W1/EDocument/app/src/Extensions/EDocumentVendor.TableExt.al create mode 100644 Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocImportedLine.Table.al create mode 100644 Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocImportedLineSub.Page.al create mode 100644 Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocLineMatching.Codeunit.al create mode 100644 Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocOrderLineMatching.Page.al create mode 100644 Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocOrderMatch.Page.al create mode 100644 Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocOrderMatch.Table.al create mode 100644 Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocPurchaseOrderSub.Page.al create mode 100644 Apps/W1/EDocument/test/src/Matching/EDocLineMatchingTest.Codeunit.al create mode 100644 Apps/W1/Sustainability/app/src/Permissions/SustainabilityAdmin.permissionset.al create mode 100644 Apps/W1/Sustainability/app/src/Permissions/d365BusFullaccessSustainability.permissionsetExt.al create mode 100644 Apps/W1/Sustainability/app/src/Reports/EmissionByCategory.Report.al create mode 100644 Apps/W1/Sustainability/app/src/Reports/EmissionByCategory.rdlc create mode 100644 Apps/W1/Sustainability/app/src/Reports/EmissionByCategory.xlsx create mode 100644 Apps/W1/Sustainability/app/src/Reports/EmissionPerFacility.Report.al create mode 100644 Apps/W1/Sustainability/app/src/Reports/EmissionPerFacility.rdlc create mode 100644 Apps/W1/Sustainability/app/src/Reports/EmissionPerFacility.xlsx create mode 100644 Apps/W1/Sustainability/app/src/Reports/TotalEmissions.Report.al create mode 100644 Apps/W1/Sustainability/app/src/Reports/TotalEmissions.rdlc create mode 100644 Apps/W1/Sustainability/app/src/Reports/TotalEmissions.xlsx create mode 100644 Apps/W1/Sustainability/app/src/Setup/InstallSustainabilitySetup.Codeunit.al create mode 100644 Apps/W1/Sustainability/test/src/LibrarySustainability.Codeunit.al create mode 100644 Apps/W1/Sustainability/test/src/SustainabilityCheckTest.Codeunit.al create mode 100644 Apps/W1/Sustainability/test/src/SustainabilityFoundationTest.Codeunit.al create mode 100644 Apps/W1/Sustainability/test/src/SustainabilityJournalTest.Codeunit.al create mode 100644 Apps/W1/Sustainability/test/src/SustainabilityPostingTest.Codeunit.al diff --git a/.github/AL-Go-Settings.json b/.github/AL-Go-Settings.json index d0b7ce3d1a..b9b39085f2 100644 --- a/.github/AL-Go-Settings.json +++ b/.github/AL-Go-Settings.json @@ -1,63 +1,63 @@ { - "type": "PTE", - "templateUrl": "https://github.com/microsoft/AL-Go-PTE@preview", - "bcContainerHelperVersion": "preview", - "runs-on": "windows-latest", - "cacheImageName": "", - "UsePsSession": false, - "artifact": "https://bcinsider.azureedge.net/sandbox/24.0.15733.0/base", - "country": "base", - "useProjectDependencies": true, - "repoVersion": "24.0", - "cleanModePreprocessorSymbols": [ - "CLEAN17", - "CLEAN18", - "CLEAN19", - "CLEAN20", - "CLEAN21", - "CLEAN22", - "CLEAN23", - "CLEAN24" - ], - "unusedALGoSystemFiles": [ - "AddExistingAppOrTestApp.yaml", - "CreateApp.yaml", - "CreateOnlineDevelopmentEnvironment.yaml", - "CreatePerformanceTestApp.yaml", - "CreateRelease.yaml", - "CreateTestApp.yaml", - "Current.yaml", - "IncrementVersionNumber.yaml", - "NextMajor.yaml", - "NextMinor.yaml", - "PublishToEnvironment.yaml", - "Test Current.settings.json" - ], - "excludeEnvironments": [ - "Official-Build" - ], - "buildModes": [ - "Translated" - ], - "CICDPushBranches": [ - "main" - ], - "CICDPullRequestBranches": [ - "main" - ], - "enableCodeCop": true, - "enableAppSourceCop": true, - "enablePerTenantExtensionCop": true, - "enableUICop": true, - "rulesetFile": "..\\..\\..\\Apps\\rulesets\\app.ruleset.json", - "skipUpgrade": true, - "fullBuildPatterns": [ - "Build/*", - "src/rulesets/*", - ".github/workflows/PullRequestHandler.yaml", - ".github/workflows/_BuildALGoProject.yaml" - ], - "UpdateALGoSystemFilesEnvironment": "Official-Build", - "PullRequestTrigger": "pull_request", - "templateSha": "0476547896ebcd3ba5455b3e0e59b48c0d4a26ca" + "type": "PTE", + "templateUrl": "https://github.com/microsoft/AL-Go-PTE@preview", + "bcContainerHelperVersion": "preview", + "runs-on": "windows-latest", + "cacheImageName": "", + "UsePsSession": false, + "artifact": "https://bcinsider.azureedge.net/sandbox/24.0.16037.0/base", + "country": "base", + "useProjectDependencies": true, + "repoVersion": "24.0", + "cleanModePreprocessorSymbols": [ + "CLEAN17", + "CLEAN18", + "CLEAN19", + "CLEAN20", + "CLEAN21", + "CLEAN22", + "CLEAN23", + "CLEAN24" + ], + "unusedALGoSystemFiles": [ + "AddExistingAppOrTestApp.yaml", + "CreateApp.yaml", + "CreateOnlineDevelopmentEnvironment.yaml", + "CreatePerformanceTestApp.yaml", + "CreateRelease.yaml", + "CreateTestApp.yaml", + "Current.yaml", + "IncrementVersionNumber.yaml", + "NextMajor.yaml", + "NextMinor.yaml", + "PublishToEnvironment.yaml", + "Test Current.settings.json" + ], + "excludeEnvironments": [ + "Official-Build" + ], + "buildModes": [ + "Translated" + ], + "CICDPushBranches": [ + "main" + ], + "CICDPullRequestBranches": [ + "main" + ], + "enableCodeCop": true, + "enableAppSourceCop": true, + "enablePerTenantExtensionCop": true, + "enableUICop": true, + "rulesetFile": "..\\..\\..\\Apps\\rulesets\\app.ruleset.json", + "skipUpgrade": true, + "fullBuildPatterns": [ + "Build/*", + "src/rulesets/*", + ".github/workflows/PullRequestHandler.yaml", + ".github/workflows/_BuildALGoProject.yaml" + ], + "UpdateALGoSystemFilesEnvironment": "Official-Build", + "PullRequestTrigger": "pull_request", + "templateSha": "0476547896ebcd3ba5455b3e0e59b48c0d4a26ca" } diff --git a/Apps/CH/SwissQRBill/app/src/core/SwissQRBillMgt.Codeunit.al b/Apps/CH/SwissQRBill/app/src/core/SwissQRBillMgt.Codeunit.al index be6dc2b6a4..4bd6f99232 100644 --- a/Apps/CH/SwissQRBill/app/src/core/SwissQRBillMgt.Codeunit.al +++ b/Apps/CH/SwissQRBill/app/src/core/SwissQRBillMgt.Codeunit.al @@ -466,7 +466,7 @@ codeunit 11518 "Swiss QR-Bill Mgt." exit(Language.GetLanguageCode(GetLanguageIdENU())); end; - internal procedure DeleteTenantMedia(MediaId: Guid) + procedure DeleteTenantMedia(MediaId: Guid) var TenantMedia: Record "Tenant Media"; begin diff --git a/Apps/CH/SwissQRBill/app/src/purchases/SwissQRBillPurchases.Codeunit.al b/Apps/CH/SwissQRBill/app/src/purchases/SwissQRBillPurchases.Codeunit.al index 14b9b1ffb8..18b6f472e8 100644 --- a/Apps/CH/SwissQRBill/app/src/purchases/SwissQRBillPurchases.Codeunit.al +++ b/Apps/CH/SwissQRBill/app/src/purchases/SwissQRBillPurchases.Codeunit.al @@ -423,6 +423,7 @@ codeunit 11502 "Swiss QR-Bill Purchases" GenJournalTemplate: Record "Gen. Journal Template"; GenJournalBatch: Record "Gen. Journal Batch"; NewGenJournalLine: Record "Gen. Journal Line"; + NoSeriesBatch: Codeunit "No. Series - Batch"; LastLineNo: Integer; Finish: Boolean; MessageResult: Text; @@ -442,7 +443,7 @@ codeunit 11502 "Swiss QR-Bill Purchases" LastLineNo += 10000; NewGenJournalLine."Line No." := LastLineNo; NewGenJournalLine.Insert(); - NewGenJournalLine.IncrementDocumentNo(GenJournalBatch, NewDocumentNo); + NewDocumentNo := NoSeriesBatch.SimulateGetNextNo(GenJournalBatch."No. Series", NewGenJournalLine."Posting Date", NewDocumentNo); Commit(); finish := not Confirm(MessageResult) end else @@ -454,7 +455,7 @@ codeunit 11502 "Swiss QR-Bill Purchases" local procedure PreparePurchaseJournalLine(var GenJournalLine: Record "Gen. Journal Line"; var GenJournalTemplate: Record "Gen. Journal Template"; var GenJournalBatch: Record "Gen. Journal Batch"; var LastLineNo: Integer; var NewDocumentNo: Code[20]) var - NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeriesBatch: Codeunit "No. Series - Batch"; begin with GenJournalLine do begin GenJournalTemplate.Get("Journal Template Name"); @@ -466,9 +467,9 @@ codeunit 11502 "Swiss QR-Bill Purchases" NewDocumentNo := "Document No."; end; if NewDocumentNo = '' then - NewDocumentNo := NoSeriesManagement.TryGetNextNo(GenJournalBatch."No. Series", WorkDate()) + NewDocumentNo := NoSeriesBatch.PeekNextNo(GenJournalBatch."No. Series", WorkDate()) else - IncrementDocumentNo(GenJournalBatch, NewDocumentNo); + NewDocumentNo := NoSeriesBatch.SimulateGetNextNo(GenJournalBatch."No. Series", GenJournalLine."Posting Date", NewDocumentNo) end; end; diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/DocumentTypeHandlerCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/DocumentTypeHandlerCZZ.Codeunit.al index 631e87356c..edfb359a19 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/DocumentTypeHandlerCZZ.Codeunit.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/DocumentTypeHandlerCZZ.Codeunit.al @@ -11,6 +11,7 @@ using Microsoft.Purchases.Payables; codeunit 31141 "Document Type Handler CZZ" { + Access = Internal; EventSubscriberInstance = Manual; [EventSubscriber(ObjectType::Table, Database::"G/L Entry", 'OnAfterCopyGLEntryFromGenJnlLine', '', false, false)] diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/PurchAdvLetterManagementCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/PurchAdvLetterManagementCZZ.Codeunit.al index ef8dcc3192..19305682a3 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/PurchAdvLetterManagementCZZ.Codeunit.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/PurchAdvLetterManagementCZZ.Codeunit.al @@ -458,7 +458,7 @@ codeunit 31019 "PurchAdvLetterManagement CZZ" PurchAdvLetterEntryCZZ2.CalcSums(Amount); TempAdvancePostingBufferCZZ.CalcSums(Amount); - if Abs(PurchAdvLetterEntryCZZ.Amount - PurchAdvLetterEntryCZZ2.Amount) < Abs(TempAdvancePostingBufferCZZ.Amount) then + if (PurchAdvLetterEntryCZZ.Amount - PurchAdvLetterEntryCZZ2.Amount) < TempAdvancePostingBufferCZZ.Amount then Error(ExceededAmountErr); GetCurrency(PurchAdvLetterEntryCZZ."Currency Code"); @@ -586,19 +586,14 @@ codeunit 31019 "PurchAdvLetterManagement CZZ" local procedure BufferAdvanceLines(PurchAdvLetterHeaderCZZ: Record "Purch. Adv. Letter Header CZZ"; var AdvancePostingBufferCZZ: Record "Advance Posting Buffer CZZ") var - AdvanceLetterTemplateCZZ: Record "Advance Letter Template CZZ"; PurchAdvLetterLineCZZ: Record "Purch. Adv. Letter Line CZZ"; TempAdvancePostingBufferCZZ: Record "Advance Posting Buffer CZZ" temporary; begin AdvancePostingBufferCZZ.Reset(); AdvancePostingBufferCZZ.DeleteAll(); - AdvanceLetterTemplateCZZ.Get(PurchAdvLetterHeaderCZZ."Advance Letter Code"); - PurchAdvLetterLineCZZ.SetRange("Document No.", PurchAdvLetterHeaderCZZ."No."); PurchAdvLetterLineCZZ.SetFilter(Amount, '<>0'); - if not AdvanceLetterTemplateCZZ."Post VAT Doc. for Rev. Charge" then - PurchAdvLetterLineCZZ.SetFilter("VAT Calculation Type", '<>%1', PurchAdvLetterLineCZZ."VAT Calculation Type"::"Reverse Charge VAT"); if PurchAdvLetterLineCZZ.FindSet() then repeat TempAdvancePostingBufferCZZ.PrepareForPurchAdvLetterLine(PurchAdvLetterLineCZZ); diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/SalesAdvLetterManagementCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/SalesAdvLetterManagementCZZ.Codeunit.al index 17dd848728..3fb9d313c2 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/SalesAdvLetterManagementCZZ.Codeunit.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/SalesAdvLetterManagementCZZ.Codeunit.al @@ -472,7 +472,7 @@ codeunit 31002 "SalesAdvLetterManagement CZZ" SalesAdvLetterEntryCZZ2.CalcSums(Amount); TempAdvancePostingBufferCZZ.CalcSums(Amount); - if Abs(SalesAdvLetterEntryCZZ.Amount - SalesAdvLetterEntryCZZ2.Amount) < Abs(TempAdvancePostingBufferCZZ.Amount) then + if (SalesAdvLetterEntryCZZ.Amount - SalesAdvLetterEntryCZZ2.Amount) < TempAdvancePostingBufferCZZ.Amount then Error(ExceededAmountErr); GetCurrency(SalesAdvLetterEntryCZZ."Currency Code"); @@ -624,19 +624,14 @@ codeunit 31002 "SalesAdvLetterManagement CZZ" local procedure BufferAdvanceLines(SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; var AdvancePostingBufferCZZ: Record "Advance Posting Buffer CZZ") var - AdvanceLetterTemplateCZZ: Record "Advance Letter Template CZZ"; SalesAdvLetterLineCZZ: Record "Sales Adv. Letter Line CZZ"; TempAdvancePostingBufferCZZ: Record "Advance Posting Buffer CZZ" temporary; begin AdvancePostingBufferCZZ.Reset(); AdvancePostingBufferCZZ.DeleteAll(); - AdvanceLetterTemplateCZZ.Get(SalesAdvLetterHeaderCZZ."Advance Letter Code"); - SalesAdvLetterLineCZZ.SetRange("Document No.", SalesAdvLetterHeaderCZZ."No."); SalesAdvLetterLineCZZ.SetFilter(Amount, '<>0'); - if not AdvanceLetterTemplateCZZ."Post VAT Doc. for Rev. Charge" then - SalesAdvLetterLineCZZ.SetFilter("VAT Calculation Type", '<>%1', SalesAdvLetterLineCZZ."VAT Calculation Type"::"Reverse Charge VAT"); if SalesAdvLetterLineCZZ.FindSet() then repeat TempAdvancePostingBufferCZZ.PrepareForSalesAdvLetterLine(SalesAdvLetterLineCZZ); diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/UpgradeApplicationCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/UpgradeApplicationCZZ.Codeunit.al index 89f8922b77..1f83d371c2 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/UpgradeApplicationCZZ.Codeunit.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/UpgradeApplicationCZZ.Codeunit.al @@ -46,7 +46,6 @@ codeunit 31088 "Upgrade Application CZZ" InstallApplicationCZZ.CopyData(); UpgradeCustomerNoInSalesAdvLetterEntries(); UpgradeAdvanceLetterApplicationAmountLCY(); - UpgradePostVATDocForReverseCharge(); end; local procedure UpgradeAdvancePaymentsReportReportSelections(); @@ -122,21 +121,6 @@ codeunit 31088 "Upgrade Application CZZ" UpgradeTag.SetUpgradeTag(UpgradeTagDefinitionsCZZ.GetAdvanceLetterApplicationAmountLCYUpgradeTag()); end; - local procedure UpgradePostVATDocForReverseCharge() - var - AdvanceLetterTemplate: Record "Advance Letter Template CZZ"; - AdvLetterTemplateDataTransfer: DataTransfer; - begin - if UpgradeTag.HasUpgradeTag(UpgradeTagDefinitionsCZZ.GetPostVATDocForReverseChargeUpgradeTag()) then - exit; - - AdvLetterTemplateDataTransfer.SetTables(Database::"Advance Letter Template CZZ", Database::"Advance Letter Template CZZ"); - AdvLetterTemplateDataTransfer.AddConstantValue(true, AdvanceLetterTemplate.FieldNo("Post VAT Doc. for Rev. Charge")); - AdvLetterTemplateDataTransfer.CopyFields(); - - UpgradeTag.SetUpgradeTag(UpgradeTagDefinitionsCZZ.GetPostVATDocForReverseChargeUpgradeTag()); - end; - local procedure GetCurrencyFactor(AdvanceLetterType: Enum "Advance Letter Type CZZ"; AdvanceLetterNo: Code[20]): Decimal var PurchAdvLetterHeader: Record "Purch. Adv. Letter Header CZZ"; diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/UpgradeTagDefinitionsCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/UpgradeTagDefinitionsCZZ.Codeunit.al index 9cfb7edc48..af436f1592 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/UpgradeTagDefinitionsCZZ.Codeunit.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Codeunits/UpgradeTagDefinitionsCZZ.Codeunit.al @@ -24,7 +24,6 @@ codeunit 31089 "Upgrade Tag Definitions CZZ" PerCompanyUpgradeTags.Add(GetDataVersion210PerCompanyUpgradeTag()); PerCompanyUpgradeTags.Add(GetSalesAdvLetterEntryCustomerNoUpgradeTag()); PerCompanyUpgradeTags.Add(GetAdvanceLetterApplicationAmountLCYUpgradeTag()); - PerCompanyUpgradeTags.Add(GetPostVATDocForReverseChargeUpgradeTag()); end; procedure GetDataVersion190PerDatabaseUpgradeTag(): Code[250] @@ -66,9 +65,4 @@ codeunit 31089 "Upgrade Tag Definitions CZZ" begin exit('CZZ-478403-AdvanceLetterApplicationAmountLCYUpgradeTag-20230717'); end; - - procedure GetPostVATDocForReverseChargeUpgradeTag(): Code[250] - begin - exit('CZZ-494279-PostVATDocForReverseChargeUpgradeTag-20240111'); - end; } diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/AdvanceLetterTemplatesCZZ.Page.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/AdvanceLetterTemplatesCZZ.Page.al index 5ba015d3f2..18a33e3b61 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/AdvanceLetterTemplatesCZZ.Page.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/AdvanceLetterTemplatesCZZ.Page.al @@ -64,11 +64,6 @@ page 31179 "Advance Letter Templates CZZ" ApplicationArea = Basic, Suite; ToolTip = 'Specifies automatic post VAT document.'; } - field("Post VAT Doc. for Rev. Charge"; Rec."Post VAT Doc. for Rev. Charge") - { - ApplicationArea = Basic, Suite; - ToolTip = 'Specifies whether the VAT document will be posting for reverse charge.'; - } #if not CLEAN23 #pragma warning disable AL0432,AS0074 field("Document Report ID"; '') diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/VATDocumentCZZ.Page.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/VATDocumentCZZ.Page.al index 269861299d..006df64ba9 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/VATDocumentCZZ.Page.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Pages/VATDocumentCZZ.Page.al @@ -37,7 +37,7 @@ page 31185 "VAT Document CZZ" trigger OnValidate() begin if DocumentNo <> InitDocumentNo then - NoSeriesManagement.TestManual(NoSeriesCode); + NoSeries.TestManual(NoSeriesCode); end; trigger OnAssistEdit() @@ -45,9 +45,7 @@ page 31185 "VAT Document CZZ" NoSeriesManagement2: Codeunit NoSeriesManagement; begin if NoSeriesManagement2.SelectSeries(InitNoSeriesCode, NoSeriesCode, NoSeriesCode) then begin - Clear(NoSeriesManagement); - - DocumentNo := NoSeriesManagement.GetNextNo(NoSeriesCode, PostingDate, false); + DocumentNo := NoSeriesBatch.GetNextNo(NoSeriesCode, PostingDate); InitDocumentNo := DocumentNo; end; end; @@ -139,7 +137,8 @@ page 31185 "VAT Document CZZ" } var - NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeriesBatch: Codeunit "No. Series - Batch"; + NoSeries: Codeunit "No. Series"; DocumentNo: Code[20]; InitDocumentNo: Code[20]; ExternalDocumentNo: Code[35]; @@ -190,7 +189,7 @@ page 31185 "VAT Document CZZ" DocumentNo := NewDocumentNo; DocumentNoEditable := false; end else begin - DocumentNo := NoSeriesManagement.GetNextNo(NoSeriesCode, PostingDate, false); + DocumentNo := NoSeriesBatch.GetNextNo(NoSeriesCode, PostingDate); DocumentNoEditable := true; end; InitDocumentNo := DocumentNo; @@ -254,7 +253,7 @@ page 31185 "VAT Document CZZ" procedure SaveNoSeries() begin - NoSeriesManagement.SaveNoSeries(); + NoSeriesBatch.SaveState(); end; local procedure UpdateCurrencyFactor(NewCurrencyFactor: Decimal) diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/AdvanceLetterTemplateCZZ.Table.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/AdvanceLetterTemplateCZZ.Table.al index 8adad0f4de..fd341e1fc1 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/AdvanceLetterTemplateCZZ.Table.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/AdvanceLetterTemplateCZZ.Table.al @@ -146,12 +146,6 @@ table 31003 "Advance Letter Template CZZ" Caption = 'Automatic Post VAT Document'; DataClassification = CustomerContent; } - field(26; "Post VAT Doc. for Rev. Charge"; Boolean) - { - Caption = 'Post VAT Document for Reverse Charge'; - DataClassification = CustomerContent; - InitValue = true; - } } keys { diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/PurchAdvLetterHeaderCZZ.Table.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/PurchAdvLetterHeaderCZZ.Table.al index c2b9c718d1..4c462ae281 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/PurchAdvLetterHeaderCZZ.Table.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/PurchAdvLetterHeaderCZZ.Table.al @@ -57,7 +57,7 @@ table 31008 "Purch. Adv. Letter Header CZZ" begin if "No." <> xRec."No." then begin GetSetup(); - NoSeriesManagement.TestManual(AdvanceLetterTemplateCZZ."Advance Letter Document Nos."); + NoSeries.TestManual(AdvanceLetterTemplateCZZ."Advance Letter Document Nos."); "No. Series" := ''; end; end; @@ -854,6 +854,7 @@ table 31008 "Purch. Adv. Letter Header CZZ" SalespersonPurchaser: Record "Salesperson/Purchaser"; ResponsibilityCenter: Record "Responsibility Center"; NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; DimensionManagement: Codeunit DimensionManagement; UserSetupManagement: Codeunit "User Setup Management"; #if not CLEAN22 @@ -931,9 +932,20 @@ table 31008 "Purch. Adv. Letter Header CZZ" if "No." = '' then begin GetSetup(); AdvanceLetterTemplateCZZ.TestField("Advance Letter Document Nos."); - NoSeriesManagement.InitSeries(AdvanceLetterTemplateCZZ."Advance Letter Document Nos.", xRec."No. Series", "Posting Date", "No.", "No. Series") +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(AdvanceLetterTemplateCZZ."Advance Letter Document Nos.", xRec."No. Series", "Posting Date", "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := AdvanceLetterTemplateCZZ."Advance Letter Document Nos."; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series", "Posting Date"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", AdvanceLetterTemplateCZZ."Advance Letter Document Nos.", "Posting Date", "No."); + end; +#endif end; - OnInitInsertOnBeforeInitRecord(Rec, xRec); InitRecord(); end; diff --git a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/SalesAdvLetterHeaderCZZ.Table.al b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/SalesAdvLetterHeaderCZZ.Table.al index b1a0ddc0f2..716bfe221d 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/SalesAdvLetterHeaderCZZ.Table.al +++ b/Apps/CZ/AdvancePaymentsLocalization/app/Src/Tables/SalesAdvLetterHeaderCZZ.Table.al @@ -52,7 +52,7 @@ table 31004 "Sales Adv. Letter Header CZZ" begin if "No." <> xRec."No." then begin GetSetup(); - NoSeriesManagement.TestManual(AdvanceLetterTemplateCZZ."Advance Letter Document Nos."); + NoSeries.TestManual(AdvanceLetterTemplateCZZ."Advance Letter Document Nos."); "No. Series" := ''; end; end; @@ -868,6 +868,7 @@ table 31004 "Sales Adv. Letter Header CZZ" SalespersonPurchaser: Record "Salesperson/Purchaser"; ResponsibilityCenter: Record "Responsibility Center"; NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; DimensionManagement: Codeunit DimensionManagement; UserSetupManagement: Codeunit "User Setup Management"; #if not CLEAN22 @@ -903,7 +904,19 @@ table 31004 "Sales Adv. Letter Header CZZ" if "No." = '' then begin GetSetup(); AdvanceLetterTemplateCZZ.TestField("Advance Letter Document Nos."); - NoSeriesManagement.InitSeries(AdvanceLetterTemplateCZZ."Advance Letter Document Nos.", xRec."No. Series", "Posting Date", "No.", "No. Series") +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(AdvanceLetterTemplateCZZ."Advance Letter Document Nos.", xRec."No. Series", "Posting Date", "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := AdvanceLetterTemplateCZZ."Advance Letter Document Nos."; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series", "Posting Date"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", AdvanceLetterTemplateCZZ."Advance Letter Document Nos.", "Posting Date", "No."); + end; +#endif end; OnInitInsertOnBeforeInitRecord(Rec, xRec); diff --git a/Apps/CZ/AdvancePaymentsLocalization/test/Src/PurchaseAdvancePaymentsCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/test/Src/PurchaseAdvancePaymentsCZZ.Codeunit.al index 8389c02b81..4c41130e98 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/test/Src/PurchaseAdvancePaymentsCZZ.Codeunit.al +++ b/Apps/CZ/AdvancePaymentsLocalization/test/Src/PurchaseAdvancePaymentsCZZ.Codeunit.al @@ -675,9 +675,6 @@ codeunit 148108 "Purchase Advance Payments CZZ" // [SCENARIO] Link purchase advance letter with reverse charge to invoice Initialize(); - // [GIVEN] Posting of VAT documents for reverse charge has been enabled - SetPostVATDocForReverseCharge(true); - // [GIVEN] Purchase advance letter has been created // [GIVEN] Purchase advance letter line with reverse charge has been created CreatePurchAdvLetterWithReverseCharge(PurchAdvLetterHeaderCZZ, PurchAdvLetterLineCZZ); @@ -727,8 +724,6 @@ codeunit 148108 "Purchase Advance Payments CZZ" // [THEN] Purchase advance letter will be closed PurchAdvLetterHeaderCZZ.Get(PurchAdvLetterHeaderCZZ."No."); PurchAdvLetterHeaderCZZ.TestField(Status, PurchAdvLetterHeaderCZZ.Status::Closed); - - SetPostVATDocForReverseCharge(false); end; [Test] @@ -2325,9 +2320,6 @@ codeunit 148108 "Purchase Advance Payments CZZ" // [SCENARIO] Create purchase advance letter with two lines with different VAT rates and link to invoice with line which is the same as second line in advance letter and one VAT rate Initialize(); - // [GIVEN] Posting of VAT documents for reverse charge has been enabled - SetPostVATDocForReverseCharge(true); - // [GIVEN] Purchase advance letter has been created // [GIVEN] Purchase advance letter line with normal VAT has been created CreatePurchAdvLetter(PurchAdvLetterHeaderCZZ, PurchAdvLetterLineCZZ1); @@ -2387,8 +2379,6 @@ codeunit 148108 "Purchase Advance Payments CZZ" VATEntry.SetRange("VAT Bus. Posting Group", VATEntry."VAT Bus. Posting Group"); VATEntry.SetRange("VAT Prod. Posting Group", VATEntry."VAT Prod. Posting Group"); Assert.RecordCount(VATEntry, VATEntryCount); - - SetPostVATDocForReverseCharge(false); end; [Test] @@ -2407,9 +2397,6 @@ codeunit 148108 "Purchase Advance Payments CZZ" // [SCENARIO] Create purchase advance letter with two lines with different VAT rates and link to invoice with line which has the higher amount as first line in advance letter and one VAT rate Initialize(); - // [GIVEN] Posting of VAT documents for reverse charge has been enabled - SetPostVATDocForReverseCharge(true); - // [GIVEN] Purchase advance letter has been created // [GIVEN] Purchase advance letter line with normal VAT has been created CreatePurchAdvLetter(PurchAdvLetterHeaderCZZ, PurchAdvLetterLineCZZ1); @@ -2464,8 +2451,6 @@ codeunit 148108 "Purchase Advance Payments CZZ" purchAdvLetterEntryCZZ2.SetRange("VAT Prod. Posting Group", PurchAdvLetterLineCZZ2."VAT Prod. Posting Group"); purchAdvLetterEntryCZZ2.SetRange("Entry Type", purchAdvLetterEntryCZZ2."Entry Type"::"VAT Usage"); Assert.RecordIsNotEmpty(PurchAdvLetterEntryCZZ2); - - SetPostVATDocForReverseCharge(false); end; [Test] @@ -2484,9 +2469,6 @@ codeunit 148108 "Purchase Advance Payments CZZ" // [SCENARIO] Create purchase advance letter with two lines with different VAT rates and link to invoice with line which has the higher amount as second line in advance letter and one VAT rate Initialize(); - // [GIVEN] Posting of VAT documents for reverse charge has been enabled - SetPostVATDocForReverseCharge(true); - // [GIVEN] Purchase advance letter has been created // [GIVEN] Purchase advance letter line with normal VAT has been created CreatePurchAdvLetter(PurchAdvLetterHeaderCZZ, PurchAdvLetterLineCZZ1); @@ -2541,8 +2523,6 @@ codeunit 148108 "Purchase Advance Payments CZZ" purchAdvLetterEntryCZZ2.SetRange("VAT Prod. Posting Group", PurchAdvLetterLineCZZ1."VAT Prod. Posting Group"); purchAdvLetterEntryCZZ2.SetRange("Entry Type", purchAdvLetterEntryCZZ2."Entry Type"::"VAT Usage"); Assert.RecordIsNotEmpty(PurchAdvLetterEntryCZZ2); - - SetPostVATDocForReverseCharge(false); end; [Test] @@ -2563,9 +2543,6 @@ codeunit 148108 "Purchase Advance Payments CZZ" // [SCENARIO] Create purchase advance letter with two lines with different VAT rates and link to invoice with two lines which have the lower amounts as lines in advance letter Initialize(); - // [GIVEN] Posting of VAT documents for reverse charge has been enabled - SetPostVATDocForReverseCharge(true); - // [GIVEN] Purchase advance letter has been created // [GIVEN] Purchase advance letter line with normal VAT has been created CreatePurchAdvLetter(PurchAdvLetterHeaderCZZ, PurchAdvLetterLineCZZ1); @@ -2639,8 +2616,6 @@ codeunit 148108 "Purchase Advance Payments CZZ" VATEntry.CalcSums(Base, Amount); Assert.AreEqual(0, VATEntry.Base, 'The sum of base amount in VAT Entries must be zero.'); Assert.AreEqual(0, VATEntry.Amount, 'The sum of VAT amount in VAT Entries must be zero.'); - - SetPostVATDocForReverseCharge(false); end; local procedure CreatePurchAdvLetterBase(var PurchAdvLetterHeaderCZZ: Record "Purch. Adv. Letter Header CZZ"; var PurchAdvLetterLineCZZ: Record "Purch. Adv. Letter Line CZZ"; VendorNo: Code[20]; CurrencyCode: Code[10]; VATPostingSetup: Record "VAT Posting Setup") @@ -2869,12 +2844,6 @@ codeunit 148108 "Purchase Advance Payments CZZ" LibraryCashDocumentCZP.PostCashDocumentCZP(CashDocumentHeaderCZP); end; - local procedure SetPostVATDocForReverseCharge(Value: Boolean) - begin - AdvanceLetterTemplateCZZ."Post VAT Doc. for Rev. Charge" := Value; - AdvanceLetterTemplateCZZ.Modify(); - end; - local procedure FindNextVATPostingSetup(var VATPostingSetup: Record "VAT Posting Setup") begin LibraryERM.FindVATPostingSetup(VATPostingSetup, VATPostingSetup."VAT Calculation Type"::"Normal VAT"); diff --git a/Apps/CZ/AdvancePaymentsLocalization/test/Src/SalesAdvancePaymentsCZZ.Codeunit.al b/Apps/CZ/AdvancePaymentsLocalization/test/Src/SalesAdvancePaymentsCZZ.Codeunit.al index 31661dd798..3b77a3e512 100644 --- a/Apps/CZ/AdvancePaymentsLocalization/test/Src/SalesAdvancePaymentsCZZ.Codeunit.al +++ b/Apps/CZ/AdvancePaymentsLocalization/test/Src/SalesAdvancePaymentsCZZ.Codeunit.al @@ -688,9 +688,6 @@ codeunit 148109 "Sales Advance Payments CZZ" // [SCENARIO] Link sales advance letter with reverse charge to invoice Initialize(); - // [GIVEN] Posting of VAT documents for reverse charge has been enabled - SetPostVATDocForReverseCharge(true); - // [GIVEN] Sales advance letter has been created // [GIVEN] Sales advance letter line with reverse charge has been created CreateSalesAdvLetterWithReverseCharge(SalesAdvLetterHeaderCZZ, SalesAdvLetterLineCZZ); @@ -737,8 +734,6 @@ codeunit 148109 "Sales Advance Payments CZZ" // [THEN] Sales advance letter will be closed SalesAdvLetterHeaderCZZ.Get(SalesAdvLetterHeaderCZZ."No."); SalesAdvLetterHeaderCZZ.TestField(Status, SalesAdvLetterHeaderCZZ.Status::Closed); - - SetPostVATDocForReverseCharge(false); end; [Test] @@ -2220,9 +2215,6 @@ codeunit 148109 "Sales Advance Payments CZZ" // with line which is the same as first line in advance letter and one VAT rate Initialize(); - // [GIVEN] Posting of VAT documents for reverse charge has been enabled - SetPostVATDocForReverseCharge(true); - // [GIVEN] Sales advance letter has been created // [GIVEN] Sales advance letter line with normal VAT has been created CreateSalesAdvLetter(SalesAdvLetterHeaderCZZ, SalesAdvLetterLineCZZ1); @@ -2279,8 +2271,6 @@ codeunit 148109 "Sales Advance Payments CZZ" VATEntry.SetRange("VAT Bus. Posting Group", VATEntry."VAT Bus. Posting Group"); VATEntry.SetRange("VAT Prod. Posting Group", VATEntry."VAT Prod. Posting Group"); Assert.RecordCount(VATEntry, VATEntryCount); - - SetPostVATDocForReverseCharge(false); end; [Test] @@ -2299,9 +2289,6 @@ codeunit 148109 "Sales Advance Payments CZZ" // [SCENARIO] Create Sales advance letter with two lines with different VAT rates and link to invoice with line which is the same as second line in advance letter and one VAT rate Initialize(); - // [GIVEN] Posting of VAT documents for reverse charge has been enabled - SetPostVATDocForReverseCharge(true); - // [GIVEN] Sales advance letter has been created // [GIVEN] Sales advance letter line with normal VAT has been created CreateSalesAdvLetter(SalesAdvLetterHeaderCZZ, SalesAdvLetterLineCZZ1); @@ -2358,8 +2345,6 @@ codeunit 148109 "Sales Advance Payments CZZ" VATEntry.SetRange("VAT Bus. Posting Group", VATEntry."VAT Bus. Posting Group"); VATEntry.SetRange("VAT Prod. Posting Group", VATEntry."VAT Prod. Posting Group"); Assert.RecordCount(VATEntry, VATEntryCount); - - SetPostVATDocForReverseCharge(false); end; [Test] @@ -2377,9 +2362,6 @@ codeunit 148109 "Sales Advance Payments CZZ" // [SCENARIO] Create Sales advance letter with two lines with different VAT rates and link to invoice with line which has the higher amount as first line in advance letter and one VAT rate Initialize(); - // [GIVEN] Posting of VAT documents for reverse charge has been enabled - SetPostVATDocForReverseCharge(true); - // [GIVEN] Sales advance letter has been created // [GIVEN] Sales advance letter line with normal VAT has been created CreateSalesAdvLetter(SalesAdvLetterHeaderCZZ, SalesAdvLetterLineCZZ1); @@ -2431,8 +2413,6 @@ codeunit 148109 "Sales Advance Payments CZZ" SalesAdvLetterEntryCZZ2.SetRange("VAT Prod. Posting Group", SalesAdvLetterLineCZZ2."VAT Prod. Posting Group"); SalesAdvLetterEntryCZZ2.SetRange("Entry Type", SalesAdvLetterEntryCZZ2."Entry Type"::"VAT Usage"); Assert.RecordIsNotEmpty(SalesAdvLetterEntryCZZ2); - - SetPostVATDocForReverseCharge(false); end; [Test] @@ -2450,9 +2430,6 @@ codeunit 148109 "Sales Advance Payments CZZ" // [SCENARIO] Create Sales advance letter with two lines with different VAT rates and link to invoice with line which has the higher amount as second line in advance letter and one VAT rate Initialize(); - // [GIVEN] Posting of VAT documents for reverse charge has been enabled - SetPostVATDocForReverseCharge(true); - // [GIVEN] Sales advance letter has been created // [GIVEN] Sales advance letter line with normal VAT has been created CreateSalesAdvLetter(SalesAdvLetterHeaderCZZ, SalesAdvLetterLineCZZ1); @@ -2504,8 +2481,6 @@ codeunit 148109 "Sales Advance Payments CZZ" SalesAdvLetterEntryCZZ2.SetRange("VAT Prod. Posting Group", SalesAdvLetterLineCZZ1."VAT Prod. Posting Group"); SalesAdvLetterEntryCZZ2.SetRange("Entry Type", SalesAdvLetterEntryCZZ2."Entry Type"::"VAT Usage"); Assert.RecordIsNotEmpty(SalesAdvLetterEntryCZZ2); - - SetPostVATDocForReverseCharge(false); end; [Test] @@ -2525,9 +2500,6 @@ codeunit 148109 "Sales Advance Payments CZZ" // [SCENARIO] Create Sales advance letter with two lines with different VAT rates and link to invoice with two lines which have the lower amounts as lines in advance letter Initialize(); - // [GIVEN] Posting of VAT documents for reverse charge has been enabled - SetPostVATDocForReverseCharge(true); - // [GIVEN] Sales advance letter has been created // [GIVEN] Sales advance letter line with normal VAT has been created CreateSalesAdvLetter(SalesAdvLetterHeaderCZZ, SalesAdvLetterLineCZZ1); @@ -2598,8 +2570,6 @@ codeunit 148109 "Sales Advance Payments CZZ" VATEntry.CalcSums(Base, Amount); Assert.AreEqual(0, VATEntry.Base, 'The sum of base amount in VAT Entries must be zero.'); Assert.AreEqual(0, VATEntry.Amount, 'The sum of VAT amount in VAT Entries must be zero.'); - - SetPostVATDocForReverseCharge(false); end; local procedure CreateSalesAdvLetterBase(var SalesAdvLetterHeaderCZZ: Record "Sales Adv. Letter Header CZZ"; var SalesAdvLetterLineCZZ: Record "Sales Adv. Letter Line CZZ"; CustomerNo: Code[20]; CurrencyCode: Code[10]; VATPostingSetup: Record "VAT Posting Setup") @@ -2723,12 +2693,6 @@ codeunit 148109 "Sales Advance Payments CZZ" exit(LibrarySales.PostSalesDocument(SalesHeader, true, true)); end; - local procedure SetPostVATDocForReverseCharge(Value: Boolean) - begin - AdvanceLetterTemplateCZZ."Post VAT Doc. for Rev. Charge" := Value; - AdvanceLetterTemplateCZZ.Modify(); - end; - local procedure FindLastPaymentAdvanceLetterEntry(AdvanceLetterNo: Code[20]; var SalesAdvLetterEntryCZZ: Record "Sales Adv. Letter Entry CZZ") begin SalesAdvLetterEntryCZZ.SetRange("Sales Adv. Letter No.", AdvanceLetterNo); diff --git a/Apps/CZ/AdvancedLocalizationPack/app/Src/Codeunits/GLEntryPostApplicationCZA.Codeunit.al b/Apps/CZ/AdvancedLocalizationPack/app/Src/Codeunits/GLEntryPostApplicationCZA.Codeunit.al index 3bb40d6a39..48b6d12267 100644 --- a/Apps/CZ/AdvancedLocalizationPack/app/Src/Codeunits/GLEntryPostApplicationCZA.Codeunit.al +++ b/Apps/CZ/AdvancedLocalizationPack/app/Src/Codeunits/GLEntryPostApplicationCZA.Codeunit.al @@ -48,16 +48,22 @@ codeunit 31370 "G/L Entry Post Application CZA" GLEntry.SetLoadFields("Entry No.", "Applies-to ID CZA", "Amount to Apply CZA", Amount, "Posting Date"); GLEntry.SetRange("Applies-to ID CZA", ApplyingGLEntry."Applies-to ID CZA"); GLEntry.SetRange("G/L Account No.", ApplyingGLEntry."G/L Account No."); + if ApplyingGLEntry.Amount > 0 then + GLEntry.SetFilter(Amount, '<0') + else + GLEntry.SetFilter(Amount, '>0'); if GLEntry.FindSet(false) then repeat - if ApplyingGLEntry."Entry No." <> GLEntry."Entry No." then - if GLEntry."Amount to Apply CZA" <> 0 then - if (GLEntry.Amount * ApplyingGLEntry.Amount) > 0 then - Error(SignAmtMustBediffErr); + if GLEntry."Amount to Apply CZA" <> 0 then + if (GLEntry.Amount * ApplyingGLEntry.Amount) > 0 then + Error(SignAmtMustBediffErr); if GLEntry."Posting Date" > PostingDate then PostingDate := GLEntry."Posting Date" until GLEntry.Next() = 0; + if ApplyingGLEntry."Posting Date" > PostingDate then + PostingDate := ApplyingGLEntry."Posting Date"; + DocumentNo := ApplyingGLEntry."Document No."; if not NotUseDialog then begin ApplyUnapplyParameters."Document No." := DocumentNo; @@ -92,6 +98,7 @@ codeunit 31370 "G/L Entry Post Application CZA" GLEntry.Modify(); end; until GLEntry.Next() = 0; + ApplyingAmount := ApplyingAmount + ApplyingGLEntry."Amount to Apply CZA"; if ApplyingAmount <> 0 then begin if ApplyingAmount > 0 then @@ -102,12 +109,16 @@ codeunit 31370 "G/L Entry Post Application CZA" GLEntry.Ascending(false); if GLEntry.FindSet(true) then repeat - GLEntry.CalcFields("Applied Amount CZA"); - if (ApplyingAmount <> 0) and - (GLEntry.Amount = GLEntry."Amount to Apply CZA" + GLEntry."Applied Amount CZA") + if (ApplyingGLEntry.Amount > 0) and (GLEntry.Amount < 0) or + (ApplyingGLEntry.Amount < 0) and (GLEntry.Amount > 0) then begin - SetAmountToApply(); - GLEntry.Modify(); + GLEntry.CalcFields("Applied Amount CZA"); + if (ApplyingAmount <> 0) and + (GLEntry.Amount = GLEntry."Amount to Apply CZA" + GLEntry."Applied Amount CZA") + then begin + SetAmountToApply(); + GLEntry.Modify(); + end; end; until GLEntry.Next() = 0; @@ -115,8 +126,12 @@ codeunit 31370 "G/L Entry Post Application CZA" GLEntry.SetFilter("Amount to Apply CZA", '<>0'); if GLEntry.FindSet(true) then repeat - SetAmountToApply(); - GLEntry.Modify(); + if (ApplyingGLEntry.Amount > 0) and (GLEntry.Amount < 0) or + (ApplyingGLEntry.Amount < 0) and (GLEntry.Amount > 0) + then begin + SetAmountToApply(); + GLEntry.Modify(); + end; until GLEntry.Next() = 0; end; GLEntry.Ascending(true); diff --git a/Apps/CZ/AdvancedLocalizationPack/app/Src/Pages/ApplyGLEntriesCZA.Page.al b/Apps/CZ/AdvancedLocalizationPack/app/Src/Pages/ApplyGLEntriesCZA.Page.al index f911a3cd13..476c3abdf2 100644 --- a/Apps/CZ/AdvancedLocalizationPack/app/Src/Pages/ApplyGLEntriesCZA.Page.al +++ b/Apps/CZ/AdvancedLocalizationPack/app/Src/Pages/ApplyGLEntriesCZA.Page.al @@ -548,10 +548,8 @@ page 31284 "Apply G/L Entries CZA" GLEntry.Reset(); GLEntry.Copy(Rec); GLEntry.SetRange("Applies-to ID CZA", GLApplID); - if GLEntry.FindSet() then - repeat - ApplyingAmount := ApplyingAmount + GLEntry."Amount to Apply CZA"; - until GLEntry.Next() = 0; + GLEntry.CalcSums("Amount to Apply CZA"); + ApplyingAmount := GLEntry."Amount to Apply CZA"; end; procedure CheckAppliesToID(var GLEntry2: Record "G/L Entry") diff --git a/Apps/CZ/AdvancedLocalizationPack/app/Src/TableExtensions/GLEntryCZA.TableExt.al b/Apps/CZ/AdvancedLocalizationPack/app/Src/TableExtensions/GLEntryCZA.TableExt.al index 40e29d0a81..5567144f94 100644 --- a/Apps/CZ/AdvancedLocalizationPack/app/Src/TableExtensions/GLEntryCZA.TableExt.al +++ b/Apps/CZ/AdvancedLocalizationPack/app/Src/TableExtensions/GLEntryCZA.TableExt.al @@ -69,6 +69,7 @@ tableextension 31265 "G/L Entry CZA" extends "G/L Entry" { key(AppliestoIDKeyCZA; "Applies-to ID CZA", "Applying Entry CZA") { + SumIndexFields = "Amount to Apply CZA"; } } diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/GenJournalLineHandlerCZB.Codeunit.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/GenJournalLineHandlerCZB.Codeunit.al index 0df3241cea..f3f64ef448 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/GenJournalLineHandlerCZB.Codeunit.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/GenJournalLineHandlerCZB.Codeunit.al @@ -100,7 +100,9 @@ codeunit 31453 "Gen. Journal Line Handler CZB" if IssBankStatementHeader.Get(GenJnlLine."Bank Statement No. CZB") then IssBankStatementHeader.UpdatePaymentJournalStatus(Enum::"Journal Status CZB"::Posted); - GenJnlLine."Bank Statement No. CZB" := ''; - GenJnlLine.Modify(); + if GenJournalLine.Get(GenJnlLine."Journal Template Name", GenJnlLine."Journal Batch Name", GenJnlLine."Line No.") then begin + GenJournalLine."Bank Statement No. CZB" := ''; + GenJournalLine.Modify(); + end; end; } diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/IssueBankStatCreateJnlCZB.Codeunit.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/IssueBankStatCreateJnlCZB.Codeunit.al new file mode 100644 index 0000000000..1c0b6f14ec --- /dev/null +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/IssueBankStatCreateJnlCZB.Codeunit.al @@ -0,0 +1,41 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace Microsoft.Bank.Documents; + +codeunit 31230 "IssueBank.Stat.Create Jnl. CZB" +{ + TableNo = "Bank Statement Header CZB"; + + trigger OnRun() + begin + BankStatementHeaderCZB.Copy(Rec); + Code(); + Rec := BankStatementHeaderCZB; + end; + + var + BankStatementHeaderCZB: Record "Bank Statement Header CZB"; + + procedure Code() + var + IssBankStatementHeaderCZB: Record "Iss. Bank Statement Header CZB"; + SuppressCommit: Boolean; + begin + Codeunit.Run(Codeunit::"Issue Bank Statement CZB", BankStatementHeaderCZB); + OnCodeOnBeforeCommit(BankStatementHeaderCZB, SuppressCommit); + if not SuppressCommit then + Commit(); + + IssBankStatementHeaderCZB.Get(BankStatementHeaderCZB."Last Issuing No."); + IssBankStatementHeaderCZB.SetRecFilter(); + IssBankStatementHeaderCZB.CreateJournal(false); + end; + + [IntegrationEvent(false, false)] + local procedure OnCodeOnBeforeCommit(BankStatementHeaderCZB: Record "Bank Statement Header CZB"; var SuppressCommit: Boolean) + begin + end; +} diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/IssuePaymentOrderExportCZB.Codeunit.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/IssuePaymentOrderExportCZB.Codeunit.al new file mode 100644 index 0000000000..9899b52559 --- /dev/null +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Codeunits/IssuePaymentOrderExportCZB.Codeunit.al @@ -0,0 +1,41 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Bank.Documents; + +codeunit 31231 "Issue Payment Order Export CZB" +{ + TableNo = "Payment Order Header CZB"; + + trigger OnRun() + begin + PaymentOrderHeaderCZB.Copy(Rec); + Code(); + Rec := PaymentOrderHeaderCZB; + end; + + var + PaymentOrderHeaderCZB: Record "Payment Order Header CZB"; + + local procedure Code() + var + IssPaymentOrderHeaderCZB: Record "Iss. Payment Order Header CZB"; + SuppressCommit: Boolean; + begin + Codeunit.Run(Codeunit::"Issue Payment Order CZB", PaymentOrderHeaderCZB); + OnCodeOnBeforeCommit(PaymentOrderHeaderCZB, SuppressCommit); + if not SuppressCommit then + Commit(); + + IssPaymentOrderHeaderCZB.Get(PaymentOrderHeaderCZB."Last Issuing No."); + IssPaymentOrderHeaderCZB.SetRecFilter(); + IssPaymentOrderHeaderCZB.ExportPaymentOrder(); + end; + + [IntegrationEvent(false, false)] + local procedure OnCodeOnBeforeCommit(PaymentOrderHeaderCZB: Record "Payment Order Header CZB"; var SuppressCommit: Boolean) + begin + end; +} + diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementCZB.Page.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementCZB.Page.al index 87a83f2504..7c6f09b3e6 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementCZB.Page.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementCZB.Page.al @@ -277,6 +277,20 @@ page 31254 "Bank Statement CZB" IssueBankStatement(Codeunit::"Issue Bank Statement YesNo CZB"); end; } + action(IssueAndCreateJournal) + { + ApplicationArea = Basic, Suite; + Caption = 'Issue and Create Journal'; + Ellipsis = true; + Image = ReleaseDoc; + ShortCutKey = 'Ctrl+F9'; + ToolTip = 'Issue the bank statement and create a journal. The bank statement will be moved to issued bank statements.'; + + trigger OnAction() + begin + IssueBankStatement(Codeunit::"IssueBank.Stat.Create Jnl. CZB"); + end; + } action(IssueAndPrint) { ApplicationArea = Basic, Suite; @@ -325,6 +339,9 @@ page 31254 "Bank Statement CZB" actionref(Issue_Promoted; Issue) { } + actionref(IssueAndCreateJournal_Promoted; IssueAndCreateJournal) + { + } actionref(IssueAndPrint_Promoted; IssueAndPrint) { } @@ -393,7 +410,8 @@ page 31254 "Bank Statement CZB" Codeunit.Run(IssuingCodeunitId, Rec); CurrPage.Update(false); - if IssuingCodeunitId <> Codeunit::"Issue Bank Statement YesNo CZB" then + if (IssuingCodeunitId <> Codeunit::"Issue Bank Statement YesNo CZB") and + (IssuingCodeunitId <> Codeunit::"IssueBank.Stat.Create Jnl. CZB") then exit; if InstructionMgt.IsEnabled(InstructionMgtCZB.GetOpeningIssuedDocumentNotificationId()) then @@ -421,10 +439,8 @@ page 31254 "Bank Statement CZB" local procedure DetermineBankStatementCZBSeriesNo(): Code[20] var BankAccount: Record "Bank Account"; - BankStatementHeaderCZB: Record "Bank Statement Header CZB"; begin BankAccount.Get(Rec."Bank Account No."); - DocumentNoVisibility.CheckNumberSeries(BankStatementHeaderCZB, BankAccount."Bank Statement Nos. CZB", BankStatementHeaderCZB.FieldNo("No.")); exit(BankAccount."Bank Statement Nos. CZB"); end; diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementsCZB.Page.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementsCZB.Page.al index d7006a1e67..a56c302fe6 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementsCZB.Page.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/BankStatementsCZB.Page.al @@ -188,6 +188,20 @@ page 31253 "Bank Statements CZB" IssueBankStatement(Codeunit::"Issue Bank Statement YesNo CZB"); end; } + action(IssueAndCreateJournal) + { + ApplicationArea = Basic, Suite; + Caption = 'Issue and Create Journal'; + Ellipsis = true; + Image = ReleaseDoc; + ShortCutKey = 'Ctrl+F9'; + ToolTip = 'Issue the bank statement and create a journal. The bank statement will be moved to issued bank statements.'; + + trigger OnAction() + begin + IssueBankStatement(Codeunit::"IssueBank.Stat.Create Jnl. CZB"); + end; + } action(IssueAndPrint) { ApplicationArea = Basic, Suite; @@ -232,6 +246,9 @@ page 31253 "Bank Statements CZB" actionref(Issue_Promoted; Issue) { } + actionref(IssueAndCreateJournal_Promoted; IssueAndCreateJournal) + { + } actionref(IssueAndPrint_Promoted; IssueAndPrint) { } @@ -282,7 +299,8 @@ page 31253 "Bank Statements CZB" Codeunit.Run(IssuingCodeunitId, Rec); CurrPage.Update(false); - if IssuingCodeunitId <> Codeunit::"Issue Bank Statement YesNo CZB" then + if (IssuingCodeunitId <> Codeunit::"Issue Bank Statement YesNo CZB") and + (IssuingCodeunitId <> Codeunit::"IssueBank.Stat.Create Jnl. CZB") then exit; if InstructionMgt.IsEnabled(InstructionMgtCZB.GetOpeningIssuedDocumentNotificationId()) then diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrderCZB.Page.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrderCZB.Page.al index 6d85d3a1f3..e50dc53a7d 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrderCZB.Page.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrderCZB.Page.al @@ -336,6 +336,20 @@ page 31262 "Payment Order CZB" IssueDocument(Codeunit::"Issue Payment Order YesNo CZB"); end; } + action(IssueAndExport) + { + ApplicationArea = Basic, Suite; + Caption = 'Issue and Export'; + Ellipsis = true; + Image = ReleaseDoc; + ShortCutKey = 'Ctrl+F9'; + ToolTip = 'Issue the payment order and export a file. The payment order will be moved to issued payment orders.'; + + trigger OnAction() + begin + IssueDocument(Codeunit::"Issue Payment Order Export CZB"); + end; + } action(IssueAndPrint) { ApplicationArea = Basic, Suite; @@ -501,6 +515,9 @@ page 31262 "Payment Order CZB" actionref(Issue_Promoted; Issue) { } + actionref(IssueAndExport_Promoted; IssueAndExport) + { + } actionref(IssueAndPrint_Promoted; IssueAndPrint) { } @@ -610,7 +627,8 @@ page 31262 "Payment Order CZB" Rec.SendToIssuing(IssuingCodeunitID); CurrPage.Update(false); - if IssuingCodeunitID <> Codeunit::"Issue Payment Order YesNo CZB" then + if (IssuingCodeunitID <> Codeunit::"Issue Payment Order YesNo CZB") and + (IssuingCodeunitID <> Codeunit::"Issue Payment Order Export CZB") then exit; if InstructionMgt.IsEnabled(InstructionMgtCZB.GetOpeningIssuedDocumentNotificationId()) then @@ -638,10 +656,8 @@ page 31262 "Payment Order CZB" local procedure DeterminePaymentOrderCZBSeriesNo(): Code[20] var BankAccount: Record "Bank Account"; - PaymentOrderHeaderCZB: Record "Payment Order Header CZB"; begin BankAccount.Get(Rec."Bank Account No."); - DocumentNoVisibility.CheckNumberSeries(PaymentOrderHeaderCZB, BankAccount."Payment Order Nos. CZB", PaymentOrderHeaderCZB.FieldNo("No.")); exit(BankAccount."Payment Order Nos. CZB"); end; diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrdersCZB.Page.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrdersCZB.Page.al index b2d11b3671..c148521b31 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrdersCZB.Page.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Pages/PaymentOrdersCZB.Page.al @@ -243,6 +243,20 @@ page 31261 "Payment Orders CZB" IssueDocument(Codeunit::"Issue Payment Order YesNo CZB"); end; } + action(IssueAndExport) + { + ApplicationArea = Basic, Suite; + Caption = 'Issue and Export'; + Ellipsis = true; + Image = ReleaseDoc; + ShortCutKey = 'Ctrl+F9'; + ToolTip = 'Issue the payment order and export a file. The payment order will be moved to issued payment orders.'; + + trigger OnAction() + begin + IssueDocument(Codeunit::"Issue Payment Order Export CZB"); + end; + } action(IssueAndPrint) { ApplicationArea = Basic, Suite; @@ -390,6 +404,9 @@ page 31261 "Payment Orders CZB" actionref(Issue_Promoted; Issue) { } + actionref(IssueAndExport_Promoted; IssueAndExport) + { + } actionref(IssueAndPrint_Promoted; IssueAndPrint) { } @@ -475,7 +492,8 @@ page 31261 "Payment Orders CZB" Rec.SendToIssuing(IssuingCodeunitID); CurrPage.Update(false); - if IssuingCodeunitID <> Codeunit::"Issue Payment Order YesNo CZB" then + if (IssuingCodeunitID <> Codeunit::"Issue Payment Order YesNo CZB") and + (IssuingCodeunitID <> Codeunit::"Issue Payment Order Export CZB") then exit; if InstructionMgt.IsEnabled(InstructionMgtCZB.GetOpeningIssuedDocumentNotificationId()) then diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Permissions/CZBankDocumentsObjCZB.PermissionSet.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Permissions/CZBankDocumentsObjCZB.PermissionSet.al index aba4782a29..a5e8366194 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Permissions/CZBankDocumentsObjCZB.PermissionSet.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Permissions/CZBankDocumentsObjCZB.PermissionSet.al @@ -27,7 +27,9 @@ Codeunit "Issue Bank Statement CZB" = X, Codeunit "Issue Bank Statement Print CZB" = X, Codeunit "Issue Bank Statement YesNo CZB" = X, + Codeunit "IssueBank.Stat.Create Jnl. CZB" = X, Codeunit "Issue Payment Order CZB" = X, + Codeunit "Issue Payment Order Export CZB" = X, Codeunit "Issue Payment Order Print CZB" = X, Codeunit "Issue Payment Order YesNo CZB" = X, Codeunit "Match Bank Payment CZB" = X, diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Tables/BankStatementHeaderCZB.Table.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Tables/BankStatementHeaderCZB.Table.al index 6e364e03b6..bc8f26ff8d 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Tables/BankStatementHeaderCZB.Table.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Tables/BankStatementHeaderCZB.Table.al @@ -33,7 +33,7 @@ table 31252 "Bank Statement Header CZB" begin if ("No." <> xRec."No.") and ("Bank Account No." <> '') then begin BankAccount.Get("Bank Account No."); - NoSeriesManagement.TestManual(BankAccount."Bank Statement Nos. CZB"); + NoSeries.TestManual(BankAccount."Bank Statement Nos. CZB"); "No. Series" := ''; end; end; @@ -384,11 +384,31 @@ table 31252 "Bank Statement Header CZB" end; trigger OnInsert() + var + BankStatementHeader: Record "Bank Statement Header CZB"; +#if not CLEAN24 + IsHandled: Boolean; +#endif begin if "No." = '' then begin BankAccount.Get("Bank Account No."); BankAccount.Testfield("Bank Statement Nos. CZB"); - NoSeriesManagement.InitSeries(BankAccount."Bank Statement Nos. CZB", xRec."No. Series", 0D, "No.", "No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(BankAccount."Bank Statement Nos. CZB", xRec."No. Series", 0D, "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := BankAccount."Bank Statement Nos. CZB"; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); + BankStatementHeader.ReadIsolation(ReadIsolation::ReadUncommitted); + BankStatementHeader.SetLoadFields("No."); + while BankStatementHeader.Get("No.") do + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", BankAccount."Bank Statement Nos. CZB", 0D, "No."); + end; +#endif end; end; @@ -403,6 +423,7 @@ table 31252 "Bank Statement Header CZB" BankAccount: Record "Bank Account"; CurrencyExchangeRate: Record "Currency Exchange Rate"; NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; ConfirmManagement: Codeunit "Confirm Management"; HideValidationDialog: Boolean; Confirmed: Boolean; diff --git a/Apps/CZ/BankingDocumentsLocalization/app/Src/Tables/PaymentOrderHeaderCZB.Table.al b/Apps/CZ/BankingDocumentsLocalization/app/Src/Tables/PaymentOrderHeaderCZB.Table.al index aadfdfd557..89f7954047 100644 --- a/Apps/CZ/BankingDocumentsLocalization/app/Src/Tables/PaymentOrderHeaderCZB.Table.al +++ b/Apps/CZ/BankingDocumentsLocalization/app/Src/Tables/PaymentOrderHeaderCZB.Table.al @@ -30,7 +30,7 @@ table 31256 "Payment Order Header CZB" begin if ("No." <> xRec."No.") and ("Bank Account No." <> '') then begin BankAccount.Get("Bank Account No."); - NoSeriesManagement.TestManual(BankAccount."Payment Order Nos. CZB"); + NoSeries.TestManual(BankAccount."Payment Order Nos. CZB"); "No. Series" := ''; end; end; @@ -321,11 +321,31 @@ table 31256 "Payment Order Header CZB" end; trigger OnInsert() + var + PaymentOrderHeader: Record "Payment Order Header CZB"; +#if not CLEAN24 + IsHandled: Boolean; +#endif begin if "No." = '' then begin BankAccount.Get("Bank Account No."); BankAccount.Testfield("Payment Order Nos. CZB"); - NoSeriesManagement.InitSeries(BankAccount."Payment Order Nos. CZB", xRec."No. Series", 0D, "No.", "No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(BankAccount."Payment Order Nos. CZB", xRec."No. Series", 0D, "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := BankAccount."Payment Order Nos. CZB"; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); + PaymentOrderHeader.ReadIsolation(ReadIsolation::ReadUncommitted); + PaymentOrderHeader.SetLoadFields("No."); + while PaymentOrderHeader.Get("No.") do + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", BankAccount."Payment Order Nos. CZB", 0D, "No."); + end; +#endif end; end; @@ -340,6 +360,7 @@ table 31256 "Payment Order Header CZB" BankAccount: Record "Bank Account"; CurrencyExchangeRate: Record "Currency Exchange Rate"; NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; BankingApprovalsMgtCZB: Codeunit "Banking Approvals Mgt. CZB"; ConfirmManagement: Codeunit "Confirm Management"; UpdateCurrFactorQst: Label 'Do you want to update the exchange rate?'; diff --git a/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/InstallApplicationCZP.Codeunit.al b/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/InstallApplicationCZP.Codeunit.al index 44a5fa2924..8fa225fcae 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/InstallApplicationCZP.Codeunit.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/Codeunits/InstallApplicationCZP.Codeunit.al @@ -257,7 +257,7 @@ codeunit 31054 "Install Application CZP" CashDeskEventCZP.Description := CashDeskEvent.Description; CashDeskEventCZP."Account Type" := CashDeskEvent."Account Type"; CashDeskEventCZP."Account No." := CashDeskEvent."Account No."; - CashDeskEventCZP."Gen. Document Type" := CashDeskEvent."Document Type"; + CashDeskEventCZP."Gen. Document Type" := "Cash Document Gen.Doc.Type CZP".FromInteger(CashDeskEvent."Document Type"); CashDeskEventCZP."Global Dimension 1 Code" := CashDeskEvent."Global Dimension 1 Code"; CashDeskEventCZP."Global Dimension 2 Code" := CashDeskEvent."Global Dimension 2 Code"; CashDeskEventCZP."Gen. Posting Type" := CashDeskEvent."Gen. Posting Type"; diff --git a/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDeskCardCZP.Page.al b/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDeskCardCZP.Page.al index 3c86e10b53..167058900a 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDeskCardCZP.Page.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/Pages/CashDeskCardCZP.Page.al @@ -595,10 +595,8 @@ page 31151 "Cash Desk Card CZP" local procedure DetermineCashDeskCZPSeriesNo(): Code[20] var GeneralLedgerSetup: Record "General Ledger Setup"; - CashDeskCZP: Record "Cash Desk CZP"; begin GeneralLedgerSetup.Get(); - DocumentNoVisibility.CheckNumberSeries(CashDeskCZP, GeneralLedgerSetup."Cash Desk Nos. CZP", CashDeskCZP.FieldNo("No.")); exit(GeneralLedgerSetup."Cash Desk Nos. CZP"); end; } diff --git a/Apps/CZ/CashDeskLocalization/app/Src/Tables/CashDeskCZP.Table.al b/Apps/CZ/CashDeskLocalization/app/Src/Tables/CashDeskCZP.Table.al index 90452b9331..265bb7636e 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/Tables/CashDeskCZP.Table.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/Tables/CashDeskCZP.Table.al @@ -45,7 +45,7 @@ table 11744 "Cash Desk CZP" begin if "No." <> xRec."No." then begin GeneralLedgerSetup.Get(); - NoSeriesManagement.TestManual(GeneralLedgerSetup."Cash Desk Nos. CZP"); + NoSeries.TestManual(GeneralLedgerSetup."Cash Desk Nos. CZP"); "No. Series" := ''; end; end; @@ -620,11 +620,31 @@ table 11744 "Cash Desk CZP" end; trigger OnInsert() + var + CashDesk: Record "Cash Desk CZP"; +#if not CLEAN24 + IsHandled: Boolean; +#endif begin if "No." = '' then begin GeneralLedgerSetup.Get(); GeneralLedgerSetup.TestField("Cash Desk Nos. CZP"); - NoSeriesManagement.InitSeries(GeneralLedgerSetup."Cash Desk Nos. CZP", xRec."No. Series", 0D, "No.", "No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(GeneralLedgerSetup."Cash Desk Nos. CZP", xRec."No. Series", 0D, "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := GeneralLedgerSetup."Cash Desk Nos. CZP"; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); + CashDesk.ReadIsolation(ReadIsolation::ReadUncommitted); + CashDesk.SetLoadFields("No."); + while CashDesk.Get("No.") do + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", GeneralLedgerSetup."Cash Desk Nos. CZP", 0D, "No."); + end; +#endif end; DimensionManagement.UpdateDefaultDim(Database::"Cash Desk CZP", "No.", "Global Dimension 1 Code", "Global Dimension 2 Code"); @@ -682,6 +702,7 @@ table 11744 "Cash Desk CZP" CommentLine: Record "Comment Line"; PostCode: Record "Post Code"; NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; ConfirmManagement: Codeunit "Confirm Management"; MoveEntries: Codeunit MoveEntries; DimensionManagement: Codeunit DimensionManagement; diff --git a/Apps/CZ/CashDeskLocalization/app/Src/Tables/CashDocumentHeaderCZP.Table.al b/Apps/CZ/CashDeskLocalization/app/Src/Tables/CashDocumentHeaderCZP.Table.al index 21e66bc1f6..706927312d 100644 --- a/Apps/CZ/CashDeskLocalization/app/Src/Tables/CashDocumentHeaderCZP.Table.al +++ b/Apps/CZ/CashDeskLocalization/app/Src/Tables/CashDocumentHeaderCZP.Table.al @@ -65,7 +65,7 @@ table 11732 "Cash Document Header CZP" TestField("No.", "No."); if "No." <> xRec."No." then begin - NoSeriesManagement.TestManual(GetNoSeriesCode()); + NoSeries.TestManual(GetNoSeriesCode()); "No. Series" := ''; end; end; @@ -618,6 +618,9 @@ table 11732 "Cash Document Header CZP" trigger OnInsert() var CashDeskUserCZP: Record "Cash Desk User CZP"; +#if not CLEAN24 + IsHandled: Boolean; +#endif begin TestField("Cash Desk No."); TestField("Document Type"); @@ -639,12 +642,34 @@ table 11732 "Cash Document Header CZP" "Document Type"::Receipt: begin CashDeskCZP.TestField("Cash Document Receipt Nos."); - NoSeriesManagement.InitSeries(CashDeskCZP."Cash Document Receipt Nos.", xRec."No. Series", WorkDate(), "No.", "No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(CashDeskCZP."Cash Document Receipt Nos.", xRec."No. Series", WorkDate(), "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := CashDeskCZP."Cash Document Receipt Nos."; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", CashDeskCZP."Cash Document Receipt Nos.", WorkDate(), "No."); + end; +#endif end; "Document Type"::Withdrawal: begin CashDeskCZP.TestField("Cash Document Withdrawal Nos."); - NoSeriesManagement.InitSeries(CashDeskCZP."Cash Document Withdrawal Nos.", xRec."No. Series", WorkDate(), "No.", "No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(CashDeskCZP."Cash Document Withdrawal Nos.", xRec."No. Series", WorkDate(), "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := CashDeskCZP."Cash Document Withdrawal Nos."; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", CashDeskCZP."Cash Document Withdrawal Nos.", WorkDate(), "No."); + end; +#endif end; end; @@ -689,6 +714,7 @@ table 11732 "Cash Document Header CZP" SalespersonPurchaser: Record "Salesperson/Purchaser"; Employee: Record Employee; NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; DimensionManagement: Codeunit DimensionManagement; UserSetupManagement: Codeunit "User Setup Management"; ConfirmManagement: Codeunit "Confirm Management"; diff --git a/Apps/CZ/CompensationLocalization/app/Src/Pages/CompensationCardCZC.Page.al b/Apps/CZ/CompensationLocalization/app/Src/Pages/CompensationCardCZC.Page.al index 56138218a6..7788bc8eaa 100644 --- a/Apps/CZ/CompensationLocalization/app/Src/Pages/CompensationCardCZC.Page.al +++ b/Apps/CZ/CompensationLocalization/app/Src/Pages/CompensationCardCZC.Page.al @@ -682,10 +682,8 @@ page 31272 "Compensation Card CZC" local procedure DetermineCompensationCZCSeriesNo(): Code[20] var CompensationsSetupCZC: Record "Compensations Setup CZC"; - CompensationHeaderCZC: Record "Compensation Header CZC"; begin CompensationsSetupCZC.Get(); - DocumentNoVisibility.CheckNumberSeries(CompensationHeaderCZC, CompensationsSetupCZC."Compensation Nos.", CompensationHeaderCZC.FieldNo("No.")); exit(CompensationsSetupCZC."Compensation Nos."); end; diff --git a/Apps/CZ/CompensationLocalization/app/Src/Tables/CompensationHeaderCZC.Table.al b/Apps/CZ/CompensationLocalization/app/Src/Tables/CompensationHeaderCZC.Table.al index 36c5dbc4a7..f5f7052ef2 100644 --- a/Apps/CZ/CompensationLocalization/app/Src/Tables/CompensationHeaderCZC.Table.al +++ b/Apps/CZ/CompensationLocalization/app/Src/Tables/CompensationHeaderCZC.Table.al @@ -36,11 +36,11 @@ table 31272 "Compensation Header CZC" trigger OnValidate() var CompensationsSetupCZC: Record "Compensations Setup CZC"; - NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; begin if "No." <> xRec."No." then begin CompensationsSetupCZC.Get(); - NoSeriesMgt.TestManual(CompensationsSetupCZC."Compensation Nos."); + NoSeries.TestManual(CompensationsSetupCZC."Compensation Nos."); "No. Series" := ''; end; end; @@ -330,12 +330,32 @@ table 31272 "Compensation Header CZC" trigger OnInsert() var CompensationsSetupCZC: Record "Compensations Setup CZC"; + CompensationHeader: Record "Compensation Header CZC"; + NoSeries: Codeunit "No. Series"; +#if not CLEAN24 NoSeriesManagement: Codeunit NoSeriesManagement; + IsHandled: Boolean; +#endif begin CompensationsSetupCZC.Get(); if "No." = '' then begin CompensationsSetupCZC.TestField("Compensation Nos."); - NoSeriesManagement.InitSeries(CompensationsSetupCZC."Compensation Nos.", xRec."No. Series", 0D, "No.", "No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(CompensationsSetupCZC."Compensation Nos.", xRec."No. Series", 0D, "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := CompensationsSetupCZC."Compensation Nos."; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); + CompensationHeader.ReadIsolation(ReadIsolation::ReadUncommitted); + CompensationHeader.SetLoadFields("No."); + while CompensationHeader.Get("No.") do + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", CompensationsSetupCZC."Compensation Nos.", 0D, "No."); + end; +#endif end; "User ID" := CopyStr(UserId(), 1, MaxStrLen("User ID")); end; diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/Codeunits/RegistrationLogMgtCZL.Codeunit.al b/Apps/CZ/CoreLocalizationPack/app/Src/Codeunits/RegistrationLogMgtCZL.Codeunit.al index d0cd74b601..aef49cec45 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/Codeunits/RegistrationLogMgtCZL.Codeunit.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/Codeunits/RegistrationLogMgtCZL.Codeunit.al @@ -121,7 +121,7 @@ codeunit 11755 "Registration Log Mgt. CZL" // Name if GetValue(ResponseObject, NameKeyTok, Value) then NewRegistrationLogCZL."Verified Name" := - CopyStr(Value, 1, MaxStrLen(NewRegistrationLogCZL."Verified Name")); + CopyStr(Value, 1, MaxStrLen(NewRegistrationLogCZL."Verified Name")); // Address information if GetValue(ResponseObject, AddressKeyTok, AddressObject) then begin @@ -133,12 +133,12 @@ codeunit 11755 "Registration Log Mgt. CZL" // City if GetValue(AddressObject, CityKeyTok, Value) then NewRegistrationLogCZL."Verified City" := - CopyStr(Value, 1, MaxStrLen(NewRegistrationLogCZL."Verified City")); + CopyStr(Value, 1, MaxStrLen(NewRegistrationLogCZL."Verified City")); // Post Code if GetValue(AddressObject, PostCodeKeyTok, Value) then NewRegistrationLogCZL."Verified Post Code" := - FormatPostCode(CopyStr(Value, 1, MaxStrLen(NewRegistrationLogCZL."Verified Post Code"))); + FormatPostCode(CopyStr(Value, 1, MaxStrLen(NewRegistrationLogCZL."Verified Post Code"))); if GetValue(AddressObject, StreetKeyTok, Value) then Address[1] := Value; // Street @@ -229,11 +229,17 @@ codeunit 11755 "Registration Log Mgt. CZL" local procedure FormatPostCode(PostCode: Text): Code[20] var + RegNoServiceConfig: Record "Reg. No. Service Config CZL"; PostCodeTok: Label '%1 %2', Locked = true; begin - if StrLen(PostCode) <> 5 then + RegNoServiceConfig.Get(); + if ((StrLen(PostCode) <> 5) and not RegNoServiceConfig."Post Code without Space") or + ((StrLen(PostCode) = 5) and RegNoServiceConfig."Post Code without Space") + then exit(CopyStr(PostCode, 1, 20)); - exit(StrSubstNo(PostCodeTok, CopyStr(PostCode, 1, 3), CopyStr(PostCode, 4, 2))); + if not RegNoServiceConfig."Post Code without Space" then + exit(StrSubstNo(PostCodeTok, CopyStr(PostCode, 1, 3), CopyStr(PostCode, 4, 2))); + exit(CopyStr(DelChr(PostCode, '=', ' '), 1, 20)); end; local procedure FormatAddress(Address: array[10] of Text): Text diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/PageExtensions/PurchasesPayablesSetupCZL.PageExt.al b/Apps/CZ/CoreLocalizationPack/app/Src/PageExtensions/PurchasesPayablesSetupCZL.PageExt.al index bc1d89af20..9de329a184 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/PageExtensions/PurchasesPayablesSetupCZL.PageExt.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/PageExtensions/PurchasesPayablesSetupCZL.PageExt.al @@ -27,7 +27,9 @@ pageextension 11719 "Purchases & Payables Setup CZL" extends "Purchases & Payabl ObsoleteTag = '22.0'; ObsoleteReason = 'All fields from this group are obsolete.'; +#pragma warning disable AL0842 field("Default VAT Date CZL"; Rec."Default VAT Date CZL") +#pragma warning restore AL0842 { ApplicationArea = Basic, Suite; ToolTip = 'Specifies the default VAT date type for purchase document (posting date, document date, blank).'; diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/Pages/CompanyOfficialCardCZL.Page.al b/Apps/CZ/CoreLocalizationPack/app/Src/Pages/CompanyOfficialCardCZL.Page.al index 893c4589d3..4c13815948 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/Pages/CompanyOfficialCardCZL.Page.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/Pages/CompanyOfficialCardCZL.Page.al @@ -273,10 +273,8 @@ page 11766 "Company Official Card CZL" local procedure DetermineCompanyOfficialSeriesNo(): Code[20] var StatutoryReportingSetupCZL: Record "Statutory Reporting Setup CZL"; - CompanyOfficialCZL: Record "Company Official CZL"; begin StatutoryReportingSetupCZL.Get(); - DocumentNoVisibility.CheckNumberSeries(CompanyOfficialCZL, StatutoryReportingSetupCZL."Company Official Nos.", CompanyOfficialCZL.FieldNo("No.")); exit(StatutoryReportingSetupCZL."Company Official Nos."); end; diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/Pages/VATCtrlReportCardCZL.Page.al b/Apps/CZ/CoreLocalizationPack/app/Src/Pages/VATCtrlReportCardCZL.Page.al index 689ab36def..f3accaa789 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/Pages/VATCtrlReportCardCZL.Page.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/Pages/VATCtrlReportCardCZL.Page.al @@ -349,10 +349,8 @@ page 31110 "VAT Ctrl. Report Card CZL" local procedure DetermineVATCtrlReportCZLSeriesNo(): Code[20] var StatutoryReportingSetupCZL: Record "Statutory Reporting Setup CZL"; - VATCtrlReportHeaderCZL: Record "VAT Ctrl. Report Header CZL"; begin StatutoryReportingSetupCZL.Get(); - DocumentNoVisibility.CheckNumberSeries(VATCtrlReportHeaderCZL, StatutoryReportingSetupCZL."VAT Control Report Nos.", VATCtrlReportHeaderCZL.FieldNo("No.")); exit(StatutoryReportingSetupCZL."VAT Control Report Nos."); end; } diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/Pages/VIESDeclarationCZL.Page.al b/Apps/CZ/CoreLocalizationPack/app/Src/Pages/VIESDeclarationCZL.Page.al index eca37c32f0..f80018f174 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/Pages/VIESDeclarationCZL.Page.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/Pages/VIESDeclarationCZL.Page.al @@ -498,10 +498,8 @@ page 31138 "VIES Declaration CZL" local procedure DetermineVIESDeclarationCZLSeriesNo(): Code[20] var StatutoryReportingSetupCZL: Record "Statutory Reporting Setup CZL"; - VIESDeclarationHeaderCZL: Record "VIES Declaration Header CZL"; begin StatutoryReportingSetupCZL.Get(); - DocumentNoVisibility.CheckNumberSeries(VIESDeclarationHeaderCZL, StatutoryReportingSetupCZL."VIES Declaration Nos.", VIESDeclarationHeaderCZL.FieldNo("No.")); exit(StatutoryReportingSetupCZL."VIES Declaration Nos."); end; } diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/Reports/CloseBalanceSheetCZL.Report.al b/Apps/CZ/CoreLocalizationPack/app/Src/Reports/CloseBalanceSheetCZL.Report.al index ae051488da..7d5f432884 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/Reports/CloseBalanceSheetCZL.Report.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/Reports/CloseBalanceSheetCZL.Report.al @@ -459,7 +459,6 @@ report 11754 "Close Balance Sheet CZL" SelectedDimension: Record "Selected Dimension"; TempSelectedDimension: Record "Selected Dimension" temporary; TempEntryNoAmountBuffer: Record "Entry No. Amount Buffer" temporary; - NoSeriesManagement: Codeunit NoSeriesManagement; GenJnlPostLine: Codeunit "Gen. Jnl.-Post Line"; DimensionManagement: Codeunit DimensionManagement; DimensionBufferManagement: Codeunit "Dimension Buffer Management"; @@ -532,14 +531,18 @@ report 11754 "Close Balance Sheet CZL" end; local procedure ValidateJnl() + var + NoSeries: Codeunit "No. Series"; begin DocNo := ''; if GenJournalBatch.Get(GenJournalLine."Journal Template Name", GenJournalLine."Journal Batch Name") then if GenJournalBatch."No. Series" <> '' then - DocNo := NoSeriesManagement.TryGetNextNo(GenJournalBatch."No. Series", EndDateReq); + DocNo := NoSeries.PeekNextNo(GenJournalBatch."No. Series", EndDateReq); end; local procedure HandleGenJnlLine() + var + NoSeriesBatch: Codeunit "No. Series - Batch"; begin GenJournalLine."Additional-Currency Posting" := GenJournalLine."Additional-Currency Posting"::None; @@ -553,8 +556,8 @@ report 11754 "Close Balance Sheet CZL" end; if GenJournalLine.Amount <> 0 then begin GenJnlPostLine.Run(GenJournalLine); - if DocNo = NoSeriesManagement.GetNextNo(GenJournalBatch."No. Series", EndDateReq, false) then - NoSeriesManagement.SaveNoSeries(); + if DocNo = NoSeriesBatch.GetNextNo(GenJournalBatch."No. Series", EndDateReq) then + NoSeriesBatch.SaveState(); end; end else if not ZeroGenJnlAmount() then diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/IntrastatJnlBatchCZL.TableExt.al b/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/IntrastatJnlBatchCZL.TableExt.al index 0edde00a93..a31ec4fd92 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/IntrastatJnlBatchCZL.TableExt.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/IntrastatJnlBatchCZL.TableExt.al @@ -39,7 +39,9 @@ tableextension 31025 "Intrastat Jnl. Batch CZL" extends "Intrastat Jnl. Batch" end; #endif } +#pragma warning disable AL0842 field(31082; "Statement Type CZL"; Enum "Intrastat Statement Type CZL") +#pragma warning restore AL0842 { Caption = 'Statement Type'; #if not CLEAN22 diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/IntrastatJnlLineCZL.TableExt.al b/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/IntrastatJnlLineCZL.TableExt.al index a72536f9d0..b48f5408d3 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/IntrastatJnlLineCZL.TableExt.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/IntrastatJnlLineCZL.TableExt.al @@ -77,7 +77,9 @@ tableextension 31026 "Intrastat Jnl. Line CZL" extends "Intrastat Jnl. Line" #endif ObsoleteReason = 'Intrastat related functionalities are moved to Intrastat extensions.'; } +#pragma warning disable AL0842 field(31086; "Statement Type CZL"; Enum "Intrastat Statement Type CZL") +#pragma warning restore AL0842 { Caption = 'Statement Type'; Editable = false; diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/PurchasesPayablesSetupCZL.TableExt.al b/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/PurchasesPayablesSetupCZL.TableExt.al index 7616849093..2cb0ebf683 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/PurchasesPayablesSetupCZL.TableExt.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/PurchasesPayablesSetupCZL.TableExt.al @@ -13,7 +13,9 @@ tableextension 11715 "Purchases & Payables Setup CZL" extends "Purchases & Payab #if not CLEAN22 #pragma warning disable AL0432 #endif +#pragma warning disable AL0842 field(11780; "Default VAT Date CZL"; Enum "Default VAT Date CZL") +#pragma warning restore AL0842 #if not CLEAN22 #pragma warning restore AL0432 #endif diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/SalesReceivablesSetupCZL.TableExt.al b/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/SalesReceivablesSetupCZL.TableExt.al index 449c39f8a8..62e4f736d4 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/SalesReceivablesSetupCZL.TableExt.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/SalesReceivablesSetupCZL.TableExt.al @@ -10,6 +10,7 @@ tableextension 11714 "Sales & Receivables Setup CZL" extends "Sales & Receivable { fields { +#pragma warning disable AL0842 #if not CLEAN22 #pragma warning disable AL0432 #endif @@ -17,6 +18,7 @@ tableextension 11714 "Sales & Receivables Setup CZL" extends "Sales & Receivable #if not CLEAN22 #pragma warning restore AL0432 #endif +#pragma warning restore AL0842 { Caption = 'Default VAT Date'; DataClassification = CustomerContent; diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/ServiceMgtSetupCZL.TableExt.al b/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/ServiceMgtSetupCZL.TableExt.al index 250e408a0a..419ca3c71d 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/ServiceMgtSetupCZL.TableExt.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/TableExtensions/ServiceMgtSetupCZL.TableExt.al @@ -13,7 +13,9 @@ tableextension 11716 "Service Mgt. Setup CZL" extends "Service Mgt. Setup" #if not CLEAN22 #pragma warning disable AL0432 #endif +#pragma warning disable AL0842 field(11780; "Default VAT Date CZL"; Enum "Default VAT Date CZL") +#pragma warning restore AL0842 #if not CLEAN22 #pragma warning restore AL0432 #endif diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/Tables/CompanyOfficialCZL.Table.al b/Apps/CZ/CoreLocalizationPack/app/Src/Tables/CompanyOfficialCZL.Table.al index b1df7d7157..04d1e83d99 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/Tables/CompanyOfficialCZL.Table.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/Tables/CompanyOfficialCZL.Table.al @@ -28,7 +28,7 @@ table 11793 "Company Official CZL" begin if "No." <> xRec."No." then begin StatutoryReportingSetupCZL.Get(); - NoSeriesManagement.TestManual(StatutoryReportingSetupCZL."Company Official Nos."); + NoSeries.TestManual(StatutoryReportingSetupCZL."Company Official Nos."); "No. Series" := ''; end; end; @@ -228,11 +228,31 @@ table 11793 "Company Official CZL" } } trigger OnInsert() + var + CompanyOfficial: Record "Company Official CZL"; +#if not CLEAN24 + IsHandled: Boolean; +#endif begin if "No." = '' then begin StatutoryReportingSetupCZL.Get(); StatutoryReportingSetupCZL.TestField("Company Official Nos."); - NoSeriesManagement.InitSeries(StatutoryReportingSetupCZL."Company Official Nos.", xRec."No. Series", 0D, "No.", "No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(StatutoryReportingSetupCZL."Company Official Nos.", xRec."No. Series", 0D, "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := StatutoryReportingSetupCZL."Company Official Nos."; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); + CompanyOfficial.ReadIsolation(ReadIsolation::ReadUncommitted); + CompanyOfficial.SetLoadFields("No."); + while CompanyOfficial.Get("No.") do + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", StatutoryReportingSetupCZL."Company Official Nos.", 0D, "No."); + end; +#endif end; end; @@ -252,6 +272,7 @@ table 11793 "Company Official CZL" PostCode: Record "Post Code"; CompanyOfficialCZL: Record "Company Official CZL"; NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; procedure AssistEdit(OldCompanyOfficialCZL: Record "Company Official CZL"): Boolean begin diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/Tables/RegNoServiceConfigCZL.Table.al b/Apps/CZ/CoreLocalizationPack/app/Src/Tables/RegNoServiceConfigCZL.Table.al index 72e681c36f..2b0156e983 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/Tables/RegNoServiceConfigCZL.Table.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/Tables/RegNoServiceConfigCZL.Table.al @@ -30,6 +30,11 @@ table 11755 "Reg. No. Service Config CZL" Caption = 'Service Endpoint'; DataClassification = CustomerContent; } + field(5; "Post Code without Space"; Boolean) + { + Caption = 'Post Code without Space'; + DataClassification = CustomerContent; + } } keys { diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/Tables/StatutoryReportingSetupCZL.Table.al b/Apps/CZ/CoreLocalizationPack/app/Src/Tables/StatutoryReportingSetupCZL.Table.al index 5cf1aeb70a..ff320580b0 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/Tables/StatutoryReportingSetupCZL.Table.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/Tables/StatutoryReportingSetupCZL.Table.al @@ -444,7 +444,9 @@ table 31105 "Statutory Reporting Setup CZL" #if not CLEAN22 #pragma warning disable AL0432 #endif +#pragma warning disable AL0842 field(167; "Get Tariff No. From"; Enum "Intrastat Detail Source CZL") +#pragma warning restore AL0842 #if not CLEAN22 #pragma warning restore AL0432 #endif @@ -463,7 +465,9 @@ table 31105 "Statutory Reporting Setup CZL" #if not CLEAN22 #pragma warning disable AL0432 #endif +#pragma warning disable AL0842 field(168; "Get Net Weight From"; Enum "Intrastat Detail Source CZL") +#pragma warning restore AL0842 #if not CLEAN22 #pragma warning restore AL0432 #endif @@ -482,7 +486,9 @@ table 31105 "Statutory Reporting Setup CZL" #if not CLEAN22 #pragma warning disable AL0432 #endif +#pragma warning disable AL0842 field(169; "Get Country/Region of Origin"; Enum "Intrastat Detail Source CZL") +#pragma warning restore AL0842 #if not CLEAN22 #pragma warning restore AL0432 #endif diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/Tables/VATCtrlReportHeaderCZL.Table.al b/Apps/CZ/CoreLocalizationPack/app/Src/Tables/VATCtrlReportHeaderCZL.Table.al index 7eaf7be9b7..4567a5ef36 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/Tables/VATCtrlReportHeaderCZL.Table.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/Tables/VATCtrlReportHeaderCZL.Table.al @@ -26,7 +26,7 @@ table 31106 "VAT Ctrl. Report Header CZL" trigger OnValidate() begin if "No." <> xRec."No." then begin - NoSeriesManagement.TestManual(GetNoSeriesCode()); + NoSeries.TestManual(GetNoSeriesCode()); "No. Series" := ''; end; end; @@ -198,9 +198,32 @@ table 31106 "VAT Ctrl. Report Header CZL" end; trigger OnInsert() + var + VATCtrlReportHeader: Record "VAT Ctrl. Report Header CZL"; + NoSeriesCode: Code[20]; +#if not CLEAN24 + IsHandled: Boolean; +#endif begin - if "No." = '' then - NoSeriesManagement.InitSeries(GetNoSeriesCode(), xRec."No. Series", WorkDate(), "No.", "No. Series"); + if "No." = '' then begin + NoSeriesCode := GetNoSeriesCode(); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(NoSeriesCode, xRec."No. Series", WorkDate(), "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := NoSeriesCode; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); + VATCtrlReportHeader.ReadIsolation(ReadIsolation::ReadUncommitted); + VATCtrlReportHeader.SetLoadFields("No."); + while VATCtrlReportHeader.Get("No.") do + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", NoSeriesCode, WorkDate(), "No."); + end; +#endif + end; InitRecord(); end; @@ -212,6 +235,7 @@ table 31106 "VAT Ctrl. Report Header CZL" var VATCtrlReportLineCZL: Record "VAT Ctrl. Report Line CZL"; NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; VATCtrlReportMgtCZL: Codeunit "VAT Ctrl. Report Mgt. CZL"; VATCtrlRepExpRunnerCZL: Codeunit "VAT Ctrl. Rep. Exp. Runner CZL"; RecordRenameErr: Label 'You cannot rename a %1.', Comment = '%1 = Header No.'; diff --git a/Apps/CZ/CoreLocalizationPack/app/Src/Tables/VIESDeclarationHeaderCZL.Table.al b/Apps/CZ/CoreLocalizationPack/app/Src/Tables/VIESDeclarationHeaderCZL.Table.al index 8335f1c3e7..a0edabab60 100644 --- a/Apps/CZ/CoreLocalizationPack/app/Src/Tables/VIESDeclarationHeaderCZL.Table.al +++ b/Apps/CZ/CoreLocalizationPack/app/Src/Tables/VIESDeclarationHeaderCZL.Table.al @@ -29,10 +29,10 @@ table 31075 "VIES Declaration Header CZL" trigger OnValidate() var - NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; begin if "No." <> xRec."No." then begin - NoSeriesMgt.TestManual(GetNoSeriesCode()); + NoSeries.TestManual(GetNoSeriesCode()); "No. Series" := ''; end; end; @@ -537,11 +537,33 @@ table 31075 "VIES Declaration Header CZL" trigger OnInsert() var + VIESDeclarationHeader: Record "VIES Declaration Header CZL"; + NoSeries: Codeunit "No. Series"; +#if not CLEAN24 NoSeriesManagement: Codeunit NoSeriesManagement; + IsHandled: Boolean; +#endif + NoSeriesCode: Code[20]; begin - if "No." = '' then - NoSeriesManagement.InitSeries(GetNoSeriesCode(), xRec."No. Series", WorkDate(), "No.", "No. Series"); - + if "No." = '' then begin + NoSeriesCode := GetNoSeriesCode(); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(NoSeriesCode, xRec."No. Series", WorkDate(), "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := NoSeriesCode; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); + VIESDeclarationHeader.ReadIsolation(ReadIsolation::ReadUncommitted); + VIESDeclarationHeader.SetLoadFields("No."); + while VIESDeclarationHeader.Get("No.") do + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", NoSeriesCode, WorkDate(), "No."); + end; +#endif + end; InitRecord(); end; diff --git a/Apps/CZ/IntrastatCZ/app/src/Codeunits/IntrastatReportManagementCZ.Codeunit.al b/Apps/CZ/IntrastatCZ/app/src/Codeunits/IntrastatReportManagementCZ.Codeunit.al index d5c0fbe2e1..e451c33704 100644 --- a/Apps/CZ/IntrastatCZ/app/src/Codeunits/IntrastatReportManagementCZ.Codeunit.al +++ b/Apps/CZ/IntrastatCZ/app/src/Codeunits/IntrastatReportManagementCZ.Codeunit.al @@ -920,6 +920,51 @@ codeunit 31302 IntrastatReportManagementCZ then IntrastatReportLineType := Enum::"Intrastat Report Line Type"::Receipt; end; + + [EventSubscriber(ObjectType::Report, Report::"Intrastat Report Get Lines", 'OnBeforeFilterFALedgerEntry', '', false, false)] + local procedure FilterFALedgerEntry(IntrastatReportHeader: Record "Intrastat Report Header"; var FALedgerEntry: Record "FA Ledger Entry"; StartDate: Date; EndDate: Date; var IsHandled: Boolean) + begin + FALedgerEntry.SetRange("FA Posting Date", StartDate, EndDate); + FALedgerEntry.SetFilter("FA Posting Type", + '%1|%2|%3', + FALedgerEntry."FA Posting Type"::"Proceeds on Disposal", + FALedgerEntry."FA Posting Type"::"Acquisition Cost", + FALedgerEntry."FA Posting Type"::"Custom 2"); + FALedgerEntry.SetFilter("Document Type", '%1|%2', FALedgerEntry."Document Type"::Invoice, FALedgerEntry."Document Type"::"Credit Memo"); + FALedgerEntry.SetRange("FA Posting Category", FALedgerEntry."FA Posting Category"::" "); + IsHandled := true; + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::IntrastatReportManagement, 'OnAfterGetIntrastatBaseCountryCodeFromFAEntry', '', false, false)] + local procedure GetCountryForCustom2FAPostingType(var FALedgerEntry: Record "FA Ledger Entry"; var IntrastatReportSetup: Record "Intrastat Report Setup"; var CountryCode: Code[10]); + var + PurchInvHeader: Record "Purch. Inv. Header"; + PurchCrMemoHdr: Record "Purch. Cr. Memo Hdr."; + begin + if FALedgerEntry."FA Posting Type" = FALedgerEntry."FA Posting Type"::"Custom 2" then + case FALedgerEntry."Document Type" of + FALedgerEntry."Document Type"::Invoice: + if PurchInvHeader.Get(FALedgerEntry."Document No.") then + case IntrastatReportSetup."Shipments Based On" of + IntrastatReportSetup."Shipments Based On"::"Ship-to Country": + CountryCode := PurchInvHeader."Buy-from Country/Region Code"; + IntrastatReportSetup."Shipments Based On"::"Sell-to Country": + CountryCode := PurchInvHeader."Buy-from Country/Region Code"; + IntrastatReportSetup."Shipments Based On"::"Bill-to Country": + CountryCode := PurchInvHeader."Pay-to Country/Region Code"; + end; + FALedgerEntry."Document Type"::"Credit Memo": + if PurchCrMemoHdr.Get(FALedgerEntry."Document No.") then + case IntrastatReportSetup."Shipments Based On" of + IntrastatReportSetup."Shipments Based On"::"Ship-to Country": + CountryCode := PurchCrMemoHdr."Buy-from Country/Region Code"; + IntrastatReportSetup."Shipments Based On"::"Sell-to Country": + CountryCode := PurchCrMemoHdr."Buy-from Country/Region Code"; + IntrastatReportSetup."Shipments Based On"::"Bill-to Country": + CountryCode := PurchCrMemoHdr."Pay-to Country/Region Code"; + end; + end; + end; #endregion #region Export diff --git a/Apps/DE/Elster/app/src/Tables/SalesVATAdvanceNotif.Table.al b/Apps/DE/Elster/app/src/Tables/SalesVATAdvanceNotif.Table.al index 5be09b8b04..6f4d4bc4a2 100644 --- a/Apps/DE/Elster/app/src/Tables/SalesVATAdvanceNotif.Table.al +++ b/Apps/DE/Elster/app/src/Tables/SalesVATAdvanceNotif.Table.al @@ -15,10 +15,12 @@ table 11021 "Sales VAT Advance Notif." DataClassification = CustomerContent; trigger OnValidate() + var + NoSeries: Codeunit "No. Series"; begin if "No." <> xRec."No." then begin ElecVATDeclSetup.Get(); - NoSeriesMgt.TestManual(ElecVATDeclSetup."Sales VAT Adv. Notif. Nos."); + NoSeries.TestManual(ElecVATDeclSetup."Sales VAT Adv. Notif. Nos."); "No. Series" := ''; end; end; @@ -240,6 +242,11 @@ table 11021 "Sales VAT Advance Notif." trigger OnInsert() var CompanyInformation: Record "Company Information"; + NoSeries: Codeunit "No. Series"; +#if not CLEAN24 + NoSeriesManagement: Codeunit NoSeriesManagement; + IsHandled: Boolean; +#endif begin FeatureTelemetry.LogUptake('0001Q0G', ElecVATAdvanceNotTok, Enum::"Feature Uptake Status"::"Used"); if xRec.FindLast() then; @@ -253,7 +260,19 @@ table 11021 "Sales VAT Advance Notif." if "No." = '' then begin ElecVATDeclSetup.Get(); ElecVATDeclSetup.TestField("Sales VAT Adv. Notif. Nos."); - NoSeriesMgt.InitSeries(ElecVATDeclSetup."Sales VAT Adv. Notif. Nos.", xRec."No. Series", WorkDate(), "No.", "No. Series"); +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(ElecVATDeclSetup."Sales VAT Adv. Notif. Nos.", xRec."No. Series", WorkDate(), "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := ElecVATDeclSetup."Sales VAT Adv. Notif. Nos."; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", ElecVATDeclSetup."Sales VAT Adv. Notif. Nos.", WorkDate(), "No."); + end; +#endif end; FeatureTelemetry.LogUsage('0001Q0H', ElecVATAdvanceNotTok, 'Elec. VAT advance notif generated'); end; @@ -270,7 +289,6 @@ table 11021 "Sales VAT Advance Notif." var ElecVATDeclSetup: Record "Elec. VAT Decl. Setup"; - NoSeriesMgt: Codeunit NoSeriesManagement; FeatureTelemetry: Codeunit "Feature Telemetry"; ElecVATAdvanceNotTok: Label 'DE Elec. VAT Advance Notifications', Locked = true; WrongPlaceErr: Label 'Places of %1 in area %2 must be %3.', Comment = '%1 = Registration No. Field Caption; %2 = Tax Office Area; %3 = VAT No.'; @@ -297,13 +315,14 @@ table 11021 "Sales VAT Advance Notif." procedure AssistEdit(OldSalesVATAdvNotif: Record "Sales VAT Advance Notif."): Boolean var SalesVATAdvNotif: Record "Sales VAT Advance Notif."; + NoSeriesManagement: Codeunit NoSeriesManagement; begin with SalesVATAdvNotif do begin SalesVATAdvNotif := Rec; ElecVATDeclSetup.Get(); ElecVATDeclSetup.TestField("Sales VAT Adv. Notif. Nos."); - if NoSeriesMgt.SelectSeries(ElecVATDeclSetup."Sales VAT Adv. Notif. Nos.", OldSalesVATAdvNotif."No. Series", "No. Series") then begin - NoSeriesMgt.SetSeries("No."); + if NoSeriesManagement.SelectSeries(ElecVATDeclSetup."Sales VAT Adv. Notif. Nos.", OldSalesVATAdvNotif."No. Series", "No. Series") then begin + NoSeriesManagement.SetSeries("No."); Rec := SalesVATAdvNotif; exit(true); end; diff --git a/Apps/DK/NemhandelNotification/app/src/CompaniesNemhandelStatus.PageExt.al b/Apps/DK/NemhandelNotification/app/src/CompaniesNemhandelStatus.PageExt.al index db0672bfc4..c409a0abd7 100644 --- a/Apps/DK/NemhandelNotification/app/src/CompaniesNemhandelStatus.PageExt.al +++ b/Apps/DK/NemhandelNotification/app/src/CompaniesNemhandelStatus.PageExt.al @@ -1,7 +1,6 @@ namespace Microsoft.EServices; using Microsoft.Foundation.Company; -using System.Environment; pageextension 13609 "Companies Nemhandel Status" extends Companies { @@ -11,19 +10,9 @@ pageextension 13609 "Companies Nemhandel Status" extends Companies trigger OnDeleteRecord(): Boolean var CompanyInformation: Record "Company Information"; - EnvironmentInformation: Codeunit "Environment Information"; -#if not CLEAN24 NemhandelStatusMgt: Codeunit "Nemhandel Status Mgt."; -#endif begin -#if not CLEAN24 - if not NemhandelStatusMgt.IsFeatureEnableDatePassed() then - exit(true); -#endif - if not EnvironmentInformation.IsProduction() then - exit(true); - - if Rec."Evaluation Company" then + if not NemhandelStatusMgt.IsSaaSProductionCompany() then exit(true); CompanyInformation.ChangeCompany(Rec.Name); diff --git a/Apps/DK/NemhandelNotification/app/src/CompanyInfoNemhandelStatus.PageExt.al b/Apps/DK/NemhandelNotification/app/src/CompanyInfoNemhandelStatus.PageExt.al index f5efc6cec8..1e2cb4fb4f 100644 --- a/Apps/DK/NemhandelNotification/app/src/CompanyInfoNemhandelStatus.PageExt.al +++ b/Apps/DK/NemhandelNotification/app/src/CompanyInfoNemhandelStatus.PageExt.al @@ -2,6 +2,7 @@ namespace Microsoft.EServices; using Microsoft.Foundation.Company; using Microsoft.Utilities; +using System.Telemetry; pageextension 13608 "Company Info. Nemhandel Status" extends "Company Information" { @@ -10,16 +11,15 @@ pageextension 13608 "Company Info. Nemhandel Status" extends "Company Informatio modify("Registration No.") { Editable = Rec."Registered with Nemhandel" <> "Nemhandel Company Status"::Registered; - ToolTip = 'Specifies the company''s CVR number. Once the CVR number that is registered in Nemhandelsregisteret is set, it cannot changed.'; + ToolTip = 'Specifies the company''s CVR number. Once the CVR number that is registered in Nemhandelsregisteret is set, it cannot be changed.'; trigger OnAfterValidate() var InputParams: Dictionary of [Text, Text]; begin -#if not CLEAN24 - if not NemhandelStatusMgt.IsFeatureEnableDatePassed() then + if not NemhandelStatusMgt.IsSaaSProductionCompany() then exit; -#endif + if Rec."Registered with Nemhandel" = "Nemhandel Company Status"::Registered then exit; @@ -42,10 +42,6 @@ pageextension 13608 "Company Info. Nemhandel Status" extends "Company Informatio var InputParams: Dictionary of [Text, Text]; begin -#if not CLEAN24 - if not NemhandelStatusMgt.IsFeatureEnableDatePassed() then - exit; -#endif if NemhandelStatusMgt.IsNemhandelStatusCheckRequired(Rec) then begin InputParams.Add(NemhandelStatusPageBckgrnd.GetCVRNumberKey(), Rec."Registration No."); RunGetCompanyStatusBackgroundTask(InputParams); @@ -59,6 +55,8 @@ pageextension 13608 "Company Info. Nemhandel Status" extends "Company Informatio trigger OnPageBackgroundTaskCompleted(TaskId: Integer; Results: Dictionary of [Text, Text]) var ActivityLog: Record "Activity Log"; + Telemetry: Codeunit Telemetry; + CustomDimensions: Dictionary of [Text, Text]; CompanyStatusTextValue: Text; CompanyStatus: Enum "Nemhandel Company Status"; begin @@ -78,9 +76,10 @@ pageextension 13608 "Company Info. Nemhandel Status" extends "Company Informatio NemhandelStatusMgt.ManageNotRegisteredNotification(Rec."Registered with Nemhandel"); - Session.LogMessage( + CustomDimensions.Add('Category', NemhandelsregisteretCategoryTxt); + Telemetry.LogMessage( '0000KXY', StrSubstNo(PageBckGrndTaskCompletedTxt, CompanyStatus, CompanyStatusTextValue), Verbosity::Normal, - DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', NemhandelsregisteretCategoryTxt); + DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, CustomDimensions); ActivityLog.LogActivity( Rec.RecordId(), ActivityLog.Status::Success, NemhandelPageBackgroundTaskTxt, NemhandelCheckCompanyStatusTxt, StrSubstNo(PageBckGrndTaskCompletedTxt, CompanyStatus, CompanyStatusTextValue)); diff --git a/Apps/DK/NemhandelNotification/app/src/CompanyInfoNemhandelStatus.TableExt.al b/Apps/DK/NemhandelNotification/app/src/CompanyInfoNemhandelStatus.TableExt.al index d3a2d911bf..2869572edc 100644 --- a/Apps/DK/NemhandelNotification/app/src/CompanyInfoNemhandelStatus.TableExt.al +++ b/Apps/DK/NemhandelNotification/app/src/CompanyInfoNemhandelStatus.TableExt.al @@ -20,15 +20,12 @@ tableextension 13608 "Company Info. Nemhandel Status" extends "Company Informati modify("Registration No.") { trigger OnBeforeValidate() -#if not CLEAN24 var NemhandelStatusMgt: Codeunit "Nemhandel Status Mgt."; -#endif begin -#if not CLEAN24 - if not NemhandelStatusMgt.IsFeatureEnableDatePassed() then + if not NemhandelStatusMgt.IsSaaSProductionCompany() then exit; -#endif + if "Registered with Nemhandel" = "Nemhandel Company Status"::Registered then begin if Rec."Registration No." <> xRec."Registration No." then Error(CannotChangeRegistrationNoErr); diff --git a/Apps/DK/NemhandelNotification/app/src/NemhandelStatusMgt.Codeunit.al b/Apps/DK/NemhandelNotification/app/src/NemhandelStatusMgt.Codeunit.al index a401358e32..81dda86d08 100644 --- a/Apps/DK/NemhandelNotification/app/src/NemhandelStatusMgt.Codeunit.al +++ b/Apps/DK/NemhandelNotification/app/src/NemhandelStatusMgt.Codeunit.al @@ -4,6 +4,9 @@ using Microsoft.Foundation.Company; using Microsoft.Utilities; using System.Environment.Configuration; using System.Privacy; +using System.Environment; +using System.DataAdministration; +using System.Telemetry; codeunit 13628 "Nemhandel Status Mgt." { @@ -15,6 +18,9 @@ codeunit 13628 "Nemhandel Status Mgt." NotificationMsg: Label 'Your accounting software is not registered in Nemhandelsregisteret.'; EnableNemhandelNotRegisteredNotificationTxt: Label 'Enable Nemhandel Not Registered Notification'; EnableNemhandelNotRegisteredNotificationDescrTxt: Label 'Notify me that the company with the given CVR number is not registered in Nemhandelsregisteret. The message is shown on the Company Information page.'; + NemhandelsregisteretCategoryTxt: Label 'Nemhandelsregisteret', Locked = true; + CVRNumberChangedTxt: Label 'CVR number was changed from %1 to %2. Modify trigger: %3.', Locked = true; + RegisteredStatusChangedTxt: Label 'Registered with Nemhandel was changed from %1 to %2. Modify trigger: %3.', Locked = true; NemhandelsregisteretUrlLbl: Label 'https://registration.nemhandel.dk/NemHandelRegisterWeb', Locked = true; NemhandelsregisteretGuidanceUrlLbl: Label 'https://nemhandel.dk/vejledning-nemhandelsregisteret-nhr', Locked = true; @@ -49,26 +55,25 @@ codeunit 13628 "Nemhandel Status Mgt." exit(true); end; -#if not CLEAN24 - internal procedure IsFeatureEnableDatePassed(): Boolean - var - FeatureEnableDatePassed: Boolean; - IsHandled: Boolean; + local procedure GetNemhandelStatusCheckIntervalMs(): Integer begin - OnBeforeCheckFeatureEnableDate(FeatureEnableDatePassed, IsHandled); - if IsHandled then - exit(FeatureEnableDatePassed); - exit(CurrentDateTime() > GetFeatureEnableDateTime()); + exit(60 * 60 * 1000); // 1 hour in milliseconds end; - local procedure GetFeatureEnableDateTime(): DateTime - begin - exit(CreateDateTime(20240101D, 0T)); // 1 January 2024 - end; -#endif - local procedure GetNemhandelStatusCheckIntervalMs(): Integer + internal procedure IsSaaSProductionCompany(): Boolean + var + EnvironmentInformation: Codeunit "Environment Information"; begin - exit(60 * 60 * 1000); // 1 hour in milliseconds + if not EnvironmentInformation.IsProduction() then + exit(false); + + if not EnvironmentInformation.IsSaaSInfrastructure() then + exit(false); + + if EnvironmentInformation.IsSandbox() then + exit(false); + + exit(true); end; internal procedure UpdateRegisteredWithNemhandel(NemhandelCompanyStatus: Enum "Nemhandel Company Status") @@ -81,6 +86,20 @@ codeunit 13628 "Nemhandel Status Mgt." CompanyInformation.Modify(); end; + local procedure ResetRegisteredWithNemhandel(CompanyName: Text) + var + CompanyInformation: Record "Company Information"; + begin + CompanyInformation.ChangeCompany(CompanyName); + if not CompanyInformation.Get() then + exit; + + CompanyInformation."Registration No." := ''; + CompanyInformation."Registered with Nemhandel" := Enum::"Nemhandel Company Status"::Unknown; + CompanyInformation."Last Nemhandel Status Check DT" := 0DT; + CompanyInformation.Modify(); + end; + internal procedure ManageNotRegisteredNotification(RegisteredWithNemhandel: Enum "Nemhandel Company Status") begin if RegisteredWithNemhandel = Enum::"Nemhandel Company Status"::Registered then @@ -164,23 +183,37 @@ codeunit 13628 "Nemhandel Status Mgt." ShowNemhandelNotRegisteredNotification(); end; - [InternalEvent(false)] - internal procedure OnBeforeCheckFeatureEnableDate(var FeatureEnableDatePassed: Boolean; var IsHandled: Boolean) + [EventSubscriber(ObjectType::Report, Report::"Copy Company", 'OnAfterCreatedNewCompanyByCopyCompany', '', false, false)] + local procedure NemhandelStatusOnAfterCreatedNewCompanyByCopyCompany(NewCompanyName: Text[30]) begin + ResetRegisteredWithNemhandel(NewCompanyName); end; - [EventSubscriber(ObjectType::Report, Report::"Copy Company", 'OnAfterCreatedNewCompanyByCopyCompany', '', false, false)] - local procedure NemhandelStatusOnAfterCreatedNewCompanyByCopyCompany(NewCompanyName: Text[30]) + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Environment Cleanup", 'OnClearCompanyConfig', '', false, false)] + local procedure NemhandelStatusOnClearCompanyConfig(CompanyName: Text; SourceEnv: Enum "Environment Type"; DestinationEnv: Enum "Environment Type") + begin + ResetRegisteredWithNemhandel(CompanyName); + end; + + [EventSubscriber(ObjectType::Table, Database::"Company Information", 'OnAfterModifyEvent', '', false, false)] + local procedure WriteLogOnAfterModifyEvent(var Rec: Record "Company Information"; var xRec: Record "Company Information"; RunTrigger: Boolean) var - CompanyInformation: Record "Company Information"; + Telemetry: Codeunit "Telemetry"; + CustomDimensions: Dictionary of [Text, Text]; begin - CompanyInformation.ChangeCompany(NewCompanyName); - if not CompanyInformation.Get() then + if Rec.IsTemporary() then exit; - CompanyInformation."Registration No." := ''; - CompanyInformation."Registered with Nemhandel" := Enum::"Nemhandel Company Status"::Unknown; - CompanyInformation."Last Nemhandel Status Check DT" := 0DT; - CompanyInformation.Modify(); + CustomDimensions.Add('Category', NemhandelsregisteretCategoryTxt); + + if Rec."Registration No." <> xRec."Registration No." then + Telemetry.LogMessage( + '0000MAR', StrSubstNo(CVRNumberChangedTxt, xRec."Registration No.", Rec."Registration No.", RunTrigger), Verbosity::Normal, + DataClassification::OrganizationIdentifiableInformation, TelemetryScope::ExtensionPublisher, CustomDimensions); + + if Rec."Registered with Nemhandel" <> xRec."Registered with Nemhandel" then + Telemetry.LogMessage( + '0000MAS', StrSubstNo(RegisteredStatusChangedTxt, xRec."Registered with Nemhandel", Rec."Registered with Nemhandel", RunTrigger), Verbosity::Normal, + DataClassification::OrganizationIdentifiableInformation, TelemetryScope::ExtensionPublisher, CustomDimensions); end; } \ No newline at end of file diff --git a/Apps/DK/NemhandelNotification/app/src/NemhandelStatusPageBckgrnd.Codeunit.al b/Apps/DK/NemhandelNotification/app/src/NemhandelStatusPageBckgrnd.Codeunit.al index 4b22c6208b..ab8599e825 100644 --- a/Apps/DK/NemhandelNotification/app/src/NemhandelStatusPageBckgrnd.Codeunit.al +++ b/Apps/DK/NemhandelNotification/app/src/NemhandelStatusPageBckgrnd.Codeunit.al @@ -1,5 +1,7 @@ namespace Microsoft.EServices; +using System.Telemetry; + codeunit 13608 "Nemhandel Status Page Bckgrnd" { Access = Internal; @@ -32,6 +34,7 @@ codeunit 13608 "Nemhandel Status Page Bckgrnd" procedure GetCompanyStatus(CVRNumber: Text) CompanyStatus: Enum "Nemhandel Company Status" var + Telemetry: Codeunit Telemetry; HttpClientNemhandel: Interface "Http Client Nemhandel Status"; HttpResponseMsgNemhandel: Interface "Http Response Msg Nemhandel"; HttpRequestMessage: HttpRequestMessage; @@ -42,10 +45,13 @@ codeunit 13608 "Nemhandel Status Page Bckgrnd" HttpStatusCode: Integer; HttpStatusReason: Text; HttpResponseLogMessage: Text; + CustomDimensions: Dictionary of [Text, Text]; begin if CVRNumber = '' then exit("Nemhandel Company Status"::NotRegistered); + CustomDimensions.Add('Category', NemhandelsregisteretCategoryTxt); + HttpClientNemhandel := NemhandelMgt.GetHttpClient(); HttpRequestURI := HttpClientNemhandel.GetRequestURI(CVRNumber); if not HttpClientNemhandel.SendGetRequest(HttpRequestURI, HttpRequestMessage, HttpResponseMsgNemhandel) then @@ -54,9 +60,9 @@ codeunit 13608 "Nemhandel Status Page Bckgrnd" else ErrorMessage := StrSubstNo(ConnectionErr, HttpRequestMessage.GetRequestUri()); if ErrorMessage <> '' then begin - Session.LogMessage( - '0000L9W', ErrorMessage, Verbosity::Warning, DataClassification::EndUserIdentifiableInformation, - TelemetryScope::ExtensionPublisher, 'Category', NemhandelsregisteretCategoryTxt); + Telemetry.LogMessage( + '0000L9W', ErrorMessage, Verbosity::Warning, DataClassification::OrganizationIdentifiableInformation, + TelemetryScope::ExtensionPublisher, CustomDimensions); CompanyStatus := "Nemhandel Company Status"::Unknown; exit; end; @@ -74,22 +80,22 @@ codeunit 13608 "Nemhandel Status Page Bckgrnd" CompanyStatus := "Nemhandel Company Status"::Registered else CompanyStatus := "Nemhandel Company Status"::NotRegistered; - Session.LogMessage( - '0000L9X', HttpResponseLogMessage, Verbosity::Normal, DataClassification::EndUserIdentifiableInformation, - TelemetryScope::ExtensionPublisher, 'Category', NemhandelsregisteretCategoryTxt); + Telemetry.LogMessage( + '0000L9X', HttpResponseLogMessage, Verbosity::Normal, DataClassification::OrganizationIdentifiableInformation, + TelemetryScope::ExtensionPublisher, CustomDimensions); end; 404: begin CompanyStatus := "Nemhandel Company Status"::NotRegistered; - Session.LogMessage( - '0000L9Y', HttpResponseLogMessage, Verbosity::Normal, DataClassification::EndUserIdentifiableInformation, - TelemetryScope::ExtensionPublisher, 'Category', NemhandelsregisteretCategoryTxt); + Telemetry.LogMessage( + '0000L9Y', HttpResponseLogMessage, Verbosity::Normal, DataClassification::OrganizationIdentifiableInformation, + TelemetryScope::ExtensionPublisher, CustomDimensions); end; else begin CompanyStatus := "Nemhandel Company Status"::Unknown; - Session.LogMessage( - '0000L9Z', HttpResponseLogMessage, Verbosity::Normal, DataClassification::EndUserIdentifiableInformation, - TelemetryScope::ExtensionPublisher, 'Category', NemhandelsregisteretCategoryTxt); + Telemetry.LogMessage( + '0000L9Z', HttpResponseLogMessage, Verbosity::Normal, DataClassification::OrganizationIdentifiableInformation, + TelemetryScope::ExtensionPublisher, CustomDimensions); end; end; end; diff --git a/Apps/DK/NemhandelNotification/app/src/RoleCenters/AccountantActivitNemhandel.PageExt.al b/Apps/DK/NemhandelNotification/app/src/RoleCenters/AccountantActivitNemhandel.PageExt.al index 0ede9e10f6..9d08daa78b 100644 --- a/Apps/DK/NemhandelNotification/app/src/RoleCenters/AccountantActivitNemhandel.PageExt.al +++ b/Apps/DK/NemhandelNotification/app/src/RoleCenters/AccountantActivitNemhandel.PageExt.al @@ -3,20 +3,26 @@ namespace Microsoft.EServices; using Microsoft.Finance.RoleCenters; using Microsoft.Foundation.Company; using Microsoft.Utilities; +using System.Telemetry; pageextension 13628 "Accountant Activit. Nemhandel" extends "Accountant Activities" { // this page is a part of page 9027 Accountant Role Center + var + NemhandelStatusPageBckgrnd: Codeunit "Nemhandel Status Page Bckgrnd"; + NemhandelStatusMgt: Codeunit "Nemhandel Status Mgt."; + BackgroundTaskId: Integer; + PageBckGrndTaskCompletedTxt: Label 'Accountant Activities Page Background Task to check Nemhandel registration status completed. Status: %1; status text: %2', Comment = '%1, %2 - Registered/NotRegisted/Unknown', Locked = true; + NemhandelsregisteretCategoryTxt: Label 'Nemhandelsregisteret', Locked = true; + NemhandelPageBackgroundTaskTxt: Label 'Nemhandel Page Background Task'; + NemhandelCheckCompanyStatusTxt: Label 'Nemhandel Check Company Status'; + trigger OnAfterGetCurrRecord() var CompanyInformation: Record "Company Information"; InputParams: Dictionary of [Text, Text]; begin -#if not CLEAN24 - if not NemhandelStatusMgt.IsFeatureEnableDatePassed() then - exit; -#endif CompanyInformation.Get(); if NemhandelStatusMgt.IsNemhandelStatusCheckRequired(CompanyInformation) then begin InputParams.Add(NemhandelStatusPageBckgrnd.GetCVRNumberKey(), CompanyInformation."Registration No."); @@ -31,6 +37,8 @@ pageextension 13628 "Accountant Activit. Nemhandel" extends "Accountant Activiti trigger OnPageBackgroundTaskCompleted(TaskId: Integer; Results: Dictionary of [Text, Text]) var ActivityLog: Record "Activity Log"; + Telemetry: Codeunit Telemetry; + CustomDimensions: Dictionary of [Text, Text]; CompanyStatusTextValue: Text; CompanyStatus: Enum "Nemhandel Company Status"; begin @@ -47,23 +55,15 @@ pageextension 13628 "Accountant Activit. Nemhandel" extends "Accountant Activiti NemhandelStatusMgt.ManageNotRegisteredNotification(CompanyStatus); - Session.LogMessage( + CustomDimensions.Add('Category', NemhandelsregisteretCategoryTxt); + Telemetry.LogMessage( '0000LB6', StrSubstNo(PageBckGrndTaskCompletedTxt, CompanyStatus, CompanyStatusTextValue), Verbosity::Normal, - DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', NemhandelsregisteretCategoryTxt); + DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, CustomDimensions); ActivityLog.LogActivity( Rec.RecordId(), ActivityLog.Status::Success, NemhandelPageBackgroundTaskTxt, NemhandelCheckCompanyStatusTxt, StrSubstNo(PageBckGrndTaskCompletedTxt, CompanyStatus, CompanyStatusTextValue)); end; - var - NemhandelStatusPageBckgrnd: Codeunit "Nemhandel Status Page Bckgrnd"; - NemhandelStatusMgt: Codeunit "Nemhandel Status Mgt."; - BackgroundTaskId: Integer; - PageBckGrndTaskCompletedTxt: Label 'Accountant Activities Page Background Task to check Nemhandel registration status completed. Status: %1; status text: %2', Comment = '%1, %2 - Registered/NotRegisted/Unknown', Locked = true; - NemhandelsregisteretCategoryTxt: Label 'Nemhandelsregisteret', Locked = true; - NemhandelPageBackgroundTaskTxt: Label 'Nemhandel Page Background Task'; - NemhandelCheckCompanyStatusTxt: Label 'Nemhandel Check Company Status'; - local procedure RunGetCompanyStatusBackgroundTask(InputParams: Dictionary of [Text, Text]) begin if BackgroundTaskId <> 0 then diff --git a/Apps/DK/NemhandelNotification/app/src/RoleCenters/O365ActivitiesNemhandel.PageExt.al b/Apps/DK/NemhandelNotification/app/src/RoleCenters/O365ActivitiesNemhandel.PageExt.al index 0440ac964a..959cd37bc9 100644 --- a/Apps/DK/NemhandelNotification/app/src/RoleCenters/O365ActivitiesNemhandel.PageExt.al +++ b/Apps/DK/NemhandelNotification/app/src/RoleCenters/O365ActivitiesNemhandel.PageExt.al @@ -2,20 +2,26 @@ namespace Microsoft.EServices; using Microsoft.Foundation.Company; using Microsoft.Utilities; +using System.Telemetry; pageextension 13629 "O365 Activities Nemhandel" extends "O365 Activities" { // this page is a part of page 9022 Business Manager Role Center + var + NemhandelStatusPageBckgrnd: Codeunit "Nemhandel Status Page Bckgrnd"; + NemhandelStatusMgt: Codeunit "Nemhandel Status Mgt."; + BackgroundTaskId: Integer; + PageBckGrndTaskCompletedTxt: Label 'O365 Activities Page Background Task to check Nemhandel registration status completed. Status: %1; status text: %2', Comment = '%1, %2 - Registered/NotRegisted/Unknown', Locked = true; + NemhandelsregisteretCategoryTxt: Label 'Nemhandelsregisteret', Locked = true; + NemhandelPageBackgroundTaskTxt: Label 'Nemhandel Page Background Task'; + NemhandelCheckCompanyStatusTxt: Label 'Nemhandel Check Company Status'; + trigger OnAfterGetCurrRecord() var CompanyInformation: Record "Company Information"; InputParams: Dictionary of [Text, Text]; begin -#if not CLEAN24 - if not NemhandelStatusMgt.IsFeatureEnableDatePassed() then - exit; -#endif CompanyInformation.Get(); if NemhandelStatusMgt.IsNemhandelStatusCheckRequired(CompanyInformation) then begin InputParams.Add(NemhandelStatusPageBckgrnd.GetCVRNumberKey(), CompanyInformation."Registration No."); @@ -30,6 +36,8 @@ pageextension 13629 "O365 Activities Nemhandel" extends "O365 Activities" trigger OnPageBackgroundTaskCompleted(TaskId: Integer; Results: Dictionary of [Text, Text]) var ActivityLog: Record "Activity Log"; + Telemetry: Codeunit Telemetry; + CustomDimensions: Dictionary of [Text, Text]; CompanyStatusTextValue: Text; CompanyStatus: Enum "Nemhandel Company Status"; begin @@ -46,23 +54,15 @@ pageextension 13629 "O365 Activities Nemhandel" extends "O365 Activities" NemhandelStatusMgt.ManageNotRegisteredNotification(CompanyStatus); - Session.LogMessage( + CustomDimensions.Add('Category', NemhandelsregisteretCategoryTxt); + Telemetry.LogMessage( '0000LB7', StrSubstNo(PageBckGrndTaskCompletedTxt, CompanyStatus, CompanyStatusTextValue), Verbosity::Normal, - DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', NemhandelsregisteretCategoryTxt); + DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, CustomDimensions); ActivityLog.LogActivity( Rec.RecordId(), ActivityLog.Status::Success, NemhandelPageBackgroundTaskTxt, NemhandelCheckCompanyStatusTxt, StrSubstNo(PageBckGrndTaskCompletedTxt, CompanyStatus, CompanyStatusTextValue)); end; - var - NemhandelStatusPageBckgrnd: Codeunit "Nemhandel Status Page Bckgrnd"; - NemhandelStatusMgt: Codeunit "Nemhandel Status Mgt."; - BackgroundTaskId: Integer; - PageBckGrndTaskCompletedTxt: Label 'O365 Activities Page Background Task to check Nemhandel registration status completed. Status: %1; status text: %2', Comment = '%1, %2 - Registered/NotRegisted/Unknown', Locked = true; - NemhandelsregisteretCategoryTxt: Label 'Nemhandelsregisteret', Locked = true; - NemhandelPageBackgroundTaskTxt: Label 'Nemhandel Page Background Task'; - NemhandelCheckCompanyStatusTxt: Label 'Nemhandel Check Company Status'; - local procedure RunGetCompanyStatusBackgroundTask(InputParams: Dictionary of [Text, Text]) begin if BackgroundTaskId <> 0 then diff --git a/Apps/DK/NemhandelNotification/app/src/RoleCenters/SOProcessorActivNemhandel.PageExt.al b/Apps/DK/NemhandelNotification/app/src/RoleCenters/SOProcessorActivNemhandel.PageExt.al index 389322a049..7be550a343 100644 --- a/Apps/DK/NemhandelNotification/app/src/RoleCenters/SOProcessorActivNemhandel.PageExt.al +++ b/Apps/DK/NemhandelNotification/app/src/RoleCenters/SOProcessorActivNemhandel.PageExt.al @@ -3,20 +3,26 @@ namespace Microsoft.EServices; using Microsoft.Foundation.Company; using Microsoft.Sales.RoleCenters; using Microsoft.Utilities; +using System.Telemetry; pageextension 13631 "SO Processor Activ. Nemhandel" extends "SO Processor Activities" { // this page is a part of page 9006 Order Processor Role Center + var + NemhandelStatusPageBckgrnd: Codeunit "Nemhandel Status Page Bckgrnd"; + NemhandelStatusMgt: Codeunit "Nemhandel Status Mgt."; + BackgroundTaskId: Integer; + PageBckGrndTaskCompletedTxt: Label 'SO Processor Activities Page Background Task to check Nemhandel registration status completed. Status: %1; status text: %2', Comment = '%1, %2 - Registered/NotRegisted/Unknown', Locked = true; + NemhandelsregisteretCategoryTxt: Label 'Nemhandelsregisteret', Locked = true; + NemhandelPageBackgroundTaskTxt: Label 'Nemhandel Page Background Task'; + NemhandelCheckCompanyStatusTxt: Label 'Nemhandel Check Company Status'; + trigger OnAfterGetCurrRecord() var CompanyInformation: Record "Company Information"; InputParams: Dictionary of [Text, Text]; begin -#if not CLEAN24 - if not NemhandelStatusMgt.IsFeatureEnableDatePassed() then - exit; -#endif CompanyInformation.Get(); if NemhandelStatusMgt.IsNemhandelStatusCheckRequired(CompanyInformation) then begin InputParams.Add(NemhandelStatusPageBckgrnd.GetCVRNumberKey(), CompanyInformation."Registration No."); @@ -31,6 +37,8 @@ pageextension 13631 "SO Processor Activ. Nemhandel" extends "SO Processor Activi trigger OnPageBackgroundTaskCompleted(TaskId: Integer; Results: Dictionary of [Text, Text]) var ActivityLog: Record "Activity Log"; + Telemetry: Codeunit Telemetry; + CustomDimensions: Dictionary of [Text, Text]; CompanyStatusTextValue: Text; CompanyStatus: Enum "Nemhandel Company Status"; begin @@ -47,23 +55,15 @@ pageextension 13631 "SO Processor Activ. Nemhandel" extends "SO Processor Activi NemhandelStatusMgt.ManageNotRegisteredNotification(CompanyStatus); - Session.LogMessage( + CustomDimensions.Add('Category', NemhandelsregisteretCategoryTxt); + Telemetry.LogMessage( '0000LB8', StrSubstNo(PageBckGrndTaskCompletedTxt, CompanyStatus, CompanyStatusTextValue), Verbosity::Normal, - DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', NemhandelsregisteretCategoryTxt); + DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, CustomDimensions); ActivityLog.LogActivity( Rec.RecordId(), ActivityLog.Status::Success, NemhandelPageBackgroundTaskTxt, NemhandelCheckCompanyStatusTxt, StrSubstNo(PageBckGrndTaskCompletedTxt, CompanyStatus, CompanyStatusTextValue)); end; - var - NemhandelStatusPageBckgrnd: Codeunit "Nemhandel Status Page Bckgrnd"; - NemhandelStatusMgt: Codeunit "Nemhandel Status Mgt."; - BackgroundTaskId: Integer; - PageBckGrndTaskCompletedTxt: Label 'SO Processor Activities Page Background Task to check Nemhandel registration status completed. Status: %1; status text: %2', Comment = '%1, %2 - Registered/NotRegisted/Unknown', Locked = true; - NemhandelsregisteretCategoryTxt: Label 'Nemhandelsregisteret', Locked = true; - NemhandelPageBackgroundTaskTxt: Label 'Nemhandel Page Background Task'; - NemhandelCheckCompanyStatusTxt: Label 'Nemhandel Check Company Status'; - local procedure RunGetCompanyStatusBackgroundTask(InputParams: Dictionary of [Text, Text]) begin if BackgroundTaskId <> 0 then diff --git a/Apps/DK/NemhandelNotification/app/src/RoleCenters/SalesMgrActivitNemhandel.PageExt.al b/Apps/DK/NemhandelNotification/app/src/RoleCenters/SalesMgrActivitNemhandel.PageExt.al index 1d36caf66e..53c705fe14 100644 --- a/Apps/DK/NemhandelNotification/app/src/RoleCenters/SalesMgrActivitNemhandel.PageExt.al +++ b/Apps/DK/NemhandelNotification/app/src/RoleCenters/SalesMgrActivitNemhandel.PageExt.al @@ -3,20 +3,26 @@ namespace Microsoft.EServices; using Microsoft.CRM.RoleCenters; using Microsoft.Foundation.Company; using Microsoft.Utilities; +using System.Telemetry; pageextension 13630 "Sales Mgr. Activit. Nemhandel" extends "Sales & Relationship Mgr. Act." { // this page is a part of page 9026 Sales & Relationship Mgr. RC + var + NemhandelStatusPageBckgrnd: Codeunit "Nemhandel Status Page Bckgrnd"; + NemhandelStatusMgt: Codeunit "Nemhandel Status Mgt."; + BackgroundTaskId: Integer; + PageBckGrndTaskCompletedTxt: Label 'Sales and Relationship Mgr. Activities Page Background Task to check Nemhandel registration status completed. Status: %1; status text: %2', Comment = '%1, %2 - Registered/NotRegisted/Unknown', Locked = true; + NemhandelsregisteretCategoryTxt: Label 'Nemhandelsregisteret', Locked = true; + NemhandelPageBackgroundTaskTxt: Label 'Nemhandel Page Background Task'; + NemhandelCheckCompanyStatusTxt: Label 'Nemhandel Check Company Status'; + trigger OnAfterGetCurrRecord() var CompanyInformation: Record "Company Information"; InputParams: Dictionary of [Text, Text]; begin -#if not CLEAN24 - if not NemhandelStatusMgt.IsFeatureEnableDatePassed() then - exit; -#endif CompanyInformation.Get(); if NemhandelStatusMgt.IsNemhandelStatusCheckRequired(CompanyInformation) then begin InputParams.Add(NemhandelStatusPageBckgrnd.GetCVRNumberKey(), CompanyInformation."Registration No."); @@ -31,6 +37,8 @@ pageextension 13630 "Sales Mgr. Activit. Nemhandel" extends "Sales & Relationshi trigger OnPageBackgroundTaskCompleted(TaskId: Integer; Results: Dictionary of [Text, Text]) var ActivityLog: Record "Activity Log"; + Telemetry: Codeunit Telemetry; + CustomDimensions: Dictionary of [Text, Text]; CompanyStatusTextValue: Text; CompanyStatus: Enum "Nemhandel Company Status"; begin @@ -47,23 +55,15 @@ pageextension 13630 "Sales Mgr. Activit. Nemhandel" extends "Sales & Relationshi NemhandelStatusMgt.ManageNotRegisteredNotification(CompanyStatus); - Session.LogMessage( + CustomDimensions.Add('Category', NemhandelsregisteretCategoryTxt); + Telemetry.LogMessage( '0000LB9', StrSubstNo(PageBckGrndTaskCompletedTxt, CompanyStatus, CompanyStatusTextValue), Verbosity::Normal, - DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', NemhandelsregisteretCategoryTxt); + DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, CustomDimensions); ActivityLog.LogActivity( Rec.RecordId(), ActivityLog.Status::Success, NemhandelPageBackgroundTaskTxt, NemhandelCheckCompanyStatusTxt, StrSubstNo(PageBckGrndTaskCompletedTxt, CompanyStatus, CompanyStatusTextValue)); end; - var - NemhandelStatusPageBckgrnd: Codeunit "Nemhandel Status Page Bckgrnd"; - NemhandelStatusMgt: Codeunit "Nemhandel Status Mgt."; - BackgroundTaskId: Integer; - PageBckGrndTaskCompletedTxt: Label 'Sales and Relationship Mgr. Activities Page Background Task to check Nemhandel registration status completed. Status: %1; status text: %2', Comment = '%1, %2 - Registered/NotRegisted/Unknown', Locked = true; - NemhandelsregisteretCategoryTxt: Label 'Nemhandelsregisteret', Locked = true; - NemhandelPageBackgroundTaskTxt: Label 'Nemhandel Page Background Task'; - NemhandelCheckCompanyStatusTxt: Label 'Nemhandel Check Company Status'; - local procedure RunGetCompanyStatusBackgroundTask(InputParams: Dictionary of [Text, Text]) begin if BackgroundTaskId <> 0 then diff --git a/Apps/DK/NemhandelNotification/app/src/RoleCenters/UserSecurityActivNemhandel.PageExt.al b/Apps/DK/NemhandelNotification/app/src/RoleCenters/UserSecurityActivNemhandel.PageExt.al index 25e3f087fc..c5a44909a7 100644 --- a/Apps/DK/NemhandelNotification/app/src/RoleCenters/UserSecurityActivNemhandel.PageExt.al +++ b/Apps/DK/NemhandelNotification/app/src/RoleCenters/UserSecurityActivNemhandel.PageExt.al @@ -3,20 +3,26 @@ namespace Microsoft.EServices; using Microsoft.Foundation.Company; using Microsoft.Utilities; using System.Security.User; +using System.Telemetry; pageextension 13632 "User Security Activ. Nemhandel" extends "User Security Activities" { // this page is a part of page 9024 Security Admin Role Center + var + NemhandelStatusPageBckgrnd: Codeunit "Nemhandel Status Page Bckgrnd"; + NemhandelStatusMgt: Codeunit "Nemhandel Status Mgt."; + BackgroundTaskId: Integer; + PageBckGrndTaskCompletedTxt: Label 'User Security Activities Page Background Task to check Nemhandel registration status completed. Status: %1; status text: %2', Comment = '%1, %2 - Registered/NotRegisted/Unknown', Locked = true; + NemhandelsregisteretCategoryTxt: Label 'Nemhandelsregisteret', Locked = true; + NemhandelPageBackgroundTaskTxt: Label 'Nemhandel Page Background Task'; + NemhandelCheckCompanyStatusTxt: Label 'Nemhandel Check Company Status'; + trigger OnAfterGetCurrRecord() var CompanyInformation: Record "Company Information"; InputParams: Dictionary of [Text, Text]; begin -#if not CLEAN24 - if not NemhandelStatusMgt.IsFeatureEnableDatePassed() then - exit; -#endif CompanyInformation.Get(); if NemhandelStatusMgt.IsNemhandelStatusCheckRequired(CompanyInformation) then begin InputParams.Add(NemhandelStatusPageBckgrnd.GetCVRNumberKey(), CompanyInformation."Registration No."); @@ -31,6 +37,8 @@ pageextension 13632 "User Security Activ. Nemhandel" extends "User Security Acti trigger OnPageBackgroundTaskCompleted(TaskId: Integer; Results: Dictionary of [Text, Text]) var ActivityLog: Record "Activity Log"; + Telemetry: Codeunit Telemetry; + CustomDimensions: Dictionary of [Text, Text]; CompanyStatusTextValue: Text; CompanyStatus: Enum "Nemhandel Company Status"; begin @@ -47,23 +55,15 @@ pageextension 13632 "User Security Activ. Nemhandel" extends "User Security Acti NemhandelStatusMgt.ManageNotRegisteredNotification(CompanyStatus); - Session.LogMessage( + CustomDimensions.Add('Category', NemhandelsregisteretCategoryTxt); + Telemetry.LogMessage( '0000LBA', StrSubstNo(PageBckGrndTaskCompletedTxt, CompanyStatus, CompanyStatusTextValue), Verbosity::Normal, - DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', NemhandelsregisteretCategoryTxt); + DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, CustomDimensions); ActivityLog.LogActivity( Rec.RecordId(), ActivityLog.Status::Success, NemhandelPageBackgroundTaskTxt, NemhandelCheckCompanyStatusTxt, StrSubstNo(PageBckGrndTaskCompletedTxt, CompanyStatus, CompanyStatusTextValue)); end; - var - NemhandelStatusPageBckgrnd: Codeunit "Nemhandel Status Page Bckgrnd"; - NemhandelStatusMgt: Codeunit "Nemhandel Status Mgt."; - BackgroundTaskId: Integer; - PageBckGrndTaskCompletedTxt: Label 'User Security Activities Page Background Task to check Nemhandel registration status completed. Status: %1; status text: %2', Comment = '%1, %2 - Registered/NotRegisted/Unknown', Locked = true; - NemhandelsregisteretCategoryTxt: Label 'Nemhandelsregisteret', Locked = true; - NemhandelPageBackgroundTaskTxt: Label 'Nemhandel Page Background Task'; - NemhandelCheckCompanyStatusTxt: Label 'Nemhandel Check Company Status'; - local procedure RunGetCompanyStatusBackgroundTask(InputParams: Dictionary of [Text, Text]) begin if BackgroundTaskId <> 0 then diff --git a/Apps/DK/NemhandelNotification/app/src/UpdRegisteredWithNemhandel.Codeunit.al b/Apps/DK/NemhandelNotification/app/src/UpdRegisteredWithNemhandel.Codeunit.al index 3c01a52528..9a6b091711 100644 --- a/Apps/DK/NemhandelNotification/app/src/UpdRegisteredWithNemhandel.Codeunit.al +++ b/Apps/DK/NemhandelNotification/app/src/UpdRegisteredWithNemhandel.Codeunit.al @@ -1,6 +1,7 @@ namespace Microsoft.EServices; using Microsoft.Foundation.Company; +using System.Telemetry; codeunit 13609 "Upd. Registered with Nemhandel" { @@ -14,14 +15,17 @@ codeunit 13609 "Upd. Registered with Nemhandel" var CompanyInformation: Record "Company Information"; NemhandelCompanyStatus: Codeunit "Nemhandel Status Page Bckgrnd"; + Telemetry: Codeunit Telemetry; + CustomDimensions: Dictionary of [Text, Text]; begin CompanyInformation.Get(); CompanyInformation."Registered with Nemhandel" := NemhandelCompanyStatus.GetCompanyStatus(CompanyInformation."Registration No."); CompanyInformation."Last Nemhandel Status Check DT" := CurrentDateTime(); CompanyInformation.Modify(); - Session.LogMessage( + CustomDimensions.Add('Category', NemhandelsregisteretCategoryTxt); + Telemetry.LogMessage( '0000KXX', StrSubstNo(BckGrndTaskCompletedTxt, CompanyInformation."Registered with Nemhandel"), Verbosity::Normal, - DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', NemhandelsregisteretCategoryTxt); + DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, CustomDimensions); end; } \ No newline at end of file diff --git a/Apps/DK/NemhandelNotification/test/src/NemhandelTests.Codeunit.al b/Apps/DK/NemhandelNotification/test/src/NemhandelTests.Codeunit.al index cb335f75e8..fe70adc1ad 100644 --- a/Apps/DK/NemhandelNotification/test/src/NemhandelTests.Codeunit.al +++ b/Apps/DK/NemhandelNotification/test/src/NemhandelTests.Codeunit.al @@ -253,7 +253,6 @@ codeunit 148012 "Nemhandel Tests" CompanyInformationPage."Registration No.".SetValue('87654321'); // [THEN] Notification "Your accounting software is not registered in Nemhandelsregisteret" was shown on Company Information page. - LibraryVariableStorage.DequeueText(); // clear notification shown when CVR number was blank NotificationText := LibraryVariableStorage.DequeueText(); Assert.ExpectedMessage('Your accounting software is not registered in Nemhandelsregisteret', NotificationText); @@ -548,14 +547,6 @@ codeunit 148012 "Nemhandel Tests" CompanyStatusGlobal := NewStatus; end; -#if not CLEAN24 - [EventSubscriber(ObjectType::Codeunit, Codeunit::"Nemhandel Status Mgt.", 'OnBeforeCheckFeatureEnableDate', '', false, false)] - local procedure OnBeforeCheckFeatureEnableDate(var FeatureEnableDatePassed: Boolean; var IsHandled: Boolean) - begin - FeatureEnableDatePassed := true; - IsHandled := true; - end; -#endif [EventSubscriber(ObjectType::Page, Page::"Company Information", 'OnAfterGetCompanyStatusCompanyInfoBckgrndTask', '', false, false)] local procedure MockStatusOnAfterGetCompanyStatusCompanyInfoBckgrndTask(var CompanyStatus: Enum "Nemhandel Company Status") begin diff --git a/Apps/DK/OIOUBL/test/src/OIOUBLCheckSalesandService.Codeunit.al b/Apps/DK/OIOUBL/test/src/OIOUBLCheckSalesandService.Codeunit.al index 8e611a1065..d5e4e080f8 100644 --- a/Apps/DK/OIOUBL/test/src/OIOUBLCheckSalesandService.Codeunit.al +++ b/Apps/DK/OIOUBL/test/src/OIOUBLCheckSalesandService.Codeunit.al @@ -26,6 +26,7 @@ codeunit 148050 "OIOUBL-Check Sales and Service" #pragma warning restore AA0470 NegativeDiscountAmountErr: Label 'The total Line Discount Amount cannot be negative.'; NegativeAmountErr: Label 'The total Line Amount cannot be negative.'; + TotalInvoiceAmountNegativeErr: Label 'The total amount for the invoice must be 0 or greater.'; GLEntryVerifyErr: Label 'The GLEntry does not exist.'; NotFoundOnPageErr: Label 'is not found on the page'; TestFieldNotFoundErr: Label 'TestFieldNotFound'; @@ -119,7 +120,8 @@ codeunit 148050 "OIOUBL-Check Sales and Service" // Exercise: Post the Sales Invoice. // Verify: Verify error message pops up when posting. asserterror LibrarySales.PostSalesDocument(SalesHeader, false, false); - Assert.ExpectedError(NegativeAmountErr); + // Assert.ExpectedError(NegativeAmountErr); -> don't get the OIOUBL error, you get the normal W1 error + Assert.ExpectedError(TotalInvoiceAmountNegativeErr); end; [Test] diff --git a/Apps/IN/INGST/app/GSTDistribution/src/Codeunit/GSTDistributionSubcsribers.codeunit.al b/Apps/IN/INGST/app/GSTDistribution/src/Codeunit/GSTDistributionSubcsribers.codeunit.al index 5a2b35378e..bb7f077980 100644 --- a/Apps/IN/INGST/app/GSTDistribution/src/Codeunit/GSTDistributionSubcsribers.codeunit.al +++ b/Apps/IN/INGST/app/GSTDistribution/src/Codeunit/GSTDistributionSubcsribers.codeunit.al @@ -412,12 +412,12 @@ codeunit 18201 "GST Distribution Subcsribers" local procedure ValidateNoField(var Rec: Record "GST Distribution Header"; var xRec: Record "GST Distribution Header") var GeneralLedgerSetup: Record "General Ledger Setup"; - NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; begin GeneralLedgerSetup.Get(); if Rec."No." <> xRec."No." then begin GeneralLedgerSetup.Get(); - NoSeriesManagement.TestManual(GeneralLedgerSetup."GST Distribution Nos."); + NoSeries.TestManual(GeneralLedgerSetup."GST Distribution Nos."); Rec."No. Series" := ''; end; end; diff --git a/Apps/IN/INGST/app/GSTServiceTransfer/src/table/ServiceTransferHeader.table.al b/Apps/IN/INGST/app/GSTServiceTransfer/src/table/ServiceTransferHeader.table.al index 21c5178a33..e97f4abfdb 100644 --- a/Apps/IN/INGST/app/GSTServiceTransfer/src/table/ServiceTransferHeader.table.al +++ b/Apps/IN/INGST/app/GSTServiceTransfer/src/table/ServiceTransferHeader.table.al @@ -28,11 +28,11 @@ table 18350 "Service Transfer Header" trigger OnValidate() var - NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; begin if "No." <> xRec."No." then begin GetInventorySetup(); - NoSeriesManagement.TestManual(GetNoSeriesCode()); + NoSeries.TestManual(GetNoSeriesCode()); "No. Series" := ''; end; end; @@ -436,17 +436,30 @@ table 18350 "Service Transfer Header" trigger OnInsert() var + NoSeries: Codeunit "No. Series"; +#if not CLEAN24 NoSeriesManagement: Codeunit NoSeriesManagement; + IsHandled: Boolean; +#endif + NoSeriesCode: Code[20]; begin GetInventorySetup(); if "No." = '' then begin InventorySetup.TestField("Service Transfer Order Nos."); - NoSeriesManagement.InitSeries( - GetNoSeriesCode(), - xRec."No. Series", - "Shipment Date", - "No.", - "No. Series"); + NoSeriesCode := GetNoSeriesCode(); +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(NoSeriesCode, xRec."No. Series", "Shipment Date", "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := NoSeriesCode; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series", "Shipment Date"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", NoSeriesCode, "Shipment Date", "No."); + end; +#endif end; InitRecord(); end; diff --git a/Apps/IN/INGST/app/GSTStockTransfer/src/codeunit/GSTTransferOrderReceipt.Codeunit.al b/Apps/IN/INGST/app/GSTStockTransfer/src/codeunit/GSTTransferOrderReceipt.Codeunit.al index 949034dc60..190a26231b 100644 --- a/Apps/IN/INGST/app/GSTStockTransfer/src/codeunit/GSTTransferOrderReceipt.Codeunit.al +++ b/Apps/IN/INGST/app/GSTStockTransfer/src/codeunit/GSTTransferOrderReceipt.Codeunit.al @@ -156,7 +156,12 @@ codeunit 18390 "GST Transfer Order Receipt" GSTGroup: Record "GST Group"; DocTransactionType: Enum "Transaction Type Enum"; DocumentType: Enum "Document Type Enum"; + IsHandled: Boolean; begin + OnBeforeInsertTransRcptLineFillBuffer(TransferLine, IsHandled); + if IsHandled then + exit; + if TransferLine.Quantity <> 0 then GSTAmountLoaded := Abs( RoundTotalGSTAmountLoadedQtyFactor( @@ -725,21 +730,24 @@ codeunit 18390 "GST Transfer Order Receipt" local procedure GetGSTAmount(TaxRecordId: RecordID): Decimal var - TaxTransValue: Record "Tax Transaction Value"; + TaxTransactionValue: Record "Tax Transaction Value"; GSTSetup: Record "GST Setup"; begin if not GSTSetup.Get() then exit; - GSTSetup.TestField("GST Tax Type"); - GSTSetup.TestField("Cess Tax Type"); - TaxTransValue.Reset(); - TaxTransValue.SetFilter("Tax Type", '%1|%2', GSTSetup."GST Tax Type", GSTSetup."Cess Tax Type"); - TaxTransValue.SetRange("Tax Record ID", TaxRecordId); - TaxTransValue.SetRange("Value Type", TaxTransValue."Value Type"::COMPONENT); - TaxTransValue.SetFilter(Amount, '<>%1', 0); - if TaxTransValue.FindFirst() then - exit(TaxTransValue.Amount); + TaxTransactionValue.SetCurrentKey("Tax Record ID", "Value Type", "Tax Type", Percent); + TaxTransactionValue.SetRange("Tax Record ID", TaxRecordId); + TaxTransactionValue.SetRange("Value Type", TaxTransactionValue."Value Type"::COMPONENT); + if GSTSetup."Cess Tax Type" <> '' then + TaxTransactionValue.SetRange("Tax Type", GSTSetup."GST Tax Type", GSTSetup."Cess Tax Type") + else + TaxTransactionValue.SetRange("Tax Type", GSTSetup."GST Tax Type"); + TaxTransactionValue.SetFilter(Percent, '<>%1', 0); + if not TaxTransactionValue.IsEmpty() then + TaxTransactionValue.CalcSums(Amount); + + exit(TaxTransactionValue.Amount); end; local procedure FillTransferBuffer(TransferLine: Record "Transfer Line") @@ -1271,4 +1279,9 @@ codeunit 18390 "GST Transfer Order Receipt" TotalQuantity := 0; TempItemJnlLine.DeleteAll(); end; + + [IntegrationEvent(false, false)] + local procedure OnBeforeInsertTransRcptLineFillBuffer(var TransferLine: Record "Transfer Line"; var IsHandled: Boolean) + begin + end; } diff --git a/Apps/IN/INGST/app/GSTSubcontracting/src/Codeunit/SubcontractingSubscribers.Codeunit.al b/Apps/IN/INGST/app/GSTSubcontracting/src/Codeunit/SubcontractingSubscribers.Codeunit.al index e5133c4d21..d4d2ab6b3e 100644 --- a/Apps/IN/INGST/app/GSTSubcontracting/src/Codeunit/SubcontractingSubscribers.Codeunit.al +++ b/Apps/IN/INGST/app/GSTSubcontracting/src/Codeunit/SubcontractingSubscribers.Codeunit.al @@ -286,6 +286,28 @@ codeunit 18469 "Subcontracting Subscribers" end; end; + [EventSubscriber(ObjectType::Table, Database::"Purchase Line", 'OnAfterValidateEvent', 'Qty. to Invoice', false, false)] + local procedure OnValidateQtyToInvoiceSubcon(var Rec: Record "Purchase Line") + var + InvalidQtyErr: label 'Quantity should be less than or equal to outstanding quantity.'; + begin + if (Rec.Subcontracting) and + (Rec."Prod. Order No." <> '') and + (Rec."Prod. Order Line No." <> 0) then + if Rec."Qty. to Invoice" > Rec.Quantity then + Error(InvalidQtyErr); + end; + + [EventSubscriber(ObjectType::Table, Database::"Purchase Line", 'OnAfterInitOutstandingQty', '', false, false)] + local procedure OnAfterInitOutstandingQty(var PurchaseLine: Record "Purchase Line") + begin + if (PurchaseLine.Subcontracting) and + (PurchaseLine."Prod. Order No." <> '') and + (PurchaseLine."Prod. Order Line No." <> 0) then + if PurchaseLine."Outstanding Qty. (Base)" <> 0 then + PurchaseLine."Outstanding Qty. (Base)" := 0; + end; + local procedure ValidateDeliveryChallanCreatedForOrder(PurchHeader: Record "Purchase Header") var DeliveryChallanLine: Record "Delivery Challan Line"; diff --git a/Apps/IN/INGST/app/GSTSubcontracting/src/Table/DeliveryChallanHeader.Table.al b/Apps/IN/INGST/app/GSTSubcontracting/src/Table/DeliveryChallanHeader.Table.al index 86b5da0138..008fdc7a31 100644 --- a/Apps/IN/INGST/app/GSTSubcontracting/src/Table/DeliveryChallanHeader.Table.al +++ b/Apps/IN/INGST/app/GSTSubcontracting/src/Table/DeliveryChallanHeader.Table.al @@ -125,21 +125,42 @@ table 18468 "Delivery Challan Header" } trigger OnInsert() + var + NoSeries: Codeunit "No. Series"; +#if not CLEAN24 + IsHandled: Boolean; +#endif begin - InitRecord(); PurchSetup.Get(); + InitRecord(); if "No." = '' then begin PurchSetup.TestField("Posted Delivery Challan Nos."); - NoSeriesMgt.InitSeries(PurchSetup."Posted Delivery Challan Nos.", xRec."No. Series", TODAY, "No.", "No. Series"); +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(PurchSetup."Posted Delivery Challan Nos.", xRec."No. Series", Today(), "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := PurchSetup."Posted Delivery Challan Nos."; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series", Today()); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", PurchSetup."Posted Delivery Challan Nos.", Today(), "No."); + end; +#endif end; end; procedure InitRecord() + var + NoSeriesManagement: Codeunit "NoSeriesManagement"; begin - NoSeriesMgt.SetDefaultSeries("No. Series", PurchSetup."Posted Delivery Challan Nos."); + NoSeriesManagement.SetDefaultSeries("No. Series", PurchSetup."Posted Delivery Challan Nos."); end; var PurchSetup: Record "Purchases & Payables Setup"; - NoSeriesMgt: Codeunit "NoSeriesManagement"; +#if not CLEAN24 + NoSeriesManagement: Codeunit "NoSeriesManagement"; +#endif } diff --git a/Apps/IN/INGST/app/GSTSubcontracting/src/Table/MultipleSubconOrderDetails.Table.al b/Apps/IN/INGST/app/GSTSubcontracting/src/Table/MultipleSubconOrderDetails.Table.al index da0d19357e..e870f6218a 100644 --- a/Apps/IN/INGST/app/GSTSubcontracting/src/Table/MultipleSubconOrderDetails.Table.al +++ b/Apps/IN/INGST/app/GSTSubcontracting/src/Table/MultipleSubconOrderDetails.Table.al @@ -24,7 +24,7 @@ table 18471 "Multiple Subcon. Order Details" begin if "No." <> xRec."No." then begin PurchasePayablesSetup.Get(); - NoSeriesMgt.TestManual(PurchasePayablesSetup."Multiple Subcon. Order Det Nos"); + NoSeries.TestManual(PurchasePayablesSetup."Multiple Subcon. Order Det Nos"); "No. Series" := ''; end; end; @@ -68,6 +68,8 @@ table 18471 "Multiple Subcon. Order Details" } trigger OnInsert() + var + NoSeries: Record "No. Series"; begin if "No." = '' then begin PurchasePayablesSetup.Get(); @@ -97,7 +99,7 @@ table 18471 "Multiple Subcon. Order Details" end; var - NoSeries: Record "No. Series"; PurchasePayablesSetup: Record "Purchases & Payables Setup"; NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; } diff --git a/Apps/IN/INGST/app/GSTSubcontracting/src/Table/SubCompRcptHeader.Table.al b/Apps/IN/INGST/app/GSTSubcontracting/src/Table/SubCompRcptHeader.Table.al index ddb4fe67dd..f2f2e2a1bc 100644 --- a/Apps/IN/INGST/app/GSTSubcontracting/src/Table/SubCompRcptHeader.Table.al +++ b/Apps/IN/INGST/app/GSTSubcontracting/src/Table/SubCompRcptHeader.Table.al @@ -267,16 +267,29 @@ table 18474 "Sub. Comp. Rcpt. Header" } trigger OnInsert() + var + NoSeries: Codeunit "No. Series"; +#if not CLEAN24 + NoSeriesManagement: Codeunit NoSeriesManagement; + IsHandled: Boolean; +#endif begin - "Purch&payableSetup".Get(); + PurchasesPayablesSetup.Get(); if "No." = '' then begin - "Purch&payableSetup".TestField("Posted SC Comp. Rcpt. Nos."); - NoSeriesMgt.InitSeries( - "Purch&payableSetup"."Posted SC Comp. Rcpt. Nos.", - xRec."No. Series", - "Posting Date", - "No.", - "No. Series"); + PurchasesPayablesSetup.TestField("Posted SC Comp. Rcpt. Nos."); +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(PurchasesPayablesSetup."Posted SC Comp. Rcpt. Nos.", xRec."No. Series", "Posting Date", "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := PurchasesPayablesSetup."Posted SC Comp. Rcpt. Nos."; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series", "Posting Date"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", PurchasesPayablesSetup."Posted SC Comp. Rcpt. Nos.", "Posting Date", "No."); + end; +#endif end; end; @@ -297,7 +310,6 @@ table 18474 "Sub. Comp. Rcpt. Header" var PostCode: Record "Post Code"; - "Purch&payableSetup": Record "Purchases & Payables Setup"; + PurchasesPayablesSetup: Record "Purchases & Payables Setup"; DimMgt: Codeunit DimensionManagement; - NoSeriesMgt: Codeunit NoSeriesManagement; } diff --git a/Apps/IN/INGST/test/GSTSales/src/GSTServiceTests.Codeunit.al b/Apps/IN/INGST/test/GSTSales/src/GSTServiceTests.Codeunit.al index 719dd95d16..4497645b0a 100644 --- a/Apps/IN/INGST/test/GSTSales/src/GSTServiceTests.Codeunit.al +++ b/Apps/IN/INGST/test/GSTSales/src/GSTServiceTests.Codeunit.al @@ -2121,21 +2121,31 @@ codeunit 18198 "GST Service Tests" ServiceContractHeader.Modify(true); end; - local procedure CreateServiceContractHeader( - var ServiceContractHeader: Record "Service Contract Header"; - ContractType: Option; - CustomerNo: Code[20]) + local procedure CreateServiceContractHeader(var ServiceContractHeader: Record "Service Contract Header"; ContractType: Option; CustomerNo: Code[20]) var ServiceContractAccountGroup: Record "Service Contract Account Group"; ServiceMgtSetup: Record "Service Mgt. Setup"; + NoSeries: Codeunit "No. Series"; +#if not CLEAN24 NoSeriesManagement: Codeunit NoSeriesManagement; + IsHandled: Boolean; +#endif begin ServiceContractHeader.Init(); ServiceMgtSetup.Get(); if ServiceContractHeader."Contract No." = '' then begin ServiceMgtSetup.TestField("Service Contract Nos."); - NoSeriesManagement.InitSeries(ServiceMgtSetup."Service Contract Nos.", ServiceContractHeader."No. Series", 0D, ServiceContractHeader. - "Contract No.", ServiceContractHeader."No. Series"); +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(ServiceMgtSetup."Service Contract Nos.", ServiceContractHeader."No. Series", 0D, ServiceContractHeader."Contract No.", ServiceContractHeader."No. Series", IsHandled); + if not IsHandled then begin +#endif + ServiceContractHeader."No. Series" := ServiceMgtSetup."Service Contract Nos."; + ServiceContractHeader."Contract No." := NoSeries.GetNextNo(ServiceContractHeader."No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries(ServiceContractHeader."No. Series", ServiceMgtSetup."Service Contract Nos.", 0D, ServiceContractHeader."Contract No."); + end; +#endif end; ServiceContractHeader."Starting Date" := WorkDate(); diff --git a/Apps/IN/INGST/test/GSTSubcontracting/src/GSTSubcontracting.Codeunit.al b/Apps/IN/INGST/test/GSTSubcontracting/src/GSTSubcontracting.Codeunit.al index ea3635753a..284670af80 100644 --- a/Apps/IN/INGST/test/GSTSubcontracting/src/GSTSubcontracting.Codeunit.al +++ b/Apps/IN/INGST/test/GSTSubcontracting/src/GSTSubcontracting.Codeunit.al @@ -879,6 +879,29 @@ codeunit 18479 "GST Subcontracting" VerifyItemLedgerEntryComponentTransfer(PurchaseLine); end; + [Test] + [HandlerFunctions('TaxRatePageHandler,DeliveryChallanSentMsgHandler,PostConfirmation')] + procedure SubconOrderToRegVendInterStateReceiveItemCheckOutstandingQtyBase() + var + ProductionOrder: Record "Production Order"; + PurchaseLine: Record "Purchase Line"; + GSTGroupType: Enum "GST Group Type"; + GSTVendorType: Enum "GST Vendor Type"; + OutstandingQtyBase: Decimal; + begin + // [SCENARIO] [498150] Check if the system on subcontracting order for Registered Vendor and after Send and Receipt from Vendor have Outstanding base quantity field showes 0 in subcontracting order + // [GIVEN] Setups created + CreateGSTSubconSetups(GSTVendorType::Registered, GSTGroupType::Goods, false); + + // [WHEN] Create Subcontracting Order from Released Purchase Order, Send Subcon Components, Receive Item + CreateSubcontractingOrderFromReleasedProdOrder(ProductionOrder, PurchaseLine); + DeliverSubconComponents(PurchaseLine, 0); + OutstandingQtyBase := ReceiptSubconItemForOutstandingQtyBase(PurchaseLine, false, false, false, WorkDate()); + + // [THEN] Purchase Line Outstanding Quantity Base Verfied for Zero value + Assert.Equal(OutstandingQtyBase, 0); + end; + local procedure CreateGSTSubconSetups( GSTVendorType: Enum "GST Vendor Type"; GSTGroupType: Enum "GST Group Type"; @@ -2118,6 +2141,46 @@ codeunit 18479 "GST Subcontracting" StorageBoolean.Set(WithDimensionLbl, false); end; + local procedure ReceiptSubconItemForOutstandingQtyBase(var PurchaseLine: Record "Purchase Line"; PartialReceipt: Boolean; RejectVE: Boolean; RejectCE: Boolean; PostingDate: Date): Decimal + var + SubConPost: Codeunit "Subcontracting Post"; + QtyToReceive: Decimal; + QtyRejectVE: Decimal; + QtyRejectCE: Decimal; + begin + PurchaseLine.FindFirst(); + PurchaseLine."Vendor Shipment No." := LibraryUtility.GenerateRandomCode(PurchaseLine.FieldNo("Vendor Shipment No."), Database::"Purchase Line"); + PurchaseLine.Validate("Posting Date", PostingDate); + + QtyToReceive := PurchaseLine.Quantity; + if PartialReceipt then + QtyToReceive := QtyToReceive div 2; + + if PartialReceipt and RejectVE then + QtyRejectVE := PurchaseLine.Quantity - QtyToReceive; + + if PartialReceipt and RejectCE then + QtyRejectCE := PurchaseLine.Quantity - QtyToReceive; + + PurchaseLine.Validate("Qty. to Receive", QtyToReceive); + if QtyRejectVE > 0 then + PurchaseLine.Validate("Qty. to Reject (V.E.)", QtyRejectVE); + + if QtyRejectCE > 0 then + PurchaseLine.Validate("Qty. to Reject (C.E.)", QtyRejectCE); + + PurchaseLine.Modify(); + + // Apply Delivery Challan + ApplyDeliveryChallan(PurchaseLine); + + // Post Receipt + PurchaseLine.SubConReceive := true; + SubConPost.PostPurchOrder(PurchaseLine); + + exit(PurchaseLine."Outstanding Qty. (Base)"); + end; + [PageHandler] procedure TaxRatePageHandler(var TaxRates: TestPage "Tax Rates") begin diff --git a/Apps/IN/INGateEntry/app/src/codeunit/GateEntrySubscribers.Codeunit.al b/Apps/IN/INGateEntry/app/src/codeunit/GateEntrySubscribers.Codeunit.al index 2ca8e3faad..5ab574e13b 100644 --- a/Apps/IN/INGateEntry/app/src/codeunit/GateEntrySubscribers.Codeunit.al +++ b/Apps/IN/INGateEntry/app/src/codeunit/GateEntrySubscribers.Codeunit.al @@ -19,7 +19,6 @@ codeunit 18604 "Gate Entry Subscribers" { var InventorySetup: Record "Inventory Setup"; - NoSeriesMgt: Codeunit NoSeriesManagement; [EventSubscriber(ObjectType::Codeunit, Codeunit::"Purch.-Post", 'OnAfterPurchRcptHeaderInsert', '', false, false)] local procedure AttachGateEntryOnReceiptInsert( @@ -77,6 +76,12 @@ codeunit 18604 "Gate Entry Subscribers" [EventSubscriber(ObjectType::Table, Database::"Gate Entry Header", 'OnAfterInsertEvent', '', false, false)] local procedure UpdateNoSeriesOnAfterInsertEvent(var Rec: Record "Gate Entry Header") + var + NoSeries: Codeunit "No. Series"; +#if not CLEAN24 + NoSeriesManagement: Codeunit NoSeriesManagement; + IsHandled: Boolean; +#endif begin Rec."Document Date" := WorkDate(); Rec."Document Time" := Time; @@ -89,12 +94,33 @@ codeunit 18604 "Gate Entry Subscribers" Rec."Entry Type"::Inward: if Rec."No." = '' then begin InventorySetup.TestField("Inward Gate Entry Nos."); - NoSeriesMgt.InitSeries(InventorySetup."Inward Gate Entry Nos.", Rec."No. Series", Rec."Posting Date", Rec."No.", Rec."No. Series"); +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(InventorySetup."Inward Gate Entry Nos.", Rec."No. Series", Rec."Posting Date", Rec."No.", Rec."No. Series", IsHandled); + if not IsHandled then begin +#endif + if not NoSeries.AreRelated(InventorySetup."Inward Gate Entry Nos.", Rec."No. Series") then + Rec."No. Series" := InventorySetup."Inward Gate Entry Nos."; + Rec."No." := NoSeries.GetNextNo(Rec."No. Series", Rec."Posting Date"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries(Rec."No. Series", InventorySetup."Inward Gate Entry Nos.", Rec."Posting Date", Rec."No."); + end; +#endif end; Rec."Entry Type"::Outward: if Rec."No." = '' then begin InventorySetup.TestField("Outward Gate Entry Nos."); - NoSeriesMgt.InitSeries(InventorySetup."Outward Gate Entry Nos.", Rec."No. Series", Rec."Posting Date", Rec."No.", Rec."No. Series"); +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(InventorySetup."Outward Gate Entry Nos.", Rec."No. Series", Rec."Posting Date", Rec."No.", Rec."No. Series", IsHandled); + if not IsHandled then begin +#endif + Rec."No. Series" := InventorySetup."Outward Gate Entry Nos."; + Rec."No." := NoSeries.GetNextNo(Rec."No. Series", Rec."Posting Date"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries(Rec."No. Series", InventorySetup."Outward Gate Entry Nos.", Rec."Posting Date", Rec."No."); + end; +#endif end; end; end; diff --git a/Apps/IN/INGateEntry/app/src/table/GateEntryHeader.Table.al b/Apps/IN/INGateEntry/app/src/table/GateEntryHeader.Table.al index d375b90cab..be2c28564a 100644 --- a/Apps/IN/INGateEntry/app/src/table/GateEntryHeader.Table.al +++ b/Apps/IN/INGateEntry/app/src/table/GateEntryHeader.Table.al @@ -153,6 +153,10 @@ table 18603 "Gate Entry Header" } trigger OnInsert() +#if not CLEAN24 + var + IsHandled: Boolean; +#endif begin "Document Date" := WorkDate(); "Document Time" := Time; @@ -166,12 +170,36 @@ table 18603 "Gate Entry Header" "Entry Type"::Inward: if "No." = '' then begin InventorySetup.TestField("Inward Gate Entry Nos."); - NoSeriesManagement.InitSeries(InventorySetup."Inward Gate Entry Nos.", xRec."No. Series", "Posting Date", "No.", "No. Series"); +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(InventorySetup."Inward Gate Entry Nos.", xRec."No. Series", "Posting Date", "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := InventorySetup."Inward Gate Entry Nos."; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series", "Posting Date"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", InventorySetup."Inward Gate Entry Nos.", "Posting Date", "No."); + end; +#endif end; "Entry Type"::Outward: if "No." = '' then begin InventorySetup.TestField("Outward Gate Entry Nos."); - NoSeriesManagement.InitSeries(InventorySetup."Outward Gate Entry Nos.", xRec."No. Series", "Posting Date", "No.", "No. Series"); +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(InventorySetup."Outward Gate Entry Nos.", xRec."No. Series", "Posting Date", "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := InventorySetup."Outward Gate Entry Nos."; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series", "Posting Date"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", InventorySetup."Outward Gate Entry Nos.", "Posting Date", "No."); + end; +#endif end; end; end; @@ -193,6 +221,7 @@ table 18603 "Gate Entry Header" var InventorySetup: Record "Inventory Setup"; NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; procedure AssistEdit(OldGateEntryHeader: Record "Gate Entry Header"): Boolean begin diff --git a/Apps/IN/INTCS/app/TCSReturnAndSettlement/src/TCS-Journal/page/TCSAdjustmentJournal.page.al b/Apps/IN/INTCS/app/TCSReturnAndSettlement/src/TCS-Journal/page/TCSAdjustmentJournal.page.al index a3e58f6fca..4840504b16 100644 --- a/Apps/IN/INTCS/app/TCSReturnAndSettlement/src/TCS-Journal/page/TCSAdjustmentJournal.page.al +++ b/Apps/IN/INTCS/app/TCSReturnAndSettlement/src/TCS-Journal/page/TCSAdjustmentJournal.page.al @@ -359,13 +359,11 @@ page 18870 "TCS Adjustment Journal" local procedure GetDocumentNo(): Code[20] var TCSJournalBatch: Record "TCS Journal Batch"; - NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; begin TCSJournalBatch.Get(Rec."Journal Template Name", Rec."Journal Batch Name"); - if TCSJournalBatch."No. Series" <> '' then begin - Clear(NoSeriesManagement); - exit(NoSeriesManagement.TryGetNextNo(TCSJournalBatch."No. Series", Rec."Posting Date")); - end; + if TCSJournalBatch."No. Series" <> '' then + exit(NoSeries.PeekNextNo(TCSJournalBatch."No. Series", Rec."Posting Date")); end; local procedure GetTCSJnlLineNo(): Integer diff --git a/Apps/IN/INTDS/app/TDSReturnAndSettlement/src/TDS-Journal/TDSAdjustmentJournal.Page.al b/Apps/IN/INTDS/app/TDSReturnAndSettlement/src/TDS-Journal/TDSAdjustmentJournal.Page.al index 1444eb991e..dda740ff92 100644 --- a/Apps/IN/INTDS/app/TDSReturnAndSettlement/src/TDS-Journal/TDSAdjustmentJournal.Page.al +++ b/Apps/IN/INTDS/app/TDSReturnAndSettlement/src/TDS-Journal/TDSAdjustmentJournal.Page.al @@ -377,15 +377,13 @@ page 18747 "TDS Adjustment Journal" GetTDSEntry: Record "TDS Entry"; TDSJournalLine: Record "TDS Journal Line"; TDSJournalBatch: Record "TDS Journal Batch"; - NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; DocumentNo: Code[20]; LineNo: Integer; begin TDSJournalBatch.Get(Rec."Journal Template Name", Rec."Journal Batch Name"); - if TDSJournalBatch."No. Series" <> '' then begin - Clear(NoSeriesManagement); - DocumentNo := NoSeriesManagement.TryGetNextNo(TDSJournalBatch."No. Series", Rec."Posting Date"); - end; + if TDSJournalBatch."No. Series" <> '' then + DocumentNo := NoSeries.PeekNextNo(TDSJournalBatch."No. Series", Rec."Posting Date"); TDSJournalLine.LockTable(); TDSJournalLine.SetRange("Journal Template Name", Rec."Journal Template Name"); TDSJournalLine.SetRange("Journal Batch Name", Rec."Journal Batch Name"); diff --git a/Apps/IN/INTaxBase/app/src/page/BankPaymentVoucher.page.al b/Apps/IN/INTaxBase/app/src/page/BankPaymentVoucher.page.al index a21e75ddcc..0589c77c31 100644 --- a/Apps/IN/INTaxBase/app/src/page/BankPaymentVoucher.page.al +++ b/Apps/IN/INTaxBase/app/src/page/BankPaymentVoucher.page.al @@ -1946,7 +1946,7 @@ page 18550 "Bank Payment Voucher" var GenJournalLine: Record "Gen. Journal Line"; GenJnlBatch: Record "Gen. Journal Batch"; - NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeriesBatch: Codeunit "No. Series - Batch"; LastDocNo: Code[20]; begin if Count() = 0 then @@ -1958,9 +1958,9 @@ page 18550 "Bank Payment Voucher" GenJournalLine.SetRange("Journal Batch Name", "Journal Batch Name"); if GenJournalLine.FindLast() then begin LastDocNo := GenJournalLine."Document No."; - IncrementDocumentNo(GenJnlBatch, LastDocNo); + LastDocNo := NoSeriesBatch.SimulateGetNextNo(GenJnlBatch."No. Series", GenJournalLine."Posting Date", LastDocNo) end else - LastDocNo := NoSeriesMgt.TryGetNextNo(GenJnlBatch."No. Series", "Posting Date"); + LastDocNo := NoSeriesBatch.PeekNextNo(GenJnlBatch."No. Series", "Posting Date"); CurrentDocNo := LastDocNo; SetDocumentNumberFilter(CurrentDocNo); diff --git a/Apps/IN/INTaxBase/app/src/page/BankReceiptVoucher.page.al b/Apps/IN/INTaxBase/app/src/page/BankReceiptVoucher.page.al index 1ba52accf9..b95ccb69d8 100644 --- a/Apps/IN/INTaxBase/app/src/page/BankReceiptVoucher.page.al +++ b/Apps/IN/INTaxBase/app/src/page/BankReceiptVoucher.page.al @@ -1898,7 +1898,7 @@ page 18553 "Bank Receipt Voucher" var GenJournalLine: Record "Gen. Journal Line"; GenJnlBatch: Record "Gen. Journal Batch"; - NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeriesBatch: Codeunit "No. Series - Batch"; LastDocNo: Code[20]; begin if Count() = 0 then @@ -1910,9 +1910,9 @@ page 18553 "Bank Receipt Voucher" GenJournalLine.SetRange("Journal Batch Name", "Journal Batch Name"); if GenJournalLine.FindLast() then begin LastDocNo := GenJournalLine."Document No."; - IncrementDocumentNo(GenJnlBatch, LastDocNo); + LastDocNo := NoSeriesBatch.SimulateGetNextNo(GenJnlBatch."No. Series", GenJournalLine."Posting Date", LastDocNo) end else - LastDocNo := NoSeriesMgt.TryGetNextNo(GenJnlBatch."No. Series", "Posting Date"); + LastDocNo := NoSeriesBatch.PeekNextNo(GenJnlBatch."No. Series", "Posting Date"); CurrentDocNo := LastDocNo; SetDocumentNumberFilter(CurrentDocNo); diff --git a/Apps/IN/INTaxBase/app/src/page/CashPaymentVoucher.page.al b/Apps/IN/INTaxBase/app/src/page/CashPaymentVoucher.page.al index d65c841609..6c1203e645 100644 --- a/Apps/IN/INTaxBase/app/src/page/CashPaymentVoucher.page.al +++ b/Apps/IN/INTaxBase/app/src/page/CashPaymentVoucher.page.al @@ -1957,7 +1957,7 @@ page 18554 "Cash Payment Voucher" var GenJournalLine: Record "Gen. Journal Line"; GenJnlBatch: Record "Gen. Journal Batch"; - NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeriesBatch: Codeunit "No. Series - Batch"; LastDocNo: Code[20]; begin if Count() = 0 then @@ -1969,9 +1969,9 @@ page 18554 "Cash Payment Voucher" GenJournalLine.SetRange("Journal Batch Name", "Journal Batch Name"); if GenJournalLine.FindLast() then begin LastDocNo := GenJournalLine."Document No."; - IncrementDocumentNo(GenJnlBatch, LastDocNo); + LastDocNo := NoSeriesBatch.SimulateGetNextNo(GenJnlBatch."No. Series", GenJournalLine."Posting Date", LastDocNo) end else - LastDocNo := NoSeriesMgt.TryGetNextNo(GenJnlBatch."No. Series", "Posting Date"); + LastDocNo := NoSeriesBatch.PeekNextNo(GenJnlBatch."No. Series", "Posting Date"); CurrentDocNo := LastDocNo; SetDocumentNumberFilter(CurrentDocNo); diff --git a/Apps/IN/INTaxBase/app/src/page/CashReceiptVoucher.page.al b/Apps/IN/INTaxBase/app/src/page/CashReceiptVoucher.page.al index b22f8eaca6..4d27e47362 100644 --- a/Apps/IN/INTaxBase/app/src/page/CashReceiptVoucher.page.al +++ b/Apps/IN/INTaxBase/app/src/page/CashReceiptVoucher.page.al @@ -1902,7 +1902,7 @@ page 18555 "Cash Receipt Voucher" var GenJournalLine: Record "Gen. Journal Line"; GenJnlBatch: Record "Gen. Journal Batch"; - NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeriesBatch: Codeunit "No. Series - Batch"; LastDocNo: Code[20]; begin if Count() = 0 then @@ -1914,9 +1914,9 @@ page 18555 "Cash Receipt Voucher" GenJournalLine.SetRange("Journal Batch Name", "Journal Batch Name"); if GenJournalLine.FindLast() then begin LastDocNo := GenJournalLine."Document No."; - IncrementDocumentNo(GenJnlBatch, LastDocNo); + LastDocNo := NoSeriesBatch.SimulateGetNextNo(GenJnlBatch."No. Series", GenJournalLine."Posting Date", LastDocNo) end else - LastDocNo := NoSeriesMgt.TryGetNextNo(GenJnlBatch."No. Series", "Posting Date"); + LastDocNo := NoSeriesBatch.PeekNextNo(GenJnlBatch."No. Series", "Posting Date"); CurrentDocNo := LastDocNo; SetDocumentNumberFilter(CurrentDocNo); diff --git a/Apps/IN/INTaxBase/app/src/page/ContraVoucher.page.al b/Apps/IN/INTaxBase/app/src/page/ContraVoucher.page.al index 6528615ddb..f591d4a1ff 100644 --- a/Apps/IN/INTaxBase/app/src/page/ContraVoucher.page.al +++ b/Apps/IN/INTaxBase/app/src/page/ContraVoucher.page.al @@ -1902,7 +1902,7 @@ page 18556 "Contra Voucher" var GenJournalLine: Record "Gen. Journal Line"; GenJnlBatch: Record "Gen. Journal Batch"; - NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeriesBatch: Codeunit "No. Series - Batch"; LastDocNo: Code[20]; begin if Count() = 0 then @@ -1914,9 +1914,9 @@ page 18556 "Contra Voucher" GenJournalLine.SetRange("Journal Batch Name", "Journal Batch Name"); if GenJournalLine.FindLast() then begin LastDocNo := GenJournalLine."Document No."; - IncrementDocumentNo(GenJnlBatch, LastDocNo); + LastDocNo := NoSeriesBatch.SimulateGetNextNo(GenJnlBatch."No. Series", GenJournalLine."Posting Date", LastDocNo) end else - LastDocNo := NoSeriesMgt.TryGetNextNo(GenJnlBatch."No. Series", "Posting Date"); + LastDocNo := NoSeriesBatch.PeekNextNo(GenJnlBatch."No. Series", "Posting Date"); CurrentDocNo := LastDocNo; SetDocumentNumberFilter(CurrentDocNo); diff --git a/Apps/IN/INTaxBase/app/src/page/JournalVoucher.page.al b/Apps/IN/INTaxBase/app/src/page/JournalVoucher.page.al index fd027b69ee..970e03bd7e 100644 --- a/Apps/IN/INTaxBase/app/src/page/JournalVoucher.page.al +++ b/Apps/IN/INTaxBase/app/src/page/JournalVoucher.page.al @@ -1900,7 +1900,7 @@ page 18557 "Journal Voucher" var GenJournalLine: Record "Gen. Journal Line"; GenJnlBatch: Record "Gen. Journal Batch"; - NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeriesBatch: Codeunit "No. Series - Batch"; LastDocNo: Code[20]; begin if Count() = 0 then @@ -1912,9 +1912,9 @@ page 18557 "Journal Voucher" GenJournalLine.SetRange("Journal Batch Name", "Journal Batch Name"); if GenJournalLine.FindLast() then begin LastDocNo := GenJournalLine."Document No."; - IncrementDocumentNo(GenJnlBatch, LastDocNo); + LastDocNo := NoSeriesBatch.SimulateGetNextNo(GenJnlBatch."No. Series", GenJournalLine."Posting Date", LastDocNo) end else - LastDocNo := NoSeriesMgt.TryGetNextNo(GenJnlBatch."No. Series", "Posting Date"); + LastDocNo := NoSeriesBatch.PeekNextNo(GenJnlBatch."No. Series", "Posting Date"); CurrentDocNo := LastDocNo; SetDocumentNumberFilter(CurrentDocNo); diff --git a/Apps/IT/IntrastatIT/test/src/IntrastatITTest.Codeunit.al b/Apps/IT/IntrastatIT/test/src/IntrastatITTest.Codeunit.al index 5cb9703e6a..9350c8b487 100644 --- a/Apps/IT/IntrastatIT/test/src/IntrastatITTest.Codeunit.al +++ b/Apps/IT/IntrastatIT/test/src/IntrastatITTest.Codeunit.al @@ -2276,17 +2276,16 @@ codeunit 139511 "Intrastat IT Test" local procedure ResetNoSeries() var - NoSeriesLinePurchase: Record "No. Series Line Purchase"; - NoSeriesLineSales: Record "No. Series Line Sales"; + NoSeriesLine: Record "No. Series Line"; VATBusinessPostingGroup: Record "VAT Business Posting Group"; begin if VATBusinessPostingGroup.FindSet() then repeat - NoSeriesLineSales.SetRange("Series Code", VATBusinessPostingGroup."Default Sales Operation Type"); - NoSeriesLineSales.ModifyAll("Last Date Used", 0D); + NoSeriesLine.SetRange("Series Code", VATBusinessPostingGroup."Default Sales Operation Type"); + NoSeriesLine.ModifyAll("Last Date Used", 0D); - NoSeriesLinePurchase.SetRange("Series Code", VATBusinessPostingGroup."Default Purch. Operation Type"); - NoSeriesLinePurchase.ModifyAll("Last Date Used", 0D); + NoSeriesLine.SetRange("Series Code", VATBusinessPostingGroup."Default Purch. Operation Type"); + NoSeriesLine.ModifyAll("Last Date Used", 0D); until VATBusinessPostingGroup.Next() = 0; end; diff --git a/Apps/IT/ServiceDeclarationIT/test/src/ServDeclITTests.Codeunit.al b/Apps/IT/ServiceDeclarationIT/test/src/ServDeclITTests.Codeunit.al index 389d746aee..4b3dd2cc35 100644 --- a/Apps/IT/ServiceDeclarationIT/test/src/ServDeclITTests.Codeunit.al +++ b/Apps/IT/ServiceDeclarationIT/test/src/ServDeclITTests.Codeunit.al @@ -545,17 +545,18 @@ codeunit 144112 "Serv. Decl. IT Tests" local procedure ResetNoSeries() var - NoSeriesLinePurchase: Record "No. Series Line Purchase"; - NoSeriesLineSales: Record "No. Series Line Sales"; + NoSeriesLine: Record "No. Series Line"; VATBusinessPostingGroup: Record "VAT Business Posting Group"; begin if VATBusinessPostingGroup.FindSet() then repeat - NoSeriesLineSales.SetRange("Series Code", VATBusinessPostingGroup."Default Sales Operation Type"); - NoSeriesLineSales.ModifyAll("Last Date Used", 0D); + NoSeriesLine.SetRange("No. Series Type", NoSeriesLine."No. Series Type"::Sales); + NoSeriesLine.SetRange("Series Code", VATBusinessPostingGroup."Default Sales Operation Type"); + NoSeriesLine.ModifyAll("Last Date Used", 0D); - NoSeriesLinePurchase.SetRange("Series Code", VATBusinessPostingGroup."Default Purch. Operation Type"); - NoSeriesLinePurchase.ModifyAll("Last Date Used", 0D); + NoSeriesLine.SetRange("No. Series Type", NoSeriesLine."No. Series Type"::Purchase); + NoSeriesLine.SetRange("Series Code", VATBusinessPostingGroup."Default Purch. Operation Type"); + NoSeriesLine.ModifyAll("Last Date Used", 0D); until VATBusinessPostingGroup.Next() = 0; end; diff --git a/Apps/NA/EnvestnetYodleeBankFeeds/app/app.json b/Apps/NA/EnvestnetYodleeBankFeeds/app/app.json index d4c53c8998..836d1683e9 100644 --- a/Apps/NA/EnvestnetYodleeBankFeeds/app/app.json +++ b/Apps/NA/EnvestnetYodleeBankFeeds/app/app.json @@ -12,7 +12,6 @@ "contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?LinkId=733362", "logo": "ExtensionLogo.png", "dependencies": [ - ], "screenshots": [ diff --git a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeAccessConsent.Page.al b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeAccessConsent.Page.al index 8102aa633e..59fc2c5a20 100644 --- a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeAccessConsent.Page.al +++ b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeAccessConsent.Page.al @@ -1,5 +1,7 @@ namespace Microsoft.Bank.StatementImport.Yodlee; +using System.Integration; + page 1458 "MS - Yodlee Access Consent" { Caption = ' '; @@ -15,7 +17,7 @@ page 1458 "MS - Yodlee Access Consent" ShowCaption = false; InstructionalText = 'NOTE: You are accessing a third-party website and service. You should review the third-parties terms and privacy policy before acquiring or using its website or service.'; } - usercontrol(WebPageViewer; "Microsoft.Dynamics.Nav.Client.WebPageViewer") + usercontrol(WebPageViewer; WebPageViewer) { ApplicationArea = Basic, Suite; diff --git a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeAccountLinking.Page.al b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeAccountLinking.Page.al index 095614eeb3..0f47e3911d 100644 --- a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeAccountLinking.Page.al +++ b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeAccountLinking.Page.al @@ -1,5 +1,7 @@ namespace Microsoft.Bank.StatementImport.Yodlee; +using System.Integration; + page 1451 "MS - Yodlee Account Linking" { Caption = ' '; @@ -21,7 +23,7 @@ page 1451 "MS - Yodlee Account Linking" ShowCaption = false; InstructionalText = 'NOTE: You are accessing a third-party''s website and service. You should review the third-party''s terms and privacy policy before acquiring or using its website or service.'; } - usercontrol(WebPageViewer; "Microsoft.Dynamics.Nav.Client.WebPageViewer") + usercontrol(WebPageViewer; WebPageViewer) { ApplicationArea = Basic, Suite; diff --git a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeEditAccount.Page.al b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeEditAccount.Page.al index 45ad433015..877c3fc303 100644 --- a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeEditAccount.Page.al +++ b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeEditAccount.Page.al @@ -1,5 +1,7 @@ namespace Microsoft.Bank.StatementImport.Yodlee; +using System.Integration; + page 1460 "MS - Yodlee Edit Account" { Caption = ' '; @@ -15,7 +17,7 @@ page 1460 "MS - Yodlee Edit Account" ShowCaption = false; InstructionalText = 'NOTE: You are accessing a third-party website and service. You should review the third-parties terms and privacy policy before acquiring or using its website or service.'; } - usercontrol(WebPageViewer; "Microsoft.Dynamics.Nav.Client.WebPageViewer") + usercontrol(WebPageViewer; WebPageViewer) { ApplicationArea = Basic, Suite; diff --git a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeGetLatestStmt.Page.al b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeGetLatestStmt.Page.al index f14cac5668..32f50db125 100644 --- a/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeGetLatestStmt.Page.al +++ b/Apps/NA/EnvestnetYodleeBankFeeds/app/src/MSYodleeGetLatestStmt.Page.al @@ -1,5 +1,7 @@ namespace Microsoft.Bank.StatementImport.Yodlee; +using System.Integration; + page 1452 "MS - Yodlee Get Latest Stmt" { Caption = ' '; @@ -15,7 +17,7 @@ page 1452 "MS - Yodlee Get Latest Stmt" ShowCaption = false; InstructionalText = 'NOTE: You are accessing a third-party website and service. You should review the third-parties terms and privacy policy before acquiring or using its website or service.'; } - usercontrol(WebPageViewer; "Microsoft.Dynamics.Nav.Client.WebPageViewer") + usercontrol(WebPageViewer; WebPageViewer) { ApplicationArea = Basic, Suite; diff --git a/Apps/RU/CDTracking/test/src/CDTransfer.Codeunit.al b/Apps/RU/CDTracking/test/src/CDTransfer.Codeunit.al index ec8b5e90ce..f53fb16c3a 100644 --- a/Apps/RU/CDTracking/test/src/CDTransfer.Codeunit.al +++ b/Apps/RU/CDTracking/test/src/CDTransfer.Codeunit.al @@ -21,7 +21,7 @@ codeunit 147103 "CD Transfer" isInitialized: Boolean; WrongInventoryErr: Label 'Wrong inventory.'; SerTxt: Label 'SER'; - QtyToHandleMessageErr: Label 'Qty. to Handle (Base) in the item tracking assigned to the document line for item %1 is currently 3. It must be 4.\\Check the assignment for serial number %2, lot number .'; + QtyToHandleMessageErr: Label 'Qty. to Handle (Base) in the item tracking assigned to the document line for item %1 is currently 3. It must be 4.\\Check the assignment for serial number %2, lot number %3, package number %4.', Comment = '%1 - Item No., %2 - Serial No., %3 - Lot No., %4 - Package No.'; PackageInfoNotExistErr: Label 'The Package No. Information does not exist.'; TearDownErr: Label 'Error in TearDown'; TemporaryPackageNoIsNotEqualErr: Label 'Temporary CD Number must be equal to ''No'' in Package No. Information'; @@ -267,7 +267,7 @@ codeunit 147103 "CD Transfer" end; asserterror PostTransferDocument(TransferHeader); - Assert.ExpectedError(StrSubstNo(QtyToHandleMessageErr, Item."No.", 'SER01')); + Assert.ExpectedError(StrSubstNo(QtyToHandleMessageErr, Item."No.", 'SER01', '', PackageNo)); TearDown(); end; diff --git a/Apps/US/IRS1096/app/src/Processing/IRS1096FormHeader.Table.al b/Apps/US/IRS1096/app/src/Processing/IRS1096FormHeader.Table.al index 966ae2c549..650819c86b 100644 --- a/Apps/US/IRS1096/app/src/Processing/IRS1096FormHeader.Table.al +++ b/Apps/US/IRS1096/app/src/Processing/IRS1096FormHeader.Table.al @@ -22,7 +22,7 @@ table 10018 "IRS 1096 Form Header" begin if "No." <> xRec."No." then begin PurchPayablesSetup.GetRecordOnce(); - NoSeriesMgt.TestManual(PurchPayablesSetup."IRS 1096 Form No. Series"); + NoSeries.TestManual(PurchPayablesSetup."IRS 1096 Form No. Series"); "No. Series" := ''; end; end; @@ -120,7 +120,8 @@ table 10018 "IRS 1096 Form Header" var PurchPayablesSetup: Record "Purchases & Payables Setup"; - NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; trigger OnInsert() var @@ -133,7 +134,19 @@ table 10018 "IRS 1096 Form Header" if "No." = '' then begin GetPurchSetupWithIRS1096NoSeries(); - NoSeriesMgt.InitSeries(PurchPayablesSetup."IRS 1096 Form No. Series", xRec."No. Series", 0D, "No.", "No. Series"); +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(PurchPayablesSetup."IRS 1096 Form No. Series", xRec."No. Series", 0D, "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := PurchPayablesSetup."IRS 1096 Form No. Series"; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", PurchPayablesSetup."IRS 1096 Form No. Series", 0D, "No."); + end; +#endif end; end; @@ -164,8 +177,8 @@ table 10018 "IRS 1096 Form Header" IRS1096FormHeader := Rec; GetPurchSetupWithIRS1096NoSeries(); - if NoSeriesMgt.SelectSeries(PurchPayablesSetup."IRS 1096 Form No. Series", xIRS1096FormHeader."No. Series", IRS1096FormHeader."No. Series") then begin - NoSeriesMgt.SetSeries(IRS1096FormHeader."No."); + if NoSeriesManagement.SelectSeries(PurchPayablesSetup."IRS 1096 Form No. Series", xIRS1096FormHeader."No. Series", IRS1096FormHeader."No. Series") then begin + NoSeriesManagement.SetSeries(IRS1096FormHeader."No."); Rec := IRS1096FormHeader; exit(true); end; diff --git a/Apps/W1/BankAccRecWithAI/app/src/BankRecAIMatchingImpl.Codeunit.al b/Apps/W1/BankAccRecWithAI/app/src/BankRecAIMatchingImpl.Codeunit.al index 16843a0cdf..f5204a5384 100644 --- a/Apps/W1/BankAccRecWithAI/app/src/BankRecAIMatchingImpl.Codeunit.al +++ b/Apps/W1/BankAccRecWithAI/app/src/BankRecAIMatchingImpl.Codeunit.al @@ -311,7 +311,7 @@ codeunit 7250 "Bank Rec. AI Matching Impl." FirstOpenParenthesisPos := StrPos(CompletionAnswerTxt, '('); FirstClosedParenthesisPos := StrPos(CompletionAnswerTxt, ')'); - while FirstOpenParenthesisPos > 0 do begin + while (FirstOpenParenthesisPos > 0) and (FirstClosedParenthesisPos > FirstOpenParenthesisPos) do begin MatchedLedgerEntryNoTxt := ''; MatchedStatementLineNoTxt := ''; MatchTripleTxt := CopyStr(CompletionAnswerTxt, FirstOpenParenthesisPos + 1, FirstClosedParenthesisPos - FirstOpenParenthesisPos - 1); diff --git a/Apps/W1/BankDeposits/app/src/codeunits/SetupBankDepositReports.Codeunit.al b/Apps/W1/BankDeposits/app/src/codeunits/SetupBankDepositReports.Codeunit.al index e0099cd434..821742e227 100644 --- a/Apps/W1/BankDeposits/app/src/codeunits/SetupBankDepositReports.Codeunit.al +++ b/Apps/W1/BankDeposits/app/src/codeunits/SetupBankDepositReports.Codeunit.al @@ -120,17 +120,17 @@ codeunit 1697 "Setup Bank Deposit Reports" procedure InitBaseSeries(var SeriesCode: Code[20]; "Code": Code[20]; Description: Text[100]; "Starting No.": Code[20]; "Ending No.": Code[20]; "Last Number Used": Code[20]; "Warning at No.": Code[20]; "Increment-by No.": Integer) begin - InitBaseSeries(SeriesCode, "Code", Description, "Starting No.", "Ending No.", "Last Number Used", "Warning at No.", "Increment-by No.", false); + InitBaseSeries(SeriesCode, "Code", Description, "Starting No.", "Ending No.", "Last Number Used", "Warning at No.", "Increment-by No.", Enum::"No. Series Implementation"::Normal); end; - internal procedure InitBaseSeries(var SeriesCode: Code[20]; "Code": Code[20]; Description: Text[100]; "Starting No.": Code[20]; "Ending No.": Code[20]; "Last Number Used": Code[20]; "Warning at No.": Code[20]; "Increment-by No.": Integer; "Allow Gaps": Boolean) + internal procedure InitBaseSeries(var SeriesCode: Code[20]; "Code": Code[20]; Description: Text[100]; "Starting No.": Code[20]; "Ending No.": Code[20]; "Last Number Used": Code[20]; "Warning at No.": Code[20]; "Increment-by No.": Integer; Implementation: Enum "No. Series Implementation") begin InsertSeries( SeriesCode, Code, Description, - "Starting No.", "Ending No.", "Last Number Used", "Warning at No.", "Increment-by No.", true, "Allow Gaps"); + "Starting No.", "Ending No.", "Last Number Used", "Warning at No.", "Increment-by No.", true, Implementation); end; - local procedure InsertSeries(var SeriesCode: Code[20]; "Code": Code[20]; Description: Text[100]; "Starting No.": Code[20]; "Ending No.": Code[20]; "Last Number Used": Code[20]; "Warning No.": Code[20]; "Increment-by No.": Integer; "Manual Nos.": Boolean; "Allow Gaps": Boolean) + local procedure InsertSeries(var SeriesCode: Code[20]; "Code": Code[20]; Description: Text[100]; "Starting No.": Code[20]; "Ending No.": Code[20]; "Last Number Used": Code[20]; "Warning No.": Code[20]; "Increment-by No.": Integer; "Manual Nos.": Boolean; Implementation: Enum "No. Series Implementation") var NoSeries: Record "No. Series"; NoSeriesLine: Record "No. Series Line"; @@ -153,7 +153,7 @@ codeunit 1697 "Setup Bank Deposit Reports" if "Warning No." <> '' then NoSeriesLine.Validate("Warning No.", "Warning No."); NoSeriesLine.Validate("Increment-by No.", "Increment-by No."); - NoSeriesLine.Validate("Allow Gaps in Nos.", "Allow Gaps"); + NoSeriesLine.Validate(Implementation, Implementation); NoSeriesLine."Line No." := 10000; NoSeriesLine.Insert(true); diff --git a/Apps/W1/BankDeposits/app/src/tables/BankDepositHeader.Table.al b/Apps/W1/BankDeposits/app/src/tables/BankDepositHeader.Table.al index 8a81e1ceea..34e62eeb26 100644 --- a/Apps/W1/BankDeposits/app/src/tables/BankDepositHeader.Table.al +++ b/Apps/W1/BankDeposits/app/src/tables/BankDepositHeader.Table.al @@ -27,7 +27,7 @@ table 1690 "Bank Deposit Header" begin if "No." <> xRec."No." then begin SalesReceivablesSetup.Get(); - NoSeriesManagement.TestManual(SalesReceivablesSetup."Bank Deposit Nos."); + NoSeries.TestManual(SalesReceivablesSetup."Bank Deposit Nos."); "No. Series" := ''; end; end; @@ -324,6 +324,7 @@ table 1690 "Bank Deposit Header" BankDepositHeader: Record "Bank Deposit Header"; GenJournalBatch: Record "Gen. Journal Batch"; NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; DimensionManagement: Codeunit DimensionManagement; GenJnlManagement: Codeunit GenJnlManagement; PostingDescriptionTxt: Label 'Deposit %1 %2', Comment = '%1 - the caption of field No.; %2 - the value of field No.'; @@ -335,6 +336,7 @@ table 1690 "Bank Deposit Header" local procedure InitInsert() var + NoSeriesCode: Code[20]; IsHandled: Boolean; begin IsHandled := false; @@ -342,7 +344,19 @@ table 1690 "Bank Deposit Header" if not IsHandled then if "No." = '' then begin TestNoSeries(); - NoSeriesManagement.InitSeries(GetNoSeriesCode(), xRec."No. Series", "Posting Date", "No.", "No. Series"); + NoSeriesCode := GetNoSeriesCode(); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(NoSeriesCode, xRec."No. Series", "Posting Date", "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := NoSeriesCode; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series", "Posting Date"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", NoSeriesCode, "Posting Date", "No."); + end; +#endif end; OnInitInsertOnBeforeInitRecord(xRec); diff --git a/Apps/W1/ConnectivityApps/app/src/Codeunits/ConnectivityAppDefinitions.Codeunit.al b/Apps/W1/ConnectivityApps/app/src/Codeunits/ConnectivityAppDefinitions.Codeunit.al index 032fbe4ecf..37ac7617d3 100644 --- a/Apps/W1/ConnectivityApps/app/src/Codeunits/ConnectivityAppDefinitions.Codeunit.al +++ b/Apps/W1/ConnectivityApps/app/src/Codeunits/ConnectivityAppDefinitions.Codeunit.al @@ -314,7 +314,7 @@ codeunit 20352 "Connectivity App Definitions" AppId := '52508c8d-fb2b-49da-9657-f49859fd43cc'; AppName := 'Sumango AutoBank'; AppPublisher := 'Sumango AS'; - AppDescription := 'AutoBank manage payments, recivables, refunds and reconciliation in all currencies directly from Business Central. Streamlines, simplifies and expands bank functionality without leaving your Business Central environment. Sumango AutoBank support banks in Norway, Sweden, Denmark, Finland, Germany, Portugal, United Kingdom and United States. Visit www.sumango.no for more information.'; + AppDescription := 'AutoBank manage payments, receivables, refunds and reconciliation in all currencies directly from Business Central. Streamlines, simplifies and expands bank functionality without leaving your Business Central environment. Sumango AutoBank support banks in Norway, Sweden, Denmark, Finland, Germany, Portugal, United Kingdom and United States. Visit www.sumango.no for more information.'; AppProviderSupportURL := 'https://oseberg.atlassian.net/wiki/spaces/Autobank/pages/2342191252/Integrated+banks'; AppSourceUrl := 'https://appsource.microsoft.com/nb-NO/product/dynamics-365-business-central/PUBID.sumango_as%7CAID.sumango_autobank%7CPAPPID.52508c8d-fb2b-49da-9657-f49859fd43cc'; AppApprovedFor := 'NO,SE'; @@ -504,4 +504,4 @@ codeunit 20352 "Connectivity App Definitions" TempApprovedConnectivityAppCountryOrRegion.DeleteAll(); TempWorksOnConnectivityAppLocalization.DeleteAll(); end; -} +} \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Common/1.Setup Data/CreateCommonNoSeries.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Common/1.Setup Data/CreateCommonNoSeries.Codeunit.al index 007834ffa3..7914d2f440 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Common/1.Setup Data/CreateCommonNoSeries.Codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Common/1.Setup Data/CreateCommonNoSeries.Codeunit.al @@ -17,19 +17,18 @@ codeunit 5128 "Create Common No Series" SalesReceivablesSetup.Get(); if SalesReceivablesSetup."Customer Nos." = '' then - ContosoNoSeries.InsertNoSeries(Customer(), CustomerLbl, 'C10', 'C99990', '', '', 1, true, true); + ContosoNoSeries.InsertNoSeries(Customer(), CustomerLbl, 'C10', 'C99990', '', '', 1, Enum::"No. Series Implementation"::Sequence, true); if SalesReceivablesSetup."Order Nos." = '' then - ContosoNoSeries.InsertNoSeries(SalesOrder(), SalesOrderLbl, '101001', '102999', '', '', 1, false, false); - + ContosoNoSeries.InsertNoSeries(SalesOrder(), SalesOrderLbl, '101001', '102999', '', '', 1, Enum::"No. Series Implementation"::Normal, false); InventorySetup.Get(); if InventorySetup."Item Nos." = '' then - ContosoNoSeries.InsertNoSeries(Item(), ItemsLbl, '1000', '9999', '', '', 1, true, true); + ContosoNoSeries.InsertNoSeries(Item(), ItemsLbl, '1000', '9999', '', '', 1, Enum::"No. Series Implementation"::Sequence, true); PurchasePayablesSetup.Get(); if PurchasePayablesSetup."Order Nos." = '' then - ContosoNoSeries.InsertNoSeries(PurchaseOrder(), PurchaseOrderLbl, '106001', '107999', '', '', 1, false, false); + ContosoNoSeries.InsertNoSeries(PurchaseOrder(), PurchaseOrderLbl, '106001', '107999', '', '', 1, Enum::"No. Series Implementation"::Normal, false); end; var diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Common/1.Setup Data/CreateCommonUnitOfMeasure.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Common/1.Setup Data/CreateCommonUnitOfMeasure.Codeunit.al index fe017af574..78cf70e0c0 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Common/1.Setup Data/CreateCommonUnitOfMeasure.Codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Common/1.Setup Data/CreateCommonUnitOfMeasure.Codeunit.al @@ -21,6 +21,8 @@ codeunit 5130 "Create Common Unit Of Measure" ContosoUnitOfMeasure.InsertUnitOfMeasure(Bag(), BagLbl, 'BAG'); ContosoUnitOfMeasure.InsertUnitOfMeasure(Gram(), GramTok, 'GRM'); ContosoUnitOfMeasure.InsertUnitOfMeasure(L(), LiterTok, 'LTR'); + ContosoUnitOfMeasure.InsertUnitOfMeasure(Ton(), TonneLbl, 'TN'); + ContosoUnitOfMeasure.InsertUnitOfMeasure(KWH(), KWHLbl, 'KWH'); end; var @@ -52,6 +54,10 @@ codeunit 5130 "Create Common Unit Of Measure" GramTok: Label 'Gram', MaxLength = 10; LTok: Label 'L', MaxLength = 10; LiterTok: Label 'Liter', MaxLength = 10; + TTok: Label 'T', MaxLength = 10; + TonneLbl: Label 'Tonne', MaxLength = 10; + KWHTok: Label 'KWH', MaxLength = 10; + KWHLbl: Label 'KW Hour', MaxLength = 10; procedure Bag(): Code[10] begin @@ -123,4 +129,13 @@ codeunit 5130 "Create Common Unit Of Measure" exit(LTok); end; + procedure Ton(): Code[10] + begin + exit(TTok); + end; + + procedure KWH(): Code[10] + begin + exit(KWHTok); + end; } \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/FixedAsset/1.Setup Data/CreateFANoSeries.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/FixedAsset/1.Setup Data/CreateFANoSeries.Codeunit.al index 9401841a1a..0ce3c03e5d 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/FixedAsset/1.Setup Data/CreateFANoSeries.Codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/FixedAsset/1.Setup Data/CreateFANoSeries.Codeunit.al @@ -7,11 +7,11 @@ codeunit 4780 "Create FA No Series" var ContosoNoSeries: Codeunit "Contoso No Series"; begin - ContosoNoSeries.InsertNoSeries(FixedAsset(), FixedAssetLbl, 'FA000010', 'FA999990', '', '', 1, false, true); - ContosoNoSeries.InsertNoSeries(Insurance(), InsuranceLbl, 'INS000010', 'INS999990', '', '', 1, false, true); - ContosoNoSeries.InsertNoSeries(FixedAssetGLJournal(), FixedAssetGLJournalLbl, 'F00010', 'F01000', '', '', 1, false, true); - ContosoNoSeries.InsertNoSeries(RecurringFixedAssetGLJournal(), RecurringFixedAssetGLJournalLbl, 'RF00010', 'RF01000', '', '', 1, false, true); - ContosoNoSeries.InsertNoSeries(InsuranceJournal(), InsuranceJournalLbl, 'N00010', 'N01000', '', '', 1, false, true); + ContosoNoSeries.InsertNoSeries(FixedAsset(), FixedAssetLbl, 'FA000010', 'FA999990', '', '', 1, enum::"No. Series Implementation"::Normal, true); + ContosoNoSeries.InsertNoSeries(Insurance(), InsuranceLbl, 'INS000010', 'INS999990', '', '', 1, enum::"No. Series Implementation"::Normal, true); + ContosoNoSeries.InsertNoSeries(FixedAssetGLJournal(), FixedAssetGLJournalLbl, 'F00010', 'F01000', '', '', 1, enum::"No. Series Implementation"::Normal, true); + ContosoNoSeries.InsertNoSeries(RecurringFixedAssetGLJournal(), RecurringFixedAssetGLJournalLbl, 'RF00010', 'RF01000', '', '', 1, enum::"No. Series Implementation"::Normal, true); + ContosoNoSeries.InsertNoSeries(InsuranceJournal(), InsuranceJournalLbl, 'N00010', 'N01000', '', '', 1, enum::"No. Series Implementation"::Normal, true); end; var diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/HumanResources/1. SetupData/CreateEmployeeNoSeries.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/HumanResources/1. SetupData/CreateEmployeeNoSeries.Codeunit.al index 7c97b313fd..292a72510b 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/HumanResources/1. SetupData/CreateEmployeeNoSeries.Codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/HumanResources/1. SetupData/CreateEmployeeNoSeries.Codeunit.al @@ -7,7 +7,7 @@ codeunit 5177 "Create Employee No Series" var ContosoNoSeries: Codeunit "Contoso No Series"; begin - ContosoNoSeries.InsertNoSeries(Employee(), EmployeeNoSeriesDescriptionLbl, 'E0010', 'E9990', '', '', 10, true, true); + ContosoNoSeries.InsertNoSeries(Employee(), EmployeeNoSeriesDescriptionLbl, 'E0010', 'E9990', '', '', 10, Enum::"No. Series Implementation"::Sequence, true); end; procedure Employee(): Code[20] diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Jobs/1.Setup Data/CreateJobNoSeries.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Jobs/1.Setup Data/CreateJobNoSeries.Codeunit.al index e673f89e06..b781965910 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Jobs/1.Setup Data/CreateJobNoSeries.Codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Jobs/1.Setup Data/CreateJobNoSeries.Codeunit.al @@ -7,7 +7,7 @@ codeunit 5195 "Create Job No Series" var ContosoNoSeries: Codeunit "Contoso No Series"; begin - ContosoNoSeries.InsertNoSeries(Job(), JobNosDescTok, 'PR00010', 'PR99999', '', '', 10, true, true); + ContosoNoSeries.InsertNoSeries(Job(), JobNosDescTok, 'PR00010', 'PR99999', '', '', 10, Enum::"No. Series Implementation"::Sequence, true); end; var diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Manufacturing/1.Setup data/CreateMfgNoSeries.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Manufacturing/1.Setup data/CreateMfgNoSeries.Codeunit.al index 1bb0da94a9..77535ff9f2 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Manufacturing/1.Setup data/CreateMfgNoSeries.Codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Manufacturing/1.Setup data/CreateMfgNoSeries.Codeunit.al @@ -7,16 +7,16 @@ codeunit 4784 "Create Mfg No Series" var ContosoNoSeries: Codeunit "Contoso No Series"; begin - ContosoNoSeries.InsertNoSeries(WorkCenter(), WorkCentersLbl, 'W10', 'W99990', '', '', 10, true, true); - ContosoNoSeries.InsertNoSeries(ProductionBOM(), ProductionBOMsLbl, 'P10', 'P99990', '', '', 10, true, true); - ContosoNoSeries.InsertNoSeries(MachineCenter(), MachineCentersLbl, 'M10', 'M99990', '', '', 10, true, true); - ContosoNoSeries.InsertNoSeries(Routing(), RoutingLbl, 'R10', 'R99990', '', '', 10, true, true); + ContosoNoSeries.InsertNoSeries(WorkCenter(), WorkCentersLbl, 'W10', 'W99990', '', '', 10, Enum::"No. Series Implementation"::Sequence, true); + ContosoNoSeries.InsertNoSeries(ProductionBOM(), ProductionBOMsLbl, 'P10', 'P99990', '', '', 10, Enum::"No. Series Implementation"::Sequence, true); + ContosoNoSeries.InsertNoSeries(MachineCenter(), MachineCentersLbl, 'M10', 'M99990', '', '', 10, Enum::"No. Series Implementation"::Sequence, true); + ContosoNoSeries.InsertNoSeries(Routing(), RoutingLbl, 'R10', 'R99990', '', '', 10, Enum::"No. Series Implementation"::Sequence, true); - ContosoNoSeries.InsertNoSeries(SimulatedOrder(), SimulatedOrdersLbl, '1001', '2999', '2995', '', 1, false, false); + ContosoNoSeries.InsertNoSeries(SimulatedOrder(), SimulatedOrdersLbl, '1001', '2999', '2995', '', 1, Enum::"No. Series Implementation"::Normal, false); - ContosoNoSeries.InsertNoSeries(PlannedOrder(), PlannedOrdersLbl, '101001', '102999', '102995', '', 1, false, false); - ContosoNoSeries.InsertNoSeries(FirmPlannedOrder(), FirmPlannedOrdersLbl, '101001', '102999', '102995', '', 1, false, false); - ContosoNoSeries.InsertNoSeries(ReleasedOrderCode(), ReleasedOrdersLbl, '101001', '102999', '102995', '', 1, false, false); + ContosoNoSeries.InsertNoSeries(PlannedOrder(), PlannedOrdersLbl, '101001', '102999', '102995', '', 1, Enum::"No. Series Implementation"::Normal, false); + ContosoNoSeries.InsertNoSeries(FirmPlannedOrder(), FirmPlannedOrdersLbl, '101001', '102999', '102995', '', 1, Enum::"No. Series Implementation"::Normal, false); + ContosoNoSeries.InsertNoSeries(ReleasedOrderCode(), ReleasedOrdersLbl, '101001', '102999', '102995', '', 1, Enum::"No. Series Implementation"::Normal, false); end; var diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Service/1.Setup Data/CreateSvcNoSeries.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Service/1.Setup Data/CreateSvcNoSeries.Codeunit.al index 5db9c9a18b..aff55df58d 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Service/1.Setup Data/CreateSvcNoSeries.Codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Service/1.Setup Data/CreateSvcNoSeries.Codeunit.al @@ -7,14 +7,14 @@ codeunit 5101 "Create Svc No Series" var ContosoNoSeries: Codeunit "Contoso No Series"; begin - ContosoNoSeries.InsertNoSeries(ServiceItem(), SeriesServiceItemNosDescTok, 'SV000001', 'SV999999', '', '', 1, true, true); - ContosoNoSeries.InsertNoSeries(ServiceOrder(), SeriesServiceOrderNosDescTok, 'SVO000001', 'SVO999999', '', '', 1, true, true); - ContosoNoSeries.InsertNoSeries(ServiceInvoice(), SeriesServiceInvoiceNosDescTok, 'SVI000001', 'SVI999999', '', '', 1, true, true); - ContosoNoSeries.InsertNoSeries(PostedServiceInvoice(), SeriesPostedServiceInvoiceNosDescTok, 'PSVI000001', 'PSVI999999', '', '', 1, true, true); - ContosoNoSeries.InsertNoSeries(PostedServiceShipment(), SeriesPostedServiceShipmentNosDescTok, 'PSVS000001', 'PSVS999999', '', '', 1, true, true); - ContosoNoSeries.InsertNoSeries(ServiceContract(), SeriesServiceContractNosDescTok, 'SVC000001', 'SVC999999', '', '', 1, true, true); - ContosoNoSeries.InsertNoSeries(ContractInvoice(), SeriesContractInvoiceNosDescTok, 'SVCI000001', 'SVCI999999', '', '', 1, true, true); - ContosoNoSeries.InsertNoSeries(ContractTemplate(), SeriesContractTemplateLbl, 'TEMPL0001', 'TEMPL9999', '', '', 1, true, true); + ContosoNoSeries.InsertNoSeries(ServiceItem(), SeriesServiceItemNosDescTok, 'SV000001', 'SV999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, true); + ContosoNoSeries.InsertNoSeries(ServiceOrder(), SeriesServiceOrderNosDescTok, 'SVO000001', 'SVO999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, true); + ContosoNoSeries.InsertNoSeries(ServiceInvoice(), SeriesServiceInvoiceNosDescTok, 'SVI000001', 'SVI999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, true); + ContosoNoSeries.InsertNoSeries(PostedServiceInvoice(), SeriesPostedServiceInvoiceNosDescTok, 'PSVI000001', 'PSVI999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, true); + ContosoNoSeries.InsertNoSeries(PostedServiceShipment(), SeriesPostedServiceShipmentNosDescTok, 'PSVS000001', 'PSVS999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, true); + ContosoNoSeries.InsertNoSeries(ServiceContract(), SeriesServiceContractNosDescTok, 'SVC000001', 'SVC999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, true); + ContosoNoSeries.InsertNoSeries(ContractInvoice(), SeriesContractInvoiceNosDescTok, 'SVCI000001', 'SVCI999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, true); + ContosoNoSeries.InsertNoSeries(ContractTemplate(), SeriesContractTemplateLbl, 'TEMPL0001', 'TEMPL9999', '', '', 1, Enum::"No. Series Implementation"::Sequence, true); end; var diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainJnlSetup.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainJnlSetup.Codeunit.al new file mode 100644 index 0000000000..2407882544 --- /dev/null +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainJnlSetup.Codeunit.al @@ -0,0 +1,109 @@ +codeunit 5217 "Create Sustain. Jnl. Setup" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + begin + CreateJournalTemplate(); + CreateJournalBatch(); + end; + + local procedure CreateJournalTemplate() + var + ContosoSustainability: Codeunit "Contoso Sustainability"; + begin + ContosoSustainability.InsertSustainabilityJournalTemplate(GeneralTemplate(), GeneralTemplateDescriptionLbl, false); + ContosoSustainability.InsertSustainabilityJournalTemplate(RecurringTemplate(), RecurringTemplateDescriptionLbl, true); + end; + + local procedure CreateJournalBatch() + var + ContosoSustainability: Codeunit "Contoso Sustainability"; + SustainabilitySetup: Codeunit "Create Sustainability Setup"; + SustainabilityNoSeries: Codeunit "Create Sustain. No Series"; + begin + ContosoSustainability.InsertSustainabilityJournalBatch(GeneralTemplate(), DefaultBatch(), DefaultBatchDescriptionLbl, SustainabilityNoSeries.JournalNoSeries(), Enum::"Emission Scope"::" ", SustainabilitySetup.SustainabilitySourceCode()); + ContosoSustainability.InsertSustainabilityJournalBatch(RecurringTemplate(), RecurringDefaultBatch(), RecurringDefaultBatchDescriptionLbl, SustainabilityNoSeries.RecurringJournalNoSeries(), Enum::"Emission Scope"::" ", SustainabilitySetup.SustainabilitySourceCode()); + + ContosoSustainability.InsertSustainabilityJournalBatch(GeneralTemplate(), Scope1Batch(), Scope1BatchDescriptionLbl, SustainabilityNoSeries.JournalNoSeries(), Enum::"Emission Scope"::"Scope 1", SustainabilitySetup.SustainabilitySourceCode()); + ContosoSustainability.InsertSustainabilityJournalBatch(GeneralTemplate(), Scope2Batch(), Scope2BatchDescriptionLbl, SustainabilityNoSeries.JournalNoSeries(), Enum::"Emission Scope"::"Scope 2", SustainabilitySetup.SustainabilitySourceCode()); + ContosoSustainability.InsertSustainabilityJournalBatch(GeneralTemplate(), Scope3Batch(), Scope3BatchDescriptionLbl, SustainabilityNoSeries.JournalNoSeries(), Enum::"Emission Scope"::"Scope 3", SustainabilitySetup.SustainabilitySourceCode()); + + ContosoSustainability.InsertSustainabilityJournalBatch(RecurringTemplate(), Scope1RecurringBatch(), Scope1RecurringBatchDescriptionLbl, SustainabilityNoSeries.RecurringJournalNoSeries(), Enum::"Emission Scope"::"Scope 1", SustainabilitySetup.SustainabilitySourceCode()); + ContosoSustainability.InsertSustainabilityJournalBatch(RecurringTemplate(), Scope2RecurringBatch(), Scope2RecurringBatchDescriptionLbl, SustainabilityNoSeries.RecurringJournalNoSeries(), Enum::"Emission Scope"::"Scope 2", SustainabilitySetup.SustainabilitySourceCode()); + ContosoSustainability.InsertSustainabilityJournalBatch(RecurringTemplate(), Scope3RecurringBatch(), Scope3RecurringBatchDescriptionLbl, SustainabilityNoSeries.RecurringJournalNoSeries(), Enum::"Emission Scope"::"Scope 3", SustainabilitySetup.SustainabilitySourceCode()); + end; + + procedure GeneralTemplate(): Code[10] + begin + exit(GeneralTemplateTok); + end; + + procedure RecurringTemplate(): Code[10] + begin + exit(RecurringTemplateTok); + end; + + procedure DefaultBatch(): Code[10] + begin + exit(DefaultBatchTok); + end; + + procedure RecurringDefaultBatch(): Code[10] + begin + exit(RecurringDefaultBatchTok); + end; + + procedure Scope1Batch(): Code[10] + begin + exit(Scope1BatchTok); + end; + + procedure Scope2Batch(): Code[10] + begin + exit(Scope2BatchTok); + end; + + procedure Scope3Batch(): Code[10] + begin + exit(Scope3BatchTok); + end; + + procedure Scope1RecurringBatch(): Code[10] + begin + exit(Scope1RecurringBatchTok); + end; + + procedure Scope2RecurringBatch(): Code[10] + begin + exit(Scope2RecurringBatchTok); + end; + + procedure Scope3RecurringBatch(): Code[10] + begin + exit(Scope3RecurringBatchTok); + end; + + var + GeneralTemplateTok: Label 'GENERAL', MaxLength = 10; + GeneralTemplateDescriptionLbl: Label 'General Emission', MaxLength = 80; + RecurringTemplateTok: Label 'RECURRING', MaxLength = 10; + RecurringTemplateDescriptionLbl: Label 'Recurring Emission', MaxLength = 80; + DefaultBatchTok: Label 'DEFAULT', MaxLength = 10; + DefaultBatchDescriptionLbl: Label 'Default Sustainability Journal Batch', MaxLength = 100; + RecurringDefaultBatchTok: Label 'DEFAULT-RC', MaxLength = 10; + RecurringDefaultBatchDescriptionLbl: Label 'Default Recurring Sustainability Journal Batch', MaxLength = 100; + Scope1BatchTok: Label 'SCOPE1', MaxLength = 10; + Scope1BatchDescriptionLbl: Label 'Scope 1 Sustainability Journal Batch', MaxLength = 100; + Scope2BatchTok: Label 'SCOPE2', MaxLength = 10; + Scope2BatchDescriptionLbl: Label 'Scope 2 Sustainability Journal Batch', MaxLength = 100; + Scope3BatchTok: Label 'SCOPE3', MaxLength = 10; + Scope3BatchDescriptionLbl: Label 'Scope 3 Sustainability Journal Batch', MaxLength = 100; + Scope1RecurringBatchTok: Label 'SCOPE1-RC', MaxLength = 10; + Scope1RecurringBatchDescriptionLbl: Label 'Scope 1 Recurring Sustainability Journal Batch', MaxLength = 100; + Scope2RecurringBatchTok: Label 'SCOPE2-RC', MaxLength = 10; + Scope2RecurringBatchDescriptionLbl: Label 'Scope 2 Recurring Sustainability Journal Batch', MaxLength = 100; + Scope3RecurringBatchTok: Label 'SCOPE3-RC', MaxLength = 10; + Scope3RecurringBatchDescriptionLbl: Label 'Scope 3 Recurring Sustainability Journal Batch', MaxLength = 100; +} \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainNoSeries.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainNoSeries.Codeunit.al new file mode 100644 index 0000000000..eddcbb107d --- /dev/null +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainNoSeries.Codeunit.al @@ -0,0 +1,33 @@ +codeunit 5220 "Create Sustain. No Series" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoNoSeries: Codeunit "Contoso No Series"; + begin + ContosoNoSeries.InsertNoSeries(JournalNoSeries(), SustainabilityJournalNoSeriesDescriptionTok, JournalStartingNoLbl, JournalEndingNoLbl, '', '', 1, Enum::"No. Series Implementation"::Normal, true); + ContosoNoSeries.InsertNoSeries(RecurringJournalNoSeries(), RecurringJournalNoSeriesDescriptionTok, RecurringJournalStartingNoLbl, RecurringJournalEndingNoLbl, '', '', 1, Enum::"No. Series Implementation"::Normal, true); + end; + + procedure JournalNoSeries(): Code[20] + begin + exit(SustainabilityJournalNoSeriesTok); + end; + + procedure RecurringJournalNoSeries(): Code[20] + begin + exit(RecurringJournalNoSeriesTok); + end; + + var + SustainabilityJournalNoSeriesTok: Label 'SUSTAIN-JNL', MaxLength = 20; + SustainabilityJournalNoSeriesDescriptionTok: Label 'Sustainability Journals', MaxLength = 100; + JournalStartingNoLbl: Label 'SJ00001', MaxLength = 20; + JournalEndingNoLbl: Label 'SJ99999', MaxLength = 20; + RecurringJournalNoSeriesTok: Label 'SUSTAIN-RCJNL', MaxLength = 20; + RecurringJournalNoSeriesDescriptionTok: Label 'Recurring Sustainability Journals', MaxLength = 100; + RecurringJournalStartingNoLbl: Label 'SRJ00001', MaxLength = 20; + RecurringJournalEndingNoLbl: Label 'SRJ99999', MaxLength = 20; +} \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainSubcategory.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainSubcategory.Codeunit.al new file mode 100644 index 0000000000..285f574310 --- /dev/null +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainSubcategory.Codeunit.al @@ -0,0 +1,389 @@ +codeunit 5214 "Create Sustain. Subcategory" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + SustainabilityCategory: Codeunit "Create Sustainability Category"; + ContosoSustainability: Codeunit "Contoso Sustainability"; + begin + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.CompanyCar(), CompanyCarMedium(), CompanyCarMediumLbl, 0.128, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.CompanyCar(), CompanyCarLarge(), CompanyCarLargeLbl, 0.149, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.CompanyCar(), CompanyCarPremium(), CompanyCarPremiumLbl, 0.177, 0, 0, false); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Fugitive(), Refrigerator(), RefrigeratorLbl, 0.24388, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Fugitive(), AirConditionerSmall(), AirConditionerSmallLbl, 0.8452, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Fugitive(), AirConditionerLarge(), AirConditionerLargeLbl, 1.3217, 0, 0, false); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Hotel(), Hotel3Star(), Hotel3StarLbl, 15.6, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Hotel(), Hotel4Star(), Hotel4StarLbl, 24.22, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Hotel(), Hotel4StarPlus(), Hotel4StarPlusLbl, 40.21, 0, 0, false); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.MobileDistance(), UrbanTruck(), UrbanTruckLbl, 0.307, 0.00039, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.MobileDistance(), LongHaulTruck(), LongHaulTruckLbl, 0.057, 0.00007, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.MobileDistance(), Bus(), BusLbl, 1.3, 0.00166, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.MobileDistance(), Rail(), RailLbl, 0.035, 0.00004, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.MobileDistance(), AirContinentalEconomy(), AirContinentalEconomyLbl, 0.30038, 0.00037, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.MobileDistance(), AirContinentalBusiness(), AirContinentalBusinessLbl, 0.44639, 0.00055, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.MobileDistance(), AirIntercontinentalEconomy(), AirIntercontinentalEconomyLbl, 0.21872, 0.00027, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.MobileDistance(), AirIntercontinentalPremiumEconomy(), AirIntercontinentalPremiumEconomyLbl, 0.32808, 0.0004, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.MobileDistance(), AirIntercontinentalBusiness(), AirIntercontinentalBusinessLbl, 0.88856, 0.00109, 0, false); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.MobileFuel(), Tractor(), TractorLbl, 2.6, 0.0032, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.MobileFuel(), Forklift(), ForkliftLbl, 2.64, 0.0032, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.MobileFuel(), Backhoe(), BackhoeLbl, 2.6391, 0.0032, 0, false); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.PurchaseGoodsGL(), PurchasedGoodsPlastic(), PurchasedGoodsPlasticLbl, 0.3, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.PurchaseGoodsGL(), PurchasedGoodsAluminum(), PurchasedGoodsAluminumLbl, 0.5, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.PurchaseGoodsGL(), PurchasedGoodsSteel(), PurchasedGoodsSteelLbl, 0.2, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.PurchaseGoodsGL(), PurchasedGoodsGlass(), PurchasedGoodsGlassLbl, 0.4, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.PurchaseGoodsGL(), PurchasedServices(), PurchasedServicesLbl, 0.15, 0, 0, false); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.RentalCar(), RentalCarMedium(), RentalCarMediumLbl, 0.197, 0, 0, false); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.SoldProductEnd(), SoldProductEnd(), SoldProductEndLbl, 0.25, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.SoldProductProcess(), SoldProductProcess(), SoldProductProcessLbl, 0.28, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.SoldProductUse(), SoldProductUse(), SoldProductUseLbl, 0.31, 0, 0, false); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Stationary(), Boiler(), BoilerLbl, 7.21616, 0.136, 0.0136, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Stationary(), HeaterSmall(), HeaterSmallLbl, 3.99675, 0.4499, 0.06544, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Stationary(), HeaterMedium(), HeaterMediumLbl, 7.9935, 0.8998, 0.13088, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Stationary(), HeaterLarge(), HeaterLargeLbl, 11.903, 1.3497, 0.19632, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Stationary(), Thermal(), ThermalLbl, 0.17704, 0.01088, 0.00021, true); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.ExternalTransportDistance(), ExternalTransportDistance(), ExternalTransportDistanceLbl, 1.425, 0.00036, 0.00014, false); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.InternalTransportDistance(), InternalTransportDistance(), InternalTransportDistanceLbl, 0.986, 0.00031, 0.00011, false); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.UtilityElectric(), ElectricityNuclear(), ElectricityNuclearLbl, 0.087, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.UtilityElectric(), ElectricityCoal(), ElectricityCoalLbl, 0.3834, 0, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.UtilityElectric(), ElectricityGreen(), ElectricityGreenLbl, 0, 0, 0, true); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.UtilityHeat(), Heat(), HeatLbl, 296.85635, 0, 0, false); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.UtilitySteam(), SteamSupplier(), SteamSupplierLbl, 2488, 0, 0, false); + + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Waste(), WasteLandFillOrganic(), WasteLandfillOrganicLbl, 0.47681, 0.05002, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Waste(), WasteLandFillPlastic(), WasteLandfillPlasticLbl, 1.80842, 0.07126, 0, false); + ContosoSustainability.InsertAccountSubcategory(SustainabilityCategory.Waste(), WasteRecycled(), WasteRecycledLbl, 0.28906, 0.02209, 0, false); + end; + + procedure CompanyCarMedium(): Code[20] + begin + exit(CompanyCarMediumTok); + end; + + procedure CompanyCarLarge(): Code[20] + begin + exit(CompanyCarLargeTok); + end; + + procedure CompanyCarPremium(): Code[20] + begin + exit(CompanyCarPremiumTok); + end; + + procedure Refrigerator(): Code[20] + begin + exit(RefrigeratorTok); + end; + + procedure AirConditionerSmall(): Code[20] + begin + exit(AirConditionerSmallTok); + end; + + procedure AirConditionerLarge(): Code[20] + begin + exit(AirConditionerLargeTok); + end; + + procedure Hotel3Star(): Code[20] + begin + exit(Hotel3StarTok); + end; + + procedure Hotel4Star(): Code[20] + begin + exit(Hotel4StarTok); + end; + + procedure Hotel4StarPlus(): Code[20] + begin + exit(Hotel4StarPlusTok); + end; + + procedure UrbanTruck(): Code[20] + begin + exit(UrbanTruckTok); + end; + + procedure LongHaulTruck(): Code[20] + begin + exit(LongHaulTruckTok); + end; + + procedure Bus(): Code[20] + begin + exit(BusTok); + end; + + procedure Rail(): Code[20] + begin + exit(RailTok); + end; + + procedure AirContinentalEconomy(): Code[20] + begin + exit(AirContinentalEconomyTok); + end; + + procedure AirContinentalBusiness(): Code[20] + begin + exit(AirContinentalBusinessTok); + end; + + procedure AirIntercontinentalEconomy(): Code[20] + begin + exit(AirIntercontinentalEconomyTok); + end; + + procedure AirIntercontinentalPremiumEconomy(): Code[20] + begin + exit(AirIntercontinentalPremiumEconomyTok); + end; + + procedure AirIntercontinentalBusiness(): Code[20] + begin + exit(AirIntercontinentalBusinessTok); + end; + + procedure Tractor(): Code[20] + begin + exit(TractorTok); + end; + + procedure Forklift(): Code[20] + begin + exit(ForkliftTok); + end; + + procedure Backhoe(): Code[20] + begin + exit(BackhoeTok); + end; + + procedure PurchasedGoodsPlastic(): Code[20] + begin + exit(PurchasedGoodsPlasticTok); + end; + + procedure PurchasedGoodsAluminum(): Code[20] + begin + exit(PurchasedGoodsAluminumTok); + end; + + procedure PurchasedGoodsSteel(): Code[20] + begin + exit(PurchasedGoodsSteelTok); + end; + + procedure PurchasedGoodsGlass(): Code[20] + begin + exit(PurchasedGoodsGlassTok); + end; + + procedure PurchasedServices(): Code[20] + begin + exit(PurchasedServicesTok); + end; + + procedure RentalCarMedium(): Code[20] + begin + exit(RentalCarMediumTok); + end; + + procedure SoldProductEnd(): Code[20] + begin + exit(SoldProductEndTok); + end; + + procedure SoldProductProcess(): Code[20] + begin + exit(SoldProductProcessTok); + end; + + procedure SoldProductUse(): Code[20] + begin + exit(SoldProductUseTok); + end; + + procedure Boiler(): Code[20] + begin + exit(BoilerTok); + end; + + procedure HeaterSmall(): Code[20] + begin + exit(HeaterSmallTok); + end; + + procedure HeaterMedium(): Code[20] + begin + exit(HeaterMediumTok); + end; + + procedure HeaterLarge(): Code[20] + begin + exit(HeaterLargeTok); + end; + + procedure Thermal(): Code[20] + begin + exit(ThermalTok); + end; + + procedure ExternalTransportDistance(): Code[20] + begin + exit(ExternalTransportDistanceTok); + end; + + procedure InternalTransportDistance(): Code[20] + begin + exit(InternalTransportDistanceTok); + end; + + procedure ElectricityNuclear(): Code[20] + begin + exit(ElectricityNuclearTok); + end; + + procedure ElectricityCoal(): Code[20] + begin + exit(ElectricityCoalTok); + end; + + procedure ElectricityGreen(): Code[20] + begin + exit(ElectricityGreenTok); + end; + + procedure Heat(): Code[20] + begin + exit(HeatTok); + end; + + procedure SteamSupplier(): Code[20] + begin + exit(SteamSupplierTok); + end; + + + procedure WasteLandFillOrganic(): Code[20] + begin + exit(WasteLandfillOrganicTok); + end; + + procedure WasteLandFillPlastic(): Code[20] + begin + exit(WasteLandfillPlasticTok); + end; + + procedure WasteRecycled(): Code[20] + begin + exit(WasteRecycledTok); + end; + + var + CompanyCarMediumTok: Label 'COMPCAR-M', MaxLength = 20; + CompanyCarMediumLbl: Label 'Company Car - Medium', MaxLength = 100; + CompanyCarLargeTok: Label 'COMPCAR-L', MaxLength = 20; + CompanyCarLargeLbl: Label 'Company Car - Large', MaxLength = 100; + CompanyCarPremiumTok: Label 'COMPCAR-P', MaxLength = 20; + CompanyCarPremiumLbl: Label 'Company Car - Premium', MaxLength = 100; + RefrigeratorTok: Label 'REFRIG', MaxLength = 20; + RefrigeratorLbl: Label 'Refrigerators', MaxLength = 100; + AirConditionerSmallTok: Label 'AIRCS', MaxLength = 20; + AirConditionerSmallLbl: Label 'Airconditioner 24000BTU/Day', MaxLength = 100; + AirConditionerLargeTok: Label 'AIRCL', MaxLength = 20; + AirConditionerLargeLbl: Label 'Airconditioner 36000BTU/Day', MaxLength = 100; + Hotel3StarTok: Label 'HOTEL3STAR', MaxLength = 20; + Hotel3StarLbl: Label 'Hotel Stay 3 stars/Day', MaxLength = 100; + Hotel4StarTok: Label 'HOTEL4STAR', MaxLength = 20; + Hotel4StarLbl: Label 'Hotel Stay 4 stars/Day', MaxLength = 100; + Hotel4StarPlusTok: Label 'HOTEL4STAR+', MaxLength = 20; + Hotel4StarPlusLbl: Label 'Hotel Stay 4 stars Suite/Day', MaxLength = 100; + UrbanTruckTok: Label 'TRUCK-U', MaxLength = 20; + UrbanTruckLbl: Label 'Truck Urban /KM/T', MaxLength = 100; + LongHaulTruckTok: Label 'TRUCK-LH', MaxLength = 20; + LongHaulTruckLbl: Label 'Truck Long-haul trailer /KM/T', MaxLength = 100; + BusTok: Label 'BUS', MaxLength = 20; + BusLbl: Label 'Buses', MaxLength = 100; + RailTok: Label 'RAIL', MaxLength = 20; + RailLbl: Label 'Rail', MaxLength = 100; + AirContinentalEconomyTok: Label 'AIR-CONT-EC', MaxLength = 20; + AirContinentalEconomyLbl: Label 'Air Continental - Economy Class /KM', MaxLength = 100; + AirContinentalBusinessTok: Label 'AIR-CONT-BUS', MaxLength = 20; + AirContinentalBusinessLbl: Label 'Air Continental - Business Class /KM', MaxLength = 100; + AirIntercontinentalEconomyTok: Label 'AIR-INT-EC', MaxLength = 20; + AirIntercontinentalEconomyLbl: Label 'Air Intercontinental - Economy Class /KM', MaxLength = 100; + AirIntercontinentalPremiumEconomyTok: Label 'AIR-INT-PREM', MaxLength = 20; + AirIntercontinentalPremiumEconomyLbl: Label 'Air Intercontinental - Premium Economy /KM', MaxLength = 100; + AirIntercontinentalBusinessTok: Label 'AIR-INT-BUS', MaxLength = 20; + AirIntercontinentalBusinessLbl: Label 'Air Intercontinental - Business Class /KM', MaxLength = 100; + TractorTok: Label 'TRACTOR', MaxLength = 20; + TractorLbl: Label 'Tractors /L', MaxLength = 100; + ForkliftTok: Label 'FORKLIFT', MaxLength = 20; + ForkliftLbl: Label 'Forklifts /L', MaxLength = 100; + BackhoeTok: Label 'BACKHOE', MaxLength = 20; + BackhoeLbl: Label 'Backhoes /L', MaxLength = 100; + PurchasedGoodsPlasticTok: Label 'PURCHGDS-PL', MaxLength = 20; + PurchasedGoodsPlasticLbl: Label 'Purchased Goods - Plastic', MaxLength = 100; + PurchasedGoodsAluminumTok: Label 'PURCHGDS-AL', MaxLength = 20; + PurchasedGoodsAluminumLbl: Label 'Purchased Goods - Aluminum', MaxLength = 100; + PurchasedGoodsSteelTok: Label 'PURCHGDS-ST', MaxLength = 20; + PurchasedGoodsSteelLbl: Label 'Purchased Goods - Steel', MaxLength = 100; + PurchasedGoodsGlassTok: Label 'PURCHGDS-GL', MaxLength = 20; + PurchasedGoodsGlassLbl: Label 'Purchased Goods - Glass', MaxLength = 100; + PurchasedServicesTok: Label 'PURCHSERVC', MaxLength = 20; + PurchasedServicesLbl: Label 'Purchased Services', MaxLength = 100; + RentalCarMediumTok: Label 'RENTALCAR-M', MaxLength = 20; + RentalCarMediumLbl: Label 'Contoso Rental Car - Medium Car', MaxLength = 100; + SoldProductEndTok: Label 'SOLDPRODEND', MaxLength = 20; + SoldProductEndLbl: Label 'End of Life Treatment of Sold Products', MaxLength = 100; + SoldProductProcessTok: Label 'SOLDPRODPROC', MaxLength = 20; + SoldProductProcessLbl: Label 'Processing of Sold Products', MaxLength = 100; + SoldProductUseTok: Label 'SOLDPRODUSE', MaxLength = 20; + SoldProductUseLbl: Label 'Use of Sold Products', MaxLength = 100; + BoilerTok: Label 'BOILER', MaxLength = 20; + BoilerLbl: Label 'Boilers', MaxLength = 100; + HeaterSmallTok: Label 'HEATER12', MaxLength = 20; + HeaterSmallLbl: Label 'Heaters 12kW', MaxLength = 100; + HeaterMediumTok: Label 'HEATER24', MaxLength = 20; + HeaterMediumLbl: Label 'Heaters 24kW', MaxLength = 100; + HeaterLargeTok: Label 'HEATER36', MaxLength = 20; + HeaterLargeLbl: Label 'Heaters 36kW', MaxLength = 100; + ThermalTok: Label 'THERMAL', MaxLength = 20; + ThermalLbl: Label 'Thermal', MaxLength = 100; + ExternalTransportDistanceTok: Label 'TRANSP-EXT-DIST', MaxLength = 20; + ExternalTransportDistanceLbl: Label 'External Transport /KM', MaxLength = 100; + InternalTransportDistanceTok: Label 'TRANSP-INT-DIST', MaxLength = 20; + InternalTransportDistanceLbl: Label 'Inrnal Transport /KM', MaxLength = 100; + ElectricityNuclearTok: Label 'ELECTRIC-NUCL', MaxLength = 20; + ElectricityNuclearLbl: Label 'Electricity supplier - nuclear', MaxLength = 100; + ElectricityCoalTok: Label 'ELECTRIC-COAL', MaxLength = 20; + ElectricityCoalLbl: Label 'Electricity supplier - coal', MaxLength = 100; + ElectricityGreenTok: Label 'ELECTRIC-GREEN', MaxLength = 20; + ElectricityGreenLbl: Label 'Electricity supplier - solar/wind', MaxLength = 100; + HeatTok: Label 'HEAT', MaxLength = 20; + HeatLbl: Label 'Heat suppliers', MaxLength = 100; + SteamSupplierTok: Label 'STEAM', MaxLength = 20; + SteamSupplierLbl: Label 'Steam suppliers', MaxLength = 100; + WasteLandfillOrganicTok: Label 'WASTE-LFORG', MaxLength = 20; + WasteLandfillOrganicLbl: Label 'Landfill Organic Waste', MaxLength = 100; + WasteLandfillPlasticTok: Label 'WASTE-LFPLA', MaxLength = 20; + WasteLandfillPlasticLbl: Label 'Landfill Plastic Waste', MaxLength = 100; + WasteRecycledTok: Label 'WASTE-RC', MaxLength = 20; + WasteRecycledLbl: Label 'Recycled Waste', MaxLength = 100; +} \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainabilityAccount.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainabilityAccount.Codeunit.al new file mode 100644 index 0000000000..990e5c8c46 --- /dev/null +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainabilityAccount.Codeunit.al @@ -0,0 +1,506 @@ +codeunit 5215 "Create Sustainability Account" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + SustainCategory: Codeunit "Create Sustainability Category"; + SustainSubcategory: Codeunit "Create Sustain. Subcategory"; + ContosoSustainability: Codeunit "Contoso Sustainability"; + SustainabilityAccountMgt: Codeunit "Sustainability Account Mgt."; + begin + ContosoSustainability.InsertSustainabilityAccount(GasEmissions(), GasEmissionsLbl, '', '', Enum::"Sustainability Account Type"::"Begin-Total", '', false); + ContosoSustainability.InsertSustainabilityAccount(Scope1(), Scope1BeginTotalLbl, '', '', Enum::"Sustainability Account Type"::"Begin-Total", '', false); + ContosoSustainability.InsertSustainabilityAccount(StationaryCombustion(), StationaryCombustionLbl, '', '', Enum::"Sustainability Account Type"::"Begin-Total", '', false); + ContosoSustainability.InsertSustainabilityAccount(Boilers(), BoilersLbl, SustainCategory.Stationary(), SustainSubcategory.Boiler(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(HeatersSmall(), HeatersSmallLbl, SustainCategory.Stationary(), SustainSubcategory.HeaterSmall(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(HeatersMedium(), HeatersMediumLbl, SustainCategory.Stationary(), SustainSubcategory.HeaterMedium(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(HeatersLarge(), HeatersLargeLbl, SustainCategory.Stationary(), SustainSubcategory.HeaterLarge(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(ThermalOxidizers(), ThermalOxidizersLbl, SustainCategory.Stationary(), SustainSubcategory.Thermal(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(TotalStationaryCombustion(), TotalStationaryCombustionLbl, '', '', Enum::"Sustainability Account Type"::"End-Total", StationaryCombustion() + '..' + TotalStationaryCombustion(), false); + + ContosoSustainability.InsertSustainabilityAccount(MobileCombustion(), MobileCombustionLbl, '', '', Enum::"Sustainability Account Type"::"Begin-Total", '', false); + ContosoSustainability.InsertSustainabilityAccount(OnRoadVehicleUrbanTrucks(), OnRoadVehiclesUrbanLbl, SustainCategory.MobileDistance(), SustainSubcategory.UrbanTruck(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(OnRoadVehiclesLongHaulTrucks(), OnRoadVehiclesLongHaulLbl, SustainCategory.MobileDistance(), SustainSubcategory.LongHaulTruck(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(OnRoadVehiclesBuses(), OnRoadVehiclesBusesLbl, SustainCategory.MobileDistance(), SustainSubcategory.Bus(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(NonRoadVehiclesTractors(), NonRoadVehiclesTractorsLbl, SustainCategory.MobileFuel(), SustainSubcategory.Tractor(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(NonRoadVehiclesForklifts(), NonRoadVehiclesForkliftsLbl, SustainCategory.MobileFuel(), SustainSubcategory.Forklift(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(NonRoadVehiclesBackhoes(), NonRoadVehiclesBackhoesLbl, SustainCategory.MobileFuel(), SustainSubcategory.Backhoe(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(Rail(), RailLbl, SustainCategory.MobileDistance(), SustainSubcategory.Rail(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(AirContinentalEconomy(), AirContinentalEconomyLbl, SustainCategory.MobileDistance(), SustainSubcategory.AirContinentalEconomy(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(AirContinentalBusiness(), AirContinentalBusinessLbl, SustainCategory.MobileDistance(), SustainSubcategory.AirContinentalBusiness(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(AirIntercontinentalEconomy(), AirIntercontinentalEconomyLbl, SustainCategory.MobileDistance(), SustainSubcategory.AirIntercontinentalEconomy(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(AirIntercontinentalPremiumEconomy(), AirIntercontinentalPremiumEconomyLbl, SustainCategory.MobileDistance(), SustainSubcategory.AirIntercontinentalPremiumEconomy(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(AirIntercontinentalBusiness(), AirIntercontinentalBusinessLbl, SustainCategory.MobileDistance(), SustainSubcategory.AirIntercontinentalBusiness(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(TotalMobileCombustion(), TotalMobileCombustionLbl, '', '', Enum::"Sustainability Account Type"::"End-Total", MobileCombustion() + '..' + TotalMobileCombustion(), false); + + ContosoSustainability.InsertSustainabilityAccount(FugitiveEmission(), FugitiveEmissionsLbl, '', '', Enum::"Sustainability Account Type"::"Begin-Total", '', false); + ContosoSustainability.InsertSustainabilityAccount(Refrigerators(), RefrigeratorsLbl, SustainCategory.Fugitive(), SustainSubcategory.Refrigerator(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(AirConditionEquipments24kW(), AirConditionEquipments24kWLbl, SustainCategory.Fugitive(), SustainSubcategory.AirConditionerSmall(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(AirConditionEquipments36kW(), AirConditionEquipments36kWLbl, SustainCategory.Fugitive(), SustainSubcategory.AirConditionerLarge(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(TotalFugitiveEmissions(), TotalFugitiveEmissionsLbl, '', '', Enum::"Sustainability Account Type"::"End-Total", FugitiveEmission() + '..' + TotalFugitiveEmissions(), false); + + ContosoSustainability.InsertSustainabilityAccount(TotalScope1(), TotalScope1DirectEmissionLbl, '', '', Enum::"Sustainability Account Type"::"End-Total", Scope1() + '..' + TotalScope1(), false); + + ContosoSustainability.InsertSustainabilityAccount(Scope2(), Scope2BeginTotalLbl, '', '', Enum::"Sustainability Account Type"::"Begin-Total", '', false); + ContosoSustainability.InsertSustainabilityAccount(UpstreamActivityScope2(), UpstreamActivitiesLbl, '', '', Enum::"Sustainability Account Type"::"Begin-Total", '', false); + ContosoSustainability.InsertSustainabilityAccount(PurchasedElectricityContosoPowerPlant(), PurchasedElectricityContosoPowerPlantLbl, SustainCategory.UtilityElectric(), SustainSubcategory.ElectricityNuclear(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(PurchasedElectricityWideWorldImporters(), PurchasedElectricityWideWorldImportersLbl, SustainCategory.UtilityElectric(), SustainSubcategory.ElectricityCoal(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(PurchasedElectricityGreenTariffEnergy(), PurchasedElectricityGreenTariffEnergyLbl, SustainCategory.UtilityElectric(), SustainSubcategory.ElectricityGreen(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(SteamFabrikamInc(), SteamFabrikamIncLbl, SustainCategory.UtilitySteam(), SustainSubcategory.SteamSupplier(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(HeatingFabrikamInc(), HeatingFabrikamIncLbl, SustainCategory.UtilityHeat(), SustainSubcategory.Heat(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(TotalUpStreamActivityScope2(), TotalUpStreamActivitiesLbl, '', '', Enum::"Sustainability Account Type"::"End-Total", UpstreamActivityScope2() + '..' + TotalUpStreamActivityScope2(), false); + ContosoSustainability.InsertSustainabilityAccount(TotalScope2(), TotalScope2IndirectEmissionLbl, '', '', Enum::"Sustainability Account Type"::"End-Total", Scope2() + '..' + TotalScope2(), false); + + ContosoSustainability.InsertSustainabilityAccount(Scope3(), Scope3BeginTotalLbl, '', '', Enum::"Sustainability Account Type"::"Begin-Total", '', false); + ContosoSustainability.InsertSustainabilityAccount(UpstreamActivityScope3(), UpstreamActivitiesLbl, '', '', Enum::"Sustainability Account Type"::"Begin-Total", '', false); + ContosoSustainability.InsertSustainabilityAccount(PurchasedGoodsPlastic(), PurchasedGoodsPlasticLbl, SustainCategory.PurchaseGoodsGL(), SustainSubcategory.PurchasedGoodsPlastic(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(PurchasedGoodsAluminum(), PurchasedGoodsAluminumLbl, SustainCategory.PurchaseGoodsGL(), SustainSubcategory.PurchasedGoodsAluminum(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(PurchasedGoodsSteel(), PurchasedGoodsSteelLbl, SustainCategory.PurchaseGoodsGL(), SustainSubcategory.PurchasedGoodsSteel(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(PurchasedGoodsGlass(), PurchasedGoodsGlassLbl, SustainCategory.PurchaseGoodsGL(), SustainSubcategory.PurchasedGoodsGlass(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(PurchasedServices(), PurchasedServicesLbl, SustainCategory.PurchaseGoodsGL(), SustainSubcategory.PurchasedServices(), Enum::"Sustainability Account Type"::Posting, '', true); + + ContosoSustainability.InsertSustainabilityAccount(ExternalTransportation(), ExternalTransportationLbl, SustainCategory.ExternalTransportDistance(), SustainSubcategory.ExternalTransportDistance(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(TransportationWithOwnTrucks(), TransportationWithOwnTrucksLbl, SustainCategory.InternalTransportDistance(), SustainSubcategory.InternalTransportDistance(), Enum::"Sustainability Account Type"::Posting, '', true); + + ContosoSustainability.InsertSustainabilityAccount(WastePlasticGeneratedInOperation(), WastePlasticGeneratedInOperationLbl, SustainCategory.Waste(), SustainSubcategory.WasteLandFillOrganic(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(WasteOrganicGeneratedInOperation(), WasteOrganicGeneratedInOperationLbl, SustainCategory.Waste(), SustainSubcategory.WasteLandFillPlastic(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(RecycledWasteGeneratedInOperation(), RecycledWasteGeneratedInOperationLbl, SustainCategory.Waste(), SustainSubcategory.WasteRecycled(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(TotalUpstreamActivityScope3(), TotalUpstreamActivitiesLbl, '', '', Enum::"Sustainability Account Type"::"End-Total", UpstreamActivityScope3() + '..' + TotalUpstreamActivityScope3(), false); + + ContosoSustainability.InsertSustainabilityAccount(DownstreamActivityScope3(), DownStreamActivitiesLbl, '', '', Enum::"Sustainability Account Type"::"Begin-Total", '', false); + ContosoSustainability.InsertSustainabilityAccount(ProcessingOfSoldProducts(), ProcessingOfSoldProductsLbl, SustainCategory.SoldProductProcess(), SustainSubcategory.SoldProductProcess(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(UseOfSoldProducts(), UseOfSoldProductsLbl, SustainCategory.SoldProductUse(), SustainSubcategory.SoldProductUse(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(EndOfLifeTreatmentOfSoldProducts(), EndOfLifeTreatmentOfSoldProductsLbl, SustainCategory.SoldProductEnd(), SustainSubcategory.SoldProductEnd(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(ExternalTransportationScope3(), ExternalTransportationLbl, SustainCategory.ExternalTransportDistance(), SustainSubcategory.ExternalTransportDistance(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(TransportationWithOwnTrucksScope3(), TransportationWithOwnTrucksLbl, SustainCategory.InternalTransportDistance(), SustainSubcategory.InternalTransportDistance(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(TotalDownstreamActivityScope3(), TotalDownstreamActivitiesLbl, '', '', Enum::"Sustainability Account Type"::"End-Total", DownstreamActivityScope3() + '..' + TotalDownstreamActivityScope3(), false); + + ContosoSustainability.InsertSustainabilityAccount(BusinessTravelAndEmployeeCommuting(), BusinessTravelAndEmployeeCommutingLbl, '', '', Enum::"Sustainability Account Type"::"Begin-Total", '', false); + ContosoSustainability.InsertSustainabilityAccount(ContosoHotel3Stars(), ContosoHotel3StarsLbl, SustainCategory.Hotel(), SustainSubcategory.Hotel3Star(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(ContosoHotel4Stars(), ContosoHotel4StarsLbl, SustainCategory.Hotel(), SustainSubcategory.Hotel4Star(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(ContosoHotel4StarsJuniorSuite(), ContosoHotel4StarsJuniorSuiteLbl, SustainCategory.Hotel(), SustainSubcategory.Hotel4StarPlus(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(ContosoRentalCar(), ContosoRentalCarLbl, SustainCategory.RentalCar(), SustainSubcategory.RentalCarMedium(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(CompanyCarMediumSize(), CompanyCarMediumSizeLbl, SustainCategory.CompanyCar(), SustainSubcategory.CompanyCarMedium(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(CompanyCarLargeSize(), CompanyCarLargeSizeLbl, SustainCategory.CompanyCar(), SustainSubcategory.CompanyCarLarge(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(CompanyCarPremiumSize(), CompanyCarPremiumSizeLbl, SustainCategory.CompanyCar(), SustainSubcategory.CompanyCarPremium(), Enum::"Sustainability Account Type"::Posting, '', true); + ContosoSustainability.InsertSustainabilityAccount(TotalBusinessTravelAndEmployeeCommuting(), TotalBusinessTravelAndEmployeeCommutingLbl, '', '', Enum::"Sustainability Account Type"::"End-Total", BusinessTravelAndEmployeeCommuting() + '..' + TotalBusinessTravelAndEmployeeCommuting(), false); + ContosoSustainability.InsertSustainabilityAccount(TotalScope3(), TotalScope3IndirectEmissionLbl, '', '', Enum::"Sustainability Account Type"::"End-Total", Scope3() + '..' + TotalScope3(), false); + ContosoSustainability.InsertSustainabilityAccount(TotalGasEmissions(), TotalGasEmissionsLbl, '', '', Enum::"Sustainability Account Type"::"End-Total", GasEmissions() + '..' + TotalGasEmissions(), false); + + SustainabilityAccountMgt.IndentChartOfSustainabilityAccounts(true); + end; + + procedure GasEmissions(): Code[20] + begin + exit('10000'); + end; + + procedure Scope1(): Code[20] + begin + exit('11000'); + end; + + procedure StationaryCombustion(): Code[20] + begin + exit('11100'); + end; + + procedure Boilers(): Code[20] + begin + exit('11101'); + end; + + procedure HeatersSmall(): Code[20] + begin + exit('11102'); + end; + + procedure HeatersMedium(): Code[20] + begin + exit('11103'); + end; + + procedure HeatersLarge(): Code[20] + begin + exit('11104'); + end; + + procedure ThermalOxidizers(): Code[20] + begin + exit('11105'); + end; + + procedure TotalStationaryCombustion(): Code[20] + begin + exit('11199'); + end; + + procedure MobileCombustion(): Code[20] + begin + exit('11200'); + end; + + procedure OnRoadVehicleUrbanTrucks(): Code[20] + begin + exit('11201'); + end; + + procedure OnRoadVehiclesLongHaulTrucks(): Code[20] + begin + exit('11202'); + end; + + procedure OnRoadVehiclesBuses(): Code[20] + begin + exit('11203'); + end; + + procedure NonRoadVehiclesTractors(): Code[20] + begin + exit('11204'); + end; + + procedure NonRoadVehiclesForklifts(): Code[20] + begin + exit('11205'); + end; + + procedure NonRoadVehiclesBackhoes(): Code[20] + begin + exit('11206'); + end; + + procedure Rail(): Code[20] + begin + exit('11207'); + end; + + procedure AirContinentalEconomy(): Code[20] + begin + exit('11210'); + end; + + procedure AirContinentalBusiness(): Code[20] + begin + exit('11211'); + end; + + procedure AirIntercontinentalEconomy(): Code[20] + begin + exit('11212'); + end; + + procedure AirIntercontinentalPremiumEconomy(): Code[20] + begin + exit('11213'); + end; + + procedure AirIntercontinentalBusiness(): Code[20] + begin + exit('11214'); + end; + + procedure TotalMobileCombustion(): Code[20] + begin + exit('11299'); + end; + + procedure FugitiveEmission(): Code[20] + begin + exit('11300'); + end; + + procedure Refrigerators(): Code[20] + begin + exit('11301'); + end; + + procedure AirConditionEquipments24kW(): Code[20] + begin + exit('11302'); + end; + + procedure AirConditionEquipments36kW(): Code[20] + begin + exit('11303'); + end; + + procedure TotalFugitiveEmissions(): Code[20] + begin + exit('11399'); + end; + + procedure TotalScope1(): Code[20] + begin + exit('11999'); + end; + + procedure Scope2(): Code[20] + begin + exit('12000'); + end; + + procedure UpstreamActivityScope2(): Code[20] + begin + exit('12100'); + end; + + procedure PurchasedElectricityContosoPowerPlant(): Code[20] + begin + exit('12101'); + end; + + procedure PurchasedElectricityWideWorldImporters(): Code[20] + begin + exit('12102'); + end; + + procedure PurchasedElectricityGreenTariffEnergy(): Code[20] + begin + exit('12103'); + end; + + procedure SteamFabrikamInc(): Code[20] + begin + exit('12104'); + end; + + procedure HeatingFabrikamInc(): Code[20] + begin + exit('12105'); + end; + + procedure TotalUpStreamActivityScope2(): Code[20] + begin + exit('12199'); + end; + + procedure TotalScope2(): Code[20] + begin + exit('12999'); + end; + + procedure Scope3(): Code[20] + begin + exit('13000'); + end; + + procedure UpstreamActivityScope3(): Code[20] + begin + exit('13100'); + end; + + procedure PurchasedGoodsPlastic(): Code[20] + begin + exit('13101'); + end; + + procedure PurchasedGoodsAluminum(): Code[20] + begin + exit('13102'); + end; + + procedure PurchasedGoodsSteel(): Code[20] + begin + exit('13103'); + end; + + procedure PurchasedGoodsGlass(): Code[20] + begin + exit('13104'); + end; + + procedure PurchasedServices(): Code[20] + begin + exit('13151'); + end; + + procedure ExternalTransportation(): Code[20] + begin + exit('13171'); + end; + + procedure TransportationWithOwnTrucks(): Code[20] + begin + exit('13172'); + end; + + procedure WastePlasticGeneratedInOperation(): Code[20] + begin + exit('13181'); + end; + + procedure WasteOrganicGeneratedInOperation(): Code[20] + begin + exit('13182'); + end; + + procedure RecycledWasteGeneratedInOperation(): Code[20] + begin + exit('13183'); + end; + + procedure TotalUpstreamActivityScope3(): Code[20] + begin + exit('13199'); + end; + + procedure DownstreamActivityScope3(): Code[20] + begin + exit('13200'); + end; + + procedure ProcessingOfSoldProducts(): Code[20] + begin + exit('13201'); + end; + + procedure UseOfSoldProducts(): Code[20] + begin + exit('13202'); + end; + + procedure EndOfLifeTreatmentOfSoldProducts(): Code[20] + begin + exit('13203'); + end; + + procedure ExternalTransportationScope3(): Code[20] + begin + exit('13211'); + end; + + procedure TransportationWithOwnTrucksScope3(): Code[20] + begin + exit('13212'); + end; + + procedure TotalDownstreamActivityScope3(): Code[20] + begin + exit('13299'); + end; + + procedure BusinessTravelAndEmployeeCommuting(): Code[20] + begin + exit('13300'); + end; + + procedure ContosoHotel3Stars(): Code[20] + begin + exit('13301'); + end; + + procedure ContosoHotel4Stars(): Code[20] + begin + exit('13302'); + end; + + procedure ContosoHotel4StarsJuniorSuite(): Code[20] + begin + exit('13303'); + end; + + procedure ContosoRentalCar(): Code[20] + begin + exit('13311'); + end; + + procedure CompanyCarMediumSize(): Code[20] + begin + exit('13321'); + end; + + procedure CompanyCarLargeSize(): Code[20] + begin + exit('13322'); + end; + + procedure CompanyCarPremiumSize(): Code[20] + begin + exit('13323'); + end; + + procedure TotalBusinessTravelAndEmployeeCommuting(): Code[20] + begin + exit('13399'); + end; + + procedure TotalScope3(): Code[20] + begin + exit('13999'); + end; + + procedure TotalGasEmissions(): Code[20] + begin + exit('19999'); + end; + + var + GasEmissionsLbl: Label 'Gas Emissions', MaxLength = 100; + Scope1BeginTotalLbl: Label 'Scope 1 - Direct Emission', MaxLength = 100; + StationaryCombustionLbl: Label 'Stationary Combustion', MaxLength = 100; + BoilersLbl: Label 'Boilers', MaxLength = 100; + HeatersSmallLbl: Label 'Heaters 12kW', MaxLength = 100; + HeatersMediumLbl: Label 'Heaters 24kW', MaxLength = 100; + HeatersLargeLbl: Label 'Heaters 36kW', MaxLength = 100; + ThermalOxidizersLbl: Label 'Thermal Oxidizers', MaxLength = 100; + TotalStationaryCombustionLbl: Label 'Total, Stationary Combustion', MaxLength = 100; + MobileCombustionLbl: Label 'Mobile Combustion', MaxLength = 100; + OnRoadVehiclesUrbanLbl: Label 'OnRoad Vehicles (Trucks: urban)', MaxLength = 100; + OnRoadVehiclesLongHaulLbl: Label 'OnRoad Vehicles (Trucks: long-haul trailer)', MaxLength = 100; + OnRoadVehiclesBusesLbl: Label 'OnRoad Vehicles (Buses)', MaxLength = 100; + NonRoadVehiclesTractorsLbl: Label 'NonRoad Vehicles (Tractors)', MaxLength = 100; + NonRoadVehiclesForkliftsLbl: Label 'NonRoad Vehicles (Forklifts)', MaxLength = 100; + NonRoadVehiclesBackhoesLbl: Label 'NonRoad Vehicles (Backhoes)', MaxLength = 100; + RailLbl: Label 'Rail', MaxLength = 100; + AirContinentalEconomyLbl: Label 'Air Continental - Economy Class', MaxLength = 100; + AirContinentalBusinessLbl: Label 'Air Continental - Business Class', MaxLength = 100; + AirIntercontinentalEconomyLbl: Label 'Air Intercontinental - Economy Class', MaxLength = 100; + AirIntercontinentalPremiumEconomyLbl: Label 'Air Intercontinental - Premium Economy', MaxLength = 100; + AirIntercontinentalBusinessLbl: Label 'Air Intercontinental - Business Class', MaxLength = 100; + TotalMobileCombustionLbl: Label 'Total, Mobile Combustion', MaxLength = 100; + FugitiveEmissionsLbl: Label 'Fugitive Emissions', MaxLength = 100; + RefrigeratorsLbl: Label 'Refrigerators', MaxLength = 100; + AirConditionEquipments24kWLbl: Label 'Air-Condition Equipments 24,000 BTU', MaxLength = 100; + AirConditionEquipments36kWLbl: Label 'Air-Condition Equipments 36,000 BTU', MaxLength = 100; + TotalFugitiveEmissionsLbl: Label 'Total, Fugitive Emissions', MaxLength = 100; + TotalScope1DirectEmissionLbl: Label 'TOTAL SCOPE 1 - DIRECT EMISSION', MaxLength = 100; + Scope2BeginTotalLbl: Label 'Scope 2 - Indirect Emission', MaxLength = 100; + UpstreamActivitiesLbl: Label 'Upstream Activities', MaxLength = 100; + PurchasedElectricityContosoPowerPlantLbl: Label 'Purchased electricity - Contoso PowerPlant', MaxLength = 100; + PurchasedElectricityWideWorldImportersLbl: Label 'Purchased electricity - Wide World Importers', MaxLength = 100; + PurchasedElectricityGreenTariffEnergyLbl: Label 'Purchased electricity - Green Tariff Energy', MaxLength = 100; + SteamFabrikamIncLbl: Label 'Steam - Fabrikam, Inc.', MaxLength = 100; + HeatingFabrikamIncLbl: Label 'Heating - Fabrikam, Inc.', MaxLength = 100; + TotalScope2IndirectEmissionLbl: Label 'TOTAL SCOPE 2 - INDIRECT EMISSION', MaxLength = 100; + Scope3BeginTotalLbl: Label 'Scope 3 - Indirect Emission', MaxLength = 100; + PurchasedGoodsPlasticLbl: Label 'Purchased Goods - Plastic', MaxLength = 100; + PurchasedGoodsAluminumLbl: Label 'Purchased Goods - Aluminum', MaxLength = 100; + PurchasedGoodsSteelLbl: Label 'Purchased Goods - Steel', MaxLength = 100; + PurchasedGoodsGlassLbl: Label 'Purchased Goods - Glass', MaxLength = 100; + PurchasedServicesLbl: Label 'Purchased Services', MaxLength = 100; + ExternalTransportationLbl: Label 'External Transportation', MaxLength = 100; + TransportationWithOwnTrucksLbl: Label 'Transportation with Own Trucks', MaxLength = 100; + WastePlasticGeneratedInOperationLbl: Label 'Waste (plastic) Generated in Operation', MaxLength = 100; + WasteOrganicGeneratedInOperationLbl: Label 'Waste (organic) Generated in Operation', MaxLength = 100; + RecycledWasteGeneratedInOperationLbl: Label 'Recycled Waste Generated in Operation', MaxLength = 100; + TotalUpstreamActivitiesLbl: Label 'Total, Upstream Activities', MaxLength = 100; + DownStreamActivitiesLbl: Label 'DownStream Activities', MaxLength = 100; + ProcessingOfSoldProductsLbl: Label 'Processing of Sold Products', MaxLength = 100; + UseOfSoldProductsLbl: Label 'Use of Sold Products', MaxLength = 100; + EndOfLifeTreatmentOfSoldProductsLbl: Label 'End of Life Treatment of Sold Products', MaxLength = 100; + TotalDownstreamActivitiesLbl: Label 'Total, Downstream Activities', MaxLength = 100; + BusinessTravelAndEmployeeCommutingLbl: Label 'Business Travel and Employee Commuting', MaxLength = 100; + ContosoHotel3StarsLbl: Label 'Contoso Hotel - 3 stars', MaxLength = 100; + ContosoHotel4StarsLbl: Label 'Contoso Hotel - 4 stars', MaxLength = 100; + ContosoHotel4StarsJuniorSuiteLbl: Label 'Contoso Hotel - 4 stars Junior Suite', MaxLength = 100; + ContosoRentalCarLbl: Label 'Contoso Rental Car', MaxLength = 100; + CompanyCarMediumSizeLbl: Label 'Company Car - Medium size', MaxLength = 100; + CompanyCarLargeSizeLbl: Label 'Company Car - Large size', MaxLength = 100; + CompanyCarPremiumSizeLbl: Label 'Company Car - Premium size', MaxLength = 100; + TotalBusinessTravelAndEmployeeCommutingLbl: Label 'Total, Business Travel and Employee Commuting', MaxLength = 100; + TotalScope3IndirectEmissionLbl: Label 'TOTAL SCOPE 3 - INDIRECT EMISSION', MaxLength = 100; + TotalGasEmissionsLbl: Label 'TOTAL GAS EMISSIONS', MaxLength = 100; +} \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainabilityCategory.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainabilityCategory.Codeunit.al new file mode 100644 index 0000000000..744e0bd789 --- /dev/null +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainabilityCategory.Codeunit.al @@ -0,0 +1,150 @@ +codeunit 5213 "Create Sustainability Category" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ContosoSustainability: Codeunit "Contoso Sustainability"; + begin + ContosoSustainability.InsertAccountCategory(CompanyCar(), CompanyCarLbl, Enum::"Emission Scope"::"Scope 3", Enum::"Calculation Foundation"::Distance, true, false, false, '', false); + ContosoSustainability.InsertAccountCategory(Fugitive(), FugitiveLbl, Enum::"Emission Scope"::"Scope 1", Enum::"Calculation Foundation"::Installations, true, false, false, '', false); + ContosoSustainability.InsertAccountCategory(Hotel(), HotelLbl, Enum::"Emission Scope"::"Scope 3", Enum::"Calculation Foundation"::Custom, true, false, false, 'NIGHT', false); + ContosoSustainability.InsertAccountCategory(MobileDistance(), MobileDistanceLbl, Enum::"Emission Scope"::"Scope 1", Enum::"Calculation Foundation"::Distance, true, true, false, '', false); + ContosoSustainability.InsertAccountCategory(MobileFuel(), MobileFuelLbl, Enum::"Emission Scope"::"Scope 1", Enum::"Calculation Foundation"::"Fuel/Electricity", true, true, false, '', false); + ContosoSustainability.InsertAccountCategory(PurchaseGoodsGL(), PurchaseGoodsGLLbl, Enum::"Emission Scope"::"Scope 3", Enum::"Calculation Foundation"::Custom, true, false, false, 'GL', true); + ContosoSustainability.InsertAccountCategory(RentalCar(), RentalCarLbl, Enum::"Emission Scope"::"Scope 3", Enum::"Calculation Foundation"::"Fuel/Electricity", true, false, false, '', false); + ContosoSustainability.InsertAccountCategory(SoldProductEnd(), SoldProductEndOfLifeTreatmentLbl, Enum::"Emission Scope"::"Scope 3", Enum::"Calculation Foundation"::Custom, true, false, false, 'GL', true); + ContosoSustainability.InsertAccountCategory(SoldProductProcess(), SoldProductProccessingLbl, Enum::"Emission Scope"::"Scope 3", Enum::"Calculation Foundation"::Custom, true, false, false, 'GL', true); + ContosoSustainability.InsertAccountCategory(SoldProductUse(), SoldProductUseLbl, Enum::"Emission Scope"::"Scope 3", Enum::"Calculation Foundation"::Custom, true, false, false, 'GL', true); + ContosoSustainability.InsertAccountCategory(Stationary(), StationaryLbl, Enum::"Emission Scope"::"Scope 1", Enum::"Calculation Foundation"::"Fuel/Electricity", true, true, true, '', false); + ContosoSustainability.InsertAccountCategory(ExternalTransportDistance(), ExternalTransportDistanceLbl, Enum::"Emission Scope"::"Scope 3", Enum::"Calculation Foundation"::Distance, true, false, false, '', false); + ContosoSustainability.InsertAccountCategory(InternalTransportDistance(), InternalTransportDistanceLbl, Enum::"Emission Scope"::"Scope 3", Enum::"Calculation Foundation"::Distance, true, false, false, '', false); + ContosoSustainability.InsertAccountCategory(UtilityElectric(), UtilityElectricLbl, Enum::"Emission Scope"::"Scope 2", Enum::"Calculation Foundation"::"Fuel/Electricity", true, false, false, '', false); + ContosoSustainability.InsertAccountCategory(UtilityHeat(), UtilityHeatLbl, Enum::"Emission Scope"::"Scope 2", Enum::"Calculation Foundation"::Custom, true, false, false, 'THERMAL UNIT', false); + ContosoSustainability.InsertAccountCategory(UtilitySteam(), UtilitySteamLbl, Enum::"Emission Scope"::"Scope 2", Enum::"Calculation Foundation"::Custom, true, false, false, 'TON/HOUR', false); + ContosoSustainability.InsertAccountCategory(Waste(), WasteLbl, Enum::"Emission Scope"::"Scope 3", Enum::"Calculation Foundation"::Custom, true, true, false, 'WASTE TON', false); + end; + + procedure CompanyCar(): Code[20] + begin + exit(CompanyCarTok); + end; + + procedure Fugitive(): Code[20] + begin + exit(FugitiveTok); + end; + + procedure Hotel(): Code[20] + begin + exit(HotelTok); + end; + + procedure MobileDistance(): Code[20] + begin + exit(MobileDistanceTok); + end; + + procedure MobileFuel(): Code[20] + begin + exit(MobileFuelTok); + end; + + procedure PurchaseGoodsGL(): Code[20] + begin + exit(PurchaseGoodsGLTok); + end; + + procedure RentalCar(): Code[20] + begin + exit(RentalCarTok); + end; + + procedure SoldProductEnd(): Code[20] + begin + exit(SoldProductEndOfLifeTreatmentTok); + end; + + procedure SoldProductProcess(): Code[20] + begin + exit(SoldProductProcessingTok); + end; + + procedure SoldProductUse(): Code[20] + begin + exit(SoldProductUseTok); + end; + + procedure Stationary(): Code[20] + begin + exit(StationaryTok); + end; + + procedure ExternalTransportDistance(): Code[20] + begin + exit(ExternalTransportDistanceTok); + end; + + procedure InternalTransportDistance(): Code[20] + begin + exit(InternalTransportDistanceTok); + end; + + + procedure UtilityElectric(): Code[20] + begin + exit(UtilityElectricTok); + end; + + procedure UtilityHeat(): Code[20] + begin + exit(UtilityHeatTok); + end; + + procedure UtilitySteam(): Code[20] + begin + exit(UtilitySteamTok); + end; + + procedure Waste(): Code[20] + begin + exit(WasteTok); + end; + + var + CompanyCarTok: Label 'COMPCAR', MaxLength = 20; + CompanyCarLbl: Label 'Company Cars', MaxLength = 100; + FugitiveTok: Label 'FUGITIVE', MaxLength = 20; + FugitiveLbl: Label 'Fugitive Emissions', MaxLength = 100; + HotelTok: Label 'HOTEL', MaxLength = 20; + HotelLbl: Label 'Hotel Night Stays', MaxLength = 100; + MobileDistanceTok: Label 'MOBILE-DISTANCE', MaxLength = 20; + MobileDistanceLbl: Label 'Mobile Combustion - Distance Calculation', MaxLength = 100; + MobileFuelTok: Label 'MOBILE-FUEL', MaxLength = 20; + MobileFuelLbl: Label 'Mobile Combustion - Fuel Calculation', MaxLength = 100; + PurchaseGoodsGLTok: Label 'PURCHGOODS-GL', MaxLength = 20; + PurchaseGoodsGLLbl: Label 'Purchased Goods - GL Based Calculation', MaxLength = 100; + RentalCarTok: Label 'RENTALCAR', MaxLength = 20; + RentalCarLbl: Label 'Rental Car Usage', MaxLength = 100; + SoldProductEndOfLifeTreatmentTok: Label 'SOLDPRODEND-GL', MaxLength = 20; + SoldProductEndOfLifeTreatmentLbl: Label 'End of Life Treatment of Sold Products', MaxLength = 100; + SoldProductProcessingTok: Label 'SOLDPRODPROC-GL', MaxLength = 20; + SoldProductProccessingLbl: Label 'Processing of Sold Products', MaxLength = 100; + SoldProductUseTok: Label 'SOLDPRODUSE-GL', MaxLength = 20; + SoldProductUseLbl: Label 'Use of Sold Products', MaxLength = 100; + StationaryTok: Label 'STATIONARY', MaxLength = 20; + StationaryLbl: Label 'Stationary Combustion', MaxLength = 100; + ExternalTransportDistanceTok: Label 'TRANSP-EXT-DIST', MaxLength = 20; + ExternalTransportDistanceLbl: Label 'External Transport - Distance Calculation', MaxLength = 100; + InternalTransportDistanceTok: Label 'TRANSP-INT-DIST', MaxLength = 20; + InternalTransportDistanceLbl: Label 'Internal Transport - Distance Calculation', MaxLength = 100; + UtilityElectricTok: Label 'UTILITY-ELECTRIC', MaxLength = 20; + UtilityElectricLbl: Label 'Utility Providers - Electricity', MaxLength = 100; + UtilityHeatTok: Label 'UTILITY-HEAT', MaxLength = 20; + UtilityHeatLbl: Label 'Utility Providers - Heating', MaxLength = 100; + UtilitySteamTok: Label 'UTILITY-STEAM', MaxLength = 20; + UtilitySteamLbl: Label 'Utility Providers - Steam', MaxLength = 100; + WasteTok: Label 'WASTE', MaxLength = 20; + WasteLbl: Label 'Waste Generated', MaxLength = 100; +} \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainabilitySetup.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainabilitySetup.Codeunit.al new file mode 100644 index 0000000000..a342f14f2c --- /dev/null +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/1.Setup Data/CreateSustainabilitySetup.Codeunit.al @@ -0,0 +1,44 @@ +codeunit 5212 "Create Sustainability Setup" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + begin + CreateSetupTable(); + CreateSourceCode(); + end; + + local procedure CreateSetupTable() + var + SustainabilitySetup: Record "Sustainability Setup"; + CommonUoM: Codeunit "Create Common Unit Of Measure"; + begin + SustainabilitySetup.Get(); + + SustainabilitySetup.Validate("Emission Unit of Measure Code", CommonUoM.KG()); + SustainabilitySetup.Validate("Emission Decimal Places", '3:5'); + + SustainabilitySetup.Validate("Fuel/El. Decimal Places", '2:5'); + SustainabilitySetup.Validate("Distance Decimal Places", '1:3'); + SustainabilitySetup.Validate("Custom Amt. Decimal Places", '2:5'); + + SustainabilitySetup.Modify(true); + end; + + local procedure CreateSourceCode() + var + ContosoAuditCode: Codeunit "Contoso Audit Code"; + begin + ContosoAuditCode.InsertSourceCode(SustainabilitySourceCode(), SustainabilityDescriptionTok); + end; + + procedure SustainabilitySourceCode(): Code[10] + begin + exit(SustainabilityTok); + end; + + var + SustainabilityTok: Label 'SUSTAIN', MaxLength = 10; + SustainabilityDescriptionTok: Label 'Sustainability Emissions', MaxLength = 100; +} \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/3. Transactions/CreateSustainabilityJournal.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/3. Transactions/CreateSustainabilityJournal.Codeunit.al new file mode 100644 index 0000000000..fa524ba035 --- /dev/null +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/3. Transactions/CreateSustainabilityJournal.Codeunit.al @@ -0,0 +1,69 @@ +codeunit 5221 "Create Sustainability Journal" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + SustainJnlSetup: Codeunit "Create Sustain. Jnl. Setup"; + ContosoUtility: Codeunit "Contoso Utilities"; + begin + CreateLinesForDefaultBatch(SustainJnlSetup.GeneralTemplate(), SustainJnlSetup.DefaultBatch(), ContosoUtility.AdjustDate(20240531D)); + CreateLinesForScope1Batch(SustainJnlSetup.GeneralTemplate(), SustainJnlSetup.Scope1Batch(), ContosoUtility.AdjustDate(20240531D)); + CreateLinesForScope2Batch(SustainJnlSetup.GeneralTemplate(), SustainJnlSetup.Scope2Batch(), ContosoUtility.AdjustDate(20240531D)); + CreateLinesForScope3Batch(SustainJnlSetup.GeneralTemplate(), SustainJnlSetup.Scope3Batch(), ContosoUtility.AdjustDate(20240531D)); + end; + + local procedure CreateLinesForDefaultBatch(TemplateName: Code[10]; BatchName: Code[10]; DefaultDate: Date) + var + ContosoSustainability: Codeunit "Contoso Sustainability"; + Account: Codeunit "Create Sustainability Account"; + CommonUoM: Codeunit "Create Common Unit Of Measure"; + begin + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'SJ00018', Account.CompanyCarLargeSize(), CommonUoM.KM(), 0, 385, 0, 1, 0, '', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'SJ00018', Account.CompanyCarMediumSize(), CommonUoM.KM(), 0, 1820, 0, 1, 0, '', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'SJ00018', Account.CompanyCarPremiumSize(), CommonUoM.KM(), 0, 268, 0, 1, 0, '', ''); + + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'SJ00018', Account.AirContinentalEconomy(), CommonUoM.KM(), 0, 4120, 0, 1, 0, '', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'SJ00018', Account.AirIntercontinentalBusiness(), CommonUoM.KM(), 0, 9860, 0, 1, 0, '', ''); + + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'SJ00018', Account.ContosoHotel3Stars(), CommonUoM.Day(), 0, 0, 2, 1, 0, '', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'SJ00018', Account.ContosoHotel4Stars(), CommonUoM.Day(), 0, 0, 6, 1, 0, '', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'SJ00018', Account.ContosoHotel4StarsJuniorSuite(), CommonUoM.Day(), 0, 0, 3, 1, 0, '', ''); + + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'SJ00018', Account.ContosoRentalCar(), CommonUoM.KM(), 0, 120, 0, 1, 0, '', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'SJ00018', Account.Rail(), CommonUoM.KM(), 0, 0, 0, 1, 0, '', ''); + + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'SJ00018', Account.PurchasedServices(), 0, 0, 0, '', ''); + end; + + local procedure CreateLinesForScope1Batch(TemplateName: Code[10]; BatchName: Code[10]; DefaultDate: Date) + var + ContosoSustainability: Codeunit "Contoso Sustainability"; + Account: Codeunit "Create Sustainability Account"; + CommonUoM: Codeunit "Create Common Unit Of Measure"; + begin + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'EMIS1-0001', Account.OnRoadVehicleUrbanTrucks(), CommonUoM.KM(), 0, 1010, 0, 1, 0, '', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'EMIS1-0001', Account.NonRoadVehiclesTractors(), CommonUoM.L(), 225, 0, 0, 1, 0, '', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'EMIS1-0001', Account.NonRoadVehiclesBackhoes(), CommonUoM.L(), 180, 0, 0, 1, 0, '', ''); + end; + + local procedure CreateLinesForScope2Batch(TemplateName: Code[10]; BatchName: Code[10]; DefaultDate: Date) + var + ContosoSustainability: Codeunit "Contoso Sustainability"; + Account: Codeunit "Create Sustainability Account"; + begin + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'EMIS1-0002', Account.SteamFabrikamInc(), '', 0, 0, 0, 1, 0, '', ''); + end; + + local procedure CreateLinesForScope3Batch(TemplateName: Code[10]; BatchName: Code[10]; DefaultDate: Date) + var + ContosoSustainability: Codeunit "Contoso Sustainability"; + Account: Codeunit "Create Sustainability Account"; + CommonUoM: Codeunit "Create Common Unit Of Measure"; + begin + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'EMIS1-0003', Account.WastePlasticGeneratedInOperation(), CommonUoM.Ton(), 0, 0, 0.41, 1, 0, '', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'EMIS1-0003', Account.WasteOrganicGeneratedInOperation(), CommonUoM.Ton(), 0, 0, 0.63, 1, 0, '', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, DefaultDate, 'EMIS1-0003', Account.RecycledWasteGeneratedInOperation(), CommonUoM.Ton(), 0, 0, 0.82, 1, 0, '', ''); + end; +} \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/4. Historical/CreateSustainabilityEntry.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/4. Historical/CreateSustainabilityEntry.Codeunit.al new file mode 100644 index 0000000000..a374f471e9 --- /dev/null +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/4. Historical/CreateSustainabilityEntry.Codeunit.al @@ -0,0 +1,71 @@ +codeunit 5222 "Create Sustainability Entry" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Sustainability Jnl. Line" = r; + + trigger OnRun() + var + SustainabilityJnlLine: Record "Sustainability Jnl. Line"; + SustainJnlSetup: Codeunit "Create Sustain. Jnl. Setup"; + LastLineNo: Integer; + begin + SustainabilityJnlLine.SetRange("Journal Template Name", SustainJnlSetup.GeneralTemplate()); + SustainabilityJnlLine.SetRange("Journal Batch Name", SustainJnlSetup.DefaultBatch()); + SustainabilityJnlLine.FindLast(); + LastLineNo := SustainabilityJnlLine."Line No."; + + CreateLinesToPost(SustainJnlSetup.GeneralTemplate(), SustainJnlSetup.DefaultBatch()); + + PostCreatedEntries(LastLineNo, SustainJnlSetup.GeneralTemplate(), SustainJnlSetup.DefaultBatch()); + end; + + local procedure CreateLinesToPost(TemplateName: Code[10]; BatchName: Code[10]) + var + ContosoUtility: Codeunit "Contoso Utilities"; + ContosoSustainability: Codeunit "Contoso Sustainability"; + Account: Codeunit "Create Sustainability Account"; + CommonUoM: Codeunit "Create Common Unit Of Measure"; + begin + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240131D), 'SJ00001', Account.Refrigerators(), CommonUoM.Piece(), 0, 0, 15, 3, 0.8, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240131D), 'SJ00001', Account.PurchasedElectricityContosoPowerPlant(), CommonUoM.KWH(), 4682, 0, 0, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240131D), 'SJ00003', Account.CompanyCarLargeSize(), CommonUoM.KM(), 0, 860, 0, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240131D), 'SJ00003', Account.ContosoHotel3Stars(), CommonUoM.Day(), 0, 0, 4, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240131D), 'SJ00003', Account.ContosoRentalCar(), CommonUoM.L(), 16, 0, 0, 1, 0, 'US', ''); + + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240228D), 'SJ00004', Account.Refrigerators(), CommonUoM.Piece(), 0, 0, 15, 3, 0.8, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240228D), 'SJ00004', Account.PurchasedElectricityContosoPowerPlant(), CommonUoM.KWH(), 5011, 0, 0, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240228D), 'SJ00006', Account.CompanyCarLargeSize(), CommonUoM.KM(), 0, 652, 0, 1, 0, 'US', ''); + + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240331D), 'SJ00007', Account.Refrigerators(), CommonUoM.Piece(), 0, 0, 15, 3, 0.8, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240331D), 'SJ00007', Account.PurchasedElectricityContosoPowerPlant(), CommonUoM.KWH(), 4998, 0, 0, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240331D), 'SJ00009', Account.CompanyCarLargeSize(), CommonUoM.KM(), 0, 860, 0, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240331D), 'SJ00009', Account.ContosoHotel4StarsJuniorSuite(), CommonUoM.Day(), 0, 0, 6, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240331D), 'SJ00009', Account.ContosoRentalCar(), CommonUoM.L(), 16, 0, 0, 1, 0, 'US', ''); + + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240430D), 'SJ00012', Account.Refrigerators(), CommonUoM.Piece(), 0, 0, 15, 3, 0.8, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240430D), 'SJ00012', Account.PurchasedElectricityContosoPowerPlant(), CommonUoM.KWH(), 4456, 0, 0, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240430D), 'SJ00014', Account.CompanyCarLargeSize(), CommonUoM.KM(), 0, 564, 0, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240430D), 'SJ00014', Account.CompanyCarPremiumSize(), CommonUoM.KM(), 0, 226, 0, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240430D), 'SJ00014', Account.ContosoHotel4StarsJuniorSuite(), CommonUoM.Day(), 0, 0, 5, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240430D), 'SJ00014', Account.ContosoHotel3Stars(), CommonUoM.Day(), 0, 0, 4, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240430D), 'SJ00014', Account.ContosoRentalCar(), CommonUoM.L(), 16, 0, 0, 1, 0, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240430D), 'SJ00016', Account.AirConditionEquipments24kW(), CommonUoM.Piece(), 0, 0, 5, 44, 0.25, 'US', ''); + + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240531D), 'SJ00017', Account.AirConditionEquipments24kW(), CommonUoM.Piece(), 0, 0, 5, 56, 0.4, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240531D), 'SJ00017', Account.Refrigerators(), CommonUoM.Piece(), 0, 0, 18, 3, 0.85, 'US', ''); + ContosoSustainability.InsertSustainabilityJournalLine(TemplateName, BatchName, ContosoUtility.AdjustDate(20240531D), 'SJ00017', Account.PurchasedElectricityContosoPowerPlant(), CommonUoM.KWH(), 5827, 0, 0, 1, 0, 'US', ''); + end; + + local procedure PostCreatedEntries(LastLineNo: Integer; TemplateName: Code[10]; BatchName: Code[10]) + var + SustainabilityJnlLine: Record "Sustainability Jnl. Line"; + begin + SustainabilityJnlLine.SetRange("Journal Template Name", TemplateName); + SustainabilityJnlLine.SetRange("Journal Batch Name", BatchName); + SustainabilityJnlLine.SetFilter("Line No.", '>%1', LastLineNo); + SustainabilityJnlLine.FindSet(); + + Codeunit.Run(Codeunit::"Sustainability Jnl.-Post", SustainabilityJnlLine); + end; +} \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/SustainabilityModule.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/SustainabilityModule.Codeunit.al new file mode 100644 index 0000000000..85d941c6bd --- /dev/null +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Sustainability/SustainabilityModule.Codeunit.al @@ -0,0 +1,39 @@ +codeunit 5218 "Sustainability Module" implements "Contoso Demo Data Module" +{ + InherentEntitlements = X; + InherentPermissions = X; + + procedure RunConfigurationPage() + begin + exit; + end; + + procedure GetDependencies() Dependencies: List of [enum "Contoso Demo Data Module"] + begin + Dependencies.Add(Enum::"Contoso Demo Data Module"::"Common Module"); + end; + + procedure CreateSetupData() + begin + Codeunit.Run(Codeunit::"Create Sustainability Setup"); + Codeunit.Run(Codeunit::"Create Sustain. No Series"); + Codeunit.Run(Codeunit::"Create Sustainability Category"); + Codeunit.Run(Codeunit::"Create Sustain. Subcategory"); + Codeunit.Run(Codeunit::"Create Sustainability Account"); + Codeunit.Run(Codeunit::"Create Sustain. Jnl. Setup"); + end; + + procedure CreateMasterData() + begin + end; + + procedure CreateTransactionalData() + begin + Codeunit.Run(Codeunit::"Create Sustainability Journal"); + end; + + procedure CreateHistoricalData() + begin + Codeunit.Run(Codeunit::"Create Sustainability Entry"); + end; +} \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Warehousing/1.Setup data/CreateWhseNoSeries.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Warehousing/1.Setup data/CreateWhseNoSeries.Codeunit.al index eda220577f..c8f59d16eb 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Warehousing/1.Setup data/CreateWhseNoSeries.Codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Warehousing/1.Setup data/CreateWhseNoSeries.Codeunit.al @@ -7,26 +7,26 @@ codeunit 4797 "Create Whse No Series" var ContosoNoSeries: codeunit "Contoso No Series"; begin - ContosoNoSeries.InsertNoSeries(TransferOrder(), TransferOrderLbl, '1001', '9999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(TransferShipment(), TransferShipmentLbl, '108001', '108999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(TransferReceipt(), TransferReceiptLbl, '109000', '109999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(InventoryPick(), InventoryPickLbl, 'IPI000001', 'IPI999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(PostedInventoryPick(), PostedInventoryPickLbl, 'PPI000001', 'PPI999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(InventoryPutAway(), InventoryPutAwayLbl, 'IPU000001', 'IPU999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(PostedInventoryPutAway(), PostedInventoryPutAwayLbl, 'PPU000001', 'PPU999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(InventoryMovement(), InventoryMovementLbl, 'IM000001', 'IM999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(RegisteredInventoryMovement(), RegisteredInventoryMomentLbl, 'RIM000001', 'RIM999999', '', '', 1, true, false); - - ContosoNoSeries.InsertNoSeries(WarehouseReceipt(), WarehouseReceiptLbl, 'RE000001', 'RE999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(PostedWarehouseReceipt(), PostedWarehouseReceiptLbl, 'R_000001', 'R_999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(WarehouseShipment(), WarehouseShipmentLbl, 'SH000001', 'SH999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(PostedWarehouseShipment(), PostedWarehouseShipmentLbl, 'S_000001', 'S_999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(WarehousePutAway(), WarehousePutAwayLbl, 'PU000001', 'PU999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(RegisteredWarehousePutAway(), RegisteredWarehousePutAwayLbl, 'PU_000001', 'PU_999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(WarehousePick(), WarehousePickLbl, 'PI000001', 'PI999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(RegisteredWarehousePick(), RegisteredWarehousePickLbl, 'P_000001', 'P_999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(WarehouseMovement(), WarehouseMovementLbl, 'WM000001', 'WM999999', '', '', 1, true, false); - ContosoNoSeries.InsertNoSeries(RegisteredWarehouseMovement(), RegisteredWarehouseMovementLbl, 'WM_000001', 'WM_999999', '', '', 1, true, false); + ContosoNoSeries.InsertNoSeries(TransferOrder(), TransferOrderLbl, '1001', '9999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(TransferShipment(), TransferShipmentLbl, '108001', '108999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(TransferReceipt(), TransferReceiptLbl, '109000', '109999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(InventoryPick(), InventoryPickLbl, 'IPI000001', 'IPI999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(PostedInventoryPick(), PostedInventoryPickLbl, 'PPI000001', 'PPI999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(InventoryPutAway(), InventoryPutAwayLbl, 'IPU000001', 'IPU999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(PostedInventoryPutAway(), PostedInventoryPutAwayLbl, 'PPU000001', 'PPU999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(InventoryMovement(), InventoryMovementLbl, 'IM000001', 'IM999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(RegisteredInventoryMovement(), RegisteredInventoryMomentLbl, 'RIM000001', 'RIM999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + + ContosoNoSeries.InsertNoSeries(WarehouseReceipt(), WarehouseReceiptLbl, 'RE000001', 'RE999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(PostedWarehouseReceipt(), PostedWarehouseReceiptLbl, 'R_000001', 'R_999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(WarehouseShipment(), WarehouseShipmentLbl, 'SH000001', 'SH999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(PostedWarehouseShipment(), PostedWarehouseShipmentLbl, 'S_000001', 'S_999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(WarehousePutAway(), WarehousePutAwayLbl, 'PU000001', 'PU999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(RegisteredWarehousePutAway(), RegisteredWarehousePutAwayLbl, 'PU_000001', 'PU_999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(WarehousePick(), WarehousePickLbl, 'PI000001', 'PI999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(RegisteredWarehousePick(), RegisteredWarehousePickLbl, 'P_000001', 'P_999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(WarehouseMovement(), WarehouseMovementLbl, 'WM000001', 'WM999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); + ContosoNoSeries.InsertNoSeries(RegisteredWarehouseMovement(), RegisteredWarehouseMovementLbl, 'WM_000001', 'WM_999999', '', '', 1, Enum::"No. Series Implementation"::Sequence, false); end; var diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoAuditCode.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoAuditCode.Codeunit.al new file mode 100644 index 0000000000..53ff806ef7 --- /dev/null +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoAuditCode.Codeunit.al @@ -0,0 +1,36 @@ +codeunit 5219 "Contoso Audit Code" +{ + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Source Code" = rim; + + var + OverwriteData: Boolean; + + procedure SetOverwriteData(Overwrite: Boolean) + begin + OverwriteData := Overwrite; + end; + + procedure InsertSourceCode(Code: Code[10]; Description: Text[100]) + var + SourceCode: Record "Source Code"; + Exists: Boolean; + begin + if SourceCode.Get(Code) then begin + Exists := true; + + if not OverwriteData then + exit; + end; + + SourceCode.Validate(Code, Code); + SourceCode.Validate(Description, Description); + + if Exists then + SourceCode.Modify(true) + else + SourceCode.Insert(true); + + end; +} \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoNoSeries.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoNoSeries.Codeunit.al index e49b229ebc..c120dc0e4c 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoNoSeries.Codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoNoSeries.Codeunit.al @@ -14,6 +14,9 @@ codeunit 5127 "Contoso No Series" OverwriteData := Overwrite; end; +#if not CLEAN24 +#pragma warning disable AL0432 + [Obsolete('Allow Gaps has been obsoleted, please specify an implementation instead. Enum value Sequence allows gaps, while Normal does not.', '24.0')] procedure InsertNoSeries(NoSeriesCode: Code[20]; Description: Text[100]; StartingNo: Code[20]; EndingNo: Code[20]; WarningNo: Code[20]; LastNoUsed: Code[20]; IncrementBy: Integer; AllowGaps: Boolean; AllowManualNo: Boolean) var NoSeries: Record "No. Series"; @@ -60,6 +63,55 @@ codeunit 5127 "Contoso No Series" else NoSeriesLine.Insert(true); end; +#pragma warning restore AL0432 +#endif + + procedure InsertNoSeries(NoSeriesCode: Code[20]; Description: Text[100]; StartingNo: Code[20]; EndingNo: Code[20]; WarningNo: Code[20]; LastNoUsed: Code[20]; IncrementBy: Integer; Implementation: Enum "No. Series Implementation"; AllowManualNo: Boolean) + var + NoSeries: Record "No. Series"; + NoSeriesLine: Record "No. Series Line"; + NoSeriesExists, NoSeriesLineExists : Boolean; + begin + if NoSeries.Get(NoSeriesCode) then begin + NoSeriesExists := true; + + if not OverwriteData then + exit; + end; + + + NoSeries.Init(); + NoSeries.Validate(Code, NoSeriesCode); + NoSeries.Validate(Description, Description); + NoSeries.Validate("Default Nos.", true); + NoSeries.Validate("Manual Nos.", AllowManualNo); + + if NoSeriesExists then + NoSeries.Modify(true) + else + NoSeries.Insert(true); + + if NoSeriesLine.Get(NoSeriesCode, GetDefaultLineNo()) then begin + NoSeriesLineExists := true; + + if not OverwriteData then + exit; + end; + + NoSeriesLine.Validate("Series Code", NoSeries.Code); + NoSeriesLine.Validate("Starting No.", StartingNo); + NoSeriesLine.Validate("Ending No.", EndingNo); + NoSeriesLine.Validate("Warning No.", WarningNo); + NoSeriesLine.Validate("Last No. Used", LastNoUsed); + NoSeriesLine.Validate("Increment-by No.", IncrementBy); + NoSeriesLine.Validate(Implementation, Implementation); + NoSeriesLine.Validate("Line No.", GetDefaultLineNo()); + + if NoSeriesLineExists then + NoSeriesLine.Modify(true) + else + NoSeriesLine.Insert(true); + end; local procedure GetDefaultLineNo(): Integer begin diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoSustainability.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoSustainability.Codeunit.al new file mode 100644 index 0000000000..9b4801f616 --- /dev/null +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/Contoso Helpers/ContosoSustainability.Codeunit.al @@ -0,0 +1,201 @@ +codeunit 5216 "Contoso Sustainability" +{ + InherentPermissions = X; + InherentEntitlements = X; + Permissions = + tabledata "Sustain. Account Category" = rim, + tabledata "Sustain. Account Subcategory" = rim, + tabledata "Sustainability Account" = rim, + tabledata "Sustainability Jnl. Template" = rim, + tabledata "Sustainability Jnl. Batch" = rim, + tabledata "Sustainability Jnl. Line" = rim; + + var + OverwriteData: Boolean; + + procedure SetOverwriteData(Overwrite: Boolean) + begin + OverwriteData := Overwrite; + end; + + procedure InsertAccountCategory(Code: Code[20]; Description: Text[100]; Scope: Enum "Emission Scope"; CalcFoundation: Enum "Calculation Foundation"; CO2: Boolean; CH4: Boolean; N2O: Boolean; CustomValue: Text[100]; CalcFromGL: Boolean) + var + SustainAccountCategory: Record "Sustain. Account Category"; + Exists: Boolean; + begin + if SustainAccountCategory.Get(Code) then begin + Exists := true; + + if not OverwriteData then + exit; + end; + + SustainAccountCategory.Validate(Code, Code); + SustainAccountCategory.Validate(Description, Description); + SustainAccountCategory.Validate("Emission Scope", Scope); + SustainAccountCategory.Validate("Calculation Foundation", CalcFoundation); + SustainAccountCategory.Validate(CO2, CO2); + SustainAccountCategory.Validate(CH4, CH4); + SustainAccountCategory.Validate(N2O, N2O); + SustainAccountCategory.Validate("Custom Value", CustomValue); + SustainAccountCategory.Validate("Calculate from General Ledger", CalcFromGL); + + if Exists then + SustainAccountCategory.Modify(true) + else + SustainAccountCategory.Insert(true); + end; + + procedure InsertAccountSubcategory(CategoryCode: Code[20]; SubcategoryCode: Code[20]; Description: Text[100]; EFCO2: Decimal; EFCH4: Decimal; EFN2O: Decimal; RenewableEnergy: Boolean) + var + SustainAccountSubcategory: Record "Sustain. Account Subcategory"; + Exists: Boolean; + begin + if SustainAccountSubcategory.Get(CategoryCode, SubcategoryCode) then begin + Exists := true; + + if not OverwriteData then + exit; + end; + + SustainAccountSubcategory.Validate("Category Code", CategoryCode); + SustainAccountSubcategory.Validate(Code, SubcategoryCode); + SustainAccountSubcategory.Validate(Description, Description); + SustainAccountSubcategory.Validate("Emission Factor CO2", EFCO2); + SustainAccountSubcategory.Validate("Emission Factor CH4", EFCH4); + SustainAccountSubcategory.Validate("Emission Factor N2O", EFN2O); + SustainAccountSubcategory.Validate("Renewable Energy", RenewableEnergy); + + if Exists then + SustainAccountSubcategory.Modify(true) + else + SustainAccountSubcategory.Insert(true); + end; + + procedure InsertSustainabilityAccount(AccountNo: Code[20]; Name: Text[100]; CategoryCode: Code[20]; SubcategoryCode: Code[20]; AccountType: Enum "Sustainability Account Type"; Totaling: Text[250]; DirectPosting: Boolean) + var + SustainabilityAccount: Record "Sustainability Account"; + Exists: Boolean; + begin + if SustainabilityAccount.Get(AccountNo) then begin + Exists := true; + + if not OverwriteData then + exit; + end; + + SustainabilityAccount.Validate("No.", AccountNo); + SustainabilityAccount.Validate(Name, Name); + SustainabilityAccount.Validate(Category, CategoryCode); + SustainabilityAccount.Validate(Subcategory, SubcategoryCode); + SustainabilityAccount.Validate("Account Type", AccountType); + SustainabilityAccount.Validate(Totaling, Totaling); + SustainabilityAccount.Validate("Direct Posting", DirectPosting); + + if Exists then + SustainabilityAccount.Modify(true) + else + SustainabilityAccount.Insert(true); + end; + + procedure InsertSustainabilityJournalTemplate(Name: Code[10]; Description: Text[80]; Recurring: Boolean) + var + SustainabilityJnlTemplate: Record "Sustainability Jnl. Template"; + Exists: Boolean; + begin + if SustainabilityJnlTemplate.Get(Name) then begin + Exists := true; + + if not OverwriteData then + exit; + end; + + SustainabilityJnlTemplate.Validate(Name, Name); + SustainabilityJnlTemplate.Validate(Description, Description); + SustainabilityJnlTemplate.Validate(Recurring, Recurring); + + if Exists then + SustainabilityJnlTemplate.Modify(true) + else + SustainabilityJnlTemplate.Insert(true); + end; + + procedure InsertSustainabilityJournalBatch(TemplateName: Code[10]; BatchName: Code[10]; Description: Text[100]; NoSeries: Code[20]; EmissionScope: Enum "Emission Scope"; SourceCode: Code[10]) + var + SustainabilityJnlBatch: Record "Sustainability Jnl. Batch"; + Exists: Boolean; + begin + if SustainabilityJnlBatch.Get(TemplateName, BatchName) then begin + Exists := true; + + if not OverwriteData then + exit; + end; + + SustainabilityJnlBatch.Validate("Journal Template Name", TemplateName); + SustainabilityJnlBatch.Validate(Name, BatchName); + SustainabilityJnlBatch.Validate(Description, Description); + SustainabilityJnlBatch.Validate("No Series", NoSeries); + SustainabilityJnlBatch.Validate("Emission Scope", EmissionScope); + SustainabilityJnlBatch.Validate("Source Code", SourceCode); + + if Exists then + SustainabilityJnlBatch.Modify(true) + else + SustainabilityJnlBatch.Insert(true); + end; + + procedure InsertSustainabilityJournalLine(TemplateName: Code[10]; BatchName: Code[10]; PostingDate: Date; DocumentNo: Code[20]; AccountNo: Code[20]; ManualInput: Boolean; UoM: Code[10]; FuelElectricity: Decimal; Distance: Decimal; CustomAmount: Decimal; Installation: Decimal; TimeFactor: Decimal; EmissionCO2: Decimal; EmissionCH4: Decimal; EmissionN2O: Decimal; CountryOrRegion: Code[10]; ResponsibilityCenter: Code[10]) + var + SustainabilityJnlLine: Record "Sustainability Jnl. Line"; + begin + SustainabilityJnlLine.Validate("Journal Template Name", TemplateName); + SustainabilityJnlLine.Validate("Journal Batch Name", BatchName); + SustainabilityJnlLine.Validate("Line No.", GetNextSustainabilityJournalLineNo(TemplateName, BatchName)); + SustainabilityJnlLine.Validate("Posting Date", PostingDate); + SustainabilityJnlLine.Validate("Document No.", DocumentNo); + SustainabilityJnlLine.Validate("Account No.", AccountNo); + SustainabilityJnlLine.Validate("Manual Input", ManualInput); + SustainabilityJnlLine.Validate("Country/Region Code", CountryOrRegion); + SustainabilityJnlLine.Validate("Responsibility Center", ResponsibilityCenter); + + if ManualInput then begin + SustainabilityJnlLine.Validate("Emission CO2", EmissionCO2); + SustainabilityJnlLine.Validate("Emission CH4", EmissionCH4); + SustainabilityJnlLine.Validate("Emission N2O", EmissionN2O); + end else begin + SustainabilityJnlLine.Validate("Unit of Measure", UoM); + SustainabilityJnlLine.Validate("Fuel/Electricity", FuelElectricity); + SustainabilityJnlLine.Validate(Distance, Distance); + SustainabilityJnlLine.Validate("Custom Amount", CustomAmount); + SustainabilityJnlLine.Validate("Installation Multiplier", Installation); + SustainabilityJnlLine.Validate("Time Factor", TimeFactor); + end; + + SustainabilityJnlLine.Insert(true); + end; + + procedure InsertSustainabilityJournalLine(TemplateName: Code[10]; BatchName: Code[10]; PostingDate: Date; DocumentNo: Code[20]; AccountNo: Code[20]; UoM: Code[10]; FuelElectricity: Decimal; Distance: Decimal; CustomAmount: Decimal; Installation: Decimal; TimeFactor: Decimal; CountryOrRegion: Code[10]; ResponsibilityCenter: Code[10]) + begin + InsertSustainabilityJournalLine(TemplateName, BatchName, PostingDate, DocumentNo, AccountNo, false, UoM, FuelElectricity, Distance, CustomAmount, Installation, TimeFactor, 0, 0, 0, CountryOrRegion, ResponsibilityCenter); + end; + + procedure InsertSustainabilityJournalLine(TemplateName: Code[10]; BatchName: Code[10]; PostingDate: Date; DocumentNo: Code[20]; AccountNo: Code[20]; EmissionCO2: Decimal; EmissionCH4: Decimal; EmissionN2O: Decimal; CountryOrRegion: Code[10]; ResponsibilityCenter: Code[10]) + begin + InsertSustainabilityJournalLine(TemplateName, BatchName, PostingDate, DocumentNo, AccountNo, true, '', 0, 0, 0, 1, 0, EmissionCO2, EmissionCH4, EmissionN2O, CountryOrRegion, ResponsibilityCenter); + end; + + local procedure GetNextSustainabilityJournalLineNo(TemplateName: Code[10]; BatchName: Code[10]): Integer + var + SustainabilityJnlLine: Record "Sustainability Jnl. Line"; + begin + SustainabilityJnlLine.SetRange("Journal Template Name", TemplateName); + SustainabilityJnlLine.SetRange("Journal Batch Name", BatchName); + SustainabilityJnlLine.SetCurrentKey("Line No."); + + if SustainabilityJnlLine.FindLast() then + exit(SustainabilityJnlLine."Line No." + 10000) + else + exit(10000); + end; +} \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/ContosoDemoDataModule.Enum.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/ContosoDemoDataModule.Enum.al index ed095f6e67..f3049405b4 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/ContosoDemoDataModule.Enum.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/ContosoDemoDataModule.Enum.al @@ -30,4 +30,8 @@ enum 5160 "Contoso Demo Data Module" implements "Contoso Demo Data Module" { Implementation = "Contoso Demo Data Module" = "Job Module"; } + value(7; "Sustainability Module") + { + Implementation = "Contoso Demo Data Module" = "Sustainability Module"; + } } \ No newline at end of file diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/app.json b/Apps/W1/ContosoCoffeeDemoDataset/app/app.json index 29c21faf56..53c3d22c3f 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/app.json +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/app.json @@ -10,7 +10,14 @@ "help": "https://go.microsoft.com/fwlink/?linkid=2187180", "url": "https://go.microsoft.com/fwlink/?linkid=724011", "logo": "./ExtensionLogo.png", - "dependencies": [], + "dependencies": [ + { + "id": "b3780cd9-f8f8-4a83-a4d5-0c2ad87b28af", + "name": "Sustainability", + "publisher": "Microsoft", + "version": "24.0.0.0" + } + ], "internalsVisibleTo": [ { "id": "c471774f-4b9e-45eb-9619-e7e0b96a8b98", diff --git a/Apps/W1/EDocument/app/Permissions/EDocCoreBasic.PermissionSet.al b/Apps/W1/EDocument/app/Permissions/EDocCoreBasic.PermissionSet.al index 3f11547bf3..473d9e4217 100644 --- a/Apps/W1/EDocument/app/Permissions/EDocCoreBasic.PermissionSet.al +++ b/Apps/W1/EDocument/app/Permissions/EDocCoreBasic.PermissionSet.al @@ -5,6 +5,7 @@ namespace Microsoft.eServices.EDocument; using Microsoft.eServices.EDocument.IO.Peppol; +using Microsoft.EServices.EDocument.OrderMatch; permissionset 6103 "E-Doc. Core - Basic" { @@ -24,5 +25,7 @@ permissionset 6103 "E-Doc. Core - Basic" tabledata "E-Document Service Status" = im, tabledata "E-Document Integration Log" = im, tabledata "E-Doc. Service Data Exch. Def." = im, - tabledata "E-Doc. Service Supported Type" = im; + tabledata "E-Doc. Service Supported Type" = im, + tabledata "E-Doc. Imported Line" = im, + tabledata "E-Doc. Order Match" = im; } diff --git a/Apps/W1/EDocument/app/Permissions/EDocCoreEdit.PermissionSet.al b/Apps/W1/EDocument/app/Permissions/EDocCoreEdit.PermissionSet.al index 69b4ed77ee..cb4f81f9bd 100644 --- a/Apps/W1/EDocument/app/Permissions/EDocCoreEdit.PermissionSet.al +++ b/Apps/W1/EDocument/app/Permissions/EDocCoreEdit.PermissionSet.al @@ -5,6 +5,7 @@ namespace Microsoft.eServices.EDocument; using Microsoft.eServices.EDocument.IO.Peppol; +using Microsoft.EServices.EDocument.OrderMatch; permissionset 6102 "E-Doc. Core - Edit" { @@ -24,5 +25,7 @@ permissionset 6102 "E-Doc. Core - Edit" tabledata "E-Document Service Status" = IMD, tabledata "E-Document Integration Log" = IMD, tabledata "E-Doc. Service Data Exch. Def." = IMD, - tabledata "E-Doc. Service Supported Type" = IMD; + tabledata "E-Doc. Service Supported Type" = IMD, + tabledata "E-Doc. Imported Line" = IMD, + tabledata "E-Doc. Order Match" = IMD; } diff --git a/Apps/W1/EDocument/app/Permissions/EDocCoreObjects.PermissionSet.al b/Apps/W1/EDocument/app/Permissions/EDocCoreObjects.PermissionSet.al index b330085d35..2e4cc0850f 100644 --- a/Apps/W1/EDocument/app/Permissions/EDocCoreObjects.PermissionSet.al +++ b/Apps/W1/EDocument/app/Permissions/EDocCoreObjects.PermissionSet.al @@ -6,6 +6,7 @@ namespace Microsoft.eServices.EDocument; using Microsoft.eServices.EDocument.IO; using Microsoft.eServices.EDocument.IO.Peppol; +using Microsoft.EServices.EDocument.OrderMatch; permissionset 6100 "E-Doc. Core - Objects" { @@ -22,6 +23,8 @@ permissionset 6100 "E-Doc. Core - Objects" table "E-Document Service Status" = X, table "E-Doc. Service Data Exch. Def." = X, table "E-Doc. Service Supported Type" = X, + table "E-Doc. Order Match" = X, + table "E-Doc. Imported Line" = X, codeunit "E-Document Import Job" = X, codeunit "E-Doc. Integration Management" = X, codeunit "E-Doc. Mapping" = X, @@ -58,6 +61,7 @@ permissionset 6100 "E-Doc. Core - Objects" codeunit "Pre-Map Service Cr. Memo Line" = X, codeunit "Pre-Map Service Inv. Line" = X, codeunit "EDoc PEPPOL BIS 3.0" = X, + codeunit "E-Doc. Line Matching" = X, page "E-Doc. Changes Part" = X, page "E-Doc. Changes Preview" = X, page "E-Document Activities" = X, @@ -71,5 +75,10 @@ permissionset 6100 "E-Doc. Core - Objects" page "E-Document Service Status" = X, page "E-Document Integration Logs" = X, page "E-Doc. Service Data Exch. Sub" = X, + page "E-Doc. Order Match" = X, + page "E-Doc. Order Line Matching" = X, + page "E-Doc. Imported Line Sub" = X, + page "E-Doc. Purchase Order Sub" = X, + page "E-Doc. Order Map. Activities" = X, page "E-Doc Service Supported Types" = X; } diff --git a/Apps/W1/EDocument/app/Permissions/EDocCoreRead.PermissionSet.al b/Apps/W1/EDocument/app/Permissions/EDocCoreRead.PermissionSet.al index 5c0b18cae4..e9def7febb 100644 --- a/Apps/W1/EDocument/app/Permissions/EDocCoreRead.PermissionSet.al +++ b/Apps/W1/EDocument/app/Permissions/EDocCoreRead.PermissionSet.al @@ -5,6 +5,7 @@ namespace Microsoft.eServices.EDocument; using Microsoft.eServices.EDocument.IO.Peppol; +using Microsoft.EServices.EDocument.OrderMatch; permissionset 6101 "E-Doc. Core - Read" { @@ -21,5 +22,7 @@ permissionset 6101 "E-Doc. Core - Read" tabledata "E-Document Service Status" = R, tabledata "E-Document Integration Log" = R, tabledata "E-Doc. Service Data Exch. Def." = R, - tabledata "E-Doc. Service Supported Type" = R; + tabledata "E-Doc. Service Supported Type" = R, + tabledata "E-Doc. Imported Line" = R, + tabledata "E-Doc. Order Match" = R; } \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/DataExchange/EDocDataExchangeImpl.Codeunit.al b/Apps/W1/EDocument/app/src/DataExchange/EDocDataExchangeImpl.Codeunit.al index 700ed0f885..2c9e02ad55 100644 --- a/Apps/W1/EDocument/app/src/DataExchange/EDocDataExchangeImpl.Codeunit.al +++ b/Apps/W1/EDocument/app/src/DataExchange/EDocDataExchangeImpl.Codeunit.al @@ -204,6 +204,7 @@ codeunit 6152 "E-Doc. Data Exchange Impl." implements "E-Document" TempFieldBuffer: Record "Field Buffer" temporary; begin AddFieldToFieldBuffer(TempFieldBuffer, EDocument.FieldNo("Incoming E-Document No.")); + AddFieldToFieldBuffer(TempFieldBuffer, EDocument.FieldNo("Order No.")); AddFieldToFieldBuffer(TempFieldBuffer, EDocument.FieldNo("Bill-to/Pay-to No.")); AddFieldToFieldBuffer(TempFieldBuffer, EDocument.FieldNo("Bill-to/Pay-to Name")); AddFieldToFieldBuffer(TempFieldBuffer, EDocument.FieldNo("Document Date")); @@ -315,8 +316,12 @@ codeunit 6152 "E-Doc. Data Exchange Impl." implements "E-Document" if EDocument."Document Type" = EDocument."Document Type"::"Purchase Credit Memo" then exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo("Vendor Cr. Memo No."))); end; + EDocument.FieldNo("Order No."): + exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo("Vendor Order No."))); EDocument.FieldNo("Bill-to/Pay-to Name"): exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo("Buy-from Vendor Name"))); + EDocument.FieldNo("Bill-to/Pay-to No."): + exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo("Buy-from Vendor No."))); EDocument.FieldNo("Document Date"): exit(DataExchLineDef.GetPath(Database::"Purchase Header", PurchaseHeader.FieldNo("Document Date"))); EDocument.FieldNo("Due Date"): diff --git a/Apps/W1/EDocument/app/src/DataExchange/PEPPOL Data Exchange Definition/src/EDocDEDPEPPOLPreMapping.Codeunit.al b/Apps/W1/EDocument/app/src/DataExchange/PEPPOL Data Exchange Definition/src/EDocDEDPEPPOLPreMapping.Codeunit.al index 2f544307ee..09664f137f 100644 --- a/Apps/W1/EDocument/app/src/DataExchange/PEPPOL Data Exchange Definition/src/EDocDEDPEPPOLPreMapping.Codeunit.al +++ b/Apps/W1/EDocument/app/src/DataExchange/PEPPOL Data Exchange Definition/src/EDocDEDPEPPOLPreMapping.Codeunit.al @@ -432,21 +432,19 @@ codeunit 6156 "E-Doc. DED PEPPOL Pre-Mapping" Clear(TempInteger); TempInteger.DeleteAll(); + IntermediateDataImport.SetCurrentKey("Data Exch. No.", "Table ID", "Record No."); IntermediateDataImport.SetRange("Data Exch. No.", DataExchEntryNo); IntermediateDataImport.SetRange("Table ID", TableID); IntermediateDataImport.SetRange("Parent Record No.", ParentRecNo); - IntermediateDataImport.SetCurrentKey("Record No."); - if not IntermediateDataImport.FindSet() then - exit; - - repeat - if CurrRecNo <> IntermediateDataImport."Record No." then begin - CurrRecNo := IntermediateDataImport."Record No."; - Clear(TempInteger); - TempInteger.Number := CurrRecNo; - TempInteger.Insert(); - end; - until IntermediateDataImport.Next() = 0; + if IntermediateDataImport.FindSet() then + repeat + if CurrRecNo <> IntermediateDataImport."Record No." then begin + CurrRecNo := IntermediateDataImport."Record No."; + Clear(TempInteger); + TempInteger.Number := CurrRecNo; + TempInteger.Insert(); + end; + until IntermediateDataImport.Next() = 0; end; local procedure ApplyInvoiceCharges(DataExchEntryNo: Integer) diff --git a/Apps/W1/EDocument/app/src/DataExchange/PEPPOL Data Exchange Definition/src/EDocDEDPEPPOLSubscribers.Codeunit.al b/Apps/W1/EDocument/app/src/DataExchange/PEPPOL Data Exchange Definition/src/EDocDEDPEPPOLSubscribers.Codeunit.al index a4b7cce647..da081cbe5d 100644 --- a/Apps/W1/EDocument/app/src/DataExchange/PEPPOL Data Exchange Definition/src/EDocDEDPEPPOLSubscribers.Codeunit.al +++ b/Apps/W1/EDocument/app/src/DataExchange/PEPPOL Data Exchange Definition/src/EDocDEDPEPPOLSubscribers.Codeunit.al @@ -35,16 +35,16 @@ codeunit 6162 "E-Doc. DED PEPPOL Subscribers" ProcessedDocType := ProcessedDocType2; end; - procedure IsRoundingLine(SalesLine: Record "Sales Line"): Boolean; + procedure IsRoundingLine(SalesLine2: Record "Sales Line"): Boolean; var Customer: Record Customer; CustomerPostingGroup: Record "Customer Posting Group"; begin - if SalesLine.Type = SalesLine.Type::"G/L Account" then begin - Customer.Get(SalesLine."Bill-to Customer No."); + if SalesLine2.Type = SalesLine2.Type::"G/L Account" then begin + Customer.Get(SalesLine2."Bill-to Customer No."); CustomerPostingGroup.SetFilter(Code, Customer."Customer Posting Group"); if CustomerPostingGroup.FindFirst() then - if SalesLine."No." = CustomerPostingGroup."Invoice Rounding Account" then + if SalesLine2."No." = CustomerPostingGroup."Invoice Rounding Account" then exit(true); end; exit(false); diff --git a/Apps/W1/EDocument/app/src/Document/EDocument.Page.al b/Apps/W1/EDocument/app/src/Document/EDocument.Page.al index 73493b9816..502b11de08 100644 --- a/Apps/W1/EDocument/app/src/Document/EDocument.Page.al +++ b/Apps/W1/EDocument/app/src/Document/EDocument.Page.al @@ -5,6 +5,7 @@ namespace Microsoft.eServices.EDocument; using Microsoft.Bank.Reconciliation; +using Microsoft.eServices.EDocument.OrderMatch; using System.Utilities; page 6121 "E-Document" @@ -15,7 +16,7 @@ page 6121 "E-Document" InsertAllowed = false; DeleteAllowed = false; ModifyAllowed = false; - AdditionalSearchTerms = 'Edoc,Electronic Document'; + RefreshOnActivate = true; layout { @@ -25,7 +26,7 @@ page 6121 "E-Document" { field(Record; RecordLinkTxt) { - Caption = 'Record'; + Caption = 'Document'; Editable = false; ToolTip = 'Specifies the record, document, journal line, or ledger entry, that is linked to the electronic document.'; @@ -35,6 +36,13 @@ page 6121 "E-Document" CurrPage.Update(); end; } + field("Electronic Document Status"; Rec.Status) + { + Editable = false; + Caption = 'Document Status'; + ToolTip = 'Specifies the status of the electronic document.'; + StyleExpr = StyleStatusTxt; + } field(Direction; Rec.Direction) { Importance = Additional; @@ -107,16 +115,11 @@ page 6121 "E-Document" Importance = Additional; ToolTip = 'Specifies the electronic document posting date.'; } - field("Electronic Document Status"; Rec.Status) - { - Editable = false; - ToolTip = 'Specifies the status of the electronic document.'; - } } group(ReceivingCompanyInfo) { Caption = 'Receiving Company Information'; - Visible = Rec.Direction = Rec.Direction::Incoming; + Visible = false; field("Receiving Company VAT Reg. No."; Rec."Receiving Company VAT Reg. No.") { @@ -145,24 +148,38 @@ page 6121 "E-Document" ToolTip = 'Specifies the receiving company address.'; } } + part(EdocoumentServiceStatus; "E-Document Service Status") + { + Caption = 'Service Status'; + SubPageLink = "E-Document Entry No" = field("Entry No"); + ShowFilter = false; + } +#if NOT CLEAN24 group(EDocServiceStatus) { - ShowCaption = false; - part(EdocoumentServiceStatus; "E-Document Service Status") - { - SubPageLink = "E-Document Entry No" = field("Entry No"); - ShowFilter = false; - } + Visible = false; + Enabled = false; + ObsoleteTag = '24.0'; + ObsoleteReason = 'Part inside group moved out'; + ObsoleteState = Pending; + } +#endif + part(ErrorMessagesPart; "Error Messages Part") + { + Visible = HasErrorsAndWarnings; + ShowFilter = false; + UpdatePropagation = Both; } +#if NOT CLEAN24 group("Errors and Warnings") { - ShowCaption = false; - part(ErrorMessagesPart; "Error Messages Part") - { - Caption = 'Errors and Warnings'; - ShowFilter = false; - } + Visible = false; + Enabled = false; + ObsoleteTag = '24.0'; + ObsoleteReason = 'Part inside group moved out'; + ObsoleteState = Pending; } +#endif } } actions @@ -172,12 +189,13 @@ page 6121 "E-Document" group(Outgoing) { Caption = 'Outgoing'; + action(Send) { Caption = 'Send Document'; ToolTip = 'Starts the document export.'; Image = SendElectronicDocument; - Visible = Rec.Direction = Rec.Direction::Outgoing; + Visible = not IsIncomingDoc; trigger OnAction() begin @@ -189,7 +207,7 @@ page 6121 "E-Document" Caption = 'Recreate Document'; ToolTip = 'Recreates the electronic document'; Image = CreateDocument; - Visible = Rec.Direction = Rec.Direction::Outgoing; + Visible = not IsIncomingDoc; trigger OnAction() var @@ -210,7 +228,7 @@ page 6121 "E-Document" Caption = 'Get Approval'; ToolTip = 'Gets if the electronic document is approved or rejected'; Image = Approval; - Visible = Rec.Direction = Rec.Direction::Outgoing; + Visible = not IsIncomingDoc; trigger OnAction() var @@ -230,7 +248,7 @@ page 6121 "E-Document" Caption = 'Cancel EDocument'; ToolTip = 'Cancels the electronic document'; Image = Cancel; - Visible = Rec.Direction = Rec.Direction::Outgoing; + Visible = not IsIncomingDoc; trigger OnAction() var @@ -249,24 +267,12 @@ page 6121 "E-Document" group(Incoming) { Caption = 'Incoming'; - action(ImportManually) - { - Caption = 'Import Manually'; - ToolTip = 'Imports the electronic document manually.'; - Image = Import; - Visible = Rec.Direction = Rec.Direction::Incoming; - - trigger OnAction() - begin - EDocImport.UploadDocument(Rec); - end; - } action(GetBasicInfo) { Caption = 'Get Basic Info'; ToolTip = 'Gets the electronic document basic info.'; Image = GetOrder; - Visible = Rec.Direction = Rec.Direction::Incoming; + Visible = false; trigger OnAction() begin @@ -275,38 +281,74 @@ page 6121 "E-Document" } action(CreateDocument) { - Caption = 'Create Document'; - ToolTip = 'Creates the document based on imported electronic document.'; - Image = CreateDocument; - Visible = Rec.Direction = Rec.Direction::Incoming; + Caption = 'Recreate Document'; + ToolTip = 'Recreate the document based on imported electronic document.'; + Image = CreateXMLFile; + Visible = (not ShowCreateJnlLine) and IsIncomingDoc and HasErrorsAndWarnings; trigger OnAction() begin - EDocImport.ProcessDocument(Rec, false, false); + EDocImport.ProcessDocument(Rec, false); end; } action(CreateJournal) { - Caption = 'Create Journal'; - ToolTip = 'Creates the journal line.'; + Caption = 'Recreate Journal Line'; + ToolTip = 'Recreate the journal line.'; Image = Journal; - Visible = Rec.Direction = Rec.Direction::Incoming; + Visible = ShowCreateJnlLine and IsIncomingDoc and HasErrorsAndWarnings; trigger OnAction() begin - EDocImport.ProcessDocument(Rec, false, true); + EDocImport.ProcessDocument(Rec, true); end; } +#if not CLEAN24 action(UpdateOrder) { Caption = 'Update Order'; ToolTip = 'Updates related order.'; Image = UpdateDescription; - Visible = Rec.Direction = Rec.Direction::Incoming; + Visible = false; + Enabled = false; + ObsoleteTag = '24.0'; + ObsoleteReason = 'Update order changed to "Receive E-Document To" on Vendor'; + ObsoleteState = Pending; + + trigger OnAction() + begin + exit; + end; + } +#endif + action(MatchToOrder) + { + Caption = 'Match Purchase Order'; + ToolTip = 'Match E-document lines to Purchase Order.'; + Image = Reconcile; + Visible = ShowMapToOrder; + + trigger OnAction() + var + EDocOrderMatch: Codeunit "E-Doc. Line Matching"; + begin + EDocOrderMatch.RunMatching(Rec); + end; + } + } + group(Troubleshoot) + { + Caption = 'Troubleshoot'; + action(ImportManually) + { + Caption = 'Replace Source Document'; + ToolTip = 'Import and replace the electronic document.'; + Image = UpdateXML; + Visible = IsIncomingDoc and HasErrorsAndWarnings; trigger OnAction() begin - EDocImport.ProcessDocument(Rec, true, false); + EDocImport.UploadDocument(Rec); end; } action(TextToAccountMapping) @@ -315,9 +357,13 @@ page 6121 "E-Document" Image = MapAccounts; RunObject = Page "Text-to-Account Mapping Wksh."; ToolTip = 'Create a mapping of text on electronic documents to identical text on specific debit, credit, and balancing accounts in the general ledger or on bank accounts so that the resulting document or journal lines are prefilled with the specified information.'; - Visible = Rec.Direction = Rec.Direction::Incoming; + Visible = IsIncomingDoc and HasErrorsAndWarnings; } } + + } + area(Navigation) + { action(EDocumentLog) { Caption = 'Logs'; @@ -330,35 +376,88 @@ page 6121 "E-Document" } area(Promoted) { - group(Out) + group(Category_Process) { - Caption = 'Outgoing'; + actionref(MatchToOrder_Promoted; MatchToOrder) { } + actionref(CreateDocument_Promoted; CreateDocument) { } + actionref(CreateJournal_Promoted; CreateJournal) { } actionref(Send_Promoted; Send) { } actionref(Recreate_Promoted; Recreate) { } actionref(Cancel_promoteed; Cancel) { } actionref(Approval_promoteed; GetApproval) { } } + group(Category_Troubleshoot) + { + Caption = 'Troubleshoot'; + actionref(ImportManually_Promoted; ImportManually) { } + actionref(TextToAccountMapping_Promoted; TextToAccountMapping) { } + } +#if not CLEAN24 + group(Out) + { + Caption = 'Outgoing'; + Visible = false; + ObsoleteTag = '24.0'; + ObsoleteReason = 'Actionrefs moved to process category'; + ObsoleteState = Pending; + } group(In) { Caption = 'Incoming'; - actionref(ImportManually_Promoted; ImportManually) { } - actionref(GetBasicInfo_Promoted; GetBasicInfo) { } + Visible = false; + ObsoleteTag = '24.0'; + ObsoleteReason = 'Actionrefs moved to process category'; + ObsoleteState = Pending; + actionref(GetBasicInfo_Promoted; GetBasicInfo) + { + ObsoleteTag = '24.0'; + ObsoleteReason = 'Actionref removed'; + ObsoleteState = Pending; + } group(CreateDoc) { + Visible = false; ShowAs = SplitButton; - actionref(CreateDocument_Promoted; CreateDocument) { } - actionref(CreateJournal_Promoted; CreateJournal) { } - actionref(UpdateOrder_Promoted; UpdateOrder) { } + ObsoleteTag = '24.0'; + ObsoleteReason = 'CreateDoc group removed'; + ObsoleteState = Pending; + + actionref(UpdateOrder_Promoted; UpdateOrder) + { + Visible = false; + ObsoleteTag = '24.0'; + ObsoleteReason = 'Update order changed to "Receive E-Document To" on Vendor'; + ObsoleteState = Pending; + } } - actionref(TextToAccountMapping_Promoted; TextToAccountMapping) { } } +#endif } } + trigger OnOpenPage() + begin + ShowMapToOrder := false; + HasErrorsAndWarnings := false; + end; + trigger OnAfterGetRecord() begin RecordLinkTxt := EDocumentHelper.GetRecordLinkText(Rec); - ShowErrors(); + HasErrorsAndWarnings := EDocumentErrorHelper.HasErrors(Rec); + if HasErrorsAndWarnings then + ShowErrors(); + + case Rec.Status of + Rec.Status::Error: + StyleStatusTxt := 'Unfavorable'; + Rec.Status::Processed: + StyleStatusTxt := 'Favorable'; + else + StyleStatusTxt := 'None'; + end; + + ShowActionsForEDocument(); end; local procedure ShowErrors() @@ -389,11 +488,33 @@ page 6121 "E-Document" EDocumentBackgroundjobs.GetEDocumentResponse(); end; + local procedure ShowActionsForEDocument() + begin + IsIncomingDoc := Rec.Direction = Rec.Direction::Incoming; + if IsIncomingDoc then + SetIncomingDocActions(); + end; + + local procedure SetIncomingDocActions() + var + EDocService: Record "E-Document Service"; + EDocServiceStatus: Record "E-Document Service Status"; + EDocLog: Codeunit "E-Document Log"; + begin + EDocService := EDocLog.GetLastServiceFromLog(Rec); + ShowCreateJnlLine := EDocService."Create Journal Lines"; + if (Rec."Document Type" = Enum::"E-Document Type"::"Purchase Order") and (Rec.Status <> Rec.Status::Processed) then + if EDocServiceStatus.Get(Rec."Entry No", EDocService.Code) then + ShowMapToOrder := EDocServiceStatus.Status = EDocServiceStatus.Status::"Order Linked"; + + end; + var EDocumentBackgroundjobs: Codeunit "E-Document Background Jobs"; EDocIntegrationManagement: Codeunit "E-Doc. Integration Management"; EDocImport: Codeunit "E-Doc. Import"; EDocumentErrorHelper: Codeunit "E-Document Error Helper"; EDocumentHelper: Codeunit "E-Document Processing"; - RecordLinkTxt: Text; + RecordLinkTxt, StyleStatusTxt : Text; + ShowMapToOrder, HasErrorsAndWarnings, ShowCreateJnlLine, IsIncomingDoc : Boolean; } diff --git a/Apps/W1/EDocument/app/src/Document/EDocumentServiceStatus.Enum.al b/Apps/W1/EDocument/app/src/Document/EDocumentServiceStatus.Enum.al index 079c5bf06c..06824f83de 100644 --- a/Apps/W1/EDocument/app/src/Document/EDocumentServiceStatus.Enum.al +++ b/Apps/W1/EDocument/app/src/Document/EDocumentServiceStatus.Enum.al @@ -10,19 +10,21 @@ enum 6106 "E-Document Service Status" AssignmentCompatibility = true; value(0; "Created") { Caption = 'Created'; } value(1; "Exported") { Caption = 'Exported'; } - value(2; "Sending Error") { Caption = 'Sending Error'; } - value(3; "Cancel Error") { Caption = 'Cancel Error'; } + value(2; "Sending Error") { Caption = 'Sending error'; } + value(3; "Cancel Error") { Caption = 'Cancel error'; } value(4; "Canceled") { Caption = 'Canceled'; } value(5; "Imported") { Caption = 'Imported'; } - value(6; "Imported Document Processing Error") { Caption = 'Imported Document Processing Error'; } - value(7; "Imported Document Created") { Caption = 'Imported Document Created'; } - value(8; "Order Updated") { Caption = 'Order Updated'; } - value(9; "Journal Line Created") { Caption = 'Journal Line Created'; } - value(10; "Pending Batch") { Caption = 'Pending Batch'; } - value(11; "Export Error") { Caption = 'Export Error'; } - value(12; "Pending Response") { Caption = 'Pending Response'; } + value(6; "Imported Document Processing Error") { Caption = 'Imported document erocessing error'; } + value(7; "Imported Document Created") { Caption = 'Imported document created'; } + value(8; "Order Updated") { Caption = 'Order updated'; } + value(9; "Journal Line Created") { Caption = 'Journal line created'; } + value(10; "Pending Batch") { Caption = 'Pending batch'; } + value(11; "Export Error") { Caption = 'Export error'; } + value(12; "Pending Response") { Caption = 'Pending response'; } value(13; "Sent") { Caption = 'Sent'; } value(14; "Approved") { Caption = 'Approved'; } value(15; "Rejected") { Caption = 'Rejected'; } - value(16; "Batch Imported") { Caption = 'Batch Imported'; } + value(16; "Batch Imported") { Caption = 'Batch imported'; } + value(17; "Order Linked") { Caption = 'Order linked'; } + value(18; "Pending") { Caption = 'Pending'; } } diff --git a/Apps/W1/EDocument/app/src/Document/EDocuments.Page.al b/Apps/W1/EDocument/app/src/Document/EDocuments.Page.al index 18ef41dc40..edb2f34e7f 100644 --- a/Apps/W1/EDocument/app/src/Document/EDocuments.Page.al +++ b/Apps/W1/EDocument/app/src/Document/EDocuments.Page.al @@ -11,6 +11,7 @@ page 6122 "E-Documents" CardPageId = "E-Document"; PageType = List; UsageCategory = Lists; + AdditionalSearchTerms = 'Edoc,Electronic Document'; RefreshOnActivate = true; Editable = false; DeleteAllowed = false; @@ -57,7 +58,7 @@ page 6122 "E-Documents" { action(ImportManually) { - Caption = 'Create From File'; + Caption = 'Create and Process From File'; ToolTip = 'Create an electronic document by manually uploading a file.'; Image = Import; @@ -68,7 +69,7 @@ page 6122 "E-Documents" begin EDocImport.UploadDocument(EDocument); if EDocument."Entry No" <> 0 then - EDocImport.GetBasicInfo(EDocument); + EDocImport.ProcessDocument(EDocument, false); end; } action(EDocumentServices) diff --git a/Apps/W1/EDocument/app/src/EDocumentInstall.Codeunit.al b/Apps/W1/EDocument/app/src/EDocumentInstall.Codeunit.al index 3e09f6ebd8..2c9660f53c 100644 --- a/Apps/W1/EDocument/app/src/EDocumentInstall.Codeunit.al +++ b/Apps/W1/EDocument/app/src/EDocumentInstall.Codeunit.al @@ -8,7 +8,6 @@ using System.IO; using System.Reflection; using System.Utilities; using System.Upgrade; - codeunit 6161 "E-Document Install" { Access = Internal; @@ -36,7 +35,7 @@ codeunit 6161 "E-Document Install" ImportServiceCreditMemoXML(); UpgradeTag.SetUpgradeTag(GetEDOCDataExchUpdateTag()); - + end; local procedure ImportServiceInvoiceXML() diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocBusManagerRC.PageExt.al b/Apps/W1/EDocument/app/src/Extensions/EDocBusManagerRC.PageExt.al new file mode 100644 index 0000000000..bff5c1180e --- /dev/null +++ b/Apps/W1/EDocument/app/src/Extensions/EDocBusManagerRC.PageExt.al @@ -0,0 +1,13 @@ +pageextension 6160 "E-Doc. Bus. Manager RC" extends "Business Manager Role Center" +{ + layout + { + addafter(ApprovalsActivities) + { + part(EDocumentActivities; "E-Doc. Order Map. Activities") + { + ApplicationArea = Basic, Suite; + } + } + } +} diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocInvManagerRC.PageExt.al b/Apps/W1/EDocument/app/src/Extensions/EDocInvManagerRC.PageExt.al new file mode 100644 index 0000000000..2f5024966d --- /dev/null +++ b/Apps/W1/EDocument/app/src/Extensions/EDocInvManagerRC.PageExt.al @@ -0,0 +1,13 @@ +pageextension 6158 "E-Doc. Inv. Manager RC" extends "Whse. Basic Role Center" +{ + layout + { + addafter(ApprovalsActivities) + { + part(EDocumentActivities; "E-Doc. Order Map. Activities") + { + ApplicationArea = Basic, Suite; + } + } + } +} diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocOrderMapActivities.Page.al b/Apps/W1/EDocument/app/src/Extensions/EDocOrderMapActivities.Page.al new file mode 100644 index 0000000000..9513a4de83 --- /dev/null +++ b/Apps/W1/EDocument/app/src/Extensions/EDocOrderMapActivities.Page.al @@ -0,0 +1,54 @@ +// ------------------------------------------------------------------------------------------------ +// 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; + +page 6159 "E-Doc. Order Map. Activities" +{ + PageType = CardPart; + RefreshOnActivate = true; + Caption = 'E-Document Activities'; + + layout + { + area(Content) + { + cuegroup("EDocument Activities") + { + ShowCaption = false; + cuegroup("IncomingEDocument") + { + Caption = 'Incoming E-Document'; + + field(MatchedPurchaseOrderCount; EDocumentHelper.MatchedPurchaseOrdersCount()) + { + ApplicationArea = Basic, Suite; + Caption = 'Matched Purchase Orders'; + ToolTip = 'Specifies the number of purchase orders that have matched to a received e-document.'; + + trigger OnDrillDown() + begin + EDocumentHelper.OpenMatchedPurchaseOrders(); + end; + } + field(WaitingPurchaseOrderCount; EDocumentHelper.MatchedPurchaseEDocumentsCount()) + { + ApplicationArea = Basic, Suite; + Caption = 'Waiting Purchase E-Documents'; + ToolTip = 'Specifies the number of received purchase e-documents that needs to be reviewed.'; + + trigger OnDrillDown() + begin + EDocumentHelper.OpenMatchedPurchaseEDoc(); + end; + } + } + } + } + } + + var + EDocumentHelper: Codeunit "E-Document Processing"; + +} \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseHeader.TableExt.al b/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseHeader.TableExt.al new file mode 100644 index 0000000000..4ed9058508 --- /dev/null +++ b/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseHeader.TableExt.al @@ -0,0 +1,26 @@ +tableextension 6169 "E-Doc. Purchase Header" extends "Purchase Header" +{ + + fields + { + field(6100; "E-Document Link"; Guid) + { + DataClassification = SystemMetadata; + Editable = false; + } + field(6101; "Amount Incl. VAT To Inv."; Decimal) + { + CalcFormula = sum("Purchase Line"."Amount Incl. VAT To Inv." where("Document Type" = field("Document Type"), + "Document No." = field("No."))); + Caption = 'Amount Incl. VAT To Inv.'; + Editable = false; + FieldClass = FlowField; + } + } + + internal procedure IsLinkedToEDoc(EDocumentToExclude: Record "E-Document"): Boolean + begin + exit(not IsNullGuid("E-Document Link") and ("E-Document Link" <> EDocumentToExclude.SystemId)); + end; + +} \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseLine.TableExt.al b/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseLine.TableExt.al new file mode 100644 index 0000000000..67f1e49f16 --- /dev/null +++ b/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseLine.TableExt.al @@ -0,0 +1,50 @@ +tableextension 6168 "E-Doc. Purchase Line" extends "Purchase Line" +{ + + fields + { + modify("Amount Including VAT") + { + trigger OnAfterValidate() + begin + Validate("Amount Incl. VAT To Inv."); + end; + } + field(6101; "Amount Incl. VAT To Inv."; Decimal) + { + Caption = 'Amount Incl. VAT To Inv.'; + Editable = false; + DataClassification = CustomerContent; + trigger OnValidate() + var + PurchaseHeader: Record "Purchase Header"; + Currency: Record Currency; + begin + GetPurchHeader(PurchaseHeader, Currency); + "Amount Incl. VAT To Inv." := Round( + "Amount Including VAT" * "Qty. to Invoice" / Quantity, + Currency."Amount Rounding Precision") + end; + } + + } + + internal procedure GetStyle() Result: Text + begin + if Rec."Qty. Rcd. Not Invoiced" = 0 then + exit('Subordinate'); + + exit('None'); + end; + + internal procedure HasEDocMatch(EDocEntryNo: Integer): Boolean + var + EDocOrderMatch: Record "E-Doc. Order Match"; + begin + EDocOrderMatch.SetRange("Document Order No.", Rec."Document No."); + EDocOrderMatch.SetRange("Document Line No.", Rec."Line No."); + EDocOrderMatch.SetRange("E-Document Entry No.", EDocEntryNo); + exit(not EDocOrderMatch.IsEmpty()); + end; + +} \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseOrder.PageExt.al b/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseOrder.PageExt.al index 7c72ed3521..51379c7967 100644 --- a/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseOrder.PageExt.al +++ b/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseOrder.PageExt.al @@ -5,6 +5,7 @@ namespace Microsoft.Purchases.Document; using Microsoft.eServices.EDocument; +using Microsoft.eServices.EDocument.OrderMatch; pageextension 6132 "E-Doc. Purchase Order" extends "Purchase Order" { @@ -14,6 +15,23 @@ pageextension 6132 "E-Doc. Purchase Order" extends "Purchase Order" { group("E-Document") { + action(MatchToOrder) + { + Caption = 'Map E-Document'; + ToolTip = 'Map received E-Document to the Purchase Order'; + ApplicationArea = All; + Image = Reconcile; + Visible = ShowMapToEDocument; + + trigger OnAction() + var + EDocument: Record "E-Document"; + EDocOrderMatch: Codeunit "E-Doc. Line Matching"; + begin + EDocument.GetBySystemId(Rec."E-Document Link"); + EDocOrderMatch.RunMatching(EDocument); + end; + } action("PreviewEDocumentMapping") { ApplicationArea = Basic, Suite; @@ -31,5 +49,21 @@ pageextension 6132 "E-Doc. Purchase Order" extends "Purchase Order" } } } + addlast(Category_Process) + { + actionref(MapEDocument_Promoted; MatchToOrder) + { + } + } } + + + var + ShowMapToEDocument: Boolean; + + trigger OnAfterGetCurrRecord() + begin + ShowMapToEDocument := not IsNullGuid(Rec."E-Document Link"); + end; + } diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseOrderList.PageExt.al b/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseOrderList.PageExt.al new file mode 100644 index 0000000000..ea9ff95c72 --- /dev/null +++ b/Apps/W1/EDocument/app/src/Extensions/EDocPurchaseOrderList.PageExt.al @@ -0,0 +1,70 @@ +// ------------------------------------------------------------------------------------------------ +// 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; + +using Microsoft.eServices.EDocument; +using Microsoft.eServices.EDocument.OrderMatch; + +pageextension 6137 "E-Doc. Purchase Order List" extends "Purchase Order List" +{ + actions + { + addafter("P&osting") + { + group("E-Document") + { + action(MatchToOrder) + { + Caption = 'Map E-Document'; + ToolTip = 'Map received E-Document to the Purchase Order'; + ApplicationArea = All; + Image = Reconcile; + Visible = ShowMapToEDocument; + + trigger OnAction() + var + EDocument: Record "E-Document"; + EDocOrderMatch: Codeunit "E-Doc. Line Matching"; + begin + EDocument.GetBySystemId(Rec."E-Document Link"); + EDocOrderMatch.RunMatching(EDocument); + end; + } + action("PreviewEDocumentMapping") + { + ApplicationArea = Basic, Suite; + Caption = 'Preview E-Document Mapping'; + Image = ViewDetails; + ToolTip = 'Preview E-Document Mapping'; + trigger OnAction() + var + PurchaseLine: Record "Purchase Line"; + EDocMapping: Codeunit "E-Doc. Mapping"; + begin + PurchaseLine.SetRange("Document No.", Rec."No."); + EDocMapping.PreviewMapping(Rec, PurchaseLine, PurchaseLine.FieldNo("Line No.")); + end; + } + } + } + addlast(Category_Process) + { + actionref(MapEDocument_Promoted; MatchToOrder) + { + } + } + + } + + + var + ShowMapToEDocument: Boolean; + + trigger OnAfterGetCurrRecord() + begin + ShowMapToEDocument := not IsNullGuid(Rec."E-Document Link"); + end; + +} diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocShipRecWmsRC.PageExt.al b/Apps/W1/EDocument/app/src/Extensions/EDocShipRecWmsRC.PageExt.al new file mode 100644 index 0000000000..a84d9dabc3 --- /dev/null +++ b/Apps/W1/EDocument/app/src/Extensions/EDocShipRecWmsRC.PageExt.al @@ -0,0 +1,13 @@ +pageextension 6157 "E-Doc. Ship Rec. WMS RC" extends "Whse. WMS Role Center" +{ + layout + { + addafter(ApprovalsActivities) + { + part(EDocumentActivities; "E-Doc. Order Map. Activities") + { + ApplicationArea = Basic, Suite; + } + } + } +} diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocVendorPage.PageExt.al b/Apps/W1/EDocument/app/src/Extensions/EDocVendorPage.PageExt.al new file mode 100644 index 0000000000..901417730d --- /dev/null +++ b/Apps/W1/EDocument/app/src/Extensions/EDocVendorPage.PageExt.al @@ -0,0 +1,17 @@ +pageextension 6161 "E-Doc. Vendor Page" extends "Vendor Card" +{ + layout + { + addlast(Receiving) + { + field("Receive E-Document To"; Rec."Receive E-Document To") + { + ApplicationArea = All; + Caption = 'Receive E-Document To'; + ToolTip = 'Specifies the default purchase document to be generated from received E-document. Users can select either a Purchase Invoice or Purchase Order. This selection does not affect the creation of corrective documents; in both scenarios, the system will generate a Credit Memo.'; + } + } + } + + +} \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocumentActivities.Page.al b/Apps/W1/EDocument/app/src/Extensions/EDocumentActivities.Page.al index 169bcec672..f0fcf0d2af 100644 --- a/Apps/W1/EDocument/app/src/Extensions/EDocumentActivities.Page.al +++ b/Apps/W1/EDocument/app/src/Extensions/EDocumentActivities.Page.al @@ -91,6 +91,28 @@ page 6127 "E-Document Activities" EDocumentHelper.OpenEDocuments(Enum::"E-Document Status"::Error, Enum::"E-Document Direction"::Incoming); end; } + field(MatchedPurchaseOrderCount; MatchedPurchaseOrderCount) + { + ApplicationArea = Basic, Suite; + Caption = 'Matched Purchase Orders'; + ToolTip = 'Specifies the number of purchase orders that have matched to a received e-document.'; + + trigger OnDrillDown() + begin + EDocumentHelper.OpenMatchedPurchaseOrders(); + end; + } + field(WaitingPurchaseOrderCount; WaitingPurchaseEDocCount) + { + ApplicationArea = Basic, Suite; + Caption = 'Waiting Purchase E-Documents'; + ToolTip = 'Specifies the number of received purchase e-documents that needs to be reviewed.'; + + trigger OnDrillDown() + begin + EDocumentHelper.OpenMatchedPurchaseEDoc(); + end; + } } } } @@ -100,6 +122,7 @@ page 6127 "E-Document Activities" EDocumentHelper: Codeunit "E-Document Processing"; OutgoingEDocumentInProgressCount, OutgoingEDocumentProcessedCount, OutgoingEDocumentErrorCount : Integer; IncomingEDocumentInProgressCount, IncomingEDocumentProcessedCount, IncomingEDocumentErrorCount : Integer; + MatchedPurchaseOrderCount, WaitingPurchaseEDocCount : Integer; trigger OnOpenPage() begin @@ -110,5 +133,7 @@ page 6127 "E-Document Activities" IncomingEDocumentInProgressCount := EDocumentHelper.GetEDocumentCount(Enum::"E-Document Status"::"In Progress", Enum::"E-Document Direction"::Incoming); IncomingEDocumentProcessedCount := EDocumentHelper.GetEDocumentCount(Enum::"E-Document Status"::Processed, Enum::"E-Document Direction"::Incoming); IncomingEDocumentErrorCount := EDocumentHelper.GetEDocumentCount(Enum::"E-Document Status"::Error, Enum::"E-Document Direction"::Incoming); + MatchedPurchaseOrderCount := EDocumentHelper.MatchedPurchaseOrdersCount(); + WaitingPurchaseEDocCount := EDocumentHelper.MatchedPurchaseEDocumentsCount(); end; } diff --git a/Apps/W1/EDocument/app/src/Extensions/EDocumentVendor.TableExt.al b/Apps/W1/EDocument/app/src/Extensions/EDocumentVendor.TableExt.al new file mode 100644 index 0000000000..509cd292f3 --- /dev/null +++ b/Apps/W1/EDocument/app/src/Extensions/EDocumentVendor.TableExt.al @@ -0,0 +1,12 @@ +tableextension 6165 "E-Document Vendor" extends Vendor +{ + fields + { + field(6101; "Receive E-Document To"; Enum "E-Document Type") + { + DataClassification = SystemMetadata; + InitValue = "Purchase Order"; + ValuesAllowed = "Purchase Order", "Purchase Invoice"; + } + } +} \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al index 3b3d28335e..6ee900478b 100644 --- a/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Integration/EDocIntegrationManagement.Codeunit.al @@ -111,14 +111,6 @@ codeunit 6134 "E-Doc. Integration Management" end; end; - local procedure SetDocumentStatusAndInsertLogs(Edocument: Record "E-Document"; EDocumentService: Record "E-Document Service"; var TempBlob: Codeunit "Temp Blob"; HttpRequest: HttpRequestMessage; HttpResponse: HttpResponseMessage; IsAsync: Boolean; SendingWasSuccessful: Boolean) - var - EDocDataStorageEntryNo: Integer; - begin - EDocDataStorageEntryNo := EDocumentLog.AddTempBlobToLog(TempBlob); - SetDocumentStatusAndInsertLogs(Edocument, EDocumentService, EDocDataStorageEntryNo, HttpRequest, HttpResponse, IsAsync, SendingWasSuccessful); - end; - local procedure SetDocumentStatusAndInsertLogs(Edocument: Record "E-Document"; EDocumentService: Record "E-Document Service"; EDocDataStorageEntryNo: Integer; HttpRequest: HttpRequestMessage; HttpResponse: HttpResponseMessage; IsAsync: Boolean; SendingWasSuccessful: Boolean) var Status: Enum "E-Document Service Status"; diff --git a/Apps/W1/EDocument/app/src/Log/EDocumentLog.Codeunit.al b/Apps/W1/EDocument/app/src/Log/EDocumentLog.Codeunit.al index 6ea6137e4c..5eba1995fc 100644 --- a/Apps/W1/EDocument/app/src/Log/EDocumentLog.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Log/EDocumentLog.Codeunit.al @@ -233,12 +233,11 @@ codeunit 6132 "E-Document Log" EDocumentServiceStatus.SetRange("E-Document Entry No", EDocument."Entry No"); EDocServiceCount := EDocumentServiceStatus.Count; - EDocumentServiceStatus.SetFilter(Status, '%1|%2|%3|%4|%5|%6|%7', + EDocumentServiceStatus.SetFilter(Status, '%1|%2|%3|%4|%5|%6', EDocumentServiceStatus.Status::Sent, EDocumentServiceStatus.Status::Exported, EDocumentServiceStatus.Status::"Imported Document Created", EDocumentServiceStatus.Status::"Journal Line Created", - EDocumentServiceStatus.Status::"Order Updated", EDocumentServiceStatus.Status::Approved, EDocumentServiceStatus.Status::Canceled); if EDocumentServiceStatus.Count = EDocServiceCount then diff --git a/Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al b/Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al index 62ac3f3544..78fdc0410d 100644 --- a/Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Processing/EDocImport.Codeunit.al @@ -5,8 +5,10 @@ namespace Microsoft.eServices.EDocument; using Microsoft.Finance.GeneralLedger.Journal; +using Microsoft.Purchases.Vendor; using Microsoft.Purchases.Document; using System.Utilities; +using Microsoft.eServices.EDocument.OrderMatch; codeunit 6140 "E-Doc. Import" { @@ -21,23 +23,21 @@ codeunit 6140 "E-Doc. Import" InStr: InStream; FileName: Text; begin - if Page.RunModal(Page::"E-Document Services", EDocumentService) <> Action::LookupOK then - exit; - - if not UploadIntoStream('', '', '', FileName, InStr) then - exit; + if Page.RunModal(Page::"E-Document Services", EDocumentService) = Action::LookupOK then begin + UploadIntoStream('', '', '', FileName, InStr); - TempBlob.CreateOutStream(OutStr); - CopyStream(OutStr, InStr); - - EDocument.Direction := EDocument.Direction::Incoming; - EDocument.Status := EDocument.Status::"In Progress"; - if EDocument."Entry No" = 0 then - EDocument.Insert(true) - else - EDocument.Modify(true); + TempBlob.CreateOutStream(OutStr); + if CopyStream(OutStr, InStr) then begin + EDocument.Direction := EDocument.Direction::Incoming; + EDocument.Status := EDocument.Status::"In Progress"; + if EDocument."Entry No" = 0 then + EDocument.Insert(true) + else + EDocument.Modify(true); - EDocumentLog.InsertLog(EDocument, EDocumentService, TempBlob, Enum::"E-Document Service Status"::Imported); + EDocumentLog.InsertLog(EDocument, EDocumentService, TempBlob, Enum::"E-Document Service Status"::Imported); + end; + end; end; internal procedure GetBasicInfo(var EDocument: Record "E-Document") @@ -53,7 +53,7 @@ codeunit 6140 "E-Doc. Import" GetDocumentBasicInfo(EDocument, EDocService, TempBlob); end; - internal procedure ProcessDocument(var EDocument: Record "E-Document"; UpdateOrder: Boolean; CreateJnlLine: Boolean) + internal procedure ProcessDocument(var EDocument: Record "E-Document"; CreateJnlLine: Boolean) var EDocService: Record "E-Document Service"; TempBlob: Codeunit "Temp Blob"; @@ -63,7 +63,7 @@ codeunit 6140 "E-Doc. Import" EDocService := EDocumentLog.GetLastServiceFromLog(EDocument); EDocumentLog.GetDocumentBlobFromLog(EDocument, EDocService, TempBlob, Enum::"E-Document Service Status"::Imported); - ProcessImportedDocument(EDocument, EDocService, TempBlob, UpdateOrder, CreateJnlLine); + ProcessImportedDocument(EDocument, EDocService, TempBlob, CreateJnlLine); if GuiAllowed and EDocErrorHelper.HasErrors(EDocument) then Message(DocNotCreatedMsg); @@ -145,7 +145,7 @@ codeunit 6140 "E-Doc. Import" if not IsProcessed then - ProcessImportedDocument(EDocument, EDocService, TempBlob, EDocService."Update Order", EDocService."Create Journal Lines"); + ProcessImportedDocument(EDocument, EDocService, TempBlob, EDocService."Create Journal Lines"); if EDocErrorHelper.HasErrors(EDocument) then begin EDocument2 := EDocument; @@ -158,14 +158,177 @@ codeunit 6140 "E-Doc. Import" Page.Run(Page::"E-Document", EDocument2); end; - local procedure ProcessImportedDocument(var EDocument: Record "E-Document"; var EDocService: Record "E-Document Service"; var TempBlob: Codeunit "Temp Blob"; UpdateOrder: Boolean; CreateJnlLine: Boolean) + local procedure ProcessExistingOrder(var EDocument: Record "E-Document"; EDocService: Record "E-Document Service"; var SourceDocumentLine: RecordRef; DocumentHeader: RecordRef; var EDocServiceStatus: Enum "E-Document Service Status") + var + PurchaseOrderHeader: Record "Purchase Header"; + TempEDocImportedLine: Record "E-Doc. Imported Line" temporary; + EDocument2: Record "E-Document"; + ErrorMessage: Record "Error Message"; + TempExistingErrorMessage: Record "Error Message" temporary; + IsAnEDocAlreadyLinkedToPO: Boolean; + ItemFound, UOMResolved : Boolean; + begin + DocumentHeader.SetTable(PurchaseOrderHeader); + + // We should mark Edoc pending if existing edoc is already linked + EDocument2.SetRange("Document Record ID", PurchaseOrderHeader.RecordId()); + EDocument2.SetFilter(Status, '<>%1', Enum::"E-Document Status"::Processed); + IsAnEDocAlreadyLinkedToPO := not EDocument2.IsEmpty(); + + // Collect any error message + ErrorMessage.SetContext(EDocument.RecordId()); + ErrorMessage.SetRange("Context Record ID", EDocument.RecordId()); + ErrorMessage.CopyToTemp(TempExistingErrorMessage); + + // Get lines + if SourceDocumentLine.FindSet() then + repeat + + if EDocService."Resolve Unit Of Measure" or EDocService."Lookup Item Reference" or + EDocService."Lookup Item GTIN" or EDocService."Lookup Account Mapping" or + EDocService."Validate Line Discount" then begin + ItemFound := false; + UOMResolved := false; + if EDocService."Resolve Unit Of Measure" then + UOMResolved := EDocImportHelper.ResolveUnitOfMeasureFromDataImport(EDocument, SourceDocumentLine) + else + UOMResolved := true; + + // Lookup Item Ref, then GTIN/Bar Code, else G/L Account + if UOMResolved then begin + if EDocService."Lookup Item Reference" then + ItemFound := EDocImportHelper.FindItemReferenceForLine(EDocument, SourceDocumentLine); + + if (not ItemFound) and EDocService."Lookup Item GTIN" then + ItemFound := EDocImportHelper.FindItemForLine(EDocument, SourceDocumentLine); + + if (not ItemFound) and EDocService."Lookup Account Mapping" then + ItemFound := EDocImportHelper.FindGLAccountForLine(EDocument, SourceDocumentLine); + end; + end; + + // Save Temp EDocument Import Line for matching to purchase order + TempEDocImportedLine.Insert(EDocument, SourceDocumentLine, TempEDocImportedLine); + until SourceDocumentLine.Next() = 0; + + // Clear any error messages created while trying to resolve and reinsert stored. + ErrorMessage.ClearLog(); + ErrorMessage.CopyFromTemp(TempExistingErrorMessage); + + // Load into imported lines and update edoc state + PersistImportedLines(EDocument, TempEDocImportedLine); + UpdateEDocumentRecordId(EDocument, DocumentHeader.Field(PurchaseOrderHeader.FieldNo("No.")).Value(), DocumentHeader.RecordId); + if IsAnEDocAlreadyLinkedToPO then begin + EDocServiceStatus := EDocServiceStatus::Pending; + EDocErrorHelper.LogWarningMessage(EDocument, EDocument2, EDocument2.FieldNo("Entry No"), StrSubstNo(CannotProcessEDocumentMsg, EDocument."Entry No", PurchaseOrderHeader."No.", EDocument2."Entry No")); + end else + EDocServiceStatus := EDocServiceStatus::"Order Linked"; + EDocument.Status := Enum::"E-Document Status"::"In Progress"; + end; + + local procedure CreatePurchaseDocumentFromImportedDocument(var EDocument: Record "E-Document"; var EDocService: Record "E-Document Service"; var SourceDocumentHeader: RecordRef; var SourceDocumentLine: RecordRef; var EDocServiceStatus: Enum "E-Document Service Status"; PurchaseDocumentType: Enum "Purchase Document Type") var - TempEDocMapping: Record "E-Doc. Mapping" temporary; PurchHeader: Record "Purchase Header"; + DocumentHeader: RecordRef; + ItemFound, UOMResolved : Boolean; + begin + if EDocService."Resolve Unit Of Measure" or EDocService."Lookup Item Reference" or + EDocService."Lookup Item GTIN" or EDocService."Lookup Account Mapping" or + EDocService."Validate Line Discount" then + if SourceDocumentLine.FindSet() then + repeat + ItemFound := false; + UOMResolved := false; + + if EDocService."Resolve Unit Of Measure" then + UOMResolved := EDocImportHelper.ResolveUnitOfMeasureFromDataImport(EDocument, SourceDocumentLine) + else + UOMResolved := true; + + // Lookup Item Ref, then GTIN/Bar Code, else G/L Account + if UOMResolved then begin + if EDocService."Lookup Item Reference" then + ItemFound := EDocImportHelper.FindItemReferenceForLine(EDocument, SourceDocumentLine); + + if (not ItemFound) and EDocService."Lookup Item GTIN" then + ItemFound := EDocImportHelper.FindItemForLine(EDocument, SourceDocumentLine); + + if (not ItemFound) and EDocService."Lookup Account Mapping" then + ItemFound := EDocImportHelper.FindGLAccountForLine(EDocument, SourceDocumentLine); + + if not ItemFound then + EDocImportHelper.LogErrorIfItemNotFound(EDocument, SourceDocumentLine); + end; + + if EDocService."Validate Line Discount" then + EDocImportHelper.ValidateLineDiscount(EDocument, SourceDocumentLine); + + SourceDocumentLine.Modify(); + until SourceDocumentLine.Next() = 0; + + if EDocErrorHelper.HasErrors(EDocument) then + exit; + + CreateDocument(EDocument, SourceDocumentHeader, SourceDocumentLine, DocumentHeader, PurchaseDocumentType); + if EDocErrorHelper.HasErrors(EDocument) then + exit; + + if EDocService."Apply Invoice Discount" then + EDocImportHelper.ApplyInvoiceDiscount(EDocument, SourceDocumentHeader, DocumentHeader); + + if EDocService."Verify Totals" then + EDocImportHelper.VerifyTotal(EDocument, SourceDocumentHeader, DocumentHeader); + + if EDocErrorHelper.HasErrors(EDocument) then + exit; + + DocumentHeader.SetTable(PurchHeader); + + PurchHeader.Validate("E-Document Link", EDocument.SystemId); + PurchHeader.Modify(); + + UpdateEDocumentRecordId(EDocument, DocumentHeader.Field(PurchHeader.FieldNo("No.")).Value(), DocumentHeader.RecordId); + EDocServiceStatus := EDocServiceStatus::"Imported Document Created"; + EDocument.Status := Enum::"E-Document Status"::Processed; + end; + + local procedure CreateJournalLineFromImportedDocument(var EDocument: Record "E-Document"; var EDocService: Record "E-Document Service"; var EDocServiceStatus: Enum "E-Document Service Status") + var GenJournalLine: Record "Gen. Journal Line"; - DocumentHeader, GenJnlLine, SourceDocumentHeader, SourceDocumentLine : RecordRef; + GenJnlLine: RecordRef; + begin + CreateJournalLine(EDocument, EDocService, GenJnlLine); + if GenJnlLine.Number <> 0 then + EDocument."Journal Line System ID" := GenJnlLine.Field(GenJnlLine.SystemIdNo).Value; + + if EDocErrorHelper.HasErrors(EDocument) then + exit; + + UpdateEDocumentRecordId(EDocument, Enum::"E-Document Type"::"General Journal", GenJnlLine.Field(GenJournalLine.FieldNo("Document No.")).Value(), GenJnlLine.RecordId); + EDocServiceStatus := Enum::"E-Document Service Status"::"Journal Line Created"; + EDocument.Status := Enum::"E-Document Status"::Processed; + end; + + local procedure UpdateEDocumentRecordId(var EDocument: Record "E-Document"; DocNo: Code[20]; RecordId: RecordId) + begin + UpdateEDocumentRecordId(EDocument, EDocument."Document Type", DocNo, RecordId); + end; + + local procedure UpdateEDocumentRecordId(var EDocument: Record "E-Document"; EDocType: enum "E-Document Type"; DocNo: Code[20]; RecordId: RecordId) + begin + EDocument."Document Type" := EDocType; + EDocument."Document No." := DocNo; + EDocument."Document Record ID" := RecordId; + EDocument.Modify(); + end; + + local procedure ProcessImportedDocument(var EDocument: Record "E-Document"; var EDocService: Record "E-Document Service"; var TempBlob: Codeunit "Temp Blob"; CreateJnlLine: Boolean) + var + TempEDocMapping: Record "E-Doc. Mapping" temporary; + Vendor: Record Vendor; + DocumentHeader, SourceDocumentHeader, SourceDocumentLine : RecordRef; EDocumentLogEntryNo: Integer; - EDocStatus: Enum "E-Document Service Status"; + EDocServiceStatus: Enum "E-Document Service Status"; begin if EDocument."Document No." <> '' then if GuiAllowed then @@ -175,72 +338,109 @@ codeunit 6140 "E-Doc. Import" EDocErrorHelper.ClearErrorMessages(EDocument); GetDocumentBasicInfo(EDocument, EDocService, TempBlob); + if EDocErrorHelper.HasErrors(EDocument) then begin + EDocumentLog.InsertLog(EDocument, EDocService, TempBlob, Enum::"E-Document Service Status"::"Imported document processing error"); + exit; + end; - if not CreateJnlLine then - PrepareReceivedEDocument(EDocument, TempBlob, SourceDocumentHeader, SourceDocumentLine, TempEDocMapping); - - if EDocumentHasErrors(EDocument, EDocService, TempBlob) then + ParseDocumentLines(EDocument, EDocService, TempBlob, SourceDocumentHeader, SourceDocumentLine, TempEDocMapping); + if EDocErrorHelper.HasErrors(EDocument) then begin + EDocumentLog.InsertLog(EDocument, EDocService, TempBlob, Enum::"E-Document Service Status"::"Imported document processing error"); exit; + end; - // Commit before creating document with error handling (if Codeunit.Run then ) - Commit(); + // Always handle corrective document, or handle based on vendor setting + if Vendor.Get(EDocument."Bill-to/Pay-to No.") then + case EDocument."Document Type" of + "E-Document Type"::"Purchase Credit Memo": + ReceiveEDocumentToPurchaseDoc(EDocument, EDocService, SourceDocumentHeader, SourceDocumentLine, EDocServiceStatus, CreateJnlLine); + else + case Vendor."Receive E-Document To" of + Enum::"E-Document Type"::"Purchase Invoice": + ReceiveEDocumentToPurchaseDoc(EDocument, EDocService, SourceDocumentHeader, SourceDocumentLine, EDocServiceStatus, CreateJnlLine); + Enum::"E-Document Type"::"Purchase Order": + ReceiveEDocumentToPurchaseOrder(EDocument, EDocService, SourceDocumentHeader, SourceDocumentLine, EDocServiceStatus, Vendor); + else begin + ReceiveEDocumentToPurchaseDoc(EDocument, EDocService, SourceDocumentHeader, SourceDocumentLine, EDocServiceStatus, CreateJnlLine); + Vendor."Receive E-Document To" := Vendor."Receive E-Document To"::"Purchase Invoice"; + Vendor.Modify(); + end; + end + end + else + EDocErrorHelper.LogErrorMessage(EDocument, Vendor, Vendor.FieldNo("No."), FailedToFindVendorErr); - if CreateJnlLine then begin - CreateJournalLine(EDocument, GenJnlLine); - EDocStatus := EDocStatus::"Journal Line Created"; - if GenJnlLine.Number <> 0 then - EDocument."Journal Line System ID" := GenJnlLine.Field(GenJnlLine.SystemIdNo).Value; - end else - if UpdateOrder and OrderExists(EDocument, DocumentHeader) then begin - UpdateDocument(EDocument, SourceDocumentHeader, SourceDocumentLine, DocumentHeader); - EDocStatus := EDocStatus::"Order Updated"; - end else begin - CreateDocument(EDocument, SourceDocumentHeader, SourceDocumentLine, DocumentHeader); - EDocStatus := EDocStatus::"Imported Document Created"; - end; + if EDocErrorHelper.HasErrors(EDocument) then + EDocumentLog.InsertLog(EDocument, EDocService, TempBlob, Enum::"E-Document Service Status"::"Imported document processing error") + else begin + EDocumentLogEntryNo := EDocumentLog.InsertLog(EDocument, EDocService, EDocServiceStatus); + EDocumentLog.InsertMappingLog(EDocumentLogEntryNo, TempEDocMapping); + end; + OnAfterProcessImportedDocument(EDocument, DocumentHeader); + end; - if EDocumentHasErrors(EDocument, EDocService, TempBlob) then + procedure ReceiveEDocumentToPurchaseOrder(var EDocument: Record "E-Document"; var EDocService: Record "E-Document Service"; var SourceDocumentHeader: RecordRef; var SourceDocumentLine: RecordRef; var EDocServiceStatus: Enum "E-Document Service Status"; Vendor: Record Vendor) + var + DocumentHeader: RecordRef; + begin + EDocument."Document Type" := "E-Document Type"::"Purchase Order"; + EDocument.Modify(); + + if (EDocument."Order No." = '') and not GuiAllowed() then begin + EDocServiceStatus := Enum::"E-Document Service Status"::Pending; exit; + end; - if not CreateJnlLine then begin - if EDocService."Apply Invoice Discount" then - EDocImportHelper.ApplyInvoiceDiscount(EDocument, SourceDocumentHeader, DocumentHeader); + if (EDocument."Order No." = '') and GuiAllowed() then + FindPurchaseOrder(EDocument, Vendor); - if EDocService."Verify Totals" then - EDocImportHelper.VerifyTotal(EDocument, SourceDocumentHeader, DocumentHeader); - end; + if OrderExists(EDocument, Vendor, DocumentHeader) then + ProcessExistingOrder(EDocument, EDocService, SourceDocumentLine, DocumentHeader, EDocServiceStatus) + else + CreatePurchaseDocumentFromImportedDocument(EDocument, EDocService, SourceDocumentHeader, SourceDocumentLine, EDocServiceStatus, Enum::"Purchase Document Type"::Order); - case EDocument."Document Type" of - EDocument."Document Type"::"Purchase Invoice", EDocument."Document Type"::"Purchase Credit Memo": - if CreateJnlLine then begin - EDocument."Document Type" := EDocument."Document Type"::"General Journal"; - EDocument."Document No." := GenJnlLine.Field(GenJournalLine.FieldNo("Document No.")).Value(); - EDocument."Document Record ID" := GenJnlLine.RecordId; - end else begin - if EDocStatus = EDocStatus::"Order Updated" then - EDocument."Document Type" := EDocument."Document Type"::"Purchase Order"; - EDocument."Document No." := DocumentHeader.Field(PurchHeader.FieldNo("No.")).Value(); - EDocument."Document Record ID" := DocumentHeader.RecordId; - end; - end; + end; - EDocument.Status := EDocStatus; - EDocument.Modify(); + local procedure FindPurchaseOrder(var EDocument: Record "E-Document"; Vendor: Record Vendor) + var + PurchaseHeader: Record "Purchase Header"; + ConfirmManagement: Codeunit "Confirm Management"; + PurchaseOrderList: Page "Purchase Order List"; + begin + if not GuiAllowed() then + exit; - OnAfterProcessImportedDocument(EDocument, DocumentHeader); + PurchaseHeader.SetRange("Buy-from Vendor No.", Vendor."No."); + PurchaseOrderList.SetTableView(PurchaseHeader); + PurchaseOrderList.LookupMode(true); + Commit(); + if PurchaseOrderList.RunModal() = Action::LookupOK then begin + PurchaseOrderList.GetRecord(PurchaseHeader); + if ConfirmManagement.GetResponseOrDefault(StrSubstNo(FindPurchaseOrderConfrimQst, PurchaseHeader."No.", EDocument."Entry No"), true) then begin + EDocument."Order No." := PurchaseHeader."No."; + EDocument.Modify(); + end; + end; + end; - EDocumentLogEntryNo := EDocumentLog.InsertLog(EDocument, EDocService, TempBlob, EDocStatus); - EDocumentLog.InsertMappingLog(EDocumentLogEntryNo, TempEDocMapping); + local procedure ReceiveEDocumentToPurchaseDoc(var EDocument: Record "E-Document"; var EDocService: Record "E-Document Service"; var SourceDocumentHeader: RecordRef; var SourceDocumentLine: RecordRef; var EDocServiceStatus: Enum "E-Document Service Status"; CreateJnlLine: Boolean) + var + PurchaseHeader: Record "Purchase Header"; + PurchaseDocumentType: Enum "Purchase Document Type"; + begin + PurchaseDocumentType := SourceDocumentHeader.Field(PurchaseHeader.FieldNo("Document Type")).Value(); + if CreateJnlLine then + CreateJournalLineFromImportedDocument(EDocument, EDocService, EDocServiceStatus) + else + CreatePurchaseDocumentFromImportedDocument(EDocument, EDocService, SourceDocumentHeader, SourceDocumentLine, EDocServiceStatus, PurchaseDocumentType); end; - local procedure PrepareReceivedEDocument(var EDocument: Record "E-Document"; var TempBlob: Codeunit "Temp Blob"; SourceDocumentHeader: RecordRef; SourceDocumentLine: RecordRef; TempEDocMapping: Record "E-Doc. Mapping" temporary) + local procedure ParseDocumentLines(var EDocument: Record "E-Document"; EDocumentService: Record "E-Document Service"; var TempBlob: Codeunit "Temp Blob"; var SourceDocumentHeader: RecordRef; var SourceDocumentLine: RecordRef; var TempEDocMapping: Record "E-Doc. Mapping" temporary) var - EDocService: Record "E-Document Service"; - EDocExport: Codeunit "E-Doc. Export"; EDocGetFullInfo: Codeunit "E-Doc. Get Complete Info"; + EDocExport: Codeunit "E-Doc. Export"; SourceDocumentHeaderMapped, SourceDocumentLineMapped : RecordRef; EDocInterface: Interface "E-Document"; - ItemFound, UOMResolved : Boolean; begin OnBeforePrepareReceivedDoc(EDocument, TempBlob, SourceDocumentHeader, SourceDocumentLine, TempEDocMapping); @@ -250,93 +450,36 @@ codeunit 6140 "E-Doc. Import" SourceDocumentHeader.Open(Database::"Purchase Header", true); SourceDocumentLine.Open(Database::"Purchase Line", true); end; - else + else begin EDocErrorHelper.LogSimpleErrorMessage(EDocument, StrSubstNo(DocTypeIsNotSupportedErr, EDocument."Document Type")); + exit; + end; end; - if SourceDocumentHeader.Number <> 0 then begin - EDocService := EDocumentLog.GetLastServiceFromLog(EDocument); - EDocInterface := EDocService."Document Format"; - - // Commit before getting full info with error handling (if Codeunit.Run then ) - Commit(); - EDocGetFullInfo.SetValues(EDocInterface, EDocument, SourceDocumentHeader, SourceDocumentLine, TempBlob); - if EDocGetFullInfo.Run() then begin - EDocGetFullInfo.GetValues(EDocInterface, EDocument, SourceDocumentHeader, SourceDocumentLine, TempBlob); - EDocExport.MapEDocument(SourceDocumentHeader, SourceDocumentLine, EDocService, SourceDocumentHeaderMapped, SourceDocumentLineMapped, TempEDocMapping, true); - - if EDocService."Resolve Unit Of Measure" or EDocService."Lookup Item Reference" or - EDocService."Lookup Item GTIN" or EDocService."Lookup Account Mapping" or - EDocService."Validate Line Discount" - then - if SourceDocumentLineMapped.FindSet() then - repeat - ItemFound := false; - UOMResolved := false; - - if EDocService."Resolve Unit Of Measure" then - UOMResolved := EDocImportHelper.ResolveUnitOfMeasureFromDataImport(EDocument, SourceDocumentLineMapped) - else - UOMResolved := true; - - // Lookup Item Ref, then GTIN/Bar Code, else G/L Account - if UOMResolved then begin - if EDocService."Lookup Item Reference" then - ItemFound := EDocImportHelper.FindItemReferenceForLine(EDocument, SourceDocumentLineMapped); - - if (not ItemFound) and EDocService."Lookup Item GTIN" then - ItemFound := EDocImportHelper.FindItemForLine(EDocument, SourceDocumentLineMapped); - - if (not ItemFound) and EDocService."Lookup Account Mapping" then - ItemFound := EDocImportHelper.FindGLAccountForLine(EDocument, SourceDocumentLineMapped); - - if not ItemFound then - EDocImportHelper.LogErrorIfItemNotFound(EDocument, SourceDocumentLineMapped); - end; - - if EDocService."Validate Line Discount" then - EDocImportHelper.ValidateLineDiscount(EDocument, SourceDocumentLineMapped); - - SourceDocumentLineMapped.Modify(); - until SourceDocumentLineMapped.Next() = 0; - - - SourceDocumentHeader.Copy(SourceDocumentHeaderMapped, true); - SourceDocumentLine.Copy(SourceDocumentLineMapped, true); - end else - EDocErrorHelper.LogSimpleErrorMessage(EDocument, GetLastErrorText()); - - OnAfterPrepareReceivedDoc(EDocument, TempBlob, SourceDocumentHeader, SourceDocumentLine, TempEDocMapping); + // Commit before getting full info with error handling (if Codeunit.Run then ) + Commit(); + EDocInterface := EDocumentService."Document Format"; + EDocGetFullInfo.SetValues(EDocInterface, EDocument, SourceDocumentHeader, SourceDocumentLine, TempBlob); + if not EDocGetFullInfo.Run() then begin + EDocErrorHelper.LogSimpleErrorMessage(EDocument, GetLastErrorText()); + exit; end; - end; - - local procedure UpdateDocument(var EDocument: Record "E-Document"; var TempDocumentHeader: RecordRef; var TempDocumentLine: RecordRef; var DocumentHeader: RecordRef) - var - EDocumentUpdateOrder: Codeunit "E-Document Update Order"; - begin - ClearLastError(); - OnBeforeUpdateDocument(EDocument, TempDocumentHeader, TempDocumentLine, DocumentHeader); + EDocGetFullInfo.GetValues(EDocInterface, EDocument, SourceDocumentHeader, SourceDocumentLine, TempBlob); + EDocExport.MapEDocument(SourceDocumentHeader, SourceDocumentLine, EDocumentService, SourceDocumentHeaderMapped, SourceDocumentLineMapped, TempEDocMapping, true); - case TempDocumentHeader.Number of - Database::"Purchase Header": - begin - Clear(EDocumentUpdateOrder); - EDocumentUpdateOrder.SetSource(EDocument, TempDocumentHeader, TempDocumentLine, DocumentHeader); - if EDocumentUpdateOrder.Run() then - DocumentHeader := EDocumentUpdateOrder.GetUpdatedDocument() - else - EDocErrorHelper.LogSimpleErrorMessage(EDocument, GetLastErrorText()); - end; - end; + SourceDocumentHeader.Copy(SourceDocumentHeaderMapped, true); + SourceDocumentLine.Copy(SourceDocumentLineMapped, true); - OnAfterUpdateDocument(EDocument, TempDocumentHeader, TempDocumentLine, DocumentHeader); + OnAfterPrepareReceivedDoc(EDocument, TempBlob, SourceDocumentHeader, SourceDocumentLine, TempEDocMapping); end; - local procedure CreateDocument(var EDocument: Record "E-Document"; var TempDocumentHeader: RecordRef; var TempDocumentLine: RecordRef; var DocumentHeader: RecordRef) + local procedure CreateDocument(var EDocument: Record "E-Document"; var TempDocumentHeader: RecordRef; var TempDocumentLine: RecordRef; var DocumentHeader: RecordRef; PurchaseDocumentType: Enum "Purchase Document Type") var EDocumentCreatePurchase: Codeunit "E-Document Create Purch. Doc."; begin + // Commit before creating document with error handling (if Codeunit.Run then ) + Commit(); ClearLastError(); OnBeforeCreateDocument(EDocument, TempDocumentHeader, TempDocumentLine, DocumentHeader); @@ -345,7 +488,7 @@ codeunit 6140 "E-Doc. Import" Database::"Purchase Header": begin Clear(EDocumentCreatePurchase); - EDocumentCreatePurchase.SetSource(EDocument, TempDocumentHeader, TempDocumentLine); + EDocumentCreatePurchase.SetSource(EDocument, TempDocumentHeader, TempDocumentLine, PurchaseDocumentType); if EDocumentCreatePurchase.Run() then DocumentHeader := EDocumentCreatePurchase.GetCreatedDocument() else @@ -356,10 +499,12 @@ codeunit 6140 "E-Doc. Import" OnAfterCreateDocument(EDocument, TempDocumentHeader, TempDocumentLine, DocumentHeader); end; - local procedure CreateJournalLine(var EDocument: Record "E-Document"; var JnlLine: RecordRef) + local procedure CreateJournalLine(var EDocument: Record "E-Document"; var EDocService: Record "E-Document Service"; var JnlLine: RecordRef) var EDocumentCreateJnlLine: Codeunit "E-Document Create Jnl. Line"; begin + // Commit before creating document with error handling (if Codeunit.Run then ) + Commit(); ClearLastError(); OnBeforeCreateJournalLine(EDocument, JnlLine); @@ -368,7 +513,7 @@ codeunit 6140 "E-Doc. Import" EDocument."Document Type"::"Purchase Invoice", EDocument."Document Type"::"Purchase Credit Memo": begin Clear(EDocumentCreateJnlLine); - EDocumentCreateJnlLine.SetSource(EDocument); + EDocumentCreateJnlLine.SetSource(EDocument, EDocService); if EDocumentCreateJnlLine.Run() then JnlLine := EDocumentCreateJnlLine.GetCreatedJnlLine() else @@ -379,31 +524,33 @@ codeunit 6140 "E-Doc. Import" OnAfterCreateJournalLine(EDocument, JnlLine); end; - local procedure EDocumentHasErrors(var EDocument: Record "E-Document"; var EDocService: Record "E-Document Service"; var TempBlob: Codeunit "Temp Blob"): Boolean + local procedure OrderExists(EDocument: Record "E-Document"; Vendor: Record Vendor; var DocumentHeader: RecordRef): Boolean + var + PurchaseHeader: Record "Purchase Header"; begin - if EDocErrorHelper.HasErrors(EDocument) then begin - EDocumentLog.InsertLog(EDocument, EDocService, TempBlob, Enum::"E-Document Service Status"::"Imported document processing error"); + PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order); + PurchaseHeader.SetRange("No.", EDocument."Order No."); + PurchaseHeader.SetRange("Pay-to Vendor No.", Vendor."No."); + + if PurchaseHeader.FindFirst() then begin + DocumentHeader.GetTable(PurchaseHeader); exit(true); - end; + end else + exit(false); end; - local procedure OrderExists(EDocument: Record "E-Document"; var DocumentHeader: RecordRef): Boolean + local procedure PersistImportedLines(EDocument: Record "E-Document"; var TempEDocImportedLine: Record "E-Doc. Imported Line" temporary) var - PurchaseHeader: Record "Purchase Header"; + EDocImportedLine: Record "E-Doc. Imported Line"; begin - case EDocument."Document Type" of - EDocument."Document Type"::"Purchase Invoice": - begin - PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order); - PurchaseHeader.SetRange("No.", EDocument."Order No."); - PurchaseHeader.SetRange("Pay-to Vendor No.", EDocument."Bill-to/Pay-to No."); - if PurchaseHeader.FindFirst() then begin - DocumentHeader.GetTable(PurchaseHeader); - exit(true); - end; - end; - end; - exit(false); + EDocImportedLine.SetRange("E-Document Entry No.", EDocument."Entry No"); + EDocImportedLine.DeleteAll(); + EDocImportedLine.Reset(); + if TempEDocImportedLine.FindSet() then + repeat + EDocImportedLine.TransferFields(TempEDocImportedLine); + if EDocImportedLine.Insert() then; + until TempEDocImportedLine.Next() = 0; end; var @@ -415,6 +562,9 @@ codeunit 6140 "E-Doc. Import" DocAlreadyExistsMsg: Label 'The document already exists.'; DocAlreadyCreatedQst: Label 'The %1 %2 was already created for the electronic document %3. Do you want to create new document?', Comment = '%1 - Document Type, %2 - Document No., %3 - E-Document ID'; DocTypeIsNotSupportedErr: Label 'Document type %1 is not supported.', Comment = '%1 - Document Type'; + FindPurchaseOrderConfrimQst: Label 'Are you sure you want to link Purchase Order %1 to E-Document %2?', Comment = '%1 - Purchase Order number, %2 - E-Document entry number'; + FailedToFindVendorErr: Label 'No vendor is set for Edocument'; + CannotProcessEDocumentMsg: Label 'Cannot process E-Document %1 with Purchase Order %2 before Purchase Order has been matched and posted for E-Document %3.', Comment = '%1 - E-Document entry no, %2 - Purchase Order number, %3 - EDocument entry no.'; [IntegrationEvent(false, false)] local procedure OnAfterProcessImportedDocument(var EDocument: Record "E-Document"; var DocumentHeader: RecordRef) diff --git a/Apps/W1/EDocument/app/src/Processing/EDocumentCreateJnlLine.Codeunit.al b/Apps/W1/EDocument/app/src/Processing/EDocumentCreateJnlLine.Codeunit.al index a772fcf1f6..e332c54ff0 100644 --- a/Apps/W1/EDocument/app/src/Processing/EDocumentCreateJnlLine.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Processing/EDocumentCreateJnlLine.Codeunit.al @@ -18,9 +18,10 @@ codeunit 6137 "E-Document Create Jnl. Line" CreateGeneralJournalLine(SourceEDocument, CreatedJnlLine); end; - internal procedure SetSource(var SourceEDocument2: Record "E-Document") + internal procedure SetSource(var SourceEDocument2: Record "E-Document"; var SourceEDocumentService2: Record "E-Document Service") begin - SourceEDocument := SourceEDocument2; + SourceEDocument.Copy(SourceEDocument2); + SourceEDocumentService.Copy(SourceEDocumentService2); end; internal procedure GetCreatedJnlLine(): RecordRef; @@ -37,11 +38,10 @@ codeunit 6137 "E-Document Create Jnl. Line" GenJournalBatch: Record "Gen. Journal Batch"; GeneralLedgerSetup: Record "General Ledger Setup"; EDocService: Record "E-Document Service"; - EDocumentLog: Codeunit "E-Document Log"; TextToAccountMappingFound: Boolean; TempGenJournalLineInserted: Boolean; begin - EDocService := EDocumentLog.GetLastServiceFromLog(EDocument); + EDocService := SourceEDocumentService; if (EDocService."General Journal Template Name" = '') or (EDocService."General Journal Batch Name" = '') then EDocumentErrorHelper.LogErrorMessage(EDocument, EDocService, EDocService.FieldNo("General Journal Template Name"), StrSubstNo(TemplateBatchNameMissingErr, @@ -196,6 +196,7 @@ codeunit 6137 "E-Document Create Jnl. Line" var SourceEDocument: Record "E-Document"; + SourceEDocumentService: Record "E-Document Service"; NoSeriesMgt: Codeunit NoSeriesManagement; EDocumentErrorHelper: Codeunit "E-Document Error Helper"; SourceDocumentHeader, CreatedJnlLine : RecordRef; diff --git a/Apps/W1/EDocument/app/src/Processing/EDocumentCreatePurchDoc.Codeunit.al b/Apps/W1/EDocument/app/src/Processing/EDocumentCreatePurchDoc.Codeunit.al index be07b1a57b..24492b1250 100644 --- a/Apps/W1/EDocument/app/src/Processing/EDocumentCreatePurchDoc.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Processing/EDocumentCreatePurchDoc.Codeunit.al @@ -14,11 +14,12 @@ codeunit 6136 "E-Document Create Purch. Doc." CreatePurchaseDocument(SourceEDocument, SourceDocumentHeader, SourceDocumentLine, CreatedDocumentHeader) end; - internal procedure SetSource(var SourceEDocument2: Record "E-Document"; var SourceDocumentHeader2: RecordRef; var SourceDocumentLine2: RecordRef) + internal procedure SetSource(var SourceEDocument2: Record "E-Document"; var SourceDocumentHeader2: RecordRef; var SourceDocumentLine2: RecordRef; SourcePurchaseDocumentType2: Enum "Purchase Document Type") begin SourceEDocument := SourceEDocument2; SourceDocumentHeader := SourceDocumentHeader2; SourceDocumentLine := SourceDocumentLine2; + SourcePurchaseDocumentType := SourcePurchaseDocumentType2; end; internal procedure GetCreatedDocument(): RecordRef; @@ -44,7 +45,7 @@ codeunit 6136 "E-Document Create Purch. Doc." DefaultDocumentLine.GetTable(DefaultPurchaseLine); // Create header - EDocumentImportHelper.ProcessField(EDocument, DocumentHeader, PurchaseHeader.FieldNo("Document Type"), TempDocumentHeader.Field(PurchaseHeader.FieldNo("Document Type")).Value()); + EDocumentImportHelper.ProcessField(EDocument, DocumentHeader, PurchaseHeader.FieldNo("Document Type"), Format(SourcePurchaseDocumentType)); OnCreateNewPurchHdrOnBeforeRecRefInsert(EDocument, TempDocumentHeader, DocumentHeader); DocumentHeader.Insert(true); @@ -188,6 +189,7 @@ codeunit 6136 "E-Document Create Purch. Doc." SourceEDocument: Record "E-Document"; EDocumentImportHelper: Codeunit "E-Document Import Helper"; SourceDocumentHeader, SourceDocumentLine, CreatedDocumentHeader : RecordRef; + SourcePurchaseDocumentType: Enum "Purchase Document Type"; [IntegrationEvent(false, false)] local procedure OnCreateNewPurchHdrOnBeforeRecRefInsert(var EDocument: Record "E-Document"; var TempDocumentHeader: RecordRef; var DocumentHeader: RecordRef); diff --git a/Apps/W1/EDocument/app/src/Processing/EDocumentProcessing.Codeunit.al b/Apps/W1/EDocument/app/src/Processing/EDocumentProcessing.Codeunit.al index 4dd336751e..8303f00186 100644 --- a/Apps/W1/EDocument/app/src/Processing/EDocumentProcessing.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Processing/EDocumentProcessing.Codeunit.al @@ -98,6 +98,44 @@ codeunit 6108 "E-Document Processing" exit(EDocument.Count()); end; + procedure MatchedPurchaseOrdersCount(): Integer + var + PurchaseHeader: Record "Purchase Header"; + Guid: Guid; + begin + PurchaseHeader.SetFilter("E-Document Link", '<>%1', Guid); + exit(PurchaseHeader.Count()); + end; + + procedure MatchedPurchaseEDocumentsCount(): Integer + var + EDocument: Record "E-Document"; + begin + EDocument.SetRange("Document Type", Enum::"E-Document Type"::"Purchase Order"); + EDocument.SetRange(Status, Enum::"E-Document Status"::"In Progress"); + EDocument.SetRange("Order No.", ''); + exit(EDocument.Count()); + end; + + procedure OpenMatchedPurchaseEDoc() + var + EDocument: Record "E-Document"; + begin + EDocument.SetRange("Document Type", Enum::"E-Document Type"::"Purchase Order"); + EDocument.SetRange(Status, Enum::"E-Document Status"::"In Progress"); + EDocument.SetRange("Order No.", ''); + Page.Run(Page::"E-Documents", EDocument); + end; + + procedure OpenMatchedPurchaseOrders() + var + PurchaseHeader: Record "Purchase Header"; + Guid: Guid; + begin + PurchaseHeader.SetFilter("E-Document Link", '<>%1', Guid); + Page.Run(Page::"Purchase Order List", PurchaseHeader); + end; + procedure OpenEDocuments(Status: Enum "E-Document Status"; Direction: Enum "E-Document Direction"): Integer var EDocument: Record "E-Document"; diff --git a/Apps/W1/EDocument/app/src/Processing/EDocumentSubscription.Codeunit.al b/Apps/W1/EDocument/app/src/Processing/EDocumentSubscription.Codeunit.al index 7f81d0b798..1c2a60129f 100644 --- a/Apps/W1/EDocument/app/src/Processing/EDocumentSubscription.Codeunit.al +++ b/Apps/W1/EDocument/app/src/Processing/EDocumentSubscription.Codeunit.al @@ -89,12 +89,13 @@ codeunit 6103 "E-Document Subscription" if SalesInvHdrNo <> '' then begin if SalesInvHeader.Get(SalesInvHdrNo) then - RunEDocumentCreation(SalesHeader, SalesInvHeader, SalesInvHdrNo); + CreateOrUpdateEDocument(SalesHeader, SalesInvHeader, SalesInvHdrNo, Enum::"E-Document Type"::"Sales Invoice"); end else if SalesCrMemoHeader.Get(SalesCrMemoHdrNo) then - RunEDocumentCreation(SalesHeader, SalesCrMemoHeader, SalesCrMemoHdrNo); + CreateOrUpdateEDocument(SalesHeader, SalesCrMemoHeader, SalesCrMemoHdrNo, Enum::"E-Document Type"::"Sales Credit Memo"); end; + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Purch.-Post", 'OnAfterPostPurchaseDoc', '', false, false)] local procedure OnAfterPostPurchaseDoc(var PurchaseHeader: Record "Purchase Header"; var GenJnlPostLine: Codeunit "Gen. Jnl.-Post Line"; PurchRcpHdrNo: Code[20]; RetShptHdrNo: Code[20]; PurchInvHdrNo: Code[20]; PurchCrMemoHdrNo: Code[20]; CommitIsSupressed: Boolean) var @@ -106,10 +107,10 @@ codeunit 6103 "E-Document Subscription" if PurchInvHdrNo <> '' then begin if PurchInvHeader.Get(PurchInvHdrNo) then - RunEDocumentCreation(PurchaseHeader, PurchInvHeader, PurchInvHdrNo); + CreateOrUpdateEDocument(PurchaseHeader, PurchInvHeader, PurchInvHdrNo, Enum::"E-Document Type"::"Purchase Invoice") end else if PurchCrMemoHdr.Get(PurchCrMemoHdrNo) then - RunEDocumentCreation(PurchaseHeader, PurchCrMemoHdr, PurchCrMemoHdrNo); + CreateOrUpdateEDocument(PurchaseHeader, PurchCrMemoHdr, PurchCrMemoHdrNo, Enum::"E-Document Type"::"Purchase Credit Memo"); end; [EventSubscriber(ObjectType::Codeunit, Codeunit::"Service-Post", 'OnAfterPostServiceDoc', '', false, false)] @@ -123,10 +124,10 @@ codeunit 6103 "E-Document Subscription" if ServInvoiceNo <> '' then begin if ServiceInvoiceHeader.Get(ServInvoiceNo) then - RunEDocumentCreation(ServiceHeader, ServiceInvoiceHeader, ServInvoiceNo); + CreateOrUpdateEDocument(ServiceHeader, ServiceInvoiceHeader, ServInvoiceNo, Enum::"E-Document Type"::"Service Invoice"); end else if ServiceCrMemoHdr.Get(ServCrMemoNo) then - RunEDocumentCreation(ServiceHeader, ServiceCrMemoHdr, ServCrMemoNo); + CreateOrUpdateEDocument(ServiceHeader, ServiceCrMemoHdr, ServCrMemoNo, Enum::"E-Document Type"::"Service Credit Memo"); end; [EventSubscriber(ObjectType::Codeunit, Codeunit::"FinChrgMemo-Issue", 'OnAfterIssueFinChargeMemo', '', false, false)] @@ -137,7 +138,7 @@ codeunit 6103 "E-Document Subscription" if IssuedFinChargeMemoNo = '' then exit; if IssuedFinChrgMemoHeader.Get(IssuedFinChargeMemoNo) then - RunEDocumentCreation(FinChargeMemoHeader, IssuedFinChrgMemoHeader, IssuedFinChargeMemoNo); + CreateOrUpdateEDocument(FinChargeMemoHeader, IssuedFinChrgMemoHeader, IssuedFinChargeMemoNo, Enum::"E-Document Type"::"Issued Finance Charge Memo"); end; [EventSubscriber(ObjectType::Codeunit, Codeunit::"Reminder-Issue", 'OnAfterIssueReminder', '', false, false)] @@ -148,7 +149,7 @@ codeunit 6103 "E-Document Subscription" if IssuedReminderNo = '' then exit; if IssuedReminderHeader.Get(IssuedReminderNo) then - RunEDocumentCreation(ReminderHeader, IssuedReminderHeader, IssuedReminderNo); + CreateOrUpdateEDocument(ReminderHeader, IssuedReminderHeader, IssuedReminderNo, Enum::"E-Document Type"::"Issued Reminder"); end; [EventSubscriber(ObjectType::Table, Database::"Document Sending Profile", 'OnCheckElectronicSendingEnabled', '', false, false)] @@ -168,6 +169,8 @@ codeunit 6103 "E-Document Subscription" [EventSubscriber(ObjectType::Codeunit, Codeunit::"Gen. Jnl.-Post Line", 'OnAfterPostGLAcc', '', false, false)] local procedure OnAfterPostGLAcc(var GenJnlLine: Record "Gen. Journal Line"; var TempGLEntryBuf: Record "G/L Entry" temporary; var NextEntryNo: Integer; var NextTransactionNo: Integer; Balancing: Boolean; var GLEntry: Record "G/L Entry"; VATPostingSetup: Record "VAT Posting Setup") + var + EDocument: Record "E-Document"; begin if not IsNullGuid(GenJnlLine.SystemId) then begin EDocument.SetRange("Journal Line System ID", GenJnlLine.SystemId); @@ -181,8 +184,18 @@ codeunit 6103 "E-Document Subscription" end; end; + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Release Purchase Document", 'OnAfterReleasePurchaseDoc', '', false, false)] + local procedure OnAfterReleasePurchaseDoc(var PurchaseHeader: Record "Purchase Header"; PreviewMode: Boolean; var LinesWereModified: Boolean; SkipWhseRequestOperations: Boolean) + var + EDocument: Record "E-Document"; + begin + if IsEDocumentLinkedToPurchaseDocument(EDocument, PurchaseHeader) then + ValidateDocumentTotalAgainstEDocument(EDocument, PurchaseHeader); + end; + local procedure RunEDocumentCheck(Record: Variant; EDocumentProcPhase: Enum "E-Document Processing Phase") var + EDocument: Record "E-Document"; SourceDocumentHeader: RecordRef; begin SourceDocumentHeader.GetTable(Record); @@ -191,25 +204,116 @@ codeunit 6103 "E-Document Subscription" EDocExport.CheckEDocument(SourceDocumentHeader, EDocumentProcPhase); end; - local procedure RunEDocumentCreation(OpenRecord: Variant; PostedRecord: Variant; PostedDocumentNo: Code[20]) + local procedure IsEDocumentLinkedToPurchaseDocument(var EDocument: Record "E-Document"; OpenRecord: Variant): Boolean var - OpenSourceDocumentHeader, PostedSourceDocumentHeader : RecordRef; + PurchaseHeader: Record "Purchase Header"; + OpenSourceDocumentHeader: RecordRef; begin - PostedSourceDocumentHeader.GetTable(PostedRecord); OpenSourceDocumentHeader.GetTable(OpenRecord); - EDocument.SetRange("Document Record ID", OpenSourceDocumentHeader.RecordId); - if EDocument.FindFirst() then begin - EDocument."Document Record ID" := PostedSourceDocumentHeader.RecordId; - EDocument."Document No." := PostedDocumentNo; - EDocument.Modify(); - end else + if OpenSourceDocumentHeader.Number() <> Database::"Purchase Header" then + exit(false); + + OpenSourceDocumentHeader.SetTable(PurchaseHeader); + PurchaseHeader.SetRecFilter(); + if EDocument.GetBySystemId(PurchaseHeader."E-Document Link") then + exit(true); + end; + + local procedure RemoveEDocumentLinkFromPurchaseDocument(OpenRecord: Variant) + var + PurchaseHeader: Record "Purchase Header"; + EDocument: Record "E-Document"; + EDocService: Record "E-Document Service"; + EDocServiceStatus: Record "E-Document Service Status"; + EDocumentLog: Codeunit "E-Document Log"; + OpenSourceDocumentHeader: RecordRef; + Guid: Guid; + begin + OpenSourceDocumentHeader.GetTable(OpenRecord); + if OpenSourceDocumentHeader.Number() <> Database::"Purchase Header" then + exit; + + OpenSourceDocumentHeader.SetTable(PurchaseHeader); + PurchaseHeader.SetRecFilter(); + PurchaseHeader."E-Document Link" := Guid; + // For invoices and fully invoiced orders, the open document is no valid + if not PurchaseHeader.IsEmpty() then begin + PurchaseHeader.Modify(); + + // Dequeue edoc list of pending edocuments and set "Order linked" + EDocument.SetRange("Document Record ID", PurchaseHeader.RecordId()); + EDocument.SetFilter(Status, '<>%1', Enum::"E-Document Status"::Processed); + if EDocument.FindFirst() then begin + EDocService := EDocumentLog.GetLastServiceFromLog(EDocument); + EDocServiceStatus.Get(EDocument."Entry No", EDocService.Code); + if EDocServiceStatus.Status = EDocServiceStatus.Status::Pending then begin + EDocServiceStatus.Status := EDocServiceStatus.Status::"Order Linked"; + EDocServiceStatus.Modify(); + end; + end; + end; + end; + + local procedure ValidateDocumentTotalAgainstEDocument(var EDocument: Record "E-Document"; PostedRecord: Variant) + var + PurchaseHeader: Record "Purchase Header"; + PostedSourceDocumentHeader: RecordRef; + begin + if EDocument.Direction <> Enum::"E-Document Direction"::Incoming then + exit; + + PostedSourceDocumentHeader.GetTable(PostedRecord); + case PostedSourceDocumentHeader.Number() of + Database::"Purchase Header": + begin + PostedSourceDocumentHeader.SetTable(PurchaseHeader); + PurchaseHeader.CalcFields("Amount Incl. VAT To Inv."); + if EDocument."Amount Incl. VAT" <> PurchaseHeader."Amount Incl. VAT To Inv." then + Error(WrongAmountErr, PurchaseHeader."Amount Incl. VAT To Inv.", EDocument."Amount Incl. VAT"); + end; + end; + end; + + local procedure UpdateToPostedEDocument(var EDocument: Record "E-Document"; PostedRecord: Variant; PostedDocumentNo: Code[20]; DocumentType: Enum "E-Document Type") + var + EDocService: Record "E-Document Service"; + EDocumentLog: Codeunit "E-Document Log"; + EDocLogHelper: Codeunit "E-Document Log Helper"; + PostedSourceDocumentHeader: RecordRef; + begin + PostedSourceDocumentHeader.GetTable(PostedRecord); + EDocument."Document Record ID" := PostedSourceDocumentHeader.RecordId; + EDocument."Document No." := PostedDocumentNo; + EDocument."Document Type" := DocumentType; + EDocument.Status := Enum::"E-Document Status"::Processed; + EDocument.Modify(); + + // If we posted from incoming document + if EDocument.Direction = Enum::"E-Document Direction"::Incoming then begin + EDocService := EDocumentLog.GetLastServiceFromLog(EDocument); + EDocLogHelper.InsertLog(EDocument, EDocService, Enum::"E-Document Service Status"::"Imported Document Created"); + end; + end; + + local procedure CreateOrUpdateEDocument(OpenRecord: Variant; PostedRecord: Variant; PostedDocumentNo: Code[20]; DocumentType: Enum "E-Document Type") + var + EDocument: Record "E-Document"; + PostedSourceDocumentHeader: RecordRef; + begin + if IsEDocumentLinkedToPurchaseDocument(EDocument, OpenRecord) then begin + UpdateToPostedEDocument(EDocument, PostedRecord, PostedDocumentNo, DocumentType); + RemoveEDocumentLinkFromPurchaseDocument(OpenRecord); + end else begin + PostedSourceDocumentHeader.GetTable(PostedRecord); if EDocumentHelper.IsElectronicDocument(PostedSourceDocumentHeader) then EDocExport.CreateEDocument(PostedSourceDocumentHeader); + end; end; + var - EDocument: Record "E-Document"; EDocExport: Codeunit "E-Doc. Export"; EDocumentHelper: Codeunit "E-Document Helper"; EDocumentProcessingPhase: Enum "E-Document Processing Phase"; + WrongAmountErr: Label 'Purchase Document cannot be released as Amount Incl. VAT: %1, is different from E-Document Amount Incl. VAT: %2', Comment = '%1 - Purchase document amount, %2 - E-document amount'; } diff --git a/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocImportedLine.Table.al b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocImportedLine.Table.al new file mode 100644 index 0000000000..e5bced079c --- /dev/null +++ b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocImportedLine.Table.al @@ -0,0 +1,154 @@ +namespace Microsoft.eServices.EDocument.OrderMatch; + +using Microsoft.Purchases.Document; +using Microsoft.eServices.EDocument; +table 6165 "E-Doc. Imported Line" +{ + DataClassification = CustomerContent; + Access = Internal; + + fields + { + field(1; "E-Document Entry No."; Integer) + { + Caption = 'E-Document Entry No.'; + TableRelation = "E-Document"; + Editable = false; + } + field(2; "Line No."; Integer) + { + Caption = 'Line No.'; + Editable = false; + } + field(3; Type; Enum "Purchase Line Type") + { + Caption = 'Type'; + Editable = false; + } + field(4; Description; Text[100]) + { + Caption = 'Description'; + Editable = false; + } + field(5; "Unit Of Measure Code"; Code[20]) + { + Caption = 'Unit Of Measure'; + Editable = false; + } + field(6; Quantity; Integer) + { + Caption = 'Quantity'; + Editable = false; + } + field(7; "Matched Quantity"; Integer) + { + Caption = 'Matched Quantity'; + Editable = false; + + trigger OnValidate() + begin + if ("Matched Quantity" > Quantity) or ("Matched Quantity" < 0) then + Error(MatchedQtyErr); + + Validate("Fully Matched"); + end; + } + field(8; "Fully Matched"; Boolean) + { + Caption = 'Fully Matched'; + Editable = false; + + trigger OnValidate() + begin + "Fully Matched" := "Matched Quantity" = Quantity; + end; + } + field(9; "Direct Unit Cost"; Decimal) + { + Caption = 'Direct Unit Cost'; + Editable = false; + } + field(10; "Line Discount %"; Decimal) + { + Caption = 'Line Discount %'; + Editable = false; + DecimalPlaces = 0 : 5; + MaxValue = 100; + MinValue = 0; + } + field(11; "No."; Code[20]) + { + Caption = 'No.'; + } + } + + keys + { + key(Key1; "E-Document Entry No.", "Line No.") + { + Clustered = true; + } + } + + var + MatchedQtyErr: Label 'The Matched Quantity should not exceed Quantity and cannot be less than zero.'; + + procedure DisplayMatches() + var + EDocOrderMatch: Record "E-Doc. Order Match"; + begin + EDocOrderMatch.SetRange("E-Document Entry No.", Rec."E-Document Entry No."); + EDocOrderMatch.SetRange("E-Document Line No.", Rec."Line No."); + if not EDocOrderMatch.IsEmpty() then + Page.Run(Page::"E-Doc. Order Match", EDocOrderMatch); + end; + + procedure Insert(EDocument: Record "E-Document"; TempDocumentLine: RecordRef; var TempEDocImportedLine: Record "E-Doc. Imported Line" temporary) + var + PurchaseLine: Record "Purchase Line"; + LineNo: Integer; + begin + if TempDocumentLine.Number <> Database::"Purchase Line" then + exit; + TempDocumentLine.SetTable(PurchaseLine); + + TempEDocImportedLine.SetRange("E-Document Entry No.", EDocument."Entry No"); + LineNo := TempEDocImportedLine.GetNextLineNo(); + + TempEDocImportedLine.Reset(); + TempEDocImportedLine."E-Document Entry No." := EDocument."Entry No"; + TempEDocImportedLine."Line No." := LineNo; + TempEDocImportedLine."No." := PurchaseLine."No."; + TempEDocImportedLine."Unit Of Measure Code" := PurchaseLine."Unit of Measure Code"; + + if TempEDocImportedLine."No." = '' then begin + TempEDocImportedLine."No." := CopyStr(PurchaseLine."Item Reference No.", 1, MaxStrLen(PurchaseLine."No.")); + TempEDocImportedLine."Unit Of Measure Code" := PurchaseLine."Item Reference Unit of Measure"; + end; + + TempEDocImportedLine.Description := PurchaseLine.Description; + TempEDocImportedLine.Type := PurchaseLine.Type; + TempEDocImportedLine.Quantity := PurchaseLine.Quantity; + TempEDocImportedLine."Direct Unit Cost" := PurchaseLine."Direct Unit Cost"; + if PurchaseLine."Line Discount Amount" > 0 then + TempEDocImportedLine."Line Discount %" := 100 * (PurchaseLine."Line Discount Amount" / (PurchaseLine.Amount + PurchaseLine."Line Discount Amount")); + TempEDocImportedLine.Insert(); + end; + + internal procedure GetNextLineNo(): Integer + begin + if Rec.FindLast() then; + exit(Rec."Line No." + 10000); + end; + + procedure GetStyle() Result: Text + begin + if Rec."Fully Matched" then + exit('Favorable'); + if Rec."Matched Quantity" > 0 then + exit('Ambiguous'); + + exit('None'); + end; + +} \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocImportedLineSub.Page.al b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocImportedLineSub.Page.al new file mode 100644 index 0000000000..fe9fe0c375 --- /dev/null +++ b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocImportedLineSub.Page.al @@ -0,0 +1,146 @@ +namespace Microsoft.eServices.EDocument.OrderMatch; + +using Microsoft.eServices.EDocument; + +page 6165 "E-Doc. Imported Line Sub" +{ + PageType = ListPart; + ApplicationArea = All; + SourceTable = "E-Doc. Imported Line"; + DeleteAllowed = false; + InsertAllowed = false; + RefreshOnActivate = true; + + layout + { + area(Content) + { + repeater(Group) + { + ShowCaption = false; + field("Line No."; Rec."Line No.") + { + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies imported line number.'; + } + field("No."; Rec."No.") + { + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies what you received, such as a product or a general ledger account.'; + } + field(Description; Rec.Description) + { + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies the description of what was received.'; + } + field("Unit Of Measure Code"; Rec."Unit Of Measure Code") + { + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies how each unit of the item or resource is measured, such as in pieces or hours.'; + } + field(Quantity; Rec.Quantity) + { + Caption = 'Quantity'; + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies the quantity that was received.'; + } + field("Matched Quantity"; Rec."Matched Quantity") + { + Editable = false; + ToolTip = 'Specifies the quantity that matched to purchase order lines.'; + + trigger OnDrillDown() + begin + if Rec."Matched Quantity" > 0 then + Rec.DisplayMatches(); + end; + + } + field("Unit Price"; Rec."Direct Unit Cost") + { + Editable = false; + StyleExpr = StyleTxt; + ToolTip = 'Specifies the price of one unit of what you received.'; + } + field("Discount %"; Rec."Line Discount %") + { + Editable = false; + StyleExpr = StyleTxt; + ToolTip = 'Specifies the discount percentage that is granted for the line.'; + } + } + } + } + + var + EDocumentBeingMatched: Record "E-Document"; + StyleTxt: Text; + + + trigger OnAfterGetRecord() + begin + SetUserInteractions(); + end; + + internal procedure GetRecords(var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary) + var + EDocumentImportedLine: Record "E-Doc. Imported Line"; + begin + Clear(TempEDocumentImportedLine); + EDocumentImportedLine.SetRange("E-Document Entry No.", EDocumentBeingMatched."Entry No"); + if EDocumentImportedLine.FindSet() then + repeat + TempEDocumentImportedLine.TransferFields(EDocumentImportedLine); + TempEDocumentImportedLine.Insert(); + until EDocumentImportedLine.Next() = 0; + end; + + internal procedure GetSelectedRecords(var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary) + var + EDocumentImportedLine: Record "E-Doc. Imported Line"; + begin + Clear(TempEDocumentImportedLine); + CurrPage.SetSelectionFilter(EDocumentImportedLine); + if EDocumentImportedLine.FindSet() then + repeat + TempEDocumentImportedLine.TransferFields(EDocumentImportedLine); + TempEDocumentImportedLine.Insert(); + until EDocumentImportedLine.Next() = 0; + end; + + internal procedure SetEDocumentBeingMatched(var EDocument: Record "E-Document") + begin + EDocumentBeingMatched := EDocument; + end; + + internal procedure SetUserInteractions() + begin + StyleTxt := Rec.GetStyle(); + end; + + internal procedure ShowIncompleteMatches() + begin + Rec.Reset(); + Rec.SetRange("E-Document Entry No.", EDocumentBeingMatched."Entry No"); + if Rec.FindSet() then + repeat + if not Rec."Fully Matched" then + Rec.Mark(true); + until Rec.Next() = 0; + Rec.MarkedOnly(true); + CurrPage.Update(false); + end; + + internal procedure ShowAll() + begin + Rec.ClearMarks(); + Rec.MarkedOnly(false); + CurrPage.Update(false); + end; + +} \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocLineMatching.Codeunit.al b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocLineMatching.Codeunit.al new file mode 100644 index 0000000000..b2d828a915 --- /dev/null +++ b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocLineMatching.Codeunit.al @@ -0,0 +1,459 @@ +namespace Microsoft.eServices.EDocument.OrderMatch; + +using Microsoft.Bank.Reconciliation; +using Microsoft.eServices.EDocument; +using Microsoft.Purchases.Document; +using System.Utilities; + + +codeunit 6164 "E-Doc. Line Matching" +{ + Access = Internal; + + var + EmptyRecordErr: Label 'Empty selection cannot be matched.'; + DiscountErr: Label 'Varied Discount found among selected %1 entries. Please review and deselect entries with different Discount in order to match selection', Comment = '%1 - Table name for selected entries'; + DiscountDiffErr: Label 'Varied Discount found in existing matching for Import line %1. Please review and undo previous matching in order to match selection', Comment = '%1 - Import line number'; + UnitCostErr: Label 'Varied Unit Costs found among selected %1 entries. Please review and deselect entries with different Unit Costs in order to match selection', Comment = '%1 - Table name for selected entries'; + UnitCostDiffErr: Label 'Varied Unit Cost found in existing matching for Import line %1. Please review and undo previous matching in order to match selection', Comment = '%1 - Import line number'; + MatchErr: Label '%1 discrepancy detected in 1 or more matches for Purchase Line %2. %3 is required across all matches.', Comment = '%1 - Field Caption, %2 - Purchase Line No., %3 - Field Caption'; + UOMErr: Label 'Varied Unit Of Measures found among selected %1 entries. Please review and deselect entries with different Unit Of Measures in order to match selection', Comment = '%1 - Table name for selected entries'; + UnmatchedImportLineErr: Label 'Matching of Imported Line %1 is incomplete. It is not fully matched to purchase order lines.', Comment = '%1 - Imported Line No.'; + OverwriteExistingMatchesTxt: Label 'There are lines for this e-document that are already matched with this purchase order.\\ Do you want to overwrite the existing matches?'; + PurchaseHeaderAlreadyLinkedErr: Label 'Cannot apply to purchase order as it is already linked to E-Document'; + + + procedure RunMatching(var EDocument: Record "E-Document") + var + EDocOrderLineMatching: Page "E-Doc. Order Line Matching"; + begin + EDocOrderLineMatching.SetRecord(EDocument); + EDocOrderLineMatching.RunModal(); + end; + + procedure ApplyToPurchaseOrder(var EDocument: Record "E-Document"; var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary) + var + PurchaseLine: Record "Purchase Line"; + PurchaseHeader: Record "Purchase Header"; + EDocOrderMatch: Record "E-Doc. Order Match"; + EDocService: Record "E-Document Service"; + EDocumentLog: Codeunit "E-Document Log"; + EDocLogHelper: Codeunit "E-Document Log Helper"; + RecordRef: RecordRef; + begin + // Check that all imorted lines have been matched + if TempEDocumentImportedLine.FindSet() then + repeat + if TempEDocumentImportedLine."Matched Quantity" <> TempEDocumentImportedLine.Quantity then + Error(UnmatchedImportLineErr, TempEDocumentImportedLine."Line No."); + until TempEDocumentImportedLine.Next() = 0; + + RecordRef.Get(EDocument."Document Record ID"); + RecordRef.SetTable(PurchaseHeader); + PurchaseHeader.Validate("Document Date", EDocument."Document Date"); + PurchaseHeader.Validate("Vendor Invoice No.", EDocument."Incoming E-Document No."); + if PurchaseHeader.IsLinkedToEDoc(EDocument) then + Error(PurchaseHeaderAlreadyLinkedErr); + PurchaseHeader.Validate("E-Document Link", EDocument.SystemId); + PurchaseHeader.Modify(); + + + EDocOrderMatch.SetRange("E-Document Entry No.", EDocument."Entry No"); + EDocOrderMatch.SetRange("Document Order No.", EDocument."Order No."); + PurchaseLine.SetRange("Document Type", Enum::"Purchase Document Type"::Order); + PurchaseLine.SetRange("Document No.", EDocument."Order No."); + + + if PurchaseLine.FindSet() then + repeat + EDocOrderMatch.SetRange("Document Line No.", PurchaseLine."Line No."); + // We check that if there is a set, then Direct Cost, UOM and Discount % is all the same, otherwise we cant + TestFieldsAreTheSameInSet(EDocOrderMatch); + + if EDocOrderMatch.FindFirst() then begin + if PurchaseLine."Direct Unit Cost" <> EDocOrderMatch."Direct Unit Cost" then + PurchaseLine.Validate("Direct Unit Cost", EDocOrderMatch."Direct Unit Cost"); + if PurchaseLine."Line Discount %" <> EDocOrderMatch."Line Discount %" then + PurchaseLine.Validate("Line Discount %", EDocOrderMatch."Line Discount %"); + PurchaseLine.Validate("Amount Including VAT"); + PurchaseLine.Modify(); + end + until PurchaseLine.Next() = 0; + + EDocService := EDocumentLog.GetLastServiceFromLog(EDocument); + EDocLogHelper.InsertLog(EDocument, EDocService, Enum::"E-Document Service Status"::"Order Updated"); + end; + + local procedure TestFieldsAreTheSameInSet(var EDocOrderMatch: Record "E-Doc. Order Match") + var + EDocOrderMatch2: Record "E-Doc. Order Match"; + begin + if not EDocOrderMatch.FindFirst() then + exit; + + EDocOrderMatch2.Copy(EDocOrderMatch); + if EDocOrderMatch2.FindSet() then + repeat + if EDocOrderMatch2."Direct Unit Cost" <> EDocOrderMatch."Direct Unit Cost" then + Error(MatchErr, EDocOrderMatch.FieldCaption("Direct Unit Cost"), EDocOrderMatch."Document Line No.", EDocOrderMatch.FieldCaption("Direct Unit Cost")); + if EDocOrderMatch2."Line Discount %" <> EDocOrderMatch."Line Discount %" then + Error(MatchErr, EDocOrderMatch.FieldCaption("Line Discount %"), EDocOrderMatch."Document Line No.", EDocOrderMatch.FieldCaption("Line Discount %")); + until EDocOrderMatch2.Next() = 0; + end; + + procedure ResetMatchedQty(var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary) + begin + UpdateMatchedQty(TempEDocumentImportedLine, -TempEDocumentImportedLine."Matched Quantity"); + end; + + procedure UpdateMatchedQty(var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary; Quantity: Integer) + begin + TempEDocumentImportedLine.Validate("Matched Quantity", TempEDocumentImportedLine."Matched Quantity" + Quantity); + TempEDocumentImportedLine.Modify(true); + end; + + procedure ResetQtyToInvoice(var TempPurchaseLine: Record "Purchase Line" temporary) + begin + UpdateQtyToInvoice(TempPurchaseLine, -TempPurchaseLine."Qty. to Invoice"); + end; + + procedure UpdateQtyToInvoice(var TempPurchaseLine: Record "Purchase Line" temporary; Quantity: Integer) + begin + TempPurchaseLine.Validate("Qty. to Invoice", TempPurchaseLine."Qty. to Invoice" + Quantity); + TempPurchaseLine.Modify(true); + end; + + procedure PersistsUpdates(var TempEDocMatchesThatWasMatched: Record "E-Doc. Order Match" temporary; RemoveMatch: Boolean) + var + EDocImportedLine: Record "E-Doc. Imported Line"; + EDocOrderMatch: Record "E-Doc. Order Match"; + PurchaseLine: Record "Purchase Line"; + begin + TempEDocMatchesThatWasMatched.Reset(); + if TempEDocMatchesThatWasMatched.FindSet() then + repeat + EDocOrderMatch.Copy(TempEDocMatchesThatWasMatched); + PurchaseLine := EDocOrderMatch.GetPurchaseLine(); + PurchaseLine.Validate("Qty. to Invoice", PurchaseLine."Qty. to Invoice" + EDocOrderMatch.Quantity); + PurchaseLine.Modify(true); + + EDocImportedLine := EDocOrderMatch.GetImportedLine(); + EDocImportedLine.Validate("Matched Quantity", EDocImportedLine."Matched Quantity" + EDocOrderMatch.Quantity); + EDocImportedLine.Modify(true); + + if RemoveMatch then + EDocOrderMatch.Delete() + else + EDocOrderMatch.Insert(); + + until TempEDocMatchesThatWasMatched.Next() = 0; + end; + + procedure ResetQtyToInvoiceBasedOnMatches(var EDocument: Record "E-Document"; var TempPurchaseLine: Record "Purchase Line" temporary) + var + EDocOrderMatch: Record "E-Doc. Order Match"; + begin + EDocOrderMatch.SetRange("E-Document Entry No.", EDocument."Entry No"); + TempPurchaseLine.Reset(); + if TempPurchaseLine.FindSet() then + repeat + EDocOrderMatch.SetRange("Document Order No.", TempPurchaseLine."Document No."); + EDocOrderMatch.SetRange("Document Line No.", TempPurchaseLine."Line No."); + EDocOrderMatch.CalcSums(Quantity); + TempPurchaseLine.Validate("Qty. to Invoice", EDocOrderMatch.Quantity); + TempPurchaseLine.Modify(); + until TempPurchaseLine.Next() = 0; + end; + + procedure ResetQtyToInvoice(var EDocument: Record "E-Document") + var + PurchaseLine: Record "Purchase Line"; + begin + PurchaseLine.SetRange("Document Type", Enum::"Purchase Document Type"::Order); + PurchaseLine.SetRange("Document No.", EDocument."Order No."); + PurchaseLine.ModifyAll("Qty. to Invoice", 0, true); + end; + + procedure RemoveAllMatches(var EDocument: Record "E-Document") + var + EDocOrderMatch: Record "E-Doc. Order Match"; + EDocImportedLine: Record "E-Doc. Imported Line"; + PurchaseLine: Record "Purchase Line"; + begin + EDocOrderMatch.SetRange("E-Document Entry No.", EDocument."Entry No"); + EDocOrderMatch.DeleteAll(); + + EDocImportedLine.SetRange("E-Document Entry No.", EDocument."Entry No"); + EDocImportedLine.ModifyAll("Matched Quantity", 0); + EDocImportedLine.ModifyAll("Fully Matched", false); + + PurchaseLine.SetRange("Document Type", Enum::"Purchase Document Type"::Order); + PurchaseLine.SetRange("Document No.", EDocument."Order No."); + PurchaseLine.ModifyAll("Qty. to Invoice", 0); + end; + + procedure FindMatchesToRemove(var EDocument: Record "E-Document"; var TempPurchaseLine: Record "Purchase Line" temporary; var TempEDocMatchesThatWasRemoved: Record "E-Doc. Order Match" temporary) + var + EDocOrderMatch: Record "E-Doc. Order Match"; + begin + if TempPurchaseLine.FindSet() then begin + EDocOrderMatch.SetRange("E-Document Entry No.", EDocument."Entry No"); + EDocOrderMatch.SetRange("Document Order No.", TempPurchaseLine."Document No."); + repeat + EDocOrderMatch.SetRange("Document Line No.", TempPurchaseLine."Line No."); + if EDocOrderMatch.FindSet() then + repeat + TempEDocMatchesThatWasRemoved := EDocOrderMatch; + TempEDocMatchesThatWasRemoved.Quantity *= -1; + TempEDocMatchesThatWasRemoved.Insert(); + until EDocOrderMatch.Next() = 0; + until TempPurchaseLine.Next() = 0; + end + end; + + + procedure MatchManually(var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary; var TempPurchaseLine: Record "Purchase Line" temporary; var TempEDocMatchesThatWasMatched: Record "E-Doc. Order Match" temporary) + begin + if TempEDocumentImportedLine.IsEmpty() or TempPurchaseLine.IsEmpty() then + Error(EmptyRecordErr); + + VerifyPurchaseOrderLinesHaveSameFieldValuesOrError(TempPurchaseLine); + VerifyImportedLinesHaveSameFieldValuesOrError(TempEDocumentImportedLine); + VerifyExistingMatchesHasSameFieldValue(TempEDocumentImportedLine, TempPurchaseLine); + if TempPurchaseLine.FindSet() then + repeat + MatchManyToOne(TempEDocumentImportedLine, TempPurchaseLine, TempEDocMatchesThatWasMatched); + until TempPurchaseLine.Next() = 0; + end; + + + local procedure VerifyImportedLinesHaveSameFieldValuesOrError(var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary) + var + UnitCost: Decimal; + Discount: Decimal; + UOM: Code[20]; + begin + TempEDocumentImportedLine.FindFirst(); + UnitCost := TempEDocumentImportedLine."Direct Unit Cost"; + Discount := TempEDocumentImportedLine."Line Discount %"; + UOM := TempEDocumentImportedLine."Unit of Measure Code"; + TempEDocumentImportedLine.FindSet(); + repeat + if UnitCost <> TempEDocumentImportedLine."Direct Unit Cost" then + Error(UnitCostErr, TempEDocumentImportedLine.TableCaption()); + if Discount <> TempEDocumentImportedLine."Line Discount %" then + Error(DiscountErr, TempEDocumentImportedLine.TableCaption()); + if UOM <> TempEDocumentImportedLine."Unit of Measure Code" then + Error(UOMErr, TempEDocumentImportedLine.TableCaption()); + until TempEDocumentImportedLine.Next() = 0; + end; + + local procedure VerifyPurchaseOrderLinesHaveSameFieldValuesOrError(var TempPurchaseLine: Record "Purchase Line" temporary) + var + UnitCost: Decimal; + Discount: Decimal; + UOM: Code[20]; + begin + TempPurchaseLine.FindFirst(); + UnitCost := TempPurchaseLine."Direct Unit Cost"; + Discount := TempPurchaseLine."Line Discount %"; + UOM := TempPurchaseLine."Unit of Measure Code"; + TempPurchaseLine.FindSet(); + repeat + if UnitCost <> TempPurchaseLine."Direct Unit Cost" then + Error(UnitCostErr, TempPurchaseLine.TableCaption()); + if Discount <> TempPurchaseLine."Line Discount %" then + Error(DiscountErr, TempPurchaseLine.TableCaption()); + if UOM <> TempPurchaseLine."Unit of Measure Code" then + Error(UOMErr, TempPurchaseLine.TableCaption()); + until TempPurchaseLine.Next() = 0; + end; + + local procedure VerifyExistingMatchesHasSameFieldValue(var TempEDocImportedLine: Record "E-Doc. Imported Line" temporary; var TempPurchaseLine: Record "Purchase Line" temporary) + var + EDocOrderMatch: Record "E-Doc. Order Match"; + begin + TempPurchaseLine.FindFirst(); + TempEDocImportedLine.FindFirst(); + + EDocOrderMatch.SetRange("Document Order No.", TempPurchaseLine."Document No."); + EDocOrderMatch.SetRange("E-Document Entry No.", TempEDocImportedLine."E-Document Entry No."); + EDocOrderMatch.SetRange("Document Line No.", TempPurchaseLine."Line No."); + if EDocOrderMatch.FindFirst() then begin + if EDocOrderMatch."Direct Unit Cost" <> TempEDocImportedLine."Direct Unit Cost" then + Error(UnitCostDiffErr, EDocOrderMatch."E-Document Line No."); + if EDocOrderMatch."Line Discount %" <> TempEDocImportedLine."Line Discount %" then + Error(DiscountDiffErr, EDocOrderMatch."E-Document Line No."); + end; + end; + + procedure AskToOverwrite(EDocument: Record "E-Document"; var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary; var TempPurchaseLine: Record "Purchase Line" temporary) + var + EDocOrderMatch: Record "E-Doc. Order Match"; + PurchaseLine: Record "Purchase Line"; + EDocImportedLine: Record "E-Doc. Imported Line"; + ConfirmManagement: Codeunit "Confirm Management"; + Overwrite: Boolean; + begin + EDocOrderMatch.SetRange("E-Document Entry No.", EDocument."Entry No"); + if not EDocOrderMatch.IsEmpty() then begin + Overwrite := ConfirmManagement.GetResponseOrDefault(OverwriteExistingMatchesTxt, false); + if Overwrite then begin + // Reset filters and qty + TempEDocumentImportedLine.Reset(); + TempPurchaseLine.Reset(); + if TempPurchaseLine.FindSet() then + repeat + ResetQtyToInvoice(TempPurchaseLine); + PurchaseLine := TempPurchaseLine; + PurchaseLine.Modify(true); + until TempPurchaseLine.Next() = 0; + + if TempEDocumentImportedLine.FindSet() then + repeat + ResetMatchedQty(TempEDocumentImportedLine); + EDocImportedLine := TempEDocumentImportedLine; + EDocImportedLine.Modify(true); + until TempEDocumentImportedLine.Next() = 0; + + EDocOrderMatch.DeleteAll(); + end + end; + end; + + procedure MatchAutomatically(EDocument: Record "E-Document"; var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary; var TempPurchaseLine: Record "Purchase Line" temporary; var TempEDocMatchesThatWasMatched: Record "E-Doc. Order Match" temporary) + var + RecordMatchMgt: Codeunit "Record Match Mgt."; + begin + if TempEDocumentImportedLine.IsEmpty() or TempPurchaseLine.IsEmpty() then + Error(EmptyRecordErr); + + // Automatic matching will do the following + // - For each Import Line, try to get full assignment in 1 or more PO lines + // - Filter on Type, then Number, Then Text + + if TempEDocumentImportedLine.FindSet() then + repeat + + // Match based on Number + TempPurchaseLine.Reset(); + TempPurchaseLine.SetRange("No.", TempEDocumentImportedLine."No."); + TempPurchaseLine.SetRange("Unit of Measure Code", TempEDocumentImportedLine."Unit Of Measure Code"); + TempPurchaseLine.SetRange("Direct Unit Cost", TempEDocumentImportedLine."Direct Unit Cost"); + TempPurchaseLine.SetRange("Line Discount %", TempEDocumentImportedLine."Line Discount %"); + + MatchOneToMany(TempEDocumentImportedLine, TempPurchaseLine, TempEDocMatchesThatWasMatched); + + if TempEDocumentImportedLine.Quantity > TempEDocumentImportedLine."Matched Quantity" then begin + + // We still have more to match for imported line + TempPurchaseLine.SetRange("No."); + TempPurchaseLine.SetFilter("No.", '<>%1', TempEDocumentImportedLine."No."); + if TempPurchaseLine.FindSet() then + // TO precheck to avoid unessesary Calc String Nearness + if TempPurchaseLine.MaxQtyToInvoice() > TempPurchaseLine."Qty. to Invoice" then + // If substring is 80% match + if RecordMatchMgt.CalculateStringNearness(TempPurchaseLine.Description, TempEDocumentImportedLine.Description, 4, 100) > 80 then + MatchOneToOne(TempEDocumentImportedLine, TempPurchaseLine, TempEDocMatchesThatWasMatched); + end; + until TempEDocumentImportedLine.Next() = 0; + + // Reset filters before exit + TempPurchaseLine.Reset(); + TempEDocumentImportedLine.Reset(); + end; + + procedure InsertOrderMatch(var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary; var TempPurchaseLine: Record "Purchase Line" temporary; var TempEDocMatchesThatWasMatched: Record "E-Doc. Order Match" temporary; Quantity: Integer; FullMatch: Boolean) + begin + TempEDocMatchesThatWasMatched.SetRange("Document Order No.", TempPurchaseLine."Document No."); + TempEDocMatchesThatWasMatched.SetRange("Document Line No.", TempPurchaseLine."Line No."); + TempEDocMatchesThatWasMatched.SetRange("E-Document Entry No.", TempEDocumentImportedLine."E-Document Entry No."); + TempEDocMatchesThatWasMatched.SetRange("E-Document Line No.", TempEDocumentImportedLine."Line No."); + TempEDocMatchesThatWasMatched.DeleteAll(); + TempEDocMatchesThatWasMatched.Reset(); + + TempEDocMatchesThatWasMatched.Init(); + TempEDocMatchesThatWasMatched.Validate("Document Order No.", TempPurchaseLine."Document No."); + TempEDocMatchesThatWasMatched.Validate("Document Line No.", TempPurchaseLine."Line No."); + TempEDocMatchesThatWasMatched.Validate("E-Document Entry No.", TempEDocumentImportedLine."E-Document Entry No."); + TempEDocMatchesThatWasMatched.Validate("E-Document Line No.", TempEDocumentImportedLine."Line No."); + TempEDocMatchesThatWasMatched.Validate(Quantity, Quantity); + TempEDocMatchesThatWasMatched.Validate("Direct Unit Cost", TempEDocumentImportedLine."Direct Unit Cost"); + TempEDocMatchesThatWasMatched.Validate("Line Discount %", TempEDocumentImportedLine."Line Discount %"); + TempEDocMatchesThatWasMatched.Validate("Unit of Measure Code", TempEDocumentImportedLine."Unit of Measure Code"); + TempEDocMatchesThatWasMatched.Validate("Fully Matched", FullMatch); + TempEDocMatchesThatWasMatched.Description := TempEDocumentImportedLine.Description; + TempEDocMatchesThatWasMatched.Insert(); + end; + + procedure MatchOneToOne(var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary; var TempPurchaseLine: Record "Purchase Line" temporary; var TempEDocMatchesThatWasMatched: Record "E-Doc. Order Match" temporary) + var + RemaningQuantityToMatch, TotalThatCanBeInvoiced : Integer; + FullMatch: Boolean; + begin + // Calculate the quantity that is available to match for purchase order line + TotalThatCanBeInvoiced := (TempPurchaseLine."Quantity Received" - TempPurchaseLine."Quantity Invoiced") - TempPurchaseLine."Qty. to Invoice"; + if TotalThatCanBeInvoiced < 1 then + exit; + + // Calculate the quantity available to match for this imported line. + RemaningQuantityToMatch := TempEDocumentImportedLine.Quantity - TempEDocumentImportedLine."Matched Quantity"; + if RemaningQuantityToMatch < TotalThatCanBeInvoiced then begin + TotalThatCanBeInvoiced := RemaningQuantityToMatch; + FullMatch := true; + end; + + if TotalThatCanBeInvoiced < 1 then + exit; + + TempPurchaseLine.Validate("Qty. to Invoice", TempPurchaseLine."Qty. to Invoice" + TotalThatCanBeInvoiced); + TempPurchaseLine.Modify(true); + TempEDocumentImportedLine.Validate("Matched Quantity", TempEDocumentImportedLine."Matched Quantity" + TotalThatCanBeInvoiced); + TempEDocumentImportedLine.Modify(true); + InsertOrderMatch(TempEDocumentImportedLine, TempPurchaseLine, TempEDocMatchesThatWasMatched, TotalThatCanBeInvoiced, FullMatch); + end; + + procedure MatchManyToOne(var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary; var TempPurchaseLine: Record "Purchase Line" temporary; var TempEDocMatchesThatWasMatched: Record "E-Doc. Order Match" temporary) + begin + if TempEDocumentImportedLine.FindSet() then + repeat + MatchOneToOne(TempEDocumentImportedLine, TempPurchaseLine, TempEDocMatchesThatWasMatched) + until TempEDocumentImportedLine.Next() = 0; + end; + + procedure MatchOneToMany(var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary; var TempPurchaseLine: Record "Purchase Line" temporary; var TempEDocMatchesThatWasMatched: Record "E-Doc. Order Match" temporary) + begin + if TempPurchaseLine.FindSet() then + repeat + MatchOneToOne(TempEDocumentImportedLine, TempPurchaseLine, TempEDocMatchesThatWasMatched) + until TempPurchaseLine.Next() = 0; + end; + + + procedure FilterOutFullyMatchedLines(var TempEDocumentImportedLine: Record "E-Doc. Imported Line" temporary; var TempPurchaseLine: Record "Purchase Line" temporary) + var + TotalThatCanBeInvoiced: Integer; + begin + TempEDocumentImportedLine.SetRange("Fully Matched", false); + + if TempPurchaseLine.FindSet() then + repeat + TotalThatCanBeInvoiced := (TempPurchaseLine."Quantity Received" - TempPurchaseLine."Quantity Invoiced") - TempPurchaseLine."Qty. to Invoice"; + if TotalThatCanBeInvoiced > 0 then + TempPurchaseLine.Mark(true); + until TempPurchaseLine.Next() = 0; + TempPurchaseLine.MarkedOnly(true); + end; + + procedure SumUnitCostForMatches(EDocument: Record "E-Document") Sum: Decimal + var + EDocOrderMatch: Record "E-Doc. Order Match"; + begin + EDocOrderMatch.SetRange("E-Document Entry No.", EDocument."Entry No"); + EDocOrderMatch.SetRange("Document Order No.", EDocument."Order No."); + if EDocOrderMatch.FindSet() then + repeat + Sum += EDocOrderMatch.Quantity * EDocOrderMatch."Direct Unit Cost"; + until EDocOrderMatch.Next() = 0; + end; +} \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocOrderLineMatching.Page.al b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocOrderLineMatching.Page.al new file mode 100644 index 0000000000..e167c767bc --- /dev/null +++ b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocOrderLineMatching.Page.al @@ -0,0 +1,328 @@ +namespace Microsoft.eServices.EDocument.OrderMatch; + +using Microsoft.eServices.EDocument; +using System.Utilities; +using Microsoft.Purchases.Document; + +page 6167 "E-Doc. Order Line Matching" +{ + Caption = 'Purchase Order Matching'; + DataCaptionExpression = 'Purchase Order ' + Rec."Order No."; + PageType = Card; + ApplicationArea = All; + SourceTable = "E-Document"; + InsertAllowed = false; + DeleteAllowed = false; + RefreshOnActivate = true; + + layout + { + area(Content) + { + group("Document Details") + { + ShowCaption = false; + field("Bill-to/Pay-to Name"; Rec."Bill-to/Pay-to Name") + { + Caption = 'Vendor Name'; + ToolTip = 'Specifies the customer/vendor name of the electronic document.'; + } + field("Incoming E-Document No."; Rec."Incoming E-Document No.") + { + Caption = 'E-Document No.'; + ToolTip = 'Specifies the electronic document number.'; + } + field("Document Date"; Rec."Document Date") + { + Caption = 'E-Document Date'; + ToolTip = 'Specifies the electronic document date.'; + } + field("Amount Excl. VAT"; Rec."Amount Excl. VAT") + { + Caption = 'E-Document Amount'; + ToolTip = 'Specifies the e-document amount excluding VAT.'; + } + + } + group(Control8) + { + ShowCaption = false; + part(ImportedLines; "E-Doc. Imported Line Sub") + { + ApplicationArea = Basic, Suite; + Caption = 'Imported Lines'; + SubPageLink = "E-Document Entry No." = field("Entry No"); + UpdatePropagation = Both; + } + part(OrderLines; "E-Doc. Purchase Order Sub") + { + ApplicationArea = Basic, Suite; + Caption = 'Purchase Order Lines'; + SubPageLink = "Document Type" = filter("Order"), "Document No." = field("Order No."), Type = filter('G/L Account|Item'); + UpdatePropagation = Both; + } + } + } + } + + actions + { + area(Processing) + { + action(ApplyToPO) + { + ApplicationArea = Basic, Suite; + Caption = 'Apply To Purchase Order'; + ToolTip = 'Applies the matching and updates purchase order lines'; + Image = ApplyEntries; + + trigger OnAction() + begin + ApplyToPurchaseOrder(); + end; + } + action(MatchManual) + { + Caption = 'Match Manually'; + ToolTip = 'Manually match selected lines in both panes to link each imported line to one or more related purchase order lines.'; + ApplicationArea = All; + Image = CheckRulesSyntax; + + trigger OnAction() + begin + MatchManually(); + SetUserInteractions(); + end; + } + action(MatchAutomatic) + { + Caption = 'Match Automatically'; + ToolTip = 'Automatically search and match lines that have same Type, No., Unit Price, Discount and Unit Of Measure.'; + ApplicationArea = All; + Image = MapAccounts; + + trigger OnAction() + begin + MatchAutomatically(); + SetUserInteractions(); + end; + } + action(RemoveMatch) + { + Caption = 'Remove Match'; + ToolTip = 'Remove selection of matched purchase order lines.'; + ApplicationArea = All; + Image = RemoveLine; + + trigger OnAction() + begin + RemoveMatches(); + SetUserInteractions(); + end; + } + action(RemoveAllMatch) + { + Caption = 'Reset Matching'; + ToolTip = 'Removes all matches made for E-Document.'; + ApplicationArea = All; + Image = ResetStatus; + + trigger OnAction() + begin + EDocMatchOrderLines.RemoveAllMatches(Rec); + SetUserInteractions(); + end; + } + action(ShowNonMatched) + { + Caption = 'Show Pending Lines'; + ToolTip = 'Show all e-document lines that have not been completely matched.'; + ApplicationArea = All; + Image = AddWatch; + + trigger OnAction() + begin + CurrPage.ImportedLines.Page.ShowIncompleteMatches(); + CurrPage.OrderLines.Page.ShowIncompleteMatches(); + end; + } + action(ShowAll) + { + Caption = 'Show All Lines'; + ToolTip = 'Show all e-document lines.'; + ApplicationArea = All; + Image = AddWatch; + + trigger OnAction() + begin + CurrPage.ImportedLines.Page.ShowAll(); + CurrPage.OrderLines.Page.ShowAll(); + end; + } + } + area(Navigation) + { + action(PurchaseOrder) + { + ApplicationArea = Basic, Suite; + Caption = 'Purchase Order'; + ToolTip = 'Opens the Purchase Order page with the related order'; + Image = Document; + RunObject = page "Purchase Order"; + RunPageLink = "No." = field("Order No."); + } + } + area(Promoted) + { + group(Category_Process) + { + actionref(ApplyToPO_Promoted; ApplyToPO) { } + } + group(Document) + { + actionref(Open_Promoted; PurchaseOrder) { } + } + group(Matching) + { + actionref(MatchManual_Promoted; MatchManual) { } + actionref(MatchAuto_Promoted; MatchAutomatic) { } + actionref(RemoveMatch_Promoted; RemoveMatch) { } + actionref(RemoveAll_Promoted; RemoveAllMatch) { } + } + group(Show) + { + actionref(ShowAll_Promoted; ShowAll) { } + actionref(ShowNonMatched_Promoted; ShowNonMatched) { } + } + } + } + + var + EDocMatchOrderLines: Codeunit "E-Doc. Line Matching"; + OpenPurchaseOrderMsg: Label 'Purchase order is not Open, which is required in order to match with e-document. Do you want to reopen purchase order?'; + LineDiscountVaryMatchMsg: Label 'Matched e-document lines (%1) has Line Discount % different from matched purchase order line. Please verify matches are correct.', Comment = '%1 - Line number'; + LineCostVaryMatchMsg: Label 'Matched e-document lines (%1) has Direct Unit Cost different from matched purchase order line. Please verify matches are correct.', Comment = '%1 - Line number'; + + trigger OnAfterGetCurrRecord() + begin + CurrPage.OrderLines.Page.SetEDocumentBeingMatched(Rec); + CurrPage.ImportedLines.Page.SetEDocumentBeingMatched(Rec); + CurrPage.OrderLines.Page.ResetQtyOnNonMatchedLines(); + + CheckPurchaseHeaderOpen(); + end; + + local procedure CheckPurchaseHeaderOpen() + var + PurchaseHeader: Record "Purchase Header"; + ConfirmManagement: Codeunit "Confirm Management"; + begin + PurchaseHeader.Get(Rec."Document Record ID"); + if PurchaseHeader.Status <> Enum::"Purchase Document Status"::Open then + if ConfirmManagement.GetResponseOrDefault(OpenPurchaseOrderMsg, true) then + PurchaseHeader.SetStatus(0) // Open + else + Error(''); + end; + + local procedure ApplyToPurchaseOrder() + var + TempEDocImportedLines: Record "E-Doc. Imported Line" temporary; + PurchaseHeader: Record "Purchase Header"; + PurchaseOrderPage: Page "Purchase Order"; + begin + CurrPage.ImportedLines.Page.GetRecords(TempEDocImportedLines); + EDocMatchOrderLines.ApplyToPurchaseOrder(Rec, TempEDocImportedLines); + + Commit(); + PurchaseHeader.Get(Rec."Document Record ID"); + PurchaseOrderPage.SetRecord(PurchaseHeader); + PurchaseOrderPage.Run(); + CurrPage.Close(); + end; + + local procedure RemoveMatches() + var + TempPurchaseLines: Record "Purchase Line" temporary; + TempEDocMatches: Record "E-Doc. Order Match" temporary; + begin + CurrPage.OrderLines.Page.GetSelectedRecords(TempPurchaseLines); + EDocMatchOrderLines.FindMatchesToRemove(Rec, TempPurchaseLines, TempEDocMatches); + if not TempEDocMatches.IsEmpty() then + EDocMatchOrderLines.PersistsUpdates(TempEDocMatches, true); + end; + + local procedure MatchManually() + var + TempEDocImportedLines: Record "E-Doc. Imported Line" temporary; + TempPurchaseLines: Record "Purchase Line" temporary; + TempEDocMatches: Record "E-Doc. Order Match" temporary; + begin + CurrPage.ImportedLines.Page.GetSelectedRecords(TempEDocImportedLines); + CurrPage.OrderLines.Page.GetSelectedRecords(TempPurchaseLines); + + EDocMatchOrderLines.MatchManually(TempEDocImportedLines, TempPurchaseLines, TempEDocMatches); + if not TempEDocMatches.IsEmpty() then begin + EDocMatchOrderLines.PersistsUpdates(TempEDocMatches, false); + NotifyUserIfCostDifference(TempEDocMatches); + end; + end; + + local procedure MatchAutomatically() + var + TempEDocImportedLines: Record "E-Doc. Imported Line" temporary; + TempPurchaseLines: Record "Purchase Line" temporary; + TempEDocMatches: Record "E-Doc. Order Match" temporary; + begin + CurrPage.ImportedLines.Page.GetRecords(TempEDocImportedLines); + CurrPage.OrderLines.Page.GetRecords(TempPurchaseLines); + + EDocMatchOrderLines.AskToOverwrite(Rec, TempEDocImportedLines, TempPurchaseLines); + EDocMatchOrderLines.MatchAutomatically(Rec, TempEDocImportedLines, TempPurchaseLines, TempEDocMatches); + if not TempEDocMatches.IsEmpty() then begin + EDocMatchOrderLines.PersistsUpdates(TempEDocMatches, false); + NotifyUserIfCostDifference(TempEDocMatches); + end; + end; + + local procedure SetUserInteractions() + begin + CurrPage.ImportedLines.Page.SetUserInteractions(); + CurrPage.OrderLines.Page.SetUserInteractions(); + end; + + local procedure NotifyUserIfCostDifference(var TempEDocMatches: Record "E-Doc. Order Match" temporary) + var + EDocImportedLine: Record "E-Doc. Imported Line"; + PurchaseLine: Record "Purchase Line"; + DiscountNotification, CostNotification : Notification; + LineDiscountNos, DirectUnitCostNos : Text; + begin + if TempEDocMatches.FindSet() then + repeat + EDocImportedLine := TempEDocMatches.GetImportedLine(); + PurchaseLine := TempEDocMatches.GetPurchaseLine(); + if EDocImportedLine."Line Discount %" <> PurchaseLine."Line Discount %" then + LineDiscountNos += Format(EDocImportedLine."Line No.") + ','; + if EDocImportedLine."Direct Unit Cost" <> PurchaseLine."Direct Unit Cost" then + DirectUnitCostNos += Format(EDocImportedLine."Line No.") + ','; + until TempEDocMatches.Next() = 0; + + if LineDiscountNos.EndsWith(',') then begin + LineDiscountNos := LineDiscountNos.Substring(1, StrLen(LineDiscountNos) - 1); + SendNotification(DiscountNotification, StrSubstNo(LineDiscountVaryMatchMsg, LineDiscountNos)); + end; + if DirectUnitCostNos.EndsWith(',') then begin + DirectUnitCostNos := DirectUnitCostNos.Substring(1, StrLen(DirectUnitCostNos) - 1); + SendNotification(CostNotification, StrSubstNo(LineCostVaryMatchMsg, DirectUnitCostNos)); + end; + end; + + local procedure SendNotification(SelectionNotification: Notification; Message: Text) + begin + SelectionNotification.Scope(NotificationScope::LocalScope); + SelectionNotification.Message(Message); + SelectionNotification.Send(); + end; + +} \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocOrderMatch.Page.al b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocOrderMatch.Page.al new file mode 100644 index 0000000000..d465694588 --- /dev/null +++ b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocOrderMatch.Page.al @@ -0,0 +1,44 @@ +namespace Microsoft.eServices.EDocument.OrderMatch; + +page 6164 "E-Doc. Order Match" +{ + PageType = List; + ApplicationArea = All; + SourceTable = "E-Doc. Order Match"; + Caption = 'E-Document Match Details'; + DataCaptionExpression = 'E-Document ' + Format(Rec."E-Document Entry No."); + Editable = false; + DeleteAllowed = false; + InsertAllowed = false; + ModifyAllowed = false; + + layout + { + area(Content) + { + repeater(Matches) + { + field("Imported Line No."; Rec."E-Document Line No.") + { + Caption = 'E-Document Line No.'; + ToolTip = 'Specifies E-Document Imported Line No.'; + } + field("Document Line No."; Rec."Document Line No.") + { + Caption = 'Purchase Order Line No.'; + ToolTip = 'Specifies Purchase Order Line No.'; + } + field("Description"; Rec.Description) + { + Caption = 'Description'; + ToolTip = 'Specifies the description of what is being matched.'; + } + field("Matched Quantity"; Rec.Quantity) + { + Caption = 'Matched Quantity'; + ToolTip = 'Specifies the quantity that was matched for the imported line to the purchase order line.'; + } + } + } + } +} \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocOrderMatch.Table.al b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocOrderMatch.Table.al new file mode 100644 index 0000000000..027966176e --- /dev/null +++ b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocOrderMatch.Table.al @@ -0,0 +1,82 @@ +namespace Microsoft.eServices.EDocument.OrderMatch; + +using Microsoft.Purchases.Document; +using Microsoft.eServices.EDocument; + +table 6164 "E-Doc. Order Match" +{ + DataClassification = CustomerContent; + Access = Internal; + + fields + { + field(1; "Document Order No."; Code[20]) + { + Caption = 'Document Order No.'; + TableRelation = "Purchase Header"."No." where("Document Type" = const(Order)); + } + field(2; "Document Line No."; Integer) + { + Caption = 'Document Line No.'; + TableRelation = "Purchase Line"."Line No." where("Document Type" = const(Order), "Document No." = field("Document Order No.")); + } + field(3; "E-Document Entry No."; Integer) + { + Caption = 'E-Document Entry No.'; + TableRelation = "E-Document"; + } + field(4; "E-Document Line No."; Integer) + { + Caption = 'E-Document Imported Line No.'; + TableRelation = "E-Doc. Imported Line"."Line No." where("E-Document Entry No." = field("E-Document Entry No.")); + } + field(5; Quantity; Integer) + { + Caption = 'Quantity'; + } + field(6; "Direct Unit Cost"; Decimal) + { + Caption = 'Unit Cost'; + } + field(7; "Line Discount %"; Decimal) + { + Caption = 'Discount %'; + } + field(8; "Unit of Measure Code"; Code[20]) + { + Caption = 'Unit of Measure'; + } + field(9; Description; Text[100]) + { + Caption = 'Description'; + } + field(10; "Fully Matched"; Boolean) + { + Caption = 'Fully Matched'; + } + } + + keys + { + key(Key1; "Document Order No.", "Document Line No.", "E-Document Entry No.", "E-Document Line No.") + { + Clustered = true; + } + key(Key2; "E-Document Entry No.", "E-Document Line No.", "Document Order No.") + { + SumIndexFields = Quantity; + } + } + + procedure GetPurchaseLine() PurchaseLine: Record "Purchase Line"; + begin + PurchaseLine.Get(Enum::"Purchase Document Type"::Order, Rec."Document Order No.", Rec."Document Line No."); + end; + + procedure GetImportedLine() ImportedLine: Record "E-Doc. Imported Line"; + begin + ImportedLine.Get(Rec."E-Document Entry No.", Rec."E-Document Line No."); + end; + + +} \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocPurchaseOrderSub.Page.al b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocPurchaseOrderSub.Page.al new file mode 100644 index 0000000000..24a36af5f7 --- /dev/null +++ b/Apps/W1/EDocument/app/src/Processing/OrderMatching/EDocPurchaseOrderSub.Page.al @@ -0,0 +1,179 @@ +namespace Microsoft.eServices.EDocument.OrderMatch; + +using Microsoft.Purchases.Document; +using Microsoft.eServices.EDocument; + +page 6168 "E-Doc. Purchase Order Sub" +{ + PageType = ListPart; + ApplicationArea = All; + SourceTable = "Purchase Line"; + DeleteAllowed = false; + InsertAllowed = false; + RefreshOnActivate = true; + + layout + { + area(Content) + { + repeater(Lines) + { + ShowCaption = false; + field("Line No."; Rec."Line No.") + { + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies purchase order line number.'; + } + field(Type; Rec.Type) + { + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies the line type.'; + } + field("No."; Rec."No.") + { + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies what you are buying, such as a product or a general ledger account.'; + } + field(Description; Rec.Description) + { + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies what is being purchased.'; + } + field("Unit of Measure Code"; Rec."Unit of Measure Code") + { + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies how each unit of the item or resource is measured, such as in pieces or hours.'; + } + field("Available Quantity"; Rec."Quantity Received" - Rec."Quantity Invoiced") + { + Caption = 'Available Quantity'; + DecimalPlaces = 0 : 0; + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies the quantity that can be matched to this line.'; + } + field("Qty. to Invoice"; Rec."Qty. to Invoice") + { + DecimalPlaces = 0 : 0; + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies the quantity that is matched to this line. Matching imported lines to this line will increase its value with the quantity of the imported line.'; + } + field("Direct Unit Cost"; Rec."Direct Unit Cost") + { + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies the price of one unit of what you''re buying.'; + } + field("Line Discount"; Rec."Line Discount %") + { + StyleExpr = StyleTxt; + Editable = false; + ToolTip = 'Specifies the discount percentage that is granted for the item on the line.'; + } + } + } + } + + var + EDocumentBeingMatched: Record "E-Document"; + StyleTxt: Text; + IsMatched: Boolean; + + trigger OnAfterGetRecord() + begin + IsMatched := Rec.HasEDocMatch(EDocumentBeingMatched."Entry No"); + SetUserInteractions(); + end; + + internal procedure SetUserInteractions() + begin + StyleTxt := Rec.GetStyle(); + if IsMatched then + StyleTxt := 'Favorable'; + end; + + internal procedure SetEDocumentBeingMatched(var EDocument: Record "E-Document") + begin + EDocumentBeingMatched := EDocument; + end; + + internal procedure ResetQtyOnNonMatchedLines() + var + EDocOrderMatch: Record "E-Doc. Order Match"; + TempPurchaseLine: Record "Purchase Line" temporary; + PurchaseLine: Record "Purchase Line"; + begin + EDocOrderMatch.SetRange("E-Document Entry No.", EDocumentBeingMatched."Entry No"); + GetRecords(TempPurchaseLine); + if TempPurchaseLine.FindSet() then + repeat + EDocOrderMatch.SetRange("Document Order No.", TempPurchaseLine."Document No."); + EDocOrderMatch.SetRange("Document Line No.", TempPurchaseLine."Line No."); + EDocOrderMatch.CalcSums(Quantity); + PurchaseLine.Copy(TempPurchaseLine); + PurchaseLine.Validate("Qty. to Invoice", EDocOrderMatch.Quantity); + PurchaseLine.Modify(); + until TempPurchaseLine.Next() = 0; + end; + + internal procedure GetRecords(var TempPurchaseLine: Record "Purchase Line" temporary) + var + PurchaseLine: Record "Purchase Line"; + begin + Clear(TempPurchaseLine); + PurchaseLine.SetRange("Document Type", Enum::"Purchase Document Type"::Order); + PurchaseLine.SetRange("Document No.", EDocumentBeingMatched."Order No."); + PurchaseLine.SetFilter(Type, 'G/L Account|Item'); + if PurchaseLine.FindSet() then + repeat + TempPurchaseLine.TransferFields(PurchaseLine); + TempPurchaseLine.Insert(); + until PurchaseLine.Next() = 0; + end; + + internal procedure GetSelectedRecords(var TempPurchaseLine: Record "Purchase Line" temporary) + var + PurchaseLine: Record "Purchase Line"; + begin + Clear(TempPurchaseLine); + CurrPage.SetSelectionFilter(PurchaseLine); + if PurchaseLine.FindSet() then + repeat + TempPurchaseLine.TransferFields(PurchaseLine); + TempPurchaseLine.Insert(); + until PurchaseLine.Next() = 0; + end; + + internal procedure ShowIncompleteMatches() + var + AvailableQty: Decimal; + begin + Rec.Reset(); + Rec.SetRange("Document Type", Enum::"Purchase Document Type"::Order); + Rec.SetRange("Document No.", EDocumentBeingMatched."Order No."); + Rec.SetFilter(Type, 'G/L Account|Item'); + Rec.SetLoadFields("Quantity Received", "Quantity Invoiced", "Qty. to Invoice"); + if Rec.FindSet() then + repeat + AvailableQty := Rec."Quantity Received" - Rec."Quantity Invoiced"; + if AvailableQty <> Rec."Qty. to Invoice" then + Rec.Mark(true); + until Rec.Next() = 0; + Rec.MarkedOnly(true); + CurrPage.Update(false); + end; + + internal procedure ShowAll() + begin + Rec.ClearMarks(); + Rec.MarkedOnly(false); + CurrPage.Update(false); + end; + +} \ No newline at end of file diff --git a/Apps/W1/EDocument/app/src/Service/EDocumentService.Table.al b/Apps/W1/EDocument/app/src/Service/EDocumentService.Table.al index a92a11082a..369cab0aed 100644 --- a/Apps/W1/EDocument/app/src/Service/EDocumentService.Table.al +++ b/Apps/W1/EDocument/app/src/Service/EDocumentService.Table.al @@ -42,7 +42,11 @@ table 6103 "E-Document Service" field(6; "Update Order"; Boolean) { Caption = 'Update Order'; - DataClassification = SystemMetadata; +#if not CLEAN24 + ObsoleteState = Pending; + ObsoleteReason = 'Replaced by "Receive E-Document To" on Vendor table'; + ObsoleteTag = '24.0'; +#endif } field(7; "Create Journal Lines"; Boolean) { diff --git a/Apps/W1/EDocument/app/src/Service/EDocumentServiceStatus.Page.al b/Apps/W1/EDocument/app/src/Service/EDocumentServiceStatus.Page.al index 6f4f5ba4a3..63bf398d81 100644 --- a/Apps/W1/EDocument/app/src/Service/EDocumentServiceStatus.Page.al +++ b/Apps/W1/EDocument/app/src/Service/EDocumentServiceStatus.Page.al @@ -27,6 +27,7 @@ page 6135 "E-Document Service Status" field(Status; Rec.Status) { ToolTip = 'Specifies the status of an E-Dcoument'; + StyleExpr = StyleTxt; } field(Logs; Rec.Logs()) { @@ -51,4 +52,29 @@ page 6135 "E-Document Service Status" } } } + + trigger OnAfterGetRecord() + begin + case Rec.Status of + Rec.Status::"Sending Error", + Rec.Status::"Export Error", + Rec.Status::"Cancel Error", + Rec.Status::"Imported Document Processing Error": + StyleTxt := 'Unfavorable'; + + Rec.Status::Sent, + Rec.Status::"Imported Document Created", + Rec.Status::Approved, + Rec.Status::"Order Linked", + Rec.Status::"Order Updated": + StyleTxt := 'Favorable'; + else + StyleTxt := 'None'; + end; + end; + + var + StyleTxt: Text; } + + diff --git a/Apps/W1/EDocument/app/src/Service/EdocumentService.Page.al b/Apps/W1/EDocument/app/src/Service/EdocumentService.Page.al index 2a4e68848f..8b033e040f 100644 --- a/Apps/W1/EDocument/app/src/Service/EdocumentService.Page.al +++ b/Apps/W1/EDocument/app/src/Service/EdocumentService.Page.al @@ -118,13 +118,20 @@ page 6133 "E-Document Service" { ToolTip = 'Specifies if an invoice total shall be verified during the import.'; } +#if not CLEAN24 field("Update Order"; Rec."Update Order") { ToolTip = 'Specifies if corresponding purchase order must be updated.'; + Visible = false; + Enabled = false; + ObsoleteTag = '24.0'; + ObsoleteState = Pending; + ObsoleteReason = 'Replaced by "Receive E-Document To" on Vendor table'; } +#endif field("Create Journal Lines"; Rec."Create Journal Lines") { - ToolTip = 'Specifies if journal line must be created instead of purchase document.'; + ToolTip = 'Specifies if journal line must be created instead of purchase document. Only applicable if vendor receives e-document to purchase invoice.'; } field("General Journal Template Name"; Rec."General Journal Template Name") { @@ -157,24 +164,22 @@ page 6133 "E-Document Service" } } } + part(EDocumentDataExchDef; "E-Doc. Service Data Exch. Sub") + { + ApplicationArea = All; + Caption = 'Data Exchange Definition'; + SubPageLink = "E-Document Format Code" = field(Code); + Visible = Rec."Document Format" = Rec."Document Format"::"Data Exchange"; + } part(EDocumentExportFormatMapping; "E-Doc. Mapping Part") { Caption = 'Export Mapping'; SubPageLink = Code = field(Code), "For Import" = const(false); - Visible = not (Rec."Document Format" = Rec."Document Format"::"Data Exchange"); } part(EDocumentImportFormatMapping; "E-Doc. Mapping Part") { Caption = 'Import Mapping'; SubPageLink = Code = field(Code), "For Import" = const(true); - Visible = not (Rec."Document Format" = Rec."Document Format"::"Data Exchange"); - } - part(EDocumentDataExchDef; "E-Doc. Service Data Exch. Sub") - { - ApplicationArea = All; - Caption = 'Data Exchange Definition'; - SubPageLink = "E-Document Format Code" = field(Code); - Visible = Rec."Document Format" = Rec."Document Format"::"Data Exchange"; } } } diff --git a/Apps/W1/EDocument/test/src/Matching/EDocLineMatchingTest.Codeunit.al b/Apps/W1/EDocument/test/src/Matching/EDocLineMatchingTest.Codeunit.al new file mode 100644 index 0000000000..31bb4fa823 --- /dev/null +++ b/Apps/W1/EDocument/test/src/Matching/EDocLineMatchingTest.Codeunit.al @@ -0,0 +1,242 @@ +codeunit 139658 "E-Doc. Line Matching Test" +{ + + Subtype = Test; + TestPermissions = Disabled; + EventSubscriberInstance = Manual; + + + var + + Assert: Codeunit Assert; + LibraryPurchase: Codeunit "Library - Purchase"; + + procedure Initialize() + var + PurchaseLine: Record "Purchase Line"; + EDocImportedLine: Record "E-Doc. Imported Line"; + begin + EDocImportedLine.DeleteAll(); + PurchaseLine.DeleteAll(); + end; + + [Test] + procedure MatchOneImportLineToOnePOLineSuccess() + var + EDocument: Record "E-Document"; + EDocImportedLine: Record "E-Doc. Imported Line"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + EDocOrderLineMatchingPage: TestPage "E-Doc. Order Line Matching"; + begin + // [FEATURE] [E-Document] [Matching] + // [SCENARIO] Match single imported line of type Item to single PO line of type Item + + // Setup E-Document with link to purchase order + Initialize(); + + // [GIVEN] We create e-document and PO line with Qty 5 + PurchaseHeader := CreatePurchaseLine(5); + CreateEDocumentWithPOReference(PurchaseHeader); + + // Receive + LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false); + LibraryPurchase.ReopenPurchaseDocument(PurchaseHeader); + EDocument.FindLast(); + + // [GIVEN] We imported a item with quantity 5 + CreateImportedLine(EDocument, 10000, 5, Enum::"Purchase Line Type"::Item); + Assert.RecordCount(EDocImportedLine, 1); + Assert.RecordCount(PurchaseLine, 1); + + // [WHEN] Open Matching page and select first entry + Commit(); + EDocOrderLineMatchingPage.OpenEdit(); + EDocOrderLineMatchingPage.Last(); + EDocOrderLineMatchingPage.ImportedLines.First(); + EDocOrderLineMatchingPage.OrderLines.First(); + + // [THEN] we have qty 5 and matched 0 + Assert.AreEqual('5', EDocOrderLineMatchingPage.ImportedLines.Quantity.Value(), ''); + Assert.AreEqual('0', EDocOrderLineMatchingPage.ImportedLines."Matched Quantity".Value(), ''); + // [THEN] we have qty 5 and qty to invoice 0 + Assert.AreEqual('5', EDocOrderLineMatchingPage.OrderLines."Available Quantity".Value(), ''); + Assert.AreEqual('0', EDocOrderLineMatchingPage.OrderLines."Qty. to Invoice".Value(), ''); + + // [GIVEN] We click "Match Manually" action + EDocOrderLineMatchingPage.MatchManual_Promoted.Invoke(); + + // [THEN] we have qty 5 and matched 5 + Assert.AreEqual('5', EDocOrderLineMatchingPage.ImportedLines.Quantity.Value(), ''); + Assert.AreEqual('5', EDocOrderLineMatchingPage.ImportedLines."Matched Quantity".Value(), ''); + // [THEN] we have qty 5 and qty to invoice 5 + Assert.AreEqual('5', EDocOrderLineMatchingPage.OrderLines."Available Quantity".Value(), ''); + Assert.AreEqual('5', EDocOrderLineMatchingPage.OrderLines."Qty. to Invoice".Value(), ''); + end; + + [Test] + procedure MatchTwoImportLineToOnePOLineSuccess() + var + EDocument: Record "E-Document"; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + TempEDocImportedLine: Record "E-Doc. Imported Line" temporary; + TempPurchaseLine: Record "Purchase Line" temporary; + TempEDocMatchesThatWasMatched: Record "E-Doc. Order Match" temporary; + EDocumentLineMatching: Codeunit "E-Doc. Line Matching"; + begin + // [FEATURE] [E-Document] [Matching] + // [SCENARIO] Match two imported lines of type Item to single PO line of type Item + + // Setup E-Document with link to purchase order + Initialize(); + + // [GIVEN] We create e-document and PO line with Qty 5 + PurchaseHeader := CreatePurchaseLine(5); + CreateEDocumentWithPOReference(PurchaseHeader); + + // Receive + LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false); + LibraryPurchase.ReopenPurchaseDocument(PurchaseHeader); + EDocument.FindLast(); + + + // [GIVEN] We imported item A with quantity 2 and item B with quantity 3 + CreateImportedLine(TempEDocImportedLine, EDocument, 10000, 2, Enum::"Purchase Line Type"::Item); + CreateImportedLine(TempEDocImportedLine, EDocument, 20000, 3, Enum::"Purchase Line Type"::Item); + + // [GIVEN] 2 Imported lines selected and 1 purchase line + TempEDocImportedLine.FindSet(); + Assert.RecordCount(TempEDocImportedLine, 2); + PurchaseLine.FindLast(); + PurchaseLine."Qty. to Invoice" := 0; + PurchaseLine.Modify(); + TempPurchaseLine := PurchaseLine; + TempPurchaseLine.Insert(); + + // [THEN] Match manually + EDocumentLineMatching.MatchManually(TempEDocImportedLine, TempPurchaseLine, TempEDocMatchesThatWasMatched); + + TempEDocImportedLine.FindSet(); + Assert.AreEqual(TempEDocImportedLine.Quantity, TempEDocImportedLine."Matched Quantity", ''); + TempEDocImportedLine.Next(); + Assert.AreEqual(TempEDocImportedLine.Quantity, TempEDocImportedLine."Matched Quantity", ''); + end; + + [Test] + procedure MatchTwoImportLineToOnePOLineFailure() + var + EDocument: Record "E-Document"; + TempEDocImportedLine: Record "E-Doc. Imported Line" temporary; + TempPurchaseLine: Record "Purchase Line" temporary; + TempEDocMatchesThatWasMatched: Record "E-Doc. Order Match" temporary; + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + EDocumentLineMatching: Codeunit "E-Doc. Line Matching"; + begin + // [FEATURE] [E-Document] [Matching] + // [SCENARIO] Match two imported lines of type Item to single PO line of type Item + + // Setup E-Document with link to purchase order + Initialize(); + + // [GIVEN] We create e-document and PO line with Qty 5 + PurchaseHeader := CreatePurchaseLine(5); + CreateEDocumentWithPOReference(PurchaseHeader); + + // Receive + LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false); + LibraryPurchase.ReopenPurchaseDocument(PurchaseHeader); + EDocument.FindLast(); + + // [GIVEN] We imported item A with quantity 2 and item B with quantity 4 + CreateImportedLine(TempEDocImportedLine, EDocument, 10000, 2, Enum::"Purchase Line Type"::Item); + CreateImportedLine(TempEDocImportedLine, EDocument, 20000, 4, Enum::"Purchase Line Type"::Item); + + // [GIVEN] 2 Imported lines selected and 1 purchase line + TempEDocImportedLine.FindSet(); + Assert.RecordCount(TempEDocImportedLine, 2); + PurchaseLine.FindLast(); + PurchaseLine."Qty. to Invoice" := 0; + PurchaseLine.Modify(); + TempPurchaseLine := PurchaseLine; + TempPurchaseLine.Insert(); + + TempEDocImportedLine.Next(); + + // [THEN] Match manually will assign what can be assigned + EDocumentLineMatching.MatchManually(TempEDocImportedLine, TempPurchaseLine, TempEDocMatchesThatWasMatched); + + // [THEN] Quantity was partially assigned + // Second line only 3 out of 4 + TempEDocImportedLine.FindSet(); + Assert.AreEqual(TempEDocImportedLine.Quantity, TempEDocImportedLine."Matched Quantity", ''); + TempEDocImportedLine.Next(); + Assert.AreEqual(3, TempEDocImportedLine."Matched Quantity", ''); + + // [THEN] Apply fails as partial assignment is not allowed + asserterror EDocumentLineMatching.ApplyToPurchaseOrder(EDocument, TempEDocImportedLine); + Assert.ExpectedError('Matching of Imported Line 20000 is incomplete. It is not fully matched to purchase order lines.'); + end; + + local procedure CreateEDocumentWithPOReference(PurchaseHeader: Record "Purchase Header") + var + EDocument: Record "E-Document"; + begin + EDocument.Init(); + EDocument."Order No." := PurchaseHeader."No."; + EDocument."Document Record ID" := PurchaseHeader.RecordId(); + EDocument."Document Type" := EDocument."Document Type"::"Purchase Order"; + EDocument.Insert(); + end; + + local procedure CreatePurchaseLine(Quantity: Integer): Record "Purchase Header"; + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + begin + LibraryPurchase.CreatePurchaseOrder(PurchaseHeader); + PurchaseLine.SetRange("Document No.", PurchaseHeader."No."); + PurchaseLine.FindLast(); + PurchaseLine.Validate(Quantity, Quantity); + PurchaseLine.Validate("Qty. to Invoice", 0); + PurchaseLine.Modify(); + + exit(PurchaseHeader); + end; + + local procedure AddPurchaseLine(Quantity: Integer; Type: Enum "Purchase Line Type") + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + begin + PurchaseHeader.FindLast(); + LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, Type, '', Quantity); + PurchaseLine.FindLast(); + PurchaseLine.Validate("Qty. to Invoice", 0); + end; + + local procedure CreateImportedLine(var TempEDocImportedLine: Record "E-Doc. Imported Line" temporary; EDocument: Record "E-Document"; LineNo: Integer; Quantity: Integer; Type: Enum "Purchase Line Type") + var + EDocImportedLine: Record "E-Doc. Imported Line"; + begin + CreateImportedLine(EDocument, LineNo, Quantity, Type); + EDocImportedLine.FindLast(); + TempEDocImportedLine.Copy(EDocImportedLine); + TempEDocImportedLine.Insert(); + end; + + local procedure CreateImportedLine(EDocument: Record "E-Document"; LineNo: Integer; Quantity: Integer; Type: Enum "Purchase Line Type") + var + EDocImportedLine: Record "E-Doc. Imported Line"; + begin + EDocImportedLine.Init(); + EDocImportedLine."E-Document Entry No." := EDocument."Entry No"; + EDocImportedLine."Line No." := LineNo; + EDocImportedLine.Quantity := Quantity; + EDocImportedLine.Type := Type; + EDocImportedLine.Insert(); + end; + + +} \ No newline at end of file diff --git a/Apps/W1/EDocument/test/src/Processing/EDocE2ETest.Codeunit.al b/Apps/W1/EDocument/test/src/Processing/EDocE2ETest.Codeunit.al index 3731418c4b..cea724a794 100644 --- a/Apps/W1/EDocument/test/src/Processing/EDocE2ETest.Codeunit.al +++ b/Apps/W1/EDocument/test/src/Processing/EDocE2ETest.Codeunit.al @@ -18,6 +18,7 @@ codeunit 139624 "E-Doc E2E Test" DocumentSendingProfileWithWorkflowErr: Label 'Workflow %1 defined for %2 in Document Sending Profile %3 is not found.', Comment = '%1 - The workflow code, %2 - Enum value set in Electronic Document, %3 - Document Sending Profile Code'; EDocEmptyErr: Label 'The E-Document table is empty.'; FailedToGetBlobErr: Label 'Failed to get exported blob from EDocument %1', Comment = '%1 - E-Document No.'; + SendingErrStateErr: Label 'E-document is Pending response and can not be sent in this state.'; [Test] procedure CreateEDocumentBeforeAfterEventsSuccessful() @@ -1315,7 +1316,6 @@ codeunit 139624 "E-Doc E2E Test" EDocument: Record "E-Document"; EDocumentService: Record "E-Document Service"; EDocumentServiceStatus: Record "E-Document Service Status"; - //JobQueueEntry: Record "Job Queue Entry"; EDocumentPage: TestPage "E-Document"; begin // [FEATURE] [E-Document] [Processing] @@ -1341,7 +1341,7 @@ codeunit 139624 "E-Doc E2E Test" EDocumentPage.OpenView(); EDocumentPage.GoToRecord(EDocument); asserterror EDocumentPage.Send.Invoke(); - Assert.ExpectedError('E-document is Pending Response and can not be sent in this state.'); + Assert.ExpectedError(SendingErrStateErr); UnbindSubscription(EDocImplState); end; diff --git a/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al b/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al index f6a336275c..7c2c2d927c 100644 --- a/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al +++ b/Apps/W1/EDocument/test/src/Receive/EDocReceiveTest.Codeunit.al @@ -54,6 +54,8 @@ codeunit 139628 "E-Doc. Receive Test" // [GIVEN] purchase invoice LibraryPurchase.CreateVendorWithAddress(Vendor); + Vendor."Receive E-Document To" := Vendor."Receive E-Document To"::"Purchase Invoice"; + Vendor.Modify(); LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Invoice, Vendor."No."); for i := 1 to 3 do begin @@ -129,6 +131,8 @@ codeunit 139628 "E-Doc. Receive Test" // [GIVEN] multiple purchase invoices for i := 1 to 5 do begin LibraryPurchase.CreateVendorWithAddress(Vendor); + Vendor."Receive E-Document To" := Vendor."Receive E-Document To"::"Purchase Invoice"; + Vendor.Modify(); LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Invoice, Vendor."No."); for j := 1 to 3 do begin @@ -214,6 +218,8 @@ codeunit 139628 "E-Doc. Receive Test" // [GIVEN] purchase credit memo LibraryPurchase.CreateVendorWithAddress(Vendor); + Vendor."Receive E-Document To" := Vendor."Receive E-Document To"::"Purchase Invoice"; + Vendor.Modify(); LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::"Credit Memo", Vendor."No."); for i := 1 to 3 do begin @@ -299,6 +305,8 @@ codeunit 139628 "E-Doc. Receive Test" // [GIVEN] purchase credit memo for i := 1 to 5 do begin LibraryPurchase.CreateVendorWithAddress(Vendor); + Vendor."Receive E-Document To" := Vendor."Receive E-Document To"::"Purchase Invoice"; + Vendor.Modify(); LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::"Credit Memo", Vendor."No."); for j := 1 to 3 do begin @@ -403,6 +411,8 @@ codeunit 139628 "E-Doc. Receive Test" // [GIVEN] purchase invoice LibraryPurchase.CreateVendorWithAddress(Vendor); + Vendor."Receive E-Document To" := Vendor."Receive E-Document To"::"Purchase Invoice"; + Vendor.Modify(); LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Invoice, Vendor."No."); PurchaseHeader."Pay-to Name" := 'Journal Test Invoice'; PurchaseHeader.Modify(); @@ -482,6 +492,8 @@ codeunit 139628 "E-Doc. Receive Test" // [GIVEN] purchase invoices for i := 1 to 5 do begin LibraryPurchase.CreateVendorWithAddress(Vendor); + Vendor."Receive E-Document To" := Vendor."Receive E-Document To"::"Purchase Invoice"; + Vendor.Modify(); LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Invoice, Vendor."No."); PurchaseHeader."Pay-to Name" := 'Journal Test Invoice no. ' + Format(i); PurchaseHeader.Modify(); @@ -560,6 +572,8 @@ codeunit 139628 "E-Doc. Receive Test" // [GIVEN] purchase credit memo LibraryPurchase.CreateVendorWithAddress(Vendor); + Vendor."Receive E-Document To" := Vendor."Receive E-Document To"::"Purchase Invoice"; + Vendor.Modify(); LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::"Credit Memo", Vendor."No."); PurchaseHeader."Pay-to Name" := 'Journal Test Invoice'; PurchaseHeader.Modify(); @@ -639,6 +653,8 @@ codeunit 139628 "E-Doc. Receive Test" // [GIVEN] purchase credit memos for i := 1 to 5 do begin LibraryPurchase.CreateVendorWithAddress(Vendor); + Vendor."Receive E-Document To" := Vendor."Receive E-Document To"::"Purchase Invoice"; + Vendor.Modify(); LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::"Credit Memo", Vendor."No."); PurchaseHeader."Pay-to Name" := 'Journal Test Invoice no. ' + Format(i); PurchaseHeader.Modify(); @@ -695,6 +711,8 @@ codeunit 139628 "E-Doc. Receive Test" // [GIVEN] purchase invoice LibraryPurchase.CreateVendorWithAddress(Vendor); + Vendor."Receive E-Document To" := Vendor."Receive E-Document To"::"Purchase Invoice"; + Vendor.Modify(); LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Invoice, Vendor."No."); for i := 1 to 3 do begin @@ -740,6 +758,8 @@ codeunit 139628 "E-Doc. Receive Test" // [GIVEN] purchase invoice LibraryPurchase.CreateVendorWithAddress(Vendor); + Vendor."Receive E-Document To" := Vendor."Receive E-Document To"::"Purchase Invoice"; + Vendor.Modify(); LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Invoice, Vendor."No."); for i := 1 to 3 do begin diff --git a/Apps/W1/EDocumentsConnector/app/src/E3Party/EDocExtEDocument.PageExt.al b/Apps/W1/EDocumentsConnector/app/src/E3Party/EDocExtEDocument.PageExt.al index e62d35539e..b1a1e3e510 100644 --- a/Apps/W1/EDocumentsConnector/app/src/E3Party/EDocExtEDocument.PageExt.al +++ b/Apps/W1/EDocumentsConnector/app/src/E3Party/EDocExtEDocument.PageExt.al @@ -10,7 +10,7 @@ pageextension 6360 "E-Doc. Ext. EDocument" extends "E-Document" { actions { - addafter(UpdateOrder) + addlast(Incoming) { action(Approve) { @@ -43,7 +43,7 @@ pageextension 6360 "E-Doc. Ext. EDocument" extends "E-Document" end; } } - addafter(UpdateOrder_Promoted) + addlast(Category_Process) { actionref(Approve_Promoted; Approve) { } actionref(Reject_Promoted; Reject) { } diff --git a/Apps/W1/EnforcedDigitalVouchers/app/src/Implementation/DigitalVoucherImpl.Codeunit.al b/Apps/W1/EnforcedDigitalVouchers/app/src/Implementation/DigitalVoucherImpl.Codeunit.al index 695b81b590..3eb4a5f273 100644 --- a/Apps/W1/EnforcedDigitalVouchers/app/src/Implementation/DigitalVoucherImpl.Codeunit.al +++ b/Apps/W1/EnforcedDigitalVouchers/app/src/Implementation/DigitalVoucherImpl.Codeunit.al @@ -379,6 +379,8 @@ codeunit 5579 "Digital Voucher Impl." RecRef: RecordRef; RelatedRecordID: RecordId; begin + if not DigitalVoucherFeature.IsFeatureEnabled() then + exit; RelatedRecordID := IncomingDocument."Related Record ID"; if RelatedRecordID.TableNo = 0 then exit; diff --git a/Apps/W1/EnforcedDigitalVouchers/test/app.json b/Apps/W1/EnforcedDigitalVouchers/test/app.json index e5aebdaa25..73c29cee88 100644 --- a/Apps/W1/EnforcedDigitalVouchers/test/app.json +++ b/Apps/W1/EnforcedDigitalVouchers/test/app.json @@ -36,6 +36,12 @@ "name": "System Application Test Library", "publisher": "Microsoft", "version": "24.0.0.0" + }, + { + "id": "5095f467-0a01-4b99-99d1-9ff1237d286f", + "publisher": "Microsoft", + "name": "Library Variable Storage", + "version": "24.0.0.0" } ], "idRanges": [ diff --git a/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al b/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al index d78a5b09fc..ed3495fccb 100644 --- a/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al +++ b/Apps/W1/EnforcedDigitalVouchers/test/src/DigitalVouchersTests.Codeunit.al @@ -9,10 +9,14 @@ codeunit 139515 "Digital Vouchers Tests" LibraryPurchase: Codeunit "Library - Purchase"; LibraryERM: Codeunit "Library - ERM"; LibraryUtility: Codeunit "Library - Utility"; + LibraryVariableStorage: Codeunit "Library - Variable Storage"; Assert: Codeunit Assert; IsInitialized: Boolean; NotPossibleToPostWithoutVoucherErr: Label 'Not possible to post without attaching the digital voucher.'; 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'; + RemovePostedRecordManuallyMsg: Label 'The reference to the posted record has been removed.\\Remember to correct the posted record if needed.'; trigger OnRun() begin @@ -181,6 +185,63 @@ codeunit 139515 "Digital Vouchers Tests" UnbindSubscription(DigVouchersDisableEnforce); end; + [Test] + [HandlerFunctions('ConfirmHandler,MessageHandler')] + procedure DotNotCheckVoucherOnBeforeRemoveReferencedRecordsWhenFeatureDisabled() + var + IncomingDocument: Record "Incoming Document"; + SalesInvHeader: Record "Sales Invoice Header"; + DigVouchersDisableEnforce: Codeunit "Dig. Vouchers Disable Enforce"; + BlankRecID: RecordId; + begin + // [FEATURE] [UT] + // [SCENARIO 498196] Stan can remove the reference to the posted document from the incoming document when the feature is disabled + Initialize(); + BindSubscription(DigVouchersDisableEnforce); + DisableDigitalVoucherFeature(); + // [GIVEN] Sales invoice and Incoming document is created + SalesInvHeader."No." := LibraryUtility.GenerateGUID(); + SalesInvHeader.Insert(); + IncomingDocument."Entry No." := LibraryUtility.GetNewRecNo(IncomingDocument, IncomingDocument.FieldNo("Entry No.")); + IncomingDocument.Posted := true; + IncomingDocument."Related Record ID" := SalesInvHeader.RecordId(); + IncomingDocument.Insert(); + LibraryVariableStorage.Enqueue(DetachQst); + LibraryVariableStorage.Enqueue(true); + LibraryVariableStorage.Enqueue(RemovePostedRecordManuallyMsg); + // [WHEN] Remove the reference to the posted document from the incoming document + IncomingDocument.RemoveReferencedRecords(); + // [THEN] The reference to the posted document is removed from the incoming document + IncomingDocument.Find(); + IncomingDocument.TestField("Related Record ID", BlankRecID); + + LibraryVariableStorage.AssertEmpty(); + UnbindSubscription(DigVouchersDisableEnforce); + end; + + [Test] + procedure CheckVoucherOnBeforeRemoveReferencedRecordsWhenFeatureEnabled() + var + IncomingDocument: Record "Incoming Document"; + SalesInvHeader: Record "Sales Invoice Header"; + begin + // [FEATURE] [UT] + // [SCENARIO 498196] Stan cannot remove the reference to the posted document from the incoming document when the feature is enabled + Initialize(); + EnableDigitalVoucherFeature(); + // [GIVEN] Sales invoice and Incoming document is created + SalesInvHeader."No." := LibraryUtility.GenerateGUID(); + SalesInvHeader.Insert(); + IncomingDocument."Entry No." := LibraryUtility.GetNewRecNo(IncomingDocument, IncomingDocument.FieldNo("Entry No.")); + IncomingDocument.Posted := true; + IncomingDocument."Related Record ID" := SalesInvHeader.RecordId(); + IncomingDocument.Insert(); + // [WHEN] Remove the reference to the posted document from the incoming document + asserterror IncomingDocument.RemoveReferencedRecords(); + // [THEN] Error "Cannot remove the reference record from the incoming document because it is used for the enforced digital voucher functionality" is shown + Assert.ExpectedError(CannotRemoveReferenceRecordFromIncDocErr); + end; + local procedure Initialize() begin LibraryTestInitialize.OnTestInitialize(Codeunit::"Digital Vouchers Tests"); @@ -314,4 +375,18 @@ codeunit 139515 "Digital Vouchers Tests" IncomingDocumentAttachment.SetRange("Incoming Document Entry No.", IncomingDocument."Entry No."); Assert.RecordCount(IncomingDocumentAttachment, AttachmentsCount); end; + + [ConfirmHandler] + procedure ConfirmHandler(Question: Text; var Reply: Boolean) + begin + Assert.ExpectedMessage(LibraryVariableStorage.DequeueText(), Question); + ; + Reply := LibraryVariableStorage.DequeueBoolean(); + end; + + [MessageHandler] + procedure MessageHandler(Message: Text) + begin + Assert.ExpectedMessage(LibraryVariableStorage.DequeueText(), Message); + end; } \ No newline at end of file diff --git a/Apps/W1/HybridBaseDeployment/app/src/codeunits/CloudMigUpgrade.codeunit.al b/Apps/W1/HybridBaseDeployment/app/src/codeunits/CloudMigUpgrade.codeunit.al index 4364c5671f..d0e8961edf 100644 --- a/Apps/W1/HybridBaseDeployment/app/src/codeunits/CloudMigUpgrade.codeunit.al +++ b/Apps/W1/HybridBaseDeployment/app/src/codeunits/CloudMigUpgrade.codeunit.al @@ -18,7 +18,7 @@ codeunit 40010 "Cloud Mig. Upgrade" if UpgradeTag.HasUpgradeTag(GetSendCloudMigrationUpgradeTelemetryTag()) then exit; - HybridCloudManagement.SendCloudMigrationTelemetry(); + HybridCloudManagement.SendCompletedCloudMigrationTelemetry(); UpgradeTag.SetUpgradeTag(GetSendCloudMigrationUpgradeTelemetryTag()); end; @@ -32,6 +32,6 @@ codeunit 40010 "Cloud Mig. Upgrade" local procedure GetSendCloudMigrationUpgradeTelemetryTag(): Text[250] begin - exit('MS-456494-CloudMigrationUptake-20230425'); + exit('MS-456494-CloudMigrationUptake-20240201'); end; } \ No newline at end of file diff --git a/Apps/W1/HybridBaseDeployment/app/src/codeunits/HybridCloudManagement.Codeunit.al b/Apps/W1/HybridBaseDeployment/app/src/codeunits/HybridCloudManagement.Codeunit.al index ad3030fd99..50d7c8e286 100644 --- a/Apps/W1/HybridBaseDeployment/app/src/codeunits/HybridCloudManagement.Codeunit.al +++ b/Apps/W1/HybridBaseDeployment/app/src/codeunits/HybridCloudManagement.Codeunit.al @@ -291,7 +291,6 @@ codeunit 4001 "Hybrid Cloud Management" DisableMigration(IntelligentCloudSetup."Product ID", DisablereplicationTxt, false) end; - [Scope('OnPrem')] procedure DisableMigration() var @@ -309,6 +308,7 @@ codeunit 4001 "Hybrid Cloud Management" HybridDeployment: Codeunit "Hybrid Deployment"; FeatureTelemetry: Codeunit "Feature Telemetry"; HybridCloudManagement: Codeunit "Hybrid Cloud Management"; + CompletedCloudMigration: Boolean; begin RestoreDataPerDatabaseTables(HybridReplicationSummary."Run ID", SourceProduct); @@ -317,6 +317,13 @@ codeunit 4001 "Hybrid Cloud Management" HybridDeployment.DisableReplication(); end; + OnIsCloudMigrationCompleted(SourceProduct, CompletedCloudMigration); + if not CompletedCloudMigration then + CompletedCloudMigration := Reason = CloudMigrationCompletedTxt; + + if CompletedCloudMigration then + SendCompletedCloudMigrationTelemetry(); + IntelligentCloud.Get(); IntelligentCloud.Enabled := false; IntelligentCloud.Modify(); @@ -629,7 +636,7 @@ codeunit 4001 "Hybrid Cloud Management" if IntelligentCloudSetup.Get() then TelemetryDimensions.Add('SourceProduct', IntelligentCloudSetup."Product ID"); - Session.LogMessage('0000IGC', DisabledCloudMigrationFromCompanyTxt, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::All, 'Category', CloudMigrationTok); + Session.LogMessage('0000IGC', DisabledCloudMigrationFromCompanyTxt, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::All, TelemetryDimensions); end; local procedure GetDisabledReasonTelemetryText(): Text @@ -853,7 +860,7 @@ codeunit 4001 "Hybrid Cloud Management" exit(ReplicationCompletedServiceTypeTxt = ServiceType); end; - internal procedure SendCloudMigrationTelemetry() + internal procedure SendCompletedCloudMigrationTelemetry() var IntelligentCloud: Record "Intelligent Cloud"; HybridCompany: Record "Hybrid Company"; @@ -872,9 +879,11 @@ codeunit 4001 "Hybrid Cloud Management" TelemetryDimensions.Add('NumberOfCompanies', Format(HybridCompany.Count(), 0, 9)); TelemetryDimensions.Add('TotalMigrationSize', Format(HybridCompany.GetTotalMigrationSize(), 0, 9)); TelemetryDimensions.Add('TotalOnPremSize', Format(HybridCompany.GetTotalOnPremSize(), 0, 9)); - IntelligentCloudSetup."Product ID" := 'Unknown'; - if IntelligentCloudSetup.Get() then; - TelemetryDimensions.Add('Product', IntelligentCloudSetup."Product ID"); + if IntelligentCloudSetup.Get() then + TelemetryDimensions.Add('Product', IntelligentCloudSetup."Product ID") + else + IntelligentCloudSetup."Product ID" := 'Unknown'; + TelemetryDimensions.Add('MigrationDateTime', Format(IntelligentCloud.SystemModifiedAt, 0, 9)); FeatureTelemetry.LogUsage('0000JMR', HybridCloudManagement.GetFeatureTelemetryName(), 'Tenant was cloud migrated', TelemetryDimensions); end; @@ -906,7 +915,6 @@ codeunit 4001 "Hybrid Cloud Management" FeatureTelemetry.LogUptake('0000JV4', HybridCloudManagement.GetFeatureTelemetryName(), Enum::"Feature Uptake Status"::Used); FeatureTelemetry.LogUsage('0000JV5', HybridCloudManagement.GetFeatureTelemetryName(), 'Completed the cloud migration succesfully'); - SendCloudMigrationTelemetry(); if GuiAllowed then Message(CloudMigrationCompletedTxt); @@ -1993,4 +2001,9 @@ codeunit 4001 "Hybrid Cloud Management" local procedure OnBeforeCanScheduleTask(var Handled: Boolean) begin end; + + [IntegrationEvent(false, false)] + local procedure OnIsCloudMigrationCompleted(SourceProduct: Text; var CloudMigrationCompleted: Boolean) + begin + end; } \ No newline at end of file diff --git a/Apps/W1/HybridGP/app/src/codeunits/GPCloudMigration.codeunit.al b/Apps/W1/HybridGP/app/src/codeunits/GPCloudMigration.codeunit.al index 6f9e153393..315a60528e 100644 --- a/Apps/W1/HybridGP/app/src/codeunits/GPCloudMigration.codeunit.al +++ b/Apps/W1/HybridGP/app/src/codeunits/GPCloudMigration.codeunit.al @@ -221,6 +221,17 @@ codeunit 4025 "GP Cloud Migration" CreateDataMigrationStatusRecords(Database::"Item", ItemsToMigrateCount, Database::"GP Item", Codeunit::"GP Item Migrator"); end; + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Hybrid Cloud Management", 'OnIsCloudMigrationCompleted', '', false, false)] + local procedure HandleIsCloudMigrationCompleted(SourceProduct: Text; var CloudMigrationCompleted: Boolean) + var + HybridGPWizard: Codeunit "Hybrid GP Wizard"; + begin + if SourceProduct <> HybridGPWizard.ProductId() then + exit; + + CloudMigrationCompleted := true; + end; + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Hybrid Cloud Management", 'OnInsertDefaultTableMappings', '', false, false)] local procedure OnInsertDefaultTableMappings(DeleteExisting: Boolean; ProductID: Text[250]) var diff --git a/Apps/W1/HybridGP/test/src/GPForecastingTests.codeunit.al b/Apps/W1/HybridGP/test/src/GPForecastingTests.codeunit.al index adef74436c..00b1cbe03f 100644 --- a/Apps/W1/HybridGP/test/src/GPForecastingTests.codeunit.al +++ b/Apps/W1/HybridGP/test/src/GPForecastingTests.codeunit.al @@ -164,9 +164,11 @@ codeunit 139668 "GP Forecasting Tests" local procedure CreateCashFlowSetup() var CashFlowSetup: Record "Cash Flow Setup"; + ApiKey: Text; begin CashFlowSetup.Get(); - CashFlowSetup.SaveUserDefinedAPIKey('dummykey'); + ApiKey := 'dummykey'; + CashFlowSetup.SaveUserDefinedAPIKey(ApiKey); CashFlowSetup.Validate("API URL", 'https://ussouthcentral.services.azureml.net'); CashFlowSetup.Validate("Period Type", CashFlowSetup."Period Type"::Year); CashFlowSetup.Validate("Historical Periods", 18); @@ -474,10 +476,13 @@ codeunit 139668 "GP Forecasting Tests" end; procedure SetupSI(); + var + ApiKey: Text; begin MSSalesForecastSetup.GetSingleInstance(); MSSalesForecastSetup.Validate("API URI", MockServiceURITxt); - MSSalesForecastSetup.SetUserDefinedAPIKey(MockServiceKeyTxt); + ApiKey := MockServiceKeyTxt; + MSSalesForecastSetup.SetUserDefinedAPIKey(ApiKey); MSSalesForecastSetup.Modify(true); end; diff --git a/Apps/W1/INTaxEngine/app/TaxEngine-Core/src/Lookup/Table/LookupTableFilter.Table.al b/Apps/W1/INTaxEngine/app/TaxEngine-Core/src/Lookup/Table/LookupTableFilter.Table.al index 41b4c5a941..5bc290c7f9 100644 --- a/Apps/W1/INTaxEngine/app/TaxEngine-Core/src/Lookup/Table/LookupTableFilter.Table.al +++ b/Apps/W1/INTaxEngine/app/TaxEngine-Core/src/Lookup/Table/LookupTableFilter.Table.al @@ -58,7 +58,12 @@ table 20142 "Lookup Table Filter" var LookupFieldFilter: Record "Lookup Field Filter"; ScriptSymbolStore: Codeunit "Script Symbol Store"; + IsHandled: Boolean; begin + OnBeforeDeleteLookupFilter(Rec, IsHandled); + if IsHandled then + exit; + ScriptSymbolStore.OnBeforeValidateIfUpdateIsAllowed("Case ID"); LookupFieldFilter.SetRange("Case ID", "Case ID"); @@ -66,4 +71,9 @@ table 20142 "Lookup Table Filter" if not LookupFieldFilter.IsEmpty() then LookupFieldFilter.DeleteAll(true); end; + + [IntegrationEvent(false, false)] + procedure OnBeforeDeleteLookupFilter(Rec: Record "Lookup Table Filter"; var IsHandled: Boolean) + begin + end; } diff --git a/Apps/W1/Intrastat/app/src/IntrastatReportGetLines.Report.al b/Apps/W1/Intrastat/app/src/IntrastatReportGetLines.Report.al index b238cc4b45..21a9d71669 100644 --- a/Apps/W1/Intrastat/app/src/IntrastatReportGetLines.Report.al +++ b/Apps/W1/Intrastat/app/src/IntrastatReportGetLines.Report.al @@ -178,9 +178,7 @@ report 4810 "Intrastat Report Get Lines" dataitem("FA Ledger Entry"; "FA Ledger Entry") { - DataItemTableView = sorting("FA No.", "Depreciation Book Code", "FA Posting Category", "FA Posting Type", "FA Posting Date", "Part of Book Value", "Reclassification Entry") - where("FA Posting Type" = filter("Proceeds on Disposal" | "Acquisition Cost"), "Document Type" = filter(Invoice | "Credit Memo"), "FA Posting Category" = const(" ")); - + DataItemTableView = sorting("FA No.", "Depreciation Book Code", "FA Posting Category", "FA Posting Type", "FA Posting Date", "Part of Book Value", "Reclassification Entry"); trigger OnAfterGetRecord() var CountryCode: Code[10]; @@ -208,8 +206,18 @@ report 4810 "Intrastat Report Get Lines" end; trigger OnPreDataItem() + var + IsHandled: Boolean; begin - SetRange("FA Posting Date", StartDate, EndDate); + IsHandled := false; + OnBeforeFilterFALedgerEntry(IntrastatReportHeader, "FA Ledger Entry", StartDate, EndDate, IsHandled); + if not IsHandled then begin + SetRange("FA Posting Date", StartDate, EndDate); + SetFilter("FA Posting Type", '%1|%2', "FA Posting Type"::"Proceeds on Disposal", "FA Posting Type"::"Acquisition Cost"); + SetFilter("Document Type", '%1|%2', "Document Type"::Invoice, "Document Type"::"Credit Memo"); + SetRange("FA Posting Category", "FA Posting Category"::" "); + end; + IntrastatReportLine2.SetCurrentKey("Source Type", "Source Entry No."); IntrastatReportLine2.SetRange("Source Type", IntrastatReportLine2."Source Type"::"FA Entry"); end; @@ -1284,6 +1292,11 @@ report 4810 "Intrastat Report Get Lines" begin end; + [IntegrationEvent(true, false)] + local procedure OnBeforeFilterFALedgerEntry(IntrastatReportHeader: Record "Intrastat Report Header"; var FALedgerEntry: Record "FA Ledger Entry"; StartDate: Date; EndDate: Date; var IsHandled: Boolean); + begin + end; + [IntegrationEvent(true, false)] local procedure OnAfterItemLedgerEntryOnPreDataItem(var ItemLedgerEntry: Record "Item Ledger Entry") begin diff --git a/Apps/W1/Intrastat/app/src/IntrastatReportHeader.Table.al b/Apps/W1/Intrastat/app/src/IntrastatReportHeader.Table.al index dbe6cf509b..f1627112b0 100644 --- a/Apps/W1/Intrastat/app/src/IntrastatReportHeader.Table.al +++ b/Apps/W1/Intrastat/app/src/IntrastatReportHeader.Table.al @@ -25,7 +25,7 @@ table 4811 "Intrastat Report Header" begin if "No." <> xRec."No." then begin IntrastatReportSetup.Get(); - NoSeriesMgt.TestManual(IntrastatReportSetup."Intrastat Nos."); + NoSeries.TestManual(IntrastatReportSetup."Intrastat Nos."); "No. Series" := ''; end; end; @@ -203,7 +203,8 @@ table 4811 "Intrastat Report Header" var IntrastatReportLine: Record "Intrastat Report Line"; IntrastatReportSetup: Record "Intrastat Report Setup"; - NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; Month: Integer; StatistiscPeriodFormatErr: Label '%1 must be 4 characters, for example, 9410 for October, 1994.', Comment = '%1 - Statistics Period'; MonthNrErr: Label 'Please check the month number.'; @@ -222,8 +223,8 @@ table 4811 "Intrastat Report Header" IntrastatReportHeader := Rec; IntrastatReportSetup.Get(); IntrastatReportSetup.TestField("Intrastat Nos."); - if NoSeriesMgt.SelectSeries(IntrastatReportSetup."Intrastat Nos.", xIntrastatReportHeader."No. Series", IntrastatReportHeader."No. Series") then begin - NoSeriesMgt.SetSeries(IntrastatReportHeader."No."); + if NoSeriesManagement.SelectSeries(IntrastatReportSetup."Intrastat Nos.", xIntrastatReportHeader."No. Series", IntrastatReportHeader."No. Series") then begin + NoSeriesManagement.SetSeries(IntrastatReportHeader."No."); Rec := IntrastatReportHeader; exit(true); end; @@ -253,7 +254,19 @@ table 4811 "Intrastat Report Header" if "No." = '' then begin IntrastatReportSetup.TestField("Intrastat Nos."); - NoSeriesMgt.InitSeries(IntrastatReportSetup."Intrastat Nos.", xRec."No. Series", 0D, "No.", "No. Series"); +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(IntrastatReportSetup."Intrastat Nos.", xRec."No. Series", 0D, "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := IntrastatReportSetup."Intrastat Nos."; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", IntrastatReportSetup."Intrastat Nos.", 0D, "No."); + end; +#endif end; end; diff --git a/Apps/W1/Intrastat/app/src/IntrastatReportManagement.Codeunit.al b/Apps/W1/Intrastat/app/src/IntrastatReportManagement.Codeunit.al index c50279ff1e..63797af1a6 100644 --- a/Apps/W1/Intrastat/app/src/IntrastatReportManagement.Codeunit.al +++ b/Apps/W1/Intrastat/app/src/IntrastatReportManagement.Codeunit.al @@ -176,6 +176,7 @@ codeunit 4810 IntrastatReportManagement CountryCode := SalesCrMemoHeader."Bill-to Country/Region Code"; end; end; + OnAfterGetIntrastatBaseCountryCodeFromFAEntry(FALedgerEntry, IntrastatReportSetup, CountryCode); end; procedure GetOriginalCurrency(FALedgerEntry: Record "FA Ledger Entry") CurrencyCode: Code[10] @@ -769,7 +770,7 @@ codeunit 4810 IntrastatReportManagement NoSeriesLine."Line No." := 10000; NoSeriesLine.Validate("Starting No.", 'INTRA00001'); NoSeriesLine.Insert(true); - NoSeriesLine.Validate("Allow Gaps in Nos.", true); + NoSeriesLine.Validate(Implementation, Enum::"No. Series Implementation"::Sequence); NoSeriesLine.Modify(true); end; @@ -1151,4 +1152,9 @@ codeunit 4810 IntrastatReportManagement local procedure OnBeforeCreateDefaultDataExchangeDef(var IsHandled: Boolean); begin end; -} + + [IntegrationEvent(true, false)] + local procedure OnAfterGetIntrastatBaseCountryCodeFromFAEntry(var FALedgerEntry: Record "FA Ledger Entry"; var IntrastatReportSetup: Record "Intrastat Report Setup"; var CountryCode: Code[10]); + begin + end; +} \ No newline at end of file diff --git a/Apps/W1/LatePaymentPredictor/app/src/LPInvoicesAtRisk.Page.al b/Apps/W1/LatePaymentPredictor/app/src/LPInvoicesAtRisk.Page.al index 07391f37d2..9a3e77be4f 100644 --- a/Apps/W1/LatePaymentPredictor/app/src/LPInvoicesAtRisk.Page.al +++ b/Apps/W1/LatePaymentPredictor/app/src/LPInvoicesAtRisk.Page.al @@ -8,7 +8,7 @@ page 1954 "LP - Invoices at Risk" { PageType = ListPart; SourceTable = "Cust. Ledger Entry"; - Caption = 'Invoices at risk'; + Caption = 'Overdue invoices'; DeleteAllowed = false; InsertAllowed = false; Editable = false; diff --git a/Apps/W1/LatePaymentPredictor/app/src/LPMachineLearningSetup.Page.al b/Apps/W1/LatePaymentPredictor/app/src/LPMachineLearningSetup.Page.al index e33877cab4..1e9ba5d959 100644 --- a/Apps/W1/LatePaymentPredictor/app/src/LPMachineLearningSetup.Page.al +++ b/Apps/W1/LatePaymentPredictor/app/src/LPMachineLearningSetup.Page.al @@ -112,7 +112,7 @@ page 1950 "LP Machine Learning Setup" if (ApiURIText <> '') and (not EncryptionEnabled()) then if Confirm(CryptographyManagement.GetEncryptionIsnotActivatedQst()) then Page.RunModal(Page::"Data Encryption Management"); - if ApiKeyText <> '' then + if (ApiKeyText <> '') and (ApiKeyText <> DummyApiKeyTok) then CheckCustomCredentialsAreSet(); end; } @@ -121,14 +121,15 @@ page 1950 "LP Machine Learning Setup" Caption = 'API Key'; ToolTip = 'Specifies the API key to connect to the Azure Machine Learning service'; ApplicationArea = Basic, Suite; + ExtendedDatatype = Masked; ShowMandatory = true; trigger OnValidate(); begin - if (ApiKeyText <> '') and (not EncryptionEnabled()) then + if (ApiKeyText <> '') and (ApiKeyText <> DummyApiKeyTok) and (not EncryptionEnabled()) then if Confirm(CryptographyManagement.GetEncryptionIsnotActivatedQst()) then Page.RunModal(Page::"Data Encryption Management"); - if ApiURIText <> '' then + if (ApiURIText <> '') and (ApiKeyText <> DummyApiKeyTok) then CheckCustomCredentialsAreSet(); end; } @@ -263,14 +264,14 @@ page 1950 "LP Machine Learning Setup" begin if LPPScheduler.JobQueueEntryCreationInProcess() then Error(JobQueueCreationInProgressErr); - GetSingleInstance(); - ApiURIText := GetApiURI(); - ApiKeyText := GetApiKey(); + Rec.GetSingleInstance(); + ApiURIText := Rec.GetApiUri(); + SetApiKey(); end; trigger OnQueryClosePage(CloseAction: Action): Boolean begin - if (CloseAction = ACTION::OK) OR (CloseAction = ACTION::LookupOK) then + if (CloseAction = ACTION::OK) or (CloseAction = ACTION::LookupOK) then CheckCustomCredentialsAreSet(); exit(true); end; @@ -280,18 +281,27 @@ page 1950 "LP Machine Learning Setup" AzureAIService := AzureAIService::"Machine Learning"; RemainingTime := AzureAIUsage.GetResourceLimit(AzureAIService) - AzureAIUsage.GetTotalProcessingTime(AzureAIService); - CustomModelExists := MyModelExists(); - ModelQualityVal := GetModelQuality(); + CustomModelExists := Rec.MyModelExists(); + ModelQualityVal := Rec.GetModelQuality(); + end; + + local procedure SetApiKey() + begin + if not Rec.GetApiKeyAsSecret().IsEmpty() then + ApiKeyText := DummyApiKeyTok; end; [NonDebuggable] local procedure CheckCustomCredentialsAreSet() begin - if "Use My Model Credentials" then begin - if (ApiKeyText = '') OR (ApiURIText = '') then + if Rec."Use My Model Credentials" then begin + if (ApiKeyText = '') or (ApiKeyText = DummyApiKeyTok) or (ApiURIText = '') then Error(ApiCredentialsNotSetFullyErr); - SaveApiURI(ApiURIText); - SaveApiKey(ApiKeyText); + Rec.SaveApiURI(ApiURIText); + if (ApiKeyText <> '') and (ApiKeyText <> DummyApiKeyTok) then begin + ApiKeyText := CopyStr(DelChr(ApiKeyText, '=', ' '), 1, 200); + Rec.SaveApiKey(ApiKeyText); + end; end; end; @@ -309,4 +319,5 @@ page 1950 "LP Machine Learning Setup" ApiCredentialsnotSetFullyErr: Label 'You must specify the API URI and the API Key.'; JobQueueCreationInProgressErr: Label 'Payment prediction updates are being scheduled. Please wait until the process is complete.'; UpdatingPaymentPredictionMsg: Label 'Payment predictions are being updated in the background. This might take a minute. You can view the updated predictions on the Customer Ledger Entries page.'; + DummyApiKeyTok: Label '*', Locked = true; } \ No newline at end of file diff --git a/Apps/W1/LatePaymentPredictor/app/src/LPMachineLearningSetup.Table.al b/Apps/W1/LatePaymentPredictor/app/src/LPMachineLearningSetup.Table.al index 537ff0ec96..0750874506 100644 --- a/Apps/W1/LatePaymentPredictor/app/src/LPMachineLearningSetup.Table.al +++ b/Apps/W1/LatePaymentPredictor/app/src/LPMachineLearningSetup.Table.al @@ -247,7 +247,6 @@ table 1950 "LP Machine Learning Setup" exit(CurrentDateTime() - "Last Background Analysis" < 7 * 24 * 60 * 60 * 1000); end; - [NonDebuggable] [Scope('OnPrem')] procedure SaveApiUri(ApiUriText: Text[250]) var @@ -257,12 +256,12 @@ table 1950 "LP Machine Learning Setup" if "Custom API Uri" <> '' then evaluate(ApiUriKeyGUID, "Custom API Uri"); - if IsNullGuid(ApiUriKeyGUID) OR NOT IsolatedStorage.Contains(ApiUriKeyGUID, DataScope::Company) then begin - ApiUriKeyGUID := FORMAT(CreateGuid()); + if IsNullGuid(ApiUriKeyGUID) or not IsolatedStorage.Contains(ApiUriKeyGUID, DataScope::Company) then begin + ApiUriKeyGUID := Format(CreateGuid()); "Custom API Uri" := ApiUriKeyGUID; end; - IF NOT EncryptionEnabled() THEN + if not EncryptionEnabled() then IsolatedStorage.Set(ApiUriKeyGUID, ApiUriText, DataScope::Company) else IsolatedStorage.SetEncrypted(ApiUriKeyGUID, ApiUriText, DataScope::Company); @@ -271,7 +270,7 @@ table 1950 "LP Machine Learning Setup" [NonDebuggable] [Scope('OnPrem')] procedure GetApiUri(): Text[250] - VAR + var ApiUriKeyGUID: Guid; ApiUriValue: Text; begin @@ -282,38 +281,66 @@ table 1950 "LP Machine Learning Setup" exit(CopyStr(ApiUriValue, 1, 250)); end; +#if not CLEAN24 [NonDebuggable] [Scope('OnPrem')] + [Obsolete('Use "SaveApiKey(ApiKeyText: SecretText)" instead.', '24.0')] procedure SaveApiKey(ApiKeyText: Text[200]) - VAR + var ApiKeyKeyGUID: Guid; begin ApiKeyText := CopyStr(DelChr(ApiKeyText, '=', ' '), 1, 200); if "Custom API Key" <> '' then evaluate(ApiKeyKeyGUID, "Custom API Key"); - if IsNullGuid(ApiKeyKeyGUID) OR NOT IsolatedStorage.Contains(ApiKeyKeyGUID, DataScope::Company) then begin + if IsNullGuid(ApiKeyKeyGUID) or not IsolatedStorage.Contains(ApiKeyKeyGUID, DataScope::Company) then begin ApiKeyKeyGUID := FORMAT(CreateGuid()); "Custom API Key" := ApiKeyKeyGUID; end; - IF not EncryptionEnabled() then + if not EncryptionEnabled() then + IsolatedStorage.Set(ApiKeyKeyGUID, ApiKeyText, DataScope::Company) + else + IsolatedStorage.SetEncrypted(ApiKeyKeyGUID, ApiKeyText, DataScope::Company); + end; +#endif + [Scope('OnPrem')] + procedure SaveApiKey(ApiKeyText: SecretText) + var + ApiKeyKeyGUID: Guid; + begin + if "Custom API Key" <> '' then + evaluate(ApiKeyKeyGUID, "Custom API Key"); + if IsNullGuid(ApiKeyKeyGUID) or not IsolatedStorage.Contains(ApiKeyKeyGUID, DataScope::Company) then begin + ApiKeyKeyGUID := FORMAT(CreateGuid()); + "Custom API Key" := ApiKeyKeyGUID; + end; + + if not EncryptionEnabled() then IsolatedStorage.Set(ApiKeyKeyGUID, ApiKeyText, DataScope::Company) else IsolatedStorage.SetEncrypted(ApiKeyKeyGUID, ApiKeyText, DataScope::Company); end; +#if not CLEAN24 [NonDebuggable] [Scope('OnPrem')] + [Obsolete('Replaced by GetApiKeySecret()', '24.0')] procedure GetApiKey(): Text[200] - VAR + begin + exit(CopyStr(GetApiKeyAsSecret().Unwrap(), 1, 200)); + end; +#endif + [Scope('OnPrem')] + procedure GetApiKeyAsSecret(): SecretText + var ApiKeyKeyGUID: GUID; - ApiValue: Text; + ApiValue: SecretText; begin if "Custom API Key" <> '' then evaluate(ApiKeyKeyGUID, "Custom API Key"); - if NOT IsNullGuid(ApiKeyKeyGUID) then + if not IsNullGuid(ApiKeyKeyGUID) then if IsolatedStorage.Get(FORMAT(ApiKeyKeyGUID), DataScope::Company, ApiValue) then - exit(CopyStr(ApiValue, 1, 200)); + exit(ApiValue); end; var diff --git a/Apps/W1/LatePaymentPredictor/app/src/LPModelManagement.Codeunit.al b/Apps/W1/LatePaymentPredictor/app/src/LPModelManagement.Codeunit.al index 8a44c80ee8..951400adb8 100644 --- a/Apps/W1/LatePaymentPredictor/app/src/LPModelManagement.Codeunit.al +++ b/Apps/W1/LatePaymentPredictor/app/src/LPModelManagement.Codeunit.al @@ -154,7 +154,7 @@ codeunit 1951 "LP Model Management" Result: Text; Title: Text; ApiURI: Text[250]; - ApiKey: Text[200]; + ApiKey: SecretText; begin if IsMachineLearningInProgress() then Error(TrainingInProgressErr); @@ -299,7 +299,7 @@ codeunit 1951 "LP Model Management" LPFeatureTableHelper: Codeunit "LP Feature Table Helper"; LPPredictionMgt: Codeunit "LP Prediction Mgt."; ApiURI: Text[250]; - ApiKey: Text[200]; + ApiKey: SecretText; begin LPMachineLearningSetup.GetSingleInstance(); if LPMachineLearningSetup.LastFeatureTableResetWasTooLongAgo() or BasedOnIncrement then diff --git a/Apps/W1/LatePaymentPredictor/app/src/LPPredictionMgt.Codeunit.al b/Apps/W1/LatePaymentPredictor/app/src/LPPredictionMgt.Codeunit.al index 557305d9ce..1dfb9cff23 100644 --- a/Apps/W1/LatePaymentPredictor/app/src/LPPredictionMgt.Codeunit.al +++ b/Apps/W1/LatePaymentPredictor/app/src/LPPredictionMgt.Codeunit.al @@ -59,7 +59,7 @@ codeunit 1950 "LP Prediction Mgt." MLPredictionManagement: Codeunit "ML Prediction Management"; LPFeatureTableHelper: Codeunit "LP Feature Table Helper"; ApiUri: Text[250]; - ApiKey: Text[200]; + ApiKey: SecretText; begin LPMachineLearningSetup.GetSingleInstance(); LPMachineLearningSetup.CheckModelQuality(); @@ -90,7 +90,7 @@ codeunit 1950 "LP Prediction Mgt." MLPredictionManagement: Codeunit "ML Prediction Management"; LPFeatureTableHelper: Codeunit "LP Feature Table Helper"; ApiUri: Text[250]; - ApiKey: Text[200]; + ApiKey: SecretText; begin LPMachineLearningSetup.GetSingleInstance(); LPMachineLearningSetup.CheckModelQuality(); @@ -115,13 +115,26 @@ codeunit 1950 "LP Prediction Mgt." begin end; +#if not CLEAN24 + [NonDebuggable] + [Obsolete('Use GetAzureMLCredentials(LPMachineLearningSetup: Record "LP Machine Learning Setup"; var ApiUri: Text[250]; var ApiKey: SecretText): Boolean instead', '24.0')] procedure GetAzureMLCredentials(LPMachineLearningSetup: Record "LP Machine Learning Setup"; var ApiUri: Text[250]; var ApiKey: Text[200]): Boolean + var + ApiKeyAsSecretText: SecretText; + begin + if GetAzureMLCredentials(LPMachineLearningSetup, ApiUri, ApiKeyAsSecretText) then begin + ApiKey := CopyStr(ApiKeyAsSecretText.Unwrap(), 1, 200); + exit(true); + end; + end; +#endif + procedure GetAzureMLCredentials(LPMachineLearningSetup: Record "LP Machine Learning Setup"; var ApiUri: Text[250]; var ApiKey: SecretText): Boolean begin if not LPMachineLearningSetup."Use My Model Credentials" then exit(false); ApiUri := LPMachineLearningSetup.GetApiUri(); - ApiKey := LPMachineLearningSetup.GetApiKey(); + ApiKey := LPMachineLearningSetup.GetApiKeyAsSecret(); exit(true); end; diff --git a/Apps/W1/MasterDataManagement/app/src/codeunits/MasterDataMgtSetupDefault.Codeunit.al b/Apps/W1/MasterDataManagement/app/src/codeunits/MasterDataMgtSetupDefault.Codeunit.al index b9cbadd713..7308ab925d 100644 --- a/Apps/W1/MasterDataManagement/app/src/codeunits/MasterDataMgtSetupDefault.Codeunit.al +++ b/Apps/W1/MasterDataManagement/app/src/codeunits/MasterDataMgtSetupDefault.Codeunit.al @@ -760,7 +760,12 @@ codeunit 7230 "Master Data Mgt. Setup Default" FieldNumbers.Add(NoSeriesLine.FieldNo(Open)); FieldNumbers.Add(NoSeriesLine.FieldNo("Sequence Name")); FieldNumbers.Add(NoSeriesLine.FieldNo("Starting Sequence No.")); +#if not CLEAN24 +#pragma warning disable AL0432 FieldNumbers.Add(NoSeriesLine.FieldNo("Allow Gaps in Nos.")); +#pragma warning restore AL0432 +#endif + FieldNumbers.Add(NoSeriesLine.FieldNo(Implementation)); GenerateIntegrationTableMapping(IntegrationTableMapping, FieldNumbers, IntegrationTableMappingName, Database::"No. Series Line", '', true, ShouldRecreateJobQueueEntry); IntegrationTableMapping."Dependency Filter" := 'MDM_NUMBERSERIES'; diff --git a/Apps/W1/MasterDataManagement/app/src/codeunits/MasterDataMgtSubscribers.Codeunit.al b/Apps/W1/MasterDataManagement/app/src/codeunits/MasterDataMgtSubscribers.Codeunit.al index a761786307..cfffc87a66 100644 --- a/Apps/W1/MasterDataManagement/app/src/codeunits/MasterDataMgtSubscribers.Codeunit.al +++ b/Apps/W1/MasterDataManagement/app/src/codeunits/MasterDataMgtSubscribers.Codeunit.al @@ -101,6 +101,18 @@ codeunit 7237 "Master Data Mgt. Subscribers" HandleOnFindingIfJobNeedsToBeRun(Sender, Result); end; + [EventSubscriber(ObjectType::Report, Report::"Copy Company", 'OnAfterCreatedNewCompanyByCopyCompany', '', false, false)] + local procedure CleanupSetupAfterCreatedNewCompanyByCopyCompany(NewCompanyName: Text[30]) + var + MasterDataMgtCoupling: Record "Master Data Mgt. Coupling"; + MasterDataManagementSetup: Record "Master Data Management Setup"; + begin + MasterDataMgtCoupling.ChangeCompany(NewCompanyName); + MasterDataMgtCoupling.DeleteAll(); + MasterDataManagementSetup.ChangeCompany(NewCompanyName); + MasterDataManagementSetup.DeleteAll(); + end; + internal procedure HandleOnFindingIfJobNeedsToBeRun(var Sender: Record "Job Queue Entry"; var Result: Boolean) var MasterDataManagementSetup: Record "Master Data Management Setup"; diff --git a/Apps/W1/PlanConfiguration/test/src/AzureADPlanModuleTest.codeunit.al b/Apps/W1/PlanConfiguration/test/src/AzureADPlanModuleTest.codeunit.al index 9bb894f88e..6c33137402 100644 --- a/Apps/W1/PlanConfiguration/test/src/AzureADPlanModuleTest.codeunit.al +++ b/Apps/W1/PlanConfiguration/test/src/AzureADPlanModuleTest.codeunit.al @@ -452,9 +452,12 @@ codeunit 139509 "Azure AD Plan Module Test" EssentialUser: Record User; AzureADPlan: Codeunit "Azure AD Plan"; PlanIds: Codeunit "Plan Ids"; + TestUserPermissionsSubs: Codeunit "Test User Permissions Subs."; begin // [SCENARIO] CheckMixedPlans show a message when user has access to the user management tables Initialize(); + BindSubscription(TestUserPermissionsSubs); + TestUserPermissionsSubs.SetCanManageUser(UserSecurityId()); LibraryLowerPermissions.SetOutsideO365Scope(); LibraryLowerPermissions.AddSecurity(); @@ -490,9 +493,12 @@ codeunit 139509 "Azure AD Plan Module Test" PremiumUser: Record User; AzureADPlan: Codeunit "Azure AD Plan"; PlanIds: Codeunit "Plan Ids"; + TestUserPermissionsSubs: Codeunit "Test User Permissions Subs."; begin // [SCENARIO] CheckMixedPlans show a message when user has access to the user management tables Initialize(); + BindSubscription(TestUserPermissionsSubs); + TestUserPermissionsSubs.SetCanManageUser(UserSecurityId()); LibraryLowerPermissions.SetOutsideO365Scope(); LibraryLowerPermissions.AddSecurity(); @@ -529,9 +535,12 @@ codeunit 139509 "Azure AD Plan Module Test" EssentialUser: Record User; AzureADPlan: Codeunit "Azure AD Plan"; PlanIds: Codeunit "Plan Ids"; + TestUserPermissionsSubs: Codeunit "Test User Permissions Subs."; begin // [SCENARIO] CheckMixedPlans show a message when user has access to the user management tables Initialize(); + BindSubscription(TestUserPermissionsSubs); + TestUserPermissionsSubs.SetCanManageUser(UserSecurityId()); LibraryLowerPermissions.SetOutsideO365Scope(); LibraryLowerPermissions.AddSecurity(); diff --git a/Apps/W1/QBMigration/app/src/Support/MSQBODataMigration.Page.al b/Apps/W1/QBMigration/app/src/Support/MSQBODataMigration.Page.al index 9e9fd35c86..4404b6ac22 100644 --- a/Apps/W1/QBMigration/app/src/Support/MSQBODataMigration.Page.al +++ b/Apps/W1/QBMigration/app/src/Support/MSQBODataMigration.Page.al @@ -28,7 +28,7 @@ page 1830 "MS - QBO Data Migration" MultiLine = true; ShowCaption = false; } - usercontrol(OAuthIntegration; OAuthControlAddIn) + usercontrol(OAuthIntegration; OAuthIntegration) { ApplicationArea = Basic, Suite; diff --git a/Apps/W1/ReviewGLEntries/app/src/enums/ReviewPolicyType.Enum.al b/Apps/W1/ReviewGLEntries/app/src/enums/ReviewPolicyType.Enum.al index 6ae9c70fee..6f92a0ec92 100644 --- a/Apps/W1/ReviewGLEntries/app/src/enums/ReviewPolicyType.Enum.al +++ b/Apps/W1/ReviewGLEntries/app/src/enums/ReviewPolicyType.Enum.al @@ -6,14 +6,14 @@ enum 22203 "Review Policy Type" value(0; None) { - + Caption = 'None'; } value(1; "Allow Review") { - + Caption = 'Allow Review'; } value(2; "Allow Review and Match Balance") { - + Caption = 'Allow Review and Match Balance'; } } \ No newline at end of file diff --git a/Apps/W1/SalesAndInventoryForecast/app/src/codeunits/SalesForecastHandler.Codeunit.al b/Apps/W1/SalesAndInventoryForecast/app/src/codeunits/SalesForecastHandler.Codeunit.al index d37e293ed2..0ed5462b6f 100644 --- a/Apps/W1/SalesAndInventoryForecast/app/src/codeunits/SalesForecastHandler.Codeunit.al +++ b/Apps/W1/SalesAndInventoryForecast/app/src/codeunits/SalesForecastHandler.Codeunit.al @@ -114,13 +114,12 @@ codeunit 1850 "Sales Forecast Handler" exit(true); end; - [NonDebuggable] procedure InitializeTimeseries(var TimeSeriesManagement: Codeunit "Time Series Management"; MSSalesForecastSetupRec: Record "MS - Sales Forecast Setup"): Boolean var AzureAIUsage: Codeunit "Azure AI Usage"; AzureAIService: Enum "Azure AI Service"; APIURI: Text[250]; - APIKey: Text[200]; + APIKey: SecretText; LimitType: Option; Limit: Decimal; begin @@ -140,7 +139,7 @@ codeunit 1850 "Sales Forecast Handler" end else if not TimeSeriesManagement.Initialize( MSSalesForecastSetupRec.GetAPIUri(), - MSSalesForecastSetupRec.GetAPIKey(), + MSSalesForecastSetupRec.GetAPIKeyAsSecret(), MSSalesForecastSetupRec."Timeout (seconds)", false) then begin Status := Status::"Failed Time Series initialization"; diff --git a/Apps/W1/SalesAndInventoryForecast/app/src/pages/SalesForecast.Page.al b/Apps/W1/SalesAndInventoryForecast/app/src/pages/SalesForecast.Page.al index 0ddee568fb..c0d04f501b 100644 --- a/Apps/W1/SalesAndInventoryForecast/app/src/pages/SalesForecast.Page.al +++ b/Apps/W1/SalesAndInventoryForecast/app/src/pages/SalesForecast.Page.al @@ -1,6 +1,7 @@ namespace Microsoft.Inventory.InventoryForecast; using Microsoft.Inventory.Item; +using System.Integration; using System.Visualization; using Microsoft.Inventory.Ledger; using System.AI; @@ -20,7 +21,7 @@ page 1850 "Sales Forecast" { area(content) { - usercontrol(ForecastBusinessChart; "Microsoft.Dynamics.Nav.Client.BusinessChart") + usercontrol(ForecastBusinessChart; BusinessChart) { ApplicationArea = Basic, Suite; @@ -455,7 +456,7 @@ page 1850 "Sales Forecast" if not IsChartAddInReady then exit; PopulateChart(BusinessChartBuffer); - BusinessChartBuffer.Update(CurrPage.ForecastBusinessChart); + BusinessChartBuffer.UpdateChart(CurrPage.ForecastBusinessChart); NeedsUpdate := false; end; diff --git a/Apps/W1/SalesAndInventoryForecast/app/src/pages/SalesForecastSetupCard.Page.al b/Apps/W1/SalesAndInventoryForecast/app/src/pages/SalesForecastSetupCard.Page.al index ba8dfbe164..7cc2138ab1 100644 --- a/Apps/W1/SalesAndInventoryForecast/app/src/pages/SalesForecastSetupCard.Page.al +++ b/Apps/W1/SalesAndInventoryForecast/app/src/pages/SalesForecastSetupCard.Page.al @@ -60,7 +60,7 @@ page 1853 "Sales Forecast Setup Card" Importance = Additional; ToolTip = 'Specifies how far in the future you want to look for stockouts. The value you enter works together with the unit of time specified in the Period Type field to determine the horizon.'; } - field("API URI"; "API URI") + field("API URI"; Rec."API URI") { ApplicationArea = Basic, Suite; ToolTip = 'Specifies the API URI for the Azure Machine Learning instance.'; @@ -72,15 +72,10 @@ page 1853 "Sales Forecast Setup Card" ExtendedDatatype = Masked; ToolTip = 'Specifies the API key for the Time Series experiment in Azure Machine Learning.'; - trigger OnDrillDown() - begin - if not IsNullGuid("API Key ID") then - Message(GetUserDefinedAPIKey()); - end; - trigger OnValidate() begin - SetUserDefinedAPIKey(APIKeyValue); + if APIKeyValue <> DummyApiKeyTok then + Rec.SetUserDefinedAPIKey(APIKeyValue); end; } field("Timeout (seconds)"; "Timeout (seconds)") @@ -206,8 +201,8 @@ page 1853 "Sales Forecast Setup Card" begin if SalesForecastScheduler.JobQueueEntryCreationInProcess() then Error(JobQueueCreationInProgressErr); - GetSingleInstance(); - APIKeyValue := GetAPIKey(); + Rec.GetSingleInstance(); + SetApiKey(); end; var @@ -216,6 +211,7 @@ page 1853 "Sales Forecast Setup Card" [NonDebuggable] APIKeyValue: Text[250]; JobQueueCreationInProgressErr: Label 'Sales forecast updates are being scheduled. Please wait until the process is complete.'; + DummyApiKeyTok: Label '*', Locked = true; local procedure GetMLTotalProcessingTime(): Decimal var @@ -227,5 +223,11 @@ page 1853 "Sales Forecast Setup Card" exit(Round(ProcessingTime, 1)); end; + + local procedure SetApiKey() + begin + if not Rec.GetApiKeyAsSecret().IsEmpty() then + APIKeyValue := DummyApiKeyTok; + end; } diff --git a/Apps/W1/SalesAndInventoryForecast/app/src/tables/MSSalesForecastSetup.Table.al b/Apps/W1/SalesAndInventoryForecast/app/src/tables/MSSalesForecastSetup.Table.al index fa0e5e51d3..50257a521e 100644 --- a/Apps/W1/SalesAndInventoryForecast/app/src/tables/MSSalesForecastSetup.Table.al +++ b/Apps/W1/SalesAndInventoryForecast/app/src/tables/MSSalesForecastSetup.Table.al @@ -179,21 +179,22 @@ table 1853 "MS - Sales Forecast Setup" CryptographyManagement: Codeunit "Cryptography Management"; begin if not CryptographyManagement.IsEncryptionEnabled() then - CryptographyManagement.EnableEncryption(FALSE); + CryptographyManagement.EnableEncryption(false); end; - [NonDebuggable] procedure URIOrKeyEmpty(): Boolean var EnvironmentInfo: Codeunit "Environment Information"; begin if EnvironmentInfo.IsSaaS() then exit(false); - exit((GetAPIUri() = '') or (GetAPIKey() = '')); + exit((GetAPIUri() = '') or GetAPIKeyAsSecret().IsEmpty()); end; +#if not CLEAN24 [NonDebuggable] [Scope('OnPrem')] + [Obsolete('Use GetUserDefinedAPIKeyAsSecret() instead.', '24.0')] procedure GetUserDefinedAPIKey(): Text[250] begin // If the user has defined the API Key in the page UI, then retrieve it from @@ -201,32 +202,58 @@ table 1853 "MS - Sales Forecast Setup" if IsNullGuid("API Key ID") then exit(''); - exit(TryReadAPICredential("API Key ID")); + exit(CopyStr(TryReadAPICredentialAsSecret("API Key ID").Unwrap(), 1, 250)); + end; +#endif + [Scope('OnPrem')] + procedure GetUserDefinedAPIKeyAsSecret(): SecretText + var + EmptyText: Text[250]; + begin + // If the user has defined the API Key in the page UI, then retrieve it from + // the encrypted Isolated Storage table + EmptyText := ''; + if IsNullGuid("API Key ID") then + exit(EmptyText); + + exit(TryReadAPICredentialAsSecret("API Key ID")); end; - [NonDebuggable] [Scope('OnPrem')] - procedure SetUserDefinedAPIKey(UserDefinedAPIKey: Text[250]) + procedure SetUserDefinedAPIKey(UserDefinedAPIKey: SecretText) begin // Store the user-defined API Key in the Isolated Storage and save its GUID in the "API Key ID" - if UserDefinedAPIKey = '' then begin + if UserDefinedAPIKey.IsEmpty() then begin DeleteAPICredential("API Key ID"); exit; end; "API Key ID" := InsertAPICredential(UserDefinedAPIKey); end; +#if not CLEAN24 [NonDebuggable] + [Obsolete('Use GetAPIKeyAsSecret() instead.', '24.0')] procedure GetAPIKey(): Text[250] var UserDefinedAPIKey: Text[250]; begin // The API Key and URI entered by the user take precedence - UserDefinedAPIKey := GetUserDefinedAPIKey(); + UserDefinedAPIKey := CopyStr(GetUserDefinedAPIKeyAsSecret().Unwrap(), 1, 250); if UserDefinedAPIKey <> '' then exit(UserDefinedAPIKey); exit(''); end; +#endif + procedure GetAPIKeyAsSecret(): SecretText + var + UserDefinedAPIKey: SecretText; + begin + // The API Key and URI entered by the user take precedence + UserDefinedAPIKey := GetUserDefinedAPIKeyAsSecret(); + if not UserDefinedAPIKey.IsEmpty() then + exit(UserDefinedAPIKey); + exit(UserDefinedAPIKey); + end; procedure GetAPIUri(): Text[250] begin @@ -236,29 +263,30 @@ table 1853 "MS - Sales Forecast Setup" exit(''); end; - [NonDebuggable] - local procedure TryReadAPICredential(CredentialGUID: Guid): Text[250] + local procedure TryReadAPICredentialAsSecret(CredentialGUID: Guid): SecretText var CredentialValue: Text; + CredentialValueAsSecret: SecretText; begin + CredentialValue := ''; + CredentialValueAsSecret := CredentialValue; if IsNullGuid(CredentialGUID) then - exit(''); + exit(CredentialValueAsSecret); if not IsolatedStorage.Contains(CredentialGUID, Datascope::Company) then - exit(''); + exit(CredentialValueAsSecret); - IsolatedStorage.Get(CredentialGUID, Datascope::Company, CredentialValue); - exit(CopyStr(CredentialValue, 1, 250)); + IsolatedStorage.Get(CredentialGUID, Datascope::Company, CredentialValueAsSecret); + exit(CredentialValueAsSecret); end; - [NonDebuggable] - local procedure InsertAPICredential(NewValue: Text[250]): Guid + local procedure InsertAPICredential(NewValue: SecretText): Guid var NewKey: Text; begin NewKey := FORMAT(CreateGuid()); - IF NOT EncryptionEnabled() THEN + if not EncryptionEnabled() then IsolatedStorage.Set(NewKey, NewValue, Datascope::Company) else IsolatedStorage.SetEncrypted(NewKey, NewValue, Datascope::Company); @@ -272,7 +300,7 @@ table 1853 "MS - Sales Forecast Setup" Modify(); // Delete the stored API Key from Isolated Storage table - if not IsolatedStorage.Contains(KeyId, Datascope::Company) THEN + if not IsolatedStorage.Contains(KeyId, Datascope::Company) then exit; IsolatedStorage.Delete(KeyId, Datascope::Company); diff --git a/Apps/W1/SalesAndInventoryForecast/test/src/SalesForecastLib.Codeunit.al b/Apps/W1/SalesAndInventoryForecast/test/src/SalesForecastLib.Codeunit.al index ae08ec2444..378f71f764 100644 --- a/Apps/W1/SalesAndInventoryForecast/test/src/SalesForecastLib.Codeunit.al +++ b/Apps/W1/SalesAndInventoryForecast/test/src/SalesForecastLib.Codeunit.al @@ -71,10 +71,13 @@ codeunit 139542 "Sales Forecast Lib" end; procedure Setup(); + var + ApiKey: Text; begin MSSalesForecastSetup.GetSingleInstance(); MSSalesForecastSetup.Validate("API URI", MockServiceURITxt); - MSSalesForecastSetup.SetUserDefinedAPIKey(MockServiceKeyTxt); + ApiKey := MockServiceKeyTxt; + MSSalesForecastSetup.SetUserDefinedAPIKey(ApiKey); MSSalesForecastSetup.Modify(true); end; diff --git a/Apps/W1/SalesAndInventoryForecast/test/src/SalesForecastTests.Codeunit.al b/Apps/W1/SalesAndInventoryForecast/test/src/SalesForecastTests.Codeunit.al index 64823569ea..73f704a7b2 100644 --- a/Apps/W1/SalesAndInventoryForecast/test/src/SalesForecastTests.Codeunit.al +++ b/Apps/W1/SalesAndInventoryForecast/test/src/SalesForecastTests.Codeunit.al @@ -304,6 +304,7 @@ codeunit 139540 "Sales Forecast Tests" procedure TestTimeout(); var Item: Record Item; + ApiKey: Text; begin // [Scenario] Call to AzureML times out if no response from service Initialize(); @@ -316,7 +317,8 @@ codeunit 139540 "Sales Forecast Tests" // [Given] The Api Uri key is set to an invalid destination and timeout = 1 second MSSalesForecastSetup.GetSingleInstance(); MSSalesForecastSetup.Validate("API URI", 'https://localhost:1234/services.azureml.net/workspaces/'); - MSSalesForecastSetup.SetUserDefinedAPIKey(MockServiceKeyTxt); + ApiKey := MockServiceKeyTxt; + MSSalesForecastSetup.SetUserDefinedAPIKey(ApiKey); MSSalesForecastSetup.Validate("Timeout (seconds)", 1); MSSalesForecastSetup.Modify(true); @@ -664,15 +666,12 @@ codeunit 139540 "Sales Forecast Tests" begin // [Scenario] When Job Queue creation in Process, Sales Item Forecast Setup record is locked // and the appropriate message is presented - // [Given] A Job Queue Entry in creation - with JobQueueEntry do begin - Init(); - Validate("Object Type to Run", "Object Type to Run"::Codeunit); - Validate("Object ID to Run", Codeunit::"Sales Forecast Update"); - Validate(Status, Status::"In Process"); - Insert(true); - end; + JobQueueEntry.Init(); + JobQueueEntry.Validate("Object Type to Run", JobQueueEntry."Object Type to Run"::Codeunit); + JobQueueEntry.Validate("Object ID to Run", Codeunit::"Sales Forecast Update"); + JobQueueEntry.Validate(Status, JobQueueEntry.Status::"In Process"); + JobQueueEntry.Insert(true); // [When] Item Sales Forecast Setup is invoked from Item List // [Then] Message is displayed (JobCreationInProgressMsgHandler) @@ -764,6 +763,7 @@ codeunit 139540 "Sales Forecast Tests" var Item: Record Item; LibraryPermissions: Codeunit "Library - Permissions"; + ApiKey: Text; begin // [Scenario] Prediction doesn't throw Limit exceeded error, if user defined API is used in SaaS Initialize(); @@ -777,7 +777,8 @@ codeunit 139540 "Sales Forecast Tests" MSSalesForecastSetup.GetSingleInstance(); MSSalesForecastSetup.Validate("Timeout (seconds)", 1); MSSalesForecastSetup.Validate("API URI", 'https://localhost:1234/services.azureml.net/workspaces/'); - MSSalesForecastSetup.SetUserDefinedAPIKey(MockServiceKeyTxt); + ApiKey := MockServiceKeyTxt; + MSSalesForecastSetup.SetUserDefinedAPIKey(ApiKey); MSSalesForecastSetup.Modify(true); // [When] Item sales is being forecasted for the given item diff --git a/Apps/W1/ServiceDeclaration/app/src/Processing/ServiceDeclarationHeader.Table.al b/Apps/W1/ServiceDeclaration/app/src/Processing/ServiceDeclarationHeader.Table.al index 0c13cb969b..0fa257f355 100644 --- a/Apps/W1/ServiceDeclaration/app/src/Processing/ServiceDeclarationHeader.Table.al +++ b/Apps/W1/ServiceDeclaration/app/src/Processing/ServiceDeclarationHeader.Table.al @@ -22,7 +22,7 @@ table 5023 "Service Declaration Header" begin if "No." <> xRec."No." then begin TestNoSeries(); - NoSeriesMgt.TestManual(ServiceDeclarationSetup."Declaration No. Series"); + NoSeries.TestManual(ServiceDeclarationSetup."Declaration No. Series"); "No. Series" := ''; end; end; @@ -87,14 +87,31 @@ table 5023 "Service Declaration Header" var ServiceDeclarationSetup: Record "Service Declaration Setup"; - NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeriesManagement: Codeunit NoSeriesManagement; + NoSeries: Codeunit "No. Series"; ServDeclAlreadyExistErr: Label 'The service declaration %1 already exists.', Comment = '%1 = service declaration number.'; trigger OnInsert() +#if not CLEAN24 + var + IsHandled: Boolean; +#endif begin if "No." = '' then begin TestNoSeries(); - NoSeriesMgt.InitSeries(ServiceDeclarationSetup."Declaration No. Series", xRec."No. Series", 0D, "No.", "No. Series"); +#if not CLEAN24 + IsHandled := false; + NoSeriesManagement.RaiseObsoleteOnBeforeInitSeries(ServiceDeclarationSetup."Declaration No. Series", xRec."No. Series", 0D, "No.", "No. Series", IsHandled); + if not IsHandled then begin +#endif + "No. Series" := ServiceDeclarationSetup."Declaration No. Series"; + if NoSeries.AreRelated("No. Series", xRec."No. Series") then + "No. Series" := xRec."No. Series"; + "No." := NoSeries.GetNextNo("No. Series"); +#if not CLEAN24 + NoSeriesManagement.RaiseObsoleteOnAfterInitSeries("No. Series", ServiceDeclarationSetup."Declaration No. Series", 0D, "No."); + end; +#endif end; end; @@ -136,8 +153,8 @@ table 5023 "Service Declaration Header" begin ServDeclHeader.Copy(Rec); TestNoSeries(); - if NoSeriesMgt.SelectSeries(ServiceDeclarationSetup."Declaration No. Series", OldServDeclHeader."No. Series", ServDeclHeader."No. Series") then begin - NoSeriesMgt.SetSeries(ServDeclHeader."No."); + if NoSeriesManagement.SelectSeries(ServiceDeclarationSetup."Declaration No. Series", OldServDeclHeader."No. Series", ServDeclHeader."No. Series") then begin + NoSeriesManagement.SetSeries(ServDeclHeader."No."); if ServDeclHeader.Get(ServDeclHeader."No.") then Error(ServDeclAlreadyExistErr, ServDeclHeader."No."); Rec := ServDeclHeader; diff --git a/Apps/W1/ServiceDeclaration/app/src/Processing/ServiceDeclarationMgt.Codeunit.al b/Apps/W1/ServiceDeclaration/app/src/Processing/ServiceDeclarationMgt.Codeunit.al index 1d0d838e94..ebe4df39aa 100644 --- a/Apps/W1/ServiceDeclaration/app/src/Processing/ServiceDeclarationMgt.Codeunit.al +++ b/Apps/W1/ServiceDeclaration/app/src/Processing/ServiceDeclarationMgt.Codeunit.al @@ -152,7 +152,7 @@ codeunit 5012 "Service Declaration Mgt." NoSeriesLine."Line No." := 10000; NoSeriesLine.Validate("Starting No.", NoSeriesCode + '00001'); NoSeriesLine.Insert(true); - NoSeriesLine.Validate("Allow Gaps in Nos.", true); + NoSeriesLine.Validate(Implementation, Enum::"No. Series Implementation"::Sequence); NoSeriesLine.Modify(true); exit(NoSeriesCode); end; diff --git a/Apps/W1/Shopify/app/app.json b/Apps/W1/Shopify/app/app.json index b7a1e6574e..60ce9eb083 100644 --- a/Apps/W1/Shopify/app/app.json +++ b/Apps/W1/Shopify/app/app.json @@ -42,5 +42,8 @@ "includeSourceInSymbolFile": true }, "application": "24.0.0.0", - "target": "OnPrem" + "target": "OnPrem", + "features": [ + "NoImplicitWith" + ] } \ No newline at end of file diff --git a/Apps/W1/Shopify/app/src/Base/Codeunits/ShpfyUpgradeMgt.Codeunit.al b/Apps/W1/Shopify/app/src/Base/Codeunits/ShpfyUpgradeMgt.Codeunit.al index 3f8a838fd3..820682b925 100644 --- a/Apps/W1/Shopify/app/src/Base/Codeunits/ShpfyUpgradeMgt.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Base/Codeunits/ShpfyUpgradeMgt.Codeunit.al @@ -34,7 +34,10 @@ codeunit 30106 "Shpfy Upgrade Mgt." LocationUpgrade(); SyncPricesWithProductsUpgrade(); SendShippingConfirmationUpgrade(); +#if CLEAN24 OrderAttributeValueUpgrade(); +#endif + CreditMemoCanBeCreatedUpgrade(); end; #if CLEAN22 @@ -383,6 +386,7 @@ codeunit 30106 "Shpfy Upgrade Mgt." UpgradeTag.SetUpgradeTag(GetSendShippingConfirmationUpgradeTag()); end; +#if CLEAN24 local procedure OrderAttributeValueUpgrade() var OrderAttribute: Record "Shpfy Order Attribute"; @@ -401,6 +405,31 @@ codeunit 30106 "Shpfy Upgrade Mgt." UpgradeTag.SetUpgradeTag(GetOrderAttributeValueUpgradeTag()); end; +#endif + + local procedure CreditMemoCanBeCreatedUpgrade() + var + RefundLine: Record "Shpfy Refund Line"; + UpgradeTag: Codeunit "Upgrade Tag"; + RefundLineDataTransfer: DataTransfer; + begin + if UpgradeTag.HasUpgradeTag(GetCreditMemoCanBeCreatedUpgradeTag()) then + exit; + + RefundLineDataTransfer.SetTables(Database::"Shpfy Refund Line", Database::"Shpfy Refund Line"); + RefundLineDataTransfer.AddSourceFilter(RefundLine.FieldNo("Restock Type"), '=%1|%2|%3', RefundLine."Restock Type"::Return, RefundLine."Restock Type"::"Legacy Restock", RefundLine."Restock Type"::"No Restock"); + RefundLineDataTransfer.AddConstantValue(true, RefundLine.FieldNo("Can Create Credit Memo")); + RefundLineDataTransfer.UpdateAuditFields(false); + RefundLineDataTransfer.CopyFields(); + Clear(RefundLineDataTransfer); + RefundLineDataTransfer.SetTables(Database::"Shpfy Refund Line", Database::"Shpfy Refund Line"); + RefundLineDataTransfer.AddSourceFilter(RefundLine.FieldNo("Restock Type"), '=%1', RefundLine."Restock Type"::Cancel); + RefundLineDataTransfer.AddConstantValue(false, RefundLine.FieldNo("Can Create Credit Memo")); + RefundLineDataTransfer.UpdateAuditFields(false); + RefundLineDataTransfer.CopyFields(); + + UpgradeTag.SetUpgradeTag(GetCreditMemoCanBeCreatedUpgradeTag()); + end; local procedure GetShopifyB2BEnabledUpgradeTag(): Code[250] begin @@ -461,10 +490,17 @@ codeunit 30106 "Shpfy Upgrade Mgt." end; #endif +#if CLEAN24 local procedure GetOrderAttributeValueUpgradeTag(): Code[250] begin exit('MS-497909-OrderAttributeValueUpgradeTag-20240125'); end; +#endif + + local procedure GetCreditMemoCanBeCreatedUpgradeTag(): Code[250] + begin + exit('MS-471880-CreditMemoCanBeCreatedUpgradeTag-20240201'); + end; local procedure GetDateBeforeFeature(): DateTime begin diff --git a/Apps/W1/Shopify/app/src/Base/Enums/ShpfyLoggingMode.Enum.al b/Apps/W1/Shopify/app/src/Base/Enums/ShpfyLoggingMode.Enum.al index 875d970ad3..e556ccc6d8 100644 --- a/Apps/W1/Shopify/app/src/Base/Enums/ShpfyLoggingMode.Enum.al +++ b/Apps/W1/Shopify/app/src/Base/Enums/ShpfyLoggingMode.Enum.al @@ -2,7 +2,6 @@ namespace Microsoft.Integration.Shopify; enum 30141 "Shpfy Logging Mode" { - Access = Internal; Extensible = false; value(0; "Error Only") diff --git a/Apps/W1/Shopify/app/src/Base/Pages/ShpfyShopCard.Page.al b/Apps/W1/Shopify/app/src/Base/Pages/ShpfyShopCard.Page.al index ef71ff62f7..01b3d303ab 100644 --- a/Apps/W1/Shopify/app/src/Base/Pages/ShpfyShopCard.Page.al +++ b/Apps/W1/Shopify/app/src/Base/Pages/ShpfyShopCard.Page.al @@ -486,6 +486,23 @@ page 30101 "Shpfy Shop Card" ApplicationArea = All; ToolTip = 'Specifies whether the customer is notified when the shipment is synchronized to Shopify.'; } +#if not CLEAN24 + field(ReplaceOrderAttributeValue; Rec."Replace Order Attribute Value") + { + ApplicationArea = All; + Caption = 'Feature Update: Enable Longer Order Attribute Value Length'; + ToolTip = 'Specifies if the connector stores order attribute values in a new field with a length of 2048 characters. Starting from version 27.0, this new field will be the only option available. However, until version 27.0 administrators can choose to continue using the old field if needed.'; + Enabled = not ReplaceOrderAttributeValueDisabled; + ObsoleteReason = 'This feature will be enabled by default with version 27.0.'; + ObsoleteState = Pending; + ObsoleteTag = '24.0'; + + trigger OnValidate() + begin + CurrPage.Update(true); + end; + } +#endif } group(ReturnsAndRefunds) { @@ -1084,6 +1101,9 @@ page 30101 "Shpfy Shop Card" ExpirationNotificationTxt: Label 'Shopify API version 30 days before expiry notification sent.', Locked = true; BlockedNotificationTxt: Label 'Shopify API version expired notification sent.', Locked = true; CategoryTok: Label 'Shopify Integration', Locked = true; +#if not CLEAN24 + ReplaceOrderAttributeValueDisabled: Boolean; +#endif trigger OnOpenPage() var @@ -1093,6 +1113,7 @@ page 30101 "Shpfy Shop Card" #endif CommunicationMgt: Codeunit "Shpfy Communication Mgt."; ShopMgt: Codeunit "Shpfy Shop Mgt."; + ApiVersionExpiryDateTime: DateTime; begin FeatureTelemetry.LogUptake('0000HUU', 'Shopify', Enum::"Feature Uptake Status"::Discovered); @@ -1117,6 +1138,9 @@ page 30101 "Shpfy Shop Card" trigger OnAfterGetCurrRecord() begin CheckReturnRefundsVisible(); +#if not CLEAN24 + CheckReplaceOrderAttributeValueDisabled(); +#endif end; local procedure GetResetSyncTo(InitDateTime: DateTime): DateTime @@ -1136,5 +1160,25 @@ page 30101 "Shpfy Shop Card" begin IsReturnRefundsVisible := Rec."Return and Refund Process" <> "Shpfy ReturnRefund ProcessType"::" "; end; + +#if not CLEAN24 + local procedure CheckReplaceOrderAttributeValueDisabled() + var + OrderHeader: Record "Shpfy Order Header"; + OrderAttribute: Record "Shpfy Order Attribute"; + begin + if Rec."Replace Order Attribute Value" then begin + OrderHeader.SetRange("Shop Code", Rec.Code); + if OrderHeader.FindSet() then + repeat + OrderAttribute.SetRange("Order Id", OrderHeader."Shopify Order Id"); + if not OrderAttribute.IsEmpty() then begin + ReplaceOrderAttributeValueDisabled := true; + exit; + end; + until OrderHeader.Next() = 0; + end; + end; +#endif } diff --git a/Apps/W1/Shopify/app/src/Base/Tables/ShpfyShop.Table.al b/Apps/W1/Shopify/app/src/Base/Tables/ShpfyShop.Table.al index 295fbe78d2..05a65530c1 100644 --- a/Apps/W1/Shopify/app/src/Base/Tables/ShpfyShop.Table.al +++ b/Apps/W1/Shopify/app/src/Base/Tables/ShpfyShop.Table.al @@ -502,6 +502,7 @@ table 30102 "Shpfy Shop" { Caption = 'Return and Refund Process'; DataClassification = CustomerContent; + InitValue = "Import Only"; trigger OnValidate() var @@ -765,6 +766,28 @@ table 30102 "Shpfy Shop" Caption = 'Company Mapping Type'; DataClassification = CustomerContent; } + field(127; "Replace Order Attribute Value"; Boolean) + { + Caption = 'Replace Order Attribute Value'; + DataClassification = SystemMetadata; + InitValue = true; + ObsoleteReason = 'This feature will be enabled by default with version 27.0.'; +#if not CLEAN24 + ObsoleteState = Pending; + ObsoleteTag = '24.0'; +#else + ObsoleteState = Removed; + ObsoleteTag = '27.0'; +#endif + +#if not CLEAN24 + trigger OnValidate() + begin + if "Replace Order Attribute Value" then + UpdateOrderAttributes(Rec.Code); + end; +#endif + } field(200; "Shop Id"; Integer) { DataClassification = SystemMetadata; @@ -1019,4 +1042,23 @@ table 30102 "Shpfy Shop" exit(true); end; end; + +#if not CLEAN24 + local procedure UpdateOrderAttributes(ShopCode: Code[20]) + var + OrderHeader: Record "Shpfy Order Header"; + OrderAttribute: Record "Shpfy Order Attribute"; + begin + OrderHeader.SetRange("Shop Code", ShopCode); + if OrderHeader.FindSet() then + repeat + OrderAttribute.SetRange("Order Id", OrderHeader."Shopify Order Id"); + if OrderAttribute.FindSet() then + repeat + OrderAttribute."Attribute Value" := OrderAttribute.Value; + OrderAttribute.Modify(); + until OrderAttribute.Next() = 0; + until OrderHeader.Next() = 0; + end; +#endif } \ No newline at end of file diff --git a/Apps/W1/Shopify/app/src/Customers/Codeunits/ShpfyUpdateCustomer.Codeunit.al b/Apps/W1/Shopify/app/src/Customers/Codeunits/ShpfyUpdateCustomer.Codeunit.al index 47c8c1957c..7b39f19b68 100644 --- a/Apps/W1/Shopify/app/src/Customers/Codeunits/ShpfyUpdateCustomer.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Customers/Codeunits/ShpfyUpdateCustomer.Codeunit.al @@ -87,7 +87,7 @@ codeunit 30124 "Shpfy Update Customer" if Customer.Name = '' then Customer.Validate(Name, IName.GetName(CustomerAddress."First Name", CustomerAddress."Last Name", CustomerAddress.Company)) else - Customer.Validate("Name 2", IName.GetName(CustomerAddress."First Name", CustomerAddress."Last Name", CustomerAddress.Company)); + Customer.Validate("Name 2", CopyStr(IName.GetName(CustomerAddress."First Name", CustomerAddress."Last Name", CustomerAddress.Company), 1, MaxStrLen(Customer."Name 2"))); IName := Shop."Contact Source"; Customer.Validate(Contact, IName.GetName(CustomerAddress."First Name", CustomerAddress."Last Name", CustomerAddress.Company)); diff --git a/Apps/W1/Shopify/app/src/Integration/Pages/ShpfyAuthentication.Page.al b/Apps/W1/Shopify/app/src/Integration/Pages/ShpfyAuthentication.Page.al index 876b0151dd..314f30d2de 100644 --- a/Apps/W1/Shopify/app/src/Integration/Pages/ShpfyAuthentication.Page.al +++ b/Apps/W1/Shopify/app/src/Integration/Pages/ShpfyAuthentication.Page.al @@ -22,7 +22,7 @@ page 30135 "Shpfy Authentication" { area(Content) { - usercontrol(OAuthIntegration; OAuthControlAddIn) + usercontrol(OAuthIntegration; OAuthIntegration) { ApplicationArea = All; trigger AuthorizationCodeRetrieved(Code: Text) diff --git a/Apps/W1/Shopify/app/src/Order Fulfillments/Codeunits/ShpfyFulfillmentOrdersAPI.Codeunit.al b/Apps/W1/Shopify/app/src/Order Fulfillments/Codeunits/ShpfyFulfillmentOrdersAPI.Codeunit.al index 5128eb16de..f1586891ca 100644 --- a/Apps/W1/Shopify/app/src/Order Fulfillments/Codeunits/ShpfyFulfillmentOrdersAPI.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Order Fulfillments/Codeunits/ShpfyFulfillmentOrdersAPI.Codeunit.al @@ -101,13 +101,15 @@ codeunit 30238 "Shpfy Fulfillment Orders API" var JFulfillmentOrders: JsonArray; JItem: JsonToken; + JObject: JsonObject; begin - if JsonHelper.GetJsonArray(JResponse, JFulfillmentOrders, 'data.order.fulfillmentOrders.edges') then begin - foreach JItem in JFulfillmentOrders do - ExtractFulfillmentOrder(ShopifyShop, JItem, Cursor); + if JsonHelper.GetJsonObject(JResponse, JObject, 'data.order') then + if JsonHelper.GetJsonArray(JResponse, JFulfillmentOrders, 'data.order.fulfillmentOrders.edges') then begin + foreach JItem in JFulfillmentOrders do + ExtractFulfillmentOrder(ShopifyShop, JItem, Cursor); - exit(true); - end; + exit(true); + end; end; internal procedure ExtractFulfillmentOrder(var ShopifyShop: Record "Shpfy Shop"; JFulfillmentOrder: JsonToken; var Cursor: Text) diff --git a/Apps/W1/Shopify/app/src/Order Refunds/Codeunits/ShpfyRefundsAPI.Codeunit.al b/Apps/W1/Shopify/app/src/Order Refunds/Codeunits/ShpfyRefundsAPI.Codeunit.al index dc4c20f135..42278a3741 100644 --- a/Apps/W1/Shopify/app/src/Order Refunds/Codeunits/ShpfyRefundsAPI.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Order Refunds/Codeunits/ShpfyRefundsAPI.Codeunit.al @@ -6,6 +6,7 @@ codeunit 30228 "Shpfy Refunds API" CommunicationMgt: Codeunit "Shpfy Communication Mgt."; JsonHelper: Codeunit "Shpfy Json Helper"; RefundEnumConvertor: Codeunit "Shpfy Refund Enum Convertor"; + RefundCantCreateCreditMemoErr: Label 'The refund imported from Shopify can''t be used to create a credit memo. Only refunds for paid items can be used to create credit memos.'; internal procedure GetRefunds(JRefunds: JsonArray) var @@ -15,15 +16,26 @@ codeunit 30228 "Shpfy Refunds API" GetRefund(JsonHelper.GetValueAsBigInteger(JRefund, 'legacyResourceId'), JsonHelper.GetValueAsDateTime(JRefund, 'updatedAt')); end; + internal procedure VerifyRefundCanCreateCreditMemo(RefundId: BigInteger) + var + RefundLine: Record "Shpfy Refund Line"; + begin + RefundLine.SetRange("Refund Id", RefundId); + RefundLine.SetRange("Can Create Credit Memo", false); + if not RefundLine.IsEmpty() then + Error(RefundCantCreateCreditMemoErr); + end; + local procedure GetRefund(RefundId: BigInteger; UpdatedAt: DateTime) var + RefundHeader: Record "Shpfy Refund Header"; GraphQLType: Enum "Shpfy GraphQL Type"; Parameters: Dictionary of [text, Text]; JResponse: JsonToken; JLines: JsonArray; JLine: JsonToken; begin - GetRefundHeader(RefundId, UpdatedAt); + GetRefundHeader(RefundId, UpdatedAt, RefundHeader); Parameters.Add('RefundId', Format(RefundId)); GraphQLType := "Shpfy GraphQL Type"::GetRefundLines; repeat @@ -35,14 +47,13 @@ codeunit 30228 "Shpfy Refunds API" else Parameters.Add('After', JsonHelper.GetValueAsText(JResponse, 'data.refund.refundLineItems.pageInfo.endCursor')); foreach JLine in JLines do - FillInRefundLine(RefundId, JLine.AsObject()); + FillInRefundLine(RefundId, JLine.AsObject(), RefundHeader."Total Refunded Amount" > 0); until not JsonHelper.GetValueAsBoolean(JResponse, 'data.refund.refundLineItems.pageInfo.hasNextPage'); end; - local procedure GetRefundHeader(RefundId: BigInteger; UpdatedAt: DateTime) + local procedure GetRefundHeader(RefundId: BigInteger; UpdatedAt: DateTime; var RefundHeader: Record "Shpfy Refund Header") var DataCapture: Record "Shpfy Data Capture"; - RefundHeader: Record "Shpfy Refund Header"; RefundHeaderRecordRef: RecordRef; IsNew: Boolean; Parameters: Dictionary of [Text, Text]; @@ -72,11 +83,12 @@ codeunit 30228 "Shpfy Refunds API" JsonHelper.GetValueIntoField(JRefund, 'totalRefundedSet.shopMoney.amount', RefundHeaderRecordRef, RefundHeader.FieldNo("Total Refunded Amount")); JsonHelper.GetValueIntoField(JRefund, 'totalRefundedSet.presentmentMoney.amount', RefundHeaderRecordRef, RefundHeader.FieldNo("Pres. Tot. Refunded Amount")); RefundHeaderRecordRef.Modify(); + RefundHeaderRecordRef.SetTable(RefundHeader); RefundHeaderRecordRef.Close(); DataCapture.Add(Database::"Shpfy Refund Header", RefundHeader.SystemId, JResponse); end; - local procedure FillInRefundLine(RefundId: BigInteger; JLine: JsonObject) + local procedure FillInRefundLine(RefundId: BigInteger; JLine: JsonObject; NonZeroRefund: Boolean) var DataCapture: Record "Shpfy Data Capture"; RefundLine: Record "Shpfy Refund Line"; @@ -100,8 +112,23 @@ codeunit 30228 "Shpfy Refunds API" JsonHelper.GetValueIntoField(JLine, 'subtotalSet.presentmentMoney.amount', RefundLineRecordRef, RefundLine.FieldNo("Presentment Subtotal Amount")); JsonHelper.GetValueIntoField(JLine, 'totalTaxSet.shopMoney.amount', RefundLineRecordRef, RefundLine.FieldNo("Total Tax Amount")); JsonHelper.GetValueIntoField(JLine, 'totalTaxSet.presentmentMoney.amount', RefundLineRecordRef, RefundLine.FieldNo("Presentment Total Tax Amount")); - RefundLineRecordRef.Modify(); + RefundLineRecordRef.SetTable(RefundLine); + RefundLine."Can Create Credit Memo" := CanRefundCreateCreditMemo(RefundLine, NonZeroRefund); + RefundLine.Modify(); RefundLineRecordRef.Close(); DataCapture.Add(Database::"Shpfy Refund Line", RefundLine.SystemId, JLine); end; + + local procedure CanRefundCreateCreditMemo(RefundLine: Record "Shpfy Refund Line"; NonZeroRefund: Boolean): Boolean + begin + case RefundLine."Restock Type" of + RefundLine."Restock Type"::Cancel: + exit(false); + RefundLine."Restock Type"::Return, + RefundLine."Restock Type"::"Legacy Restock": + exit(true); + RefundLine."Restock Type"::"No Restock": + exit(NonZeroRefund); + end; + end; } \ No newline at end of file diff --git a/Apps/W1/Shopify/app/src/Order Refunds/Pages/ShpfyRefund.Page.al b/Apps/W1/Shopify/app/src/Order Refunds/Pages/ShpfyRefund.Page.al index fdd1aeb0d4..a7ffbcc7c3 100644 --- a/Apps/W1/Shopify/app/src/Order Refunds/Pages/ShpfyRefund.Page.al +++ b/Apps/W1/Shopify/app/src/Order Refunds/Pages/ShpfyRefund.Page.al @@ -127,9 +127,11 @@ page 30145 "Shpfy Refund" trigger OnAction() var + RefundsAPI: Codeunit "Shpfy Refunds API"; IReturnRefundProcess: Interface "Shpfy IReturnRefund Process"; ErrorInfo: ErrorInfo; begin + RefundsAPI.VerifyRefundCanCreateCreditMemo(Rec."Refund Id"); IReturnRefundProcess := "Shpfy ReturnRefund ProcessType"::"Auto Create Credit Memo"; if IReturnRefundProcess.CanCreateSalesDocumentFor("Shpfy Source Document Type"::Refund, Rec."Refund Id", ErrorInfo) then IReturnRefundProcess.CreateSalesDocument("Shpfy Source Document Type"::Refund, Rec."Refund Id") diff --git a/Apps/W1/Shopify/app/src/Order Refunds/Pages/ShpfyRefunds.Page.al b/Apps/W1/Shopify/app/src/Order Refunds/Pages/ShpfyRefunds.Page.al index 7ef1c7252d..44e56c2655 100644 --- a/Apps/W1/Shopify/app/src/Order Refunds/Pages/ShpfyRefunds.Page.al +++ b/Apps/W1/Shopify/app/src/Order Refunds/Pages/ShpfyRefunds.Page.al @@ -97,9 +97,11 @@ page 30147 "Shpfy Refunds" trigger OnAction() var + RefundsAPI: Codeunit "Shpfy Refunds API"; IReturnRefundProcess: Interface "Shpfy IReturnRefund Process"; ErrorInfo: ErrorInfo; begin + RefundsAPI.VerifyRefundCanCreateCreditMemo(Rec."Refund Id"); IReturnRefundProcess := "Shpfy ReturnRefund ProcessType"::"Auto Create Credit Memo"; if IReturnRefundProcess.CanCreateSalesDocumentFor("Shpfy Source Document Type"::Refund, Rec."Refund Id", ErrorInfo) then IReturnRefundProcess.CreateSalesDocument("Shpfy Source Document Type"::Refund, Rec."Refund Id") diff --git a/Apps/W1/Shopify/app/src/Order Refunds/Tables/ShpfyRefundLine.Table.al b/Apps/W1/Shopify/app/src/Order Refunds/Tables/ShpfyRefundLine.Table.al index bbaa86f0c5..65d2030dfc 100644 --- a/Apps/W1/Shopify/app/src/Order Refunds/Tables/ShpfyRefundLine.Table.al +++ b/Apps/W1/Shopify/app/src/Order Refunds/Tables/ShpfyRefundLine.Table.al @@ -81,6 +81,12 @@ table 30145 "Shpfy Refund Line" DataClassification = SystemMetadata; Editable = false; } + field(13; "Can Create Credit Memo"; Boolean) + { + Caption = 'Can Create Credit Memo'; + DataClassification = SystemMetadata; + Editable = false; + } field(101; "Item No."; Code[20]) { Caption = 'Item No.'; diff --git a/Apps/W1/Shopify/app/src/Order Return Refund Processing/Codeunits/ShpfyRetRefProcCrMemo.Codeunit.al b/Apps/W1/Shopify/app/src/Order Return Refund Processing/Codeunits/ShpfyRetRefProcCrMemo.Codeunit.al index cc3bd26317..593a587eb3 100644 --- a/Apps/W1/Shopify/app/src/Order Return Refund Processing/Codeunits/ShpfyRetRefProcCrMemo.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Order Return Refund Processing/Codeunits/ShpfyRetRefProcCrMemo.Codeunit.al @@ -57,6 +57,7 @@ codeunit 30243 "Shpfy RetRefProc Cr.Memo" implements "Shpfy IReturnRefund Proces procedure CreateSalesDocument(SourceDocumentType: Enum "Shpfy Source Document Type"; SourceDocumentId: BigInteger) SalesHeader: Record "Sales Header" var + RefundLine: Record "Shpfy Refund Line"; CreateSalesDocRefund: codeunit "Shpfy Create Sales Doc. Refund"; IDocumentSource: Interface "Shpfy IDocument Source"; ErrorInfo: ErrorInfo; @@ -71,6 +72,10 @@ codeunit 30243 "Shpfy RetRefProc Cr.Memo" implements "Shpfy IReturnRefund Proces IDocumentSource.SetErrorInfo(SourceDocumentId, TextBuilder.ToText()); exit; end; + RefundLine.SetRange("Refund Id", SourceDocumentId); + RefundLine.SetRange("Can Create Credit Memo", false); + if not RefundLine.IsEmpty() then + exit; CreateSalesDocRefund.SetSource(SourceDocumentId); CreateSalesDocRefund.SetTargetDocumentType(SalesHeader."Document Type"::"Credit Memo"); diff --git a/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyImportOrder.Codeunit.al b/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyImportOrder.Codeunit.al index f841f2dc03..625108d13b 100644 --- a/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyImportOrder.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyImportOrder.Codeunit.al @@ -70,6 +70,12 @@ codeunit 30161 "Shpfy Import Order" OrderEvents: Codeunit "Shpfy Order Events"; OrderFulfillments: Codeunit "Shpfy Order Fulfillments"; ProcessedConflictErr: Label 'The order has already been processed in Business Central, but an edition was received from Shopify. Changes were not propagated to the processed order. Update the processed documents to ensure data consistency.'; + OrderHeaderTotalAmountPathTok: Label 'totalPriceSet.shopMoney.amount', Locked = true; + OrderHeaderPresentmentTotalAmountPathTok: Label 'totalPriceSet.presentmentMoney.amount', Locked = true; + OrderHeaderSubtotalAmountPathTok: Label 'subtotalPriceSet.shopMoney.amount', Locked = true; + OrderHeaderPresentmentSubtotalAmountPathTok: Label 'subtotalPriceSet.presentmentMoney.amount', Locked = true; + OrderHeaderVATAmountPathTok: Label 'totalTaxSet.shopMoney.amount', Locked = true; + OrderHeaderPresentmentVATAmountPathTok: Label 'totalTaxSet.presentmentMoney.amount', Locked = true; local procedure ImportOrderAndCreateOrUpdate(ShopCode: Code[20]; OrderId: BigInteger; SkipIfConclicting: Boolean) @@ -86,14 +92,16 @@ codeunit 30161 "Shpfy Import Order" exit; UpdatingOrderHeader := EnsureOrderHeaderExists(OrderId, ShopCode, OrderHeader); - if UpdatingOrderHeader and SkipIfConclicting and OrderHeader.IsProcessed() then begin - SetOrderAsConflicting(OrderHeader); - exit; - end; if not RetrieveOrderHeaderJson(OrderId, OrderHeader.SystemId, JOrder) then exit; + if UpdatingOrderHeader and SkipIfConclicting and OrderHeader.IsProcessed() then + if IsImportedOrderConflictingExistingOrder(JOrder, OrderHeader) then begin + SetOrderAsConflicting(OrderHeader); + exit; + end; + if not SetOrderHeaderValuesFromJson(JOrder, UpdatingOrderHeader, OrderHeader) then exit; SetAndCreateRelatedRecords(JOrder, OrderHeader); @@ -103,6 +111,10 @@ codeunit 30161 "Shpfy Import Order" OrderLine.DeleteAll(); RetrieveAndSetOrderLines(OrderId, OrderLine, true); OrderFulfillments.GetFulfillments(Shop, OrderHeader."Shopify Order Id"); + + ConsiderRefundsInQuantityAndAmounts(OrderHeader); + DeleteZeroQuantityLines(OrderHeader); + if CheckToCloseOrder(OrderHeader) then CloseOrder(OrderHeader); end; @@ -117,6 +129,93 @@ codeunit 30161 "Shpfy Import Order" exit(false); end; + local procedure DeleteZeroQuantityLines(OrderHeader: Record "Shpfy Order Header") + var + OrderLine: Record "Shpfy Order Line"; + begin + OrderLine.SetRange("Shopify Order Id", OrderHeader."Shopify Order Id"); + OrderLine.SetRange(Quantity, 0); + OrderLine.DeleteAll(); + end; + + local procedure ConsiderRefundsInQuantityAndAmounts(OrderHeader: Record "Shpfy Order Header") + var + OrderLine: Record "Shpfy Order Line"; + RefundLine: Record "Shpfy Refund Line"; + IReturnRefundProcess: Interface "Shpfy IReturnRefund Process"; + begin + IReturnRefundProcess := Shop."Return and Refund Process"; + if not IReturnRefundProcess.IsImportNeededFor("Shpfy Source Document Type"::Refund) then + exit; + OrderLine.SetRange("Shopify Order Id", OrderHeader."Shopify Order Id"); + if not OrderLine.FindSet() then + exit; + repeat + Clear(RefundLine); + RefundLine.SetRange("Order Line Id", OrderLine."Line Id"); + RefundLine.SetRange("Can Create Credit Memo", false); + RefundLine.CalcSums("Presentment Amount", Amount, "Subtotal Amount", "Presentment Total Tax Amount", Quantity); + OrderLine.Quantity -= RefundLine.Quantity; + OrderLine.Modify(); + OrderHeader."Total Amount" -= RefundLine."Subtotal Amount"; + OrderHeader."Subtotal Amount" -= RefundLine."Subtotal Amount"; + OrderHeader."Presentment Total Amount" -= RefundLine."Presentment Subtotal Amount"; + OrderHeader."Presentment Subtotal Amount" -= RefundLine."Presentment Subtotal Amount"; + OrderHeader."VAT Amount" -= RefundLine."Total Tax Amount"; + OrderHeader."Presentment VAT Amount" -= RefundLine."Presentment Total Tax Amount"; + until OrderLine.Next() = 0; + OrderHeader.Modify(); + end; + + local procedure UpdateOrderHeaderToValuesWithoutRefunds(var OrderHeader: Record "Shpfy Order Header") + var + OrderLine: Record "Shpfy Order Line"; + RefundLine: Record "Shpfy Refund Line"; + IReturnRefundProcess: Interface "Shpfy IReturnRefund Process"; + begin + IReturnRefundProcess := Shop."Return and Refund Process"; + if not IReturnRefundProcess.IsImportNeededFor("Shpfy Source Document Type"::Refund) then + exit; + OrderLine.SetRange("Shopify Order Id", OrderHeader."Shopify Order Id"); + if not OrderLine.FindSet() then + exit; + repeat + RefundLine.SetRange("Order Line Id", OrderLine."Line Id"); + RefundLine.SetRange("Can Create Credit Memo", false); + RefundLine.CalcSums("Presentment Amount", Amount, "Subtotal Amount", "Presentment Total Tax Amount", Quantity); + OrderHeader."Total Amount" += RefundLine."Subtotal Amount"; + OrderHeader."Subtotal Amount" += RefundLine."Subtotal Amount"; + OrderHeader."Presentment Total Amount" += RefundLine."Presentment Subtotal Amount"; + OrderHeader."Presentment Subtotal Amount" += RefundLine."Presentment Subtotal Amount"; + OrderHeader."VAT Amount" += RefundLine."Total Tax Amount"; + OrderHeader."Presentment VAT Amount" += RefundLine."Presentment Total Tax Amount"; + until OrderLine.Next() = 0; + end; + + local procedure IsImportedOrderConflictingExistingOrder(JOrder: JsonObject; OrderHeader: Record "Shpfy Order Header"): Boolean + begin + UpdateOrderHeaderToValuesWithoutRefunds(OrderHeader); + if OrderHeader."Total Amount" <> JsonHelper.GetValueAsDecimal(JOrder, OrderHeaderTotalAmountPathTok) then + exit(true); + + if OrderHeader."Presentment Total Amount" <> JsonHelper.GetValueAsDecimal(JOrder, OrderHeaderPresentmentTotalAmountPathTok) then + exit(true); + + if OrderHeader."Subtotal Amount" <> JsonHelper.GetValueAsDecimal(JOrder, OrderHeaderSubtotalAmountPathTok) then + exit(true); + + if OrderHeader."Presentment Subtotal Amount" <> JsonHelper.GetValueAsDecimal(JOrder, OrderHeaderPresentmentSubtotalAmountPathTok) then + exit(true); + + if OrderHeader."VAT Amount" <> JsonHelper.GetValueAsDecimal(JOrder, OrderHeaderVATAmountPathTok) then + exit(true); + + if OrderHeader."Presentment VAT Amount" <> JsonHelper.GetValueAsDecimal(JOrder, OrderHeaderPresentmentVATAmountPathTok) then + exit(true); + + exit(false); + end; + local procedure SetAndCreateRelatedRecords(JOrder: JsonObject; var OrderHeader: Record "Shpfy Order Header") var FulfillmentOrdersAPI: Codeunit "Shpfy Fulfillment Orders API"; @@ -357,14 +456,14 @@ codeunit 30161 "Shpfy Import Order" JsonHelper.GetValueIntoField(JOrder, 'totalWeight', OrderHeaderRecordRef, OrderHeader.FieldNo("Total Weight")); JsonHelper.GetValueIntoField(JOrder, 'refundable', OrderHeaderRecordRef, OrderHeader.FieldNo(Refundable)); JsonHelper.GetValueIntoField(JOrder, 'taxesIncluded', OrderHeaderRecordRef, OrderHeader.FieldNo("VAT Included")); - JsonHelper.GetValueIntoField(JOrder, 'totalPriceSet.shopMoney.amount', OrderHeaderRecordRef, OrderHeader.FieldNo("Total Amount")); - JsonHelper.GetValueIntoField(JOrder, 'totalPriceSet.presentmentMoney.amount', OrderHeaderRecordRef, OrderHeader.FieldNo("Presentment Total Amount")); - JsonHelper.GetValueIntoField(JOrder, 'subtotalPriceSet.shopMoney.amount', OrderHeaderRecordRef, OrderHeader.FieldNo("Subtotal Amount")); - JsonHelper.GetValueIntoField(JOrder, 'subtotalPriceSet.presentmentMoney.amount', OrderHeaderRecordRef, OrderHeader.FieldNo("Presentment Subtotal Amount")); + JsonHelper.GetValueIntoField(JOrder, OrderHeaderTotalAmountPathTok, OrderHeaderRecordRef, OrderHeader.FieldNo("Total Amount")); + JsonHelper.GetValueIntoField(JOrder, OrderHeaderPresentmentTotalAmountPathTok, OrderHeaderRecordRef, OrderHeader.FieldNo("Presentment Total Amount")); + JsonHelper.GetValueIntoField(JOrder, OrderHeaderSubtotalAmountPathTok, OrderHeaderRecordRef, OrderHeader.FieldNo("Subtotal Amount")); + JsonHelper.GetValueIntoField(JOrder, OrderHeaderPresentmentSubtotalAmountPathTok, OrderHeaderRecordRef, OrderHeader.FieldNo("Presentment Subtotal Amount")); JsonHelper.GetValueIntoField(JOrder, 'totalTipReceivedSet.shopMoney.amount', OrderHeaderRecordRef, OrderHeader.FieldNo("Total Tip Received")); JsonHelper.GetValueIntoField(JOrder, 'totalTipReceivedSet.presentmentMoney.amount', OrderHeaderRecordRef, OrderHeader.FieldNo("Presentment Total Tip Received")); - JsonHelper.GetValueIntoField(JOrder, 'totalTaxSet.shopMoney.amount', OrderHeaderRecordRef, OrderHeader.FieldNo("VAT Amount")); - JsonHelper.GetValueIntoField(JOrder, 'totalTaxSet.presentmentMoney.amount', OrderHeaderRecordRef, OrderHeader.FieldNo("Presentment VAT Amount")); + JsonHelper.GetValueIntoField(JOrder, OrderHeaderVATAmountPathTok, OrderHeaderRecordRef, OrderHeader.FieldNo("VAT Amount")); + JsonHelper.GetValueIntoField(JOrder, OrderHeaderPresentmentVATAmountPathTok, OrderHeaderRecordRef, OrderHeader.FieldNo("Presentment VAT Amount")); JsonHelper.GetValueIntoField(JOrder, 'totalDiscountsSet.shopMoney.amount', OrderHeaderRecordRef, OrderHeader.FieldNo("Discount Amount")); JsonHelper.GetValueIntoField(JOrder, 'totalDiscountsSet.presentmentMoney.amount', OrderHeaderRecordRef, OrderHeader.FieldNo("Presentment Discount Amount")); JsonHelper.GetValueIntoField(JOrder, 'totalShippingPriceSet.shopMoney.amount', OrderHeaderRecordRef, OrderHeader.FieldNo("Shipping Charges Amount")); @@ -396,15 +495,9 @@ codeunit 30161 "Shpfy Import Order" local procedure SetOrderLineValuesFromJson(JOrderLine: JsonToken; OrderId: BigInteger; var OrderLine: Record "Shpfy Order Line"): Boolean var OrderLineRecordRef: RecordRef; - CurrentQuantity: Decimal; LineId: BigInteger; begin LineId := CommunicationMgt.GetIdOfGId(JsonHelper.GetValueAsText(JOrderLine, 'id')); - CurrentQuantity := JsonHelper.GetValueAsDecimal(JOrderLine, 'currentQuantity'); - - if CurrentQuantity = 0 then - exit(false); - OrderLine."Shopify Order Id" := OrderId; OrderLine."Line Id" := LineId; OrderLineRecordRef.GetTable(OrderLine); @@ -412,7 +505,7 @@ codeunit 30161 "Shpfy Import Order" OrderLineRecordRef.Field(OrderLine.FieldNo(Tip)).Value := true; JsonHelper.GetValueIntoField(JOrderLine, 'product.legacyResourceId', OrderLineRecordRef, OrderLine.FieldNo("Shopify Product Id")); JsonHelper.GetValueIntoField(JOrderLine, 'title', OrderLineRecordRef, OrderLine.FieldNo(Description)); - JsonHelper.GetValueIntoField(JOrderLine, 'currentQuantity', OrderLineRecordRef, OrderLine.FieldNo(Quantity)); + JsonHelper.GetValueIntoField(JOrderLine, 'quantity', OrderLineRecordRef, OrderLine.FieldNo(Quantity)); JsonHelper.GetValueIntoField(JOrderLine, 'variant.legacyResourceId', OrderLineRecordRef, OrderLine.FieldNo("Shopify Variant Id")); JsonHelper.GetValueIntoField(JOrderLine, 'variantTitle', OrderLineRecordRef, OrderLine.FieldNo("Variant Description")); JsonHelper.GetValueIntoField(JOrderLine, 'fulfillmentService.location.legacyResourceId', OrderLineRecordRef, OrderLine.FieldNo("Location Id")); @@ -493,7 +586,12 @@ codeunit 30161 "Shpfy Import Order" Clear(OrderAttribute); OrderAttribute."Order Id" := ShopifyOrderId; OrderAttribute.Key := CopyStr(JsonHelper.GetValueAsText(JToken, 'key', MaxStrLen(OrderAttribute."Key")), 1, MaxStrLen(OrderAttribute."Key")); - OrderAttribute."Attribute Value" := CopyStr(JsonHelper.GetValueAsText(JToken, 'value', MaxStrLen(OrderAttribute."Attribute Value")), 1, MaxStrLen(OrderAttribute."Attribute Value")); +#if not CLEAN24 + if not Shop."Replace Order Attribute Value" then + OrderAttribute.Value := CopyStr(JsonHelper.GetValueAsText(JToken, 'value', MaxStrLen(OrderAttribute.Value)), 1, MaxStrLen(OrderAttribute.Value)) + else +#endif + OrderAttribute."Attribute Value" := CopyStr(JsonHelper.GetValueAsText(JToken, 'value', MaxStrLen(OrderAttribute."Attribute Value")), 1, MaxStrLen(OrderAttribute."Attribute Value")); OrderAttribute.Insert(); end; end; @@ -501,19 +599,19 @@ codeunit 30161 "Shpfy Import Order" [NonDebuggable] local procedure ImportCustomAttributtes(ShopifyOrderId: BigInteger; OrderLineId: Guid; JCustomAttributtes: JsonArray) var - OrderAttribute: Record "Shpfy Order Line Attribute"; + OrderLineAttribute: Record "Shpfy Order Line Attribute"; JToken: JsonToken; begin - OrderAttribute.SetRange("Order Id", ShopifyOrderId); - if not OrderAttribute.IsEmpty then - OrderAttribute.DeleteAll(); + OrderLineAttribute.SetRange("Order Id", ShopifyOrderId); + if not OrderLineAttribute.IsEmpty then + OrderLineAttribute.DeleteAll(); foreach JToken in JCustomAttributtes do begin - Clear(OrderAttribute); - OrderAttribute."Order Id" := ShopifyOrderId; - OrderAttribute."Order Line Id" := OrderLineId; - OrderAttribute.Key := JsonHelper.GetValueAsText(JToken, 'key', MaxStrLen(OrderAttribute."Key")); - OrderAttribute.Value := JsonHelper.GetValueAsText(JToken, 'value', MaxStrLen(OrderAttribute.Value)); - OrderAttribute.Insert(); + Clear(OrderLineAttribute); + OrderLineAttribute."Order Id" := ShopifyOrderId; + OrderLineAttribute."Order Line Id" := OrderLineId; + OrderLineAttribute.Key := JsonHelper.GetValueAsText(JToken, 'key', MaxStrLen(OrderLineAttribute."Key")); + OrderLineAttribute.Value := JsonHelper.GetValueAsText(JToken, 'value', MaxStrLen(OrderLineAttribute.Value)); + OrderLineAttribute.Insert(); end; end; diff --git a/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyOrdersAPI.Codeunit.al b/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyOrdersAPI.Codeunit.al index 419ffc8548..a338f546b9 100644 --- a/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyOrdersAPI.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyOrdersAPI.Codeunit.al @@ -72,7 +72,12 @@ codeunit 30165 "Shpfy Orders API" /// /// Parameter of type BigInteger. /// Parameter of type JsonArray. +#if not CLEAN24 + /// Parameter of type Record "Shpfy Shop". + local procedure UpdateOrderAttributes(OrderId: BigInteger; JAttributes: JsonArray; ShopifyShop: Record "Shpfy Shop") +#else local procedure UpdateOrderAttributes(OrderId: BigInteger; JAttributes: JsonArray) +#endif var OrderAttribute: Record "Shpfy Order Attribute"; JItem: JsonToken; @@ -87,7 +92,12 @@ codeunit 30165 "Shpfy Orders API" #pragma warning disable AA0139 OrderAttribute."Key" := JsonHelper.GetValueAsText(JItem, 'key', MaxStrLen(OrderAttribute."Key")); #pragma warning restore AA0139 - OrderAttribute."Attribute Value" := CopyStr(JsonHelper.GetValueAsText(JItem, 'value').Replace('\\', '\').Replace('\"', '"'), 1, MaxStrLen(OrderAttribute."Attribute Value")); +#if not CLEAN24 + if not ShopifyShop."Replace Order Attribute Value" then + OrderAttribute.Value := CopyStr(JsonHelper.GetValueAsText(JItem, 'value').Replace('\\', '\').Replace('\"', '"'), 1, MaxStrLen(OrderAttribute.Value)) + else +#endif + OrderAttribute."Attribute Value" := CopyStr(JsonHelper.GetValueAsText(JItem, 'value').Replace('\\', '\').Replace('\"', '"'), 1, MaxStrLen(OrderAttribute."Attribute Value")); OrderAttribute.Insert(); end; end; @@ -111,7 +121,12 @@ codeunit 30165 "Shpfy Orders API" Clear(OrderAttribute); OrderAttribute."Order Id" := OrderHeader."Shopify Order Id"; OrderAttribute."Key" := CopyStr(KeyName, 1, MaxStrLen(OrderAttribute."Key")); - OrderAttribute."Attribute Value" := CopyStr(Value, 1, MaxStrLen(OrderAttribute."Attribute Value")); +#if not CLEAN24 + if not Shop."Replace Order Attribute Value" then + OrderAttribute.Value := CopyStr(Value, 1, MaxStrLen(OrderAttribute.Value)) + else +#endif + OrderAttribute."Attribute Value" := CopyStr(Value, 1, MaxStrLen(OrderAttribute."Attribute Value")); if not OrderAttribute.Insert() then OrderAttribute.Modify(); @@ -121,7 +136,12 @@ codeunit 30165 "Shpfy Orders API" repeat Clear(JAttrib); JAttrib.Add('key', OrderAttribute."Key"); - JAttrib.Add('value', OrderAttribute."Attribute Value"); +#if not CLEAN24 + if not Shop."Replace Order Attribute Value" then + JAttrib.Add('value', OrderAttribute.Value) + else +#endif + JAttrib.Add('value', OrderAttribute."Attribute Value"); JAttributes.Add(JAttrib); until OrderAttribute.Next() = 0; @@ -229,7 +249,11 @@ codeunit 30165 "Shpfy Orders API" else OrdersToImport."Purchasing Entity" := OrdersToImport."Purchasing Entity"::Customer; if JsonHelper.GetJsonArray(JNode, JArray, 'customAttributes') then +#if not CLEAN24 + UpdateOrderAttributes(OrdersToImport.Id, JArray, ShopifyShop); +#else UpdateOrderAttributes(OrdersToImport.Id, JArray); +#endif if JsonHelper.GetJsonArray(JNode, JArray, 'tags') then begin Clear(Tags); foreach JLineItem in JArray do begin diff --git a/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyProcessOrder.Codeunit.al b/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyProcessOrder.Codeunit.al index 7718bfaa31..b7d7d5d83c 100644 --- a/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyProcessOrder.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyProcessOrder.Codeunit.al @@ -135,6 +135,7 @@ codeunit 30166 "Shpfy Process Order" if ShopifyOrderHeader."Work Description".HasValue then SalesHeader.SetWorkDescription(ShopifyOrderHeader.GetWorkDescription()); end; + OrdersAPI.SetShop(ShopifyShop); OrdersAPI.AddOrderAttribute(ShopifyOrderHeader, 'BC Doc. No.', SalesHeader."No."); DocLinkToBCDoc.Init(); DocLinkToBCDoc."Shopify Document Type" := "Shpfy Shop Document Type"::"Shopify Shop Order"; diff --git a/Apps/W1/Shopify/app/src/Order handling/Enums/ShpfyTrackingCompanies.Enum.al b/Apps/W1/Shopify/app/src/Order handling/Enums/ShpfyTrackingCompanies.Enum.al index f25b2bb6ca..9afecbb7f1 100644 --- a/Apps/W1/Shopify/app/src/Order handling/Enums/ShpfyTrackingCompanies.Enum.al +++ b/Apps/W1/Shopify/app/src/Order handling/Enums/ShpfyTrackingCompanies.Enum.al @@ -8,9 +8,8 @@ namespace Microsoft.Integration.Shopify; /// enum 30122 "Shpfy Tracking Companies" { - Access = Internal; Caption = 'Shopify Tracking Companies'; - Extensible = true; + Extensible = false; value(0; " ") { diff --git a/Apps/W1/Shopify/app/src/Order handling/Pages/ShpfyOrderAttributes.Page.al b/Apps/W1/Shopify/app/src/Order handling/Pages/ShpfyOrderAttributes.Page.al index ea35d1a8c9..9f3dc0f93b 100644 --- a/Apps/W1/Shopify/app/src/Order handling/Pages/ShpfyOrderAttributes.Page.al +++ b/Apps/W1/Shopify/app/src/Order handling/Pages/ShpfyOrderAttributes.Page.al @@ -27,8 +27,8 @@ page 30114 "Shpfy Order Attributes" { ApplicationArea = All; ToolTip = 'Specifies the value of the attribute.'; - Visible = false; - ObsoleteReason = 'Replace with "Attribute Value" field.'; + Visible = not ReplaceOrderAtributeValueEnabled; + ObsoleteReason = 'Replaced with "Attribute Value" field.'; ObsoleteState = Pending; ObsoleteTag = '24.0'; } @@ -37,9 +37,33 @@ page 30114 "Shpfy Order Attributes" { ApplicationArea = All; ToolTip = 'Specifies the value of the attribute.'; +#if not CLEAN24 + Visible = ReplaceOrderAtributeValueEnabled; +#endif } } } } +#if not CLEAN24 + trigger OnAfterGetRecord() + var + Shop: Record "Shpfy Shop"; + OrderHeader: Record "Shpfy Order Header"; + OrdersToImport: Record "Shpfy Orders To Import"; + begin + if OrderHeader.Get(Rec."Order Id") then + if Shop.Get(OrderHeader."Shop Code") then begin + ReplaceOrderAtributeValueEnabled := Shop."Replace Order Attribute Value"; + exit; + end; + OrdersToImport.SetRange(Id, Rec."Order Id"); + if OrdersToImport.FindFirst() then + if Shop.Get(OrdersToImport."Shop Code") then + ReplaceOrderAtributeValueEnabled := Shop."Replace Order Attribute Value"; + end; + + var + ReplaceOrderAtributeValueEnabled: Boolean; +#endif } diff --git a/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyPaymentTransType.Enum.al b/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyPaymentTransType.Enum.al index 6bfe10c3be..7b7bdc73ef 100644 --- a/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyPaymentTransType.Enum.al +++ b/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyPaymentTransType.Enum.al @@ -5,9 +5,8 @@ namespace Microsoft.Integration.Shopify; /// enum 30127 "Shpfy Payment Trans. Type" { - Access = Internal; Caption = 'Shopify Payment Transcation Type'; - Extensible = true; + Extensible = false; value(0; Unknown) { diff --git a/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyPayoutStatus.Enum.al b/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyPayoutStatus.Enum.al index f130473705..a97bd396e7 100644 --- a/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyPayoutStatus.Enum.al +++ b/Apps/W1/Shopify/app/src/Payments/Enums/ShpfyPayoutStatus.Enum.al @@ -5,9 +5,8 @@ namespace Microsoft.Integration.Shopify; /// enum 30128 "Shpfy Payout Status" { - Access = Internal; - Caption = ' Payout Status'; - Extensible = true; + Caption = 'Payout Status'; + Extensible = false; value(0; Unknown) { diff --git a/Apps/W1/Shopify/app/src/Shipping/Codeunits/ShpfyShippingCharges.Codeunit.al b/Apps/W1/Shopify/app/src/Shipping/Codeunits/ShpfyShippingCharges.Codeunit.al index 8dbfb201e9..0119c566d3 100644 --- a/Apps/W1/Shopify/app/src/Shipping/Codeunits/ShpfyShippingCharges.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Shipping/Codeunits/ShpfyShippingCharges.Codeunit.al @@ -91,6 +91,7 @@ codeunit 30191 "Shpfy Shipping Charges" RecordRef.GetTable(OrderShippingCharges); JsonHelper.GetValueIntoField(JToken, 'title', RecordRef, OrderShippingCharges.FieldNo(Title)); JsonHelper.GetValueIntoField(JToken, 'code', RecordRef, OrderShippingCharges.FieldNo(Code)); + JsonHelper.GetValueIntoField(JToken, 'code', RecordRef, OrderShippingCharges.FieldNo("Code Value")); JsonHelper.GetValueIntoField(JToken, 'source', RecordRef, OrderShippingCharges.FieldNo(Source)); JsonHelper.GetValueIntoField(JToken, 'originalPriceSet.shopMoney.amount', RecordRef, OrderShippingCharges.FieldNo(Amount)); JsonHelper.GetValueIntoField(JToken, 'originalPriceSet.presentmentMoney.amount', RecordRef, OrderShippingCharges.FieldNo("Presentment Amount")); diff --git a/Apps/W1/Shopify/app/src/Shipping/Queries/ShpfyShipmentLocation.Query.al b/Apps/W1/Shopify/app/src/Shipping/Queries/ShpfyShipmentLocation.Query.al index 40fc9487c7..4acbe5c317 100644 --- a/Apps/W1/Shopify/app/src/Shipping/Queries/ShpfyShipmentLocation.Query.al +++ b/Apps/W1/Shopify/app/src/Shipping/Queries/ShpfyShipmentLocation.Query.al @@ -19,7 +19,6 @@ query 30100 "Shpfy Shipment Location" DataItemLink = "Document No." = SalesShipmentHeader."No."; DataItemTableFilter = Type = const(Item), Quantity = filter('>0'); SqlJoinType = InnerJoin; - column(Shpfy_Order_Line_Id; "Shpfy Order Line Id") { } dataitem(OrderLine; "Shpfy Order Line") { diff --git a/Apps/W1/Shopify/app/src/Shipping/Tables/ShpfyOrderShippingCharges.Table.al b/Apps/W1/Shopify/app/src/Shipping/Tables/ShpfyOrderShippingCharges.Table.al index af9c42d1b4..abf119098d 100644 --- a/Apps/W1/Shopify/app/src/Shipping/Tables/ShpfyOrderShippingCharges.Table.al +++ b/Apps/W1/Shopify/app/src/Shipping/Tables/ShpfyOrderShippingCharges.Table.al @@ -38,7 +38,7 @@ table 30130 "Shpfy Order Shipping Charges" } field(6; "Code"; Code[50]) { - Caption = 'Code'; + Caption = 'Code Preview'; DataClassification = SystemMetadata; } field(7; "Discount Amount"; Decimal) @@ -56,6 +56,11 @@ table 30130 "Shpfy Order Shipping Charges" Caption = 'Presentment Discount Amount'; DataClassification = SystemMetadata; } + field(10; "Code Value"; Text[2048]) + { + Caption = 'Code Value'; + DataClassification = SystemMetadata; + } } keys diff --git a/Apps/W1/Shopify/app/src/Transactions/Enums/ShpfyTransactionStatus.Enum.al b/Apps/W1/Shopify/app/src/Transactions/Enums/ShpfyTransactionStatus.Enum.al index 103a9dc4a1..7b90d1b5de 100644 --- a/Apps/W1/Shopify/app/src/Transactions/Enums/ShpfyTransactionStatus.Enum.al +++ b/Apps/W1/Shopify/app/src/Transactions/Enums/ShpfyTransactionStatus.Enum.al @@ -5,9 +5,8 @@ namespace Microsoft.Integration.Shopify; /// enum 30133 "Shpfy Transaction Status" { - Access = Internal; Caption = 'Shopify Transaction Status'; - Extensible = true; + Extensible = false; value(0; " ") { diff --git a/Apps/W1/Shopify/app/src/Transactions/Enums/ShpfyTransactionType.Enum.al b/Apps/W1/Shopify/app/src/Transactions/Enums/ShpfyTransactionType.Enum.al index e46c26b9d1..973a3d99d7 100644 --- a/Apps/W1/Shopify/app/src/Transactions/Enums/ShpfyTransactionType.Enum.al +++ b/Apps/W1/Shopify/app/src/Transactions/Enums/ShpfyTransactionType.Enum.al @@ -5,9 +5,8 @@ namespace Microsoft.Integration.Shopify; /// enum 30134 "Shpfy Transaction Type" { - Access = Internal; Caption = 'Shopify Transaction Type'; - Extensible = true; + Extensible = false; value(0; " ") { diff --git a/Apps/W1/Shopify/app/src/Transactions/Tables/ShpfyOrderTransaction.Table.al b/Apps/W1/Shopify/app/src/Transactions/Tables/ShpfyOrderTransaction.Table.al index 01d3fac639..989acc2559 100644 --- a/Apps/W1/Shopify/app/src/Transactions/Tables/ShpfyOrderTransaction.Table.al +++ b/Apps/W1/Shopify/app/src/Transactions/Tables/ShpfyOrderTransaction.Table.al @@ -32,7 +32,7 @@ table 30133 "Shpfy Order Transaction" DataClassification = SystemMetadata; Editable = false; } - field(4; Type; enum "Shpfy Transaction Type") + field(4; Type; Enum "Shpfy Transaction Type") { Caption = 'Type'; DataClassification = SystemMetadata; @@ -44,7 +44,7 @@ table 30133 "Shpfy Order Transaction" DataClassification = SystemMetadata; Editable = false; } - field(6; Status; enum "Shpfy Transaction Status") + field(6; Status; Enum "Shpfy Transaction Status") { Caption = 'Status'; DataClassification = SystemMetadata; diff --git a/Apps/W1/Shopify/test/Order Refunds/ShpfyOrderRefundsHelper.Codeunit.al b/Apps/W1/Shopify/test/Order Refunds/ShpfyOrderRefundsHelper.Codeunit.al index 1443ddc9f9..8abb79482b 100644 --- a/Apps/W1/Shopify/test/Order Refunds/ShpfyOrderRefundsHelper.Codeunit.al +++ b/Apps/W1/Shopify/test/Order Refunds/ShpfyOrderRefundsHelper.Codeunit.al @@ -207,6 +207,7 @@ codeunit 139564 "Shpfy Order Refunds Helper" RefundLine.Restocked := true; RefundLine.Amount := 156.38; RefundLine."Subtotal Amount" := 156.38; + RefundLine."Can Create Credit Memo" := true; RefundLine.Insert(); end; diff --git a/Apps/W1/Sustainability/app/app.json b/Apps/W1/Sustainability/app/app.json index e0121a9d4d..acaaf11937 100644 --- a/Apps/W1/Sustainability/app/app.json +++ b/Apps/W1/Sustainability/app/app.json @@ -12,7 +12,13 @@ "url": "https://go.microsoft.com/fwlink/?linkid=724011", "logo": "./ExtensionLogo.png", "dependencies": [], - "internalsVisibleTo": [], + "internalsVisibleTo": [ + { + "id": "6723f320-28a1-40cc-bf4d-d4dce362cb39", + "name": "Sustainability Tests", + "publisher": "Microsoft" + } + ], "screenshots": [], "platform": "24.0.0.0", "application": "24.0.0.0", diff --git a/Apps/W1/Sustainability/app/src/Account/CalculationFoundation.Enum.al b/Apps/W1/Sustainability/app/src/Account/CalculationFoundation.Enum.al index c53eded160..830c9bdb43 100644 --- a/Apps/W1/Sustainability/app/src/Account/CalculationFoundation.Enum.al +++ b/Apps/W1/Sustainability/app/src/Account/CalculationFoundation.Enum.al @@ -2,7 +2,6 @@ namespace Microsoft.Sustainability.Account; enum 6210 "Calculation Foundation" { - Access = Internal; Extensible = false; value(0; " ") { Caption = ' '; } diff --git a/Apps/W1/Sustainability/app/src/Account/ChartOfSustainAccounts.Page.al b/Apps/W1/Sustainability/app/src/Account/ChartOfSustainAccounts.Page.al index 1e3c263bdf..4f433f0fd7 100644 --- a/Apps/W1/Sustainability/app/src/Account/ChartOfSustainAccounts.Page.al +++ b/Apps/W1/Sustainability/app/src/Account/ChartOfSustainAccounts.Page.al @@ -3,6 +3,7 @@ namespace Microsoft.Sustainability.Account; using Microsoft.Finance.Dimension; using Microsoft.Sustainability.Journal; using Microsoft.Foundation.Comment; +using Microsoft.Sustainability.Reports; using Microsoft.Sustainability.Ledger; page 6210 "Chart of Sustain. Accounts" @@ -226,7 +227,7 @@ page 6210 "Chart of Sustain. Accounts" var SustainabilityAccountMgt: Codeunit "Sustainability Account Mgt."; begin - SustainabilityAccountMgt.IndentChartOfSustainabilityAccounts(); + SustainabilityAccountMgt.IndentChartOfSustainabilityAccounts(false); end; } } @@ -245,6 +246,27 @@ page 6210 "Chart of Sustain. Accounts" } area(reporting) { + action(TotalEmissions) + { + Caption = 'Total Emissions'; + RunObject = report "Total Emissions"; + Image = Report; + ToolTip = 'View the total emissions balance for the sustainability accounts that you specify.'; + } + action(EmissionByCategory) + { + Caption = 'Emission By Category'; + RunObject = report "Emission By Category"; + Image = Report; + ToolTip = 'View emissions details by category.'; + } + action(EmissionPerFacility) + { + Caption = 'Emission Per Facility'; + RunObject = report "Emission Per Facility"; + Image = Report; + ToolTip = 'View emissions details by responsibility center.'; + } } area(Promoted) { @@ -275,6 +297,9 @@ page 6210 "Chart of Sustain. Accounts" group(Category_Report) { Caption = 'Report'; + actionref(TotalEmissions_Promoted; TotalEmissions) { } + actionref(EmissionPerFacility_Promoted; EmissionPerFacility) { } + actionref(EmissionByCategory_Promoted; EmissionByCategory) { } } } } diff --git a/Apps/W1/Sustainability/app/src/Account/EmissionScope.Enum.al b/Apps/W1/Sustainability/app/src/Account/EmissionScope.Enum.al index 3bf56bf79d..f760b5ccde 100644 --- a/Apps/W1/Sustainability/app/src/Account/EmissionScope.Enum.al +++ b/Apps/W1/Sustainability/app/src/Account/EmissionScope.Enum.al @@ -2,7 +2,6 @@ namespace Microsoft.Sustainability.Account; enum 6212 "Emission Scope" { - Access = Internal; Extensible = false; value(0; " ") { Caption = ' '; } diff --git a/Apps/W1/Sustainability/app/src/Account/SustainAccountCategory.Table.al b/Apps/W1/Sustainability/app/src/Account/SustainAccountCategory.Table.al index af684bd311..5d7d33b71a 100644 --- a/Apps/W1/Sustainability/app/src/Account/SustainAccountCategory.Table.al +++ b/Apps/W1/Sustainability/app/src/Account/SustainAccountCategory.Table.al @@ -212,6 +212,6 @@ table 6211 "Sustain. Account Category" SustainabilityAccountMgt: Codeunit "Sustainability Account Mgt."; begin SustainabilityAccountMgt.CheckIfChangeAllowedForCategory(Code, FieldCaption); - SustainabilityAccountMgt.ReCalculateJournalLinesForCategory(Code); + SustainabilityAccountMgt.ReCalculateJournalLinesForCategory(Rec); end; } \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Account/SustainAccountSubcategory.Table.al b/Apps/W1/Sustainability/app/src/Account/SustainAccountSubcategory.Table.al index 2f7c6df333..06ee8adf76 100644 --- a/Apps/W1/Sustainability/app/src/Account/SustainAccountSubcategory.Table.al +++ b/Apps/W1/Sustainability/app/src/Account/SustainAccountSubcategory.Table.al @@ -1,5 +1,7 @@ namespace Microsoft.Sustainability.Account; +using Microsoft.Sustainability.Setup; + table 6212 "Sustain. Account Subcategory" { Caption = 'Sustainability Account Subcategory'; @@ -26,6 +28,8 @@ table 6212 "Sustain. Account Subcategory" } field(4; "Emission Factor CO2"; Decimal) { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); Caption = 'Emission Factor CO2'; trigger OnValidate() @@ -35,6 +39,8 @@ table 6212 "Sustain. Account Subcategory" } field(5; "Emission Factor CH4"; Decimal) { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); Caption = 'Emission Factor CH4'; trigger OnValidate() @@ -44,6 +50,8 @@ table 6212 "Sustain. Account Subcategory" } field(6; "Emission Factor N2O"; Decimal) { + AutoFormatType = 11; + AutoFormatExpression = SustainabilitySetup.GetFormat(SustainabilitySetup.FieldNo("Emission Decimal Places")); Caption = 'Emission Factor N2O'; trigger OnValidate() @@ -89,11 +97,14 @@ table 6212 "Sustain. Account Subcategory" TestField(Code); end; + var + SustainabilitySetup: Record "Sustainability Setup"; + local procedure CheckIfChangeAllowedAndRecalculateJournalLines(FieldCaption: Text) var SustainabilityAccountMgt: Codeunit "Sustainability Account Mgt."; begin SustainabilityAccountMgt.CheckIfChangeAllowedForSubcategory(Code, FieldCaption); - SustainabilityAccountMgt.ReCalculateJournalLinesForSubcategory(Code); + SustainabilityAccountMgt.ReCalculateJournalLinesForSubcategory(Rec); end; } \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Account/SustainabilityAccount.Table.al b/Apps/W1/Sustainability/app/src/Account/SustainabilityAccount.Table.al index c3945c9daa..a36f7c44e6 100644 --- a/Apps/W1/Sustainability/app/src/Account/SustainabilityAccount.Table.al +++ b/Apps/W1/Sustainability/app/src/Account/SustainabilityAccount.Table.al @@ -92,7 +92,13 @@ table 6210 "Sustainability Account" end; end; } - field(8; "Account Type"; Enum "Sustainability Account Type") + field(8; "Emission Scope"; Enum "Emission Scope") + { + Caption = 'Emission Scope'; + FieldClass = FlowField; + CalcFormula = lookup("Sustain. Account Category"."Emission Scope" where(Code = field(Category))); + } + field(9; "Account Type"; Enum "Sustainability Account Type") { Caption = 'Account Type'; trigger OnValidate() @@ -111,12 +117,12 @@ table 6210 "Sustainability Account" "Direct Posting" := false; end; } - field(9; Totaling; Text[250]) + field(10; Totaling; Text[250]) { Caption = 'Totaling'; trigger OnValidate() begin - if IsPosting() then + if IsPosting() and (Totaling <> '') then FieldError("Account Type"); CalcFields("Net Change (CO2)", "Balance at Date (CO2)", "Balance (CO2)", "Net Change (CH4)", "Balance at Date (CH4)", "Balance (CH4)", "Net Change (N2O)", "Balance at Date (N2O)", "Balance (N2O)"); end; @@ -130,21 +136,21 @@ table 6210 "Sustainability Account" Validate(Totaling, CopyStr(SustainAccountList.GetSelectionFilter(), 1, MaxStrLen(Totaling))); end; } - field(10; Blocked; Boolean) + field(11; Blocked; Boolean) { Caption = 'Blocked'; } - field(11; "Direct Posting"; Boolean) + field(12; "Direct Posting"; Boolean) { Caption = 'Direct Posting'; InitValue = true; } - field(12; Indentation; Integer) + field(13; Indentation; Integer) { Caption = 'Indentation'; Editable = false; } - field(13; "Global Dimension 1 Code"; Code[20]) + field(14; "Global Dimension 1 Code"; Code[20]) { CaptionClass = '1,1,1'; Caption = 'Global Dimension 1 Code'; @@ -154,7 +160,7 @@ table 6210 "Sustainability Account" ValidateShortcutDimCode(1, "Global Dimension 1 Code"); end; } - field(14; "Global Dimension 2 Code"; Code[20]) + field(15; "Global Dimension 2 Code"; Code[20]) { CaptionClass = '1,1,2'; Caption = 'Global Dimension 2 Code'; @@ -164,7 +170,7 @@ table 6210 "Sustainability Account" ValidateShortcutDimCode(2, "Global Dimension 2 Code"); end; } - field(15; Comment; Boolean) + field(16; Comment; Boolean) { CalcFormula = exist("Comment Line" where("Table Name" = const("Sustainability Account"), "No." = field("No."))); Caption = 'Comment'; @@ -347,8 +353,8 @@ table 6210 "Sustainability Account" fieldgroups { - fieldgroup(DropDown; "No.", Name, Blocked, "Direct Posting") { } - fieldgroup(Brick; "No.", Name, Blocked) { } + fieldgroup(DropDown; "No.", Name, "Emission Scope", Blocked, "Direct Posting") { } + fieldgroup(Brick; "No.", Name, "Emission Scope", Blocked) { } } trigger OnDelete() diff --git a/Apps/W1/Sustainability/app/src/Account/SustainabilityAccountList.Page.al b/Apps/W1/Sustainability/app/src/Account/SustainabilityAccountList.Page.al index 770132c2e6..5a1495c866 100644 --- a/Apps/W1/Sustainability/app/src/Account/SustainabilityAccountList.Page.al +++ b/Apps/W1/Sustainability/app/src/Account/SustainabilityAccountList.Page.al @@ -46,6 +46,11 @@ page 6212 "Sustainability Account List" { ToolTip = 'Specifies the subcategory of the category of the sustainability account.'; } + field("Emission Scope"; Rec."Emission Scope") + { + DrillDown = false; + ToolTip = 'Specifies the scope of the emissions that are associated with the sustainability account. Scope 1: Direct emissions from sources that are owned or controlled by the reporting entity. Scope 2: Indirect emissions from the generation of purchased electricity, heat, or steam consumed by the reporting entity. Scope 3: Other indirect emissions, such as the extraction and production of purchased materials and fuels, transport-related activities in vehicles not owned or controlled by the reporting entity, and waste disposal.'; + } field("Account Type"; Rec."Account Type") { ToolTip = 'Specifies the purpose of the account. Total: Used to total a series of balances on accounts from many different account groupings. To use Total, leave this field blank. Begin-Total: A marker for the beginning of a series of accounts to be totaled that ends with an End-Total account. End-Total: A total of a series of accounts that starts with the preceding Begin-Total account. The total is defined in the Totaling field.'; diff --git a/Apps/W1/Sustainability/app/src/Account/SustainabilityAccountMgt.Codeunit.al b/Apps/W1/Sustainability/app/src/Account/SustainabilityAccountMgt.Codeunit.al index 7946d480cc..eb3dd73ada 100644 --- a/Apps/W1/Sustainability/app/src/Account/SustainabilityAccountMgt.Codeunit.al +++ b/Apps/W1/Sustainability/app/src/Account/SustainabilityAccountMgt.Codeunit.al @@ -18,7 +18,7 @@ codeunit 6210 "Sustainability Account Mgt." ChangeCriticalSetupEvenThereAreTransactionQst: Label 'You are changing %1 field of %2 %3, which is already used in associated transactions.\\We recommend to create new %2 instead of modifying current one.\\Do you want to change the value?', Comment = '%1 - Field Caption, %2 - Table Caption %3 - Account No.'; ChangeAndUpdateJournalLinesQst: Label 'There are journal lines associated with %1. Do you want to continue and update them?', Comment = '%1 = Account No. or Category Code'; - procedure IndentChartOfSustainabilityAccounts() + procedure IndentChartOfSustainabilityAccounts(HideConfirmDialog: Boolean) var SustainAccount: Record "Sustainability Account"; ConfirmManagement: Codeunit "Confirm Management"; @@ -26,15 +26,18 @@ codeunit 6210 "Sustainability Account Mgt." AccNo: array[10] of Code[20]; Indentation: Integer; begin - if not ConfirmManagement.GetResponseOrDefault(SustainAccIndentQst, true) then - exit; + if not HideConfirmDialog then + if not ConfirmManagement.GetResponseOrDefault(SustainAccIndentQst, true) then + exit; - Window.Open(IndSustainAccountsTxt); + if GuiAllowed() then + Window.Open(IndSustainAccountsTxt); Indentation := 0; if SustainAccount.FindSet() then repeat - Window.Update(1, SustainAccount."No."); + if GuiAllowed() then + Window.Update(1, SustainAccount."No."); if SustainAccount."Account Type" = SustainAccount."Account Type"::"End-Total" then begin if Indentation < 1 then @@ -54,7 +57,8 @@ codeunit 6210 "Sustainability Account Mgt." end; until SustainAccount.Next() = 0; - Window.Close(); + if GuiAllowed() then + Window.Close(); end; procedure CheckIfChangeAllowedForAccount(AccountNo: Code[20]; FieldCaption: Text) @@ -120,38 +124,42 @@ codeunit 6210 "Sustainability Account Mgt." exit(false); end; - procedure ReCalculateJournalLinesForCategory(CategoryCode: Code[20]) + procedure ReCalculateJournalLinesForCategory(SustainAccountCategory: Record "Sustain. Account Category") var + SustainAccountSubcategory: Record "Sustain. Account Subcategory"; SustainabilityJnlLine: Record "Sustainability Jnl. Line"; SustainabilityCalcMgt: Codeunit "Sustainability Calc. Mgt."; begin - SustainabilityJnlLine.SetRange("Account Category", CategoryCode); + SustainabilityJnlLine.SetRange("Account Category", SustainAccountCategory.Code); if not SustainabilityJnlLine.IsEmpty() then - if not Dialog.Confirm(StrSubstNo(ChangeAndUpdateJournalLinesQst, CategoryCode), false) then + if not Dialog.Confirm(StrSubstNo(ChangeAndUpdateJournalLinesQst, SustainAccountCategory.Code), false) then Error('') else if SustainabilityJnlLine.FindSet() then repeat - SustainabilityCalcMgt.CalculationEmissions(SustainabilityJnlLine); + SustainAccountSubcategory.Get(SustainAccountCategory.Code, SustainabilityJnlLine."Account Subcategory"); + SustainabilityCalcMgt.CalculationEmissions(SustainabilityJnlLine, SustainAccountCategory, SustainAccountSubcategory); SustainabilityJnlLine.Modify(true); until SustainabilityJnlLine.Next() = 0; end; - procedure ReCalculateJournalLinesForSubcategory(SubcategoryCode: Code[20]) + procedure ReCalculateJournalLinesForSubcategory(SustainAccountSubcategory: Record "Sustain. Account Subcategory") var + SustainAccountCategory: Record "Sustain. Account Category"; SustainabilityJnlLine: Record "Sustainability Jnl. Line"; SustainabilityCalcMgt: Codeunit "Sustainability Calc. Mgt."; begin - SustainabilityJnlLine.SetRange("Account Subcategory", SubcategoryCode); + SustainabilityJnlLine.SetRange("Account Subcategory", SustainAccountSubcategory.Code); if not SustainabilityJnlLine.IsEmpty() then - if not Dialog.Confirm(StrSubstNo(ChangeAndUpdateJournalLinesQst, SubcategoryCode), false) then + if not Dialog.Confirm(StrSubstNo(ChangeAndUpdateJournalLinesQst, SustainAccountSubcategory.Code), false) then Error('') else if SustainabilityJnlLine.FindSet() then repeat - SustainabilityCalcMgt.CalculationEmissions(SustainabilityJnlLine); + SustainAccountCategory.Get(SustainabilityJnlLine."Account Category"); + SustainabilityCalcMgt.CalculationEmissions(SustainabilityJnlLine, SustainAccountCategory, SustainAccountSubcategory); SustainabilityJnlLine.Modify(true); until SustainabilityJnlLine.Next() = 0; end; diff --git a/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al b/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al index d0bd9e810e..19d5086062 100644 --- a/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al +++ b/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalcMgt.Codeunit.al @@ -7,7 +7,6 @@ using Microsoft.Finance.GeneralLedger.Ledger; codeunit 6218 "Sustainability Calc. Mgt." { Access = Internal; - Permissions = tabledata "Sustainability Jnl. Line" = r; var FromToFilterLbl: Label '%1..%2', Locked = true; @@ -15,16 +14,19 @@ codeunit 6218 "Sustainability Calc. Mgt." procedure CalculationEmissions(var SustainabilityJnlLine: Record "Sustainability Jnl. Line") var SustainAccountCategory: Record "Sustain. Account Category"; - SustainabilityCalculation: Codeunit "Sustainability Calculation"; + SustainAccountSubcategory: Record "Sustain. Account Subcategory"; begin - if SustainabilityJnlLine."Manual Input" then - exit; + SustainAccountCategory.Get(SustainabilityJnlLine."Account Category"); + SustainAccountSubcategory.Get(SustainabilityJnlLine."Account Category", SustainabilityJnlLine."Account Subcategory"); - SustainabilityJnlLine.Validate("Emission CO2", 0); - SustainabilityJnlLine.Validate("Emission CH4", 0); - SustainabilityJnlLine.Validate("Emission N2O", 0); + CalculationEmissions(SustainabilityJnlLine, SustainAccountCategory, SustainAccountSubcategory); + end; - if not SustainAccountCategory.Get(SustainabilityJnlLine."Account Category") then + procedure CalculationEmissions(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; SustainAccountCategory: Record "Sustain. Account Category"; SustainAccountSubcategory: Record "Sustain. Account Subcategory") + var + SustainabilityCalculation: Codeunit "Sustainability Calculation"; + begin + if SustainabilityJnlLine."Manual Input" then exit; SustainAccountCategory.TestField("Emission Scope"); @@ -32,13 +34,13 @@ codeunit 6218 "Sustainability Calc. Mgt." case SustainAccountCategory."Emission Scope" of Enum::"Emission Scope"::"Scope 1": - SustainabilityCalculation.CalculateScope1Emissions(SustainabilityJnlLine, SustainAccountCategory); + SustainabilityCalculation.CalculateScope1Emissions(SustainabilityJnlLine, SustainAccountCategory, SustainAccountSubcategory); Enum::"Emission Scope"::"Scope 2": - SustainabilityCalculation.CalculateScope2Emissions(SustainabilityJnlLine, SustainAccountCategory); + SustainabilityCalculation.CalculateScope2Emissions(SustainabilityJnlLine, SustainAccountCategory, SustainAccountSubcategory); Enum::"Emission Scope"::"Scope 3": - SustainabilityCalculation.CalculateScope3Emissions(SustainabilityJnlLine, SustainAccountCategory); + SustainabilityCalculation.CalculateScope3Emissions(SustainabilityJnlLine, SustainAccountCategory, SustainAccountSubcategory); end; if not SustainAccountCategory.CO2 then @@ -52,7 +54,7 @@ codeunit 6218 "Sustainability Calc. Mgt." end; /// - /// Filter general ledger entreis by criteria defined in sustainability category and by date and calculate the total + /// Filter general ledger entries by criteria defined in sustainability category and by date and calculate the total /// /// Specifies the sustainability category that contains default filters. /// Specifies the "from" part of a date filter . diff --git a/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalculation.Codeunit.al b/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalculation.Codeunit.al index 11409d18b0..b342adea4e 100644 --- a/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalculation.Codeunit.al +++ b/Apps/W1/Sustainability/app/src/Calculation/SustainabilityCalculation.Codeunit.al @@ -6,34 +6,23 @@ using Microsoft.Sustainability.Account; codeunit 6215 "Sustainability Calculation" { Access = Internal; - Permissions = tabledata "Sustainability Jnl. Line" = rm; - internal procedure CalculateScope1Emissions(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; SustainAccountCategory: Record "Sustain. Account Category") - var - SustainAccountSubcategory: Record "Sustain. Account Subcategory"; + internal procedure CalculateScope1Emissions(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; SustainAccountCategory: Record "Sustain. Account Category"; SustainAccountSubcategory: Record "Sustain. Account Subcategory") begin - if not SustainAccountSubcategory.Get(SustainAccountCategory.Code, SustainabilityJnlLine."Account Subcategory") then - exit; - case SustainAccountCategory."Calculation Foundation" of Enum::"Calculation Foundation"::"Fuel/Electricity": CalculateFuelOrElectricityEmissions(SustainabilityJnlLine, SustainAccountSubcategory); Enum::"Calculation Foundation"::Distance: CalculateDistanceEmissions(SustainabilityJnlLine, SustainAccountSubcategory); Enum::"Calculation Foundation"::Installations: - CalculateInstallationsEmissions(SustainabilityJnlLine) + CalculateInstallationsEmissions(SustainabilityJnlLine, SustainAccountSubcategory) else Error(CalculationNotSupportedErr, SustainAccountCategory."Calculation Foundation", SustainAccountCategory."Emission Scope"); end; end; - internal procedure CalculateScope2Emissions(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; SustainAccountCategory: Record "Sustain. Account Category") - var - SustainAccountSubcategory: Record "Sustain. Account Subcategory"; + internal procedure CalculateScope2Emissions(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; SustainAccountCategory: Record "Sustain. Account Category"; SustainAccountSubcategory: Record "Sustain. Account Subcategory") begin - if not SustainAccountSubcategory.Get(SustainAccountCategory.Code, SustainabilityJnlLine."Account Subcategory") then - exit; - case SustainAccountCategory."Calculation Foundation" of Enum::"Calculation Foundation"::"Fuel/Electricity": CalculateFuelOrElectricityEmissions(SustainabilityJnlLine, SustainAccountSubcategory); @@ -44,13 +33,8 @@ codeunit 6215 "Sustainability Calculation" end; end; - internal procedure CalculateScope3Emissions(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; SustainAccountCategory: Record "Sustain. Account Category") - var - SustainAccountSubcategory: Record "Sustain. Account Subcategory"; + internal procedure CalculateScope3Emissions(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; SustainAccountCategory: Record "Sustain. Account Category"; SustainAccountSubcategory: Record "Sustain. Account Subcategory") begin - if not SustainAccountSubcategory.Get(SustainAccountCategory.Code, SustainabilityJnlLine."Account Subcategory") then - exit; - case SustainAccountCategory."Calculation Foundation" of Enum::"Calculation Foundation"::"Fuel/Electricity": CalculateFuelOrElectricityEmissions(SustainabilityJnlLine, SustainAccountSubcategory); @@ -87,13 +71,13 @@ codeunit 6215 "Sustainability Calculation" SustainabilityJnlLine.Validate("Emission N2O", SustainabilityJnlLine.Distance * SustainAccountSubcategory."Emission Factor N2O"); end; - local procedure CalculateInstallationsEmissions(var SustainabilityJnlLine: Record "Sustainability Jnl. Line") + local procedure CalculateInstallationsEmissions(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; SustainAccountSubcategory: Record "Sustain. Account Subcategory") begin - SustainabilityJnlLine.Validate("Emission CO2", CalculateInstallationEmission(SustainabilityJnlLine)); + SustainabilityJnlLine.Validate("Emission CO2", CalculateInstallationEmission(SustainabilityJnlLine) * SustainAccountSubcategory."Emission Factor CO2"); - SustainabilityJnlLine.Validate("Emission CH4", CalculateInstallationEmission(SustainabilityJnlLine)); + SustainabilityJnlLine.Validate("Emission CH4", CalculateInstallationEmission(SustainabilityJnlLine) * SustainAccountSubcategory."Emission Factor CH4"); - SustainabilityJnlLine.Validate("Emission N2O", CalculateInstallationEmission(SustainabilityJnlLine)); + SustainabilityJnlLine.Validate("Emission N2O", CalculateInstallationEmission(SustainabilityJnlLine) * SustainAccountSubcategory."Emission Factor N2O"); end; local procedure CalculateCustomEmissions(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; SustainAccountSubcategory: Record "Sustain. Account Subcategory") diff --git a/Apps/W1/Sustainability/app/src/Journal/SustainabilityJnlLine.Table.al b/Apps/W1/Sustainability/app/src/Journal/SustainabilityJnlLine.Table.al index 84d7484085..82d9ccd41d 100644 --- a/Apps/W1/Sustainability/app/src/Journal/SustainabilityJnlLine.Table.al +++ b/Apps/W1/Sustainability/app/src/Journal/SustainabilityJnlLine.Table.al @@ -14,6 +14,7 @@ table 6214 "Sustainability Jnl. Line" Caption = 'Sustainability Journal Line'; Access = Public; DataClassification = CustomerContent; + LookupPageId = "Sustainability Journal"; DataPerCompany = true; Extensible = true; @@ -87,7 +88,7 @@ table 6214 "Sustainability Jnl. Line" } field(9; "Account Category"; Code[20]) { - Caption = 'Category'; + Caption = 'Account Category'; Editable = false; TableRelation = "Sustain. Account Category"; @@ -99,7 +100,7 @@ table 6214 "Sustainability Jnl. Line" } field(10; "Account Subcategory"; Code[20]) { - Caption = 'Subcategory'; + Caption = 'Account Subcategory'; Editable = false; TableRelation = "Sustain. Account Subcategory".Code where("Category Code" = field("Account Category")); } @@ -228,11 +229,21 @@ table 6214 "Sustainability Jnl. Line" { Caption = 'Expiration Date'; } - field(27; "Dimension Set ID"; Integer) + field(480; "Dimension Set ID"; Integer) { Caption = 'Dimension Set ID'; Editable = false; TableRelation = "Dimension Set Entry"; + + trigger OnLookup() + begin + ShowDimensions(); + end; + + trigger OnValidate() + begin + DimMgt.UpdateGlobalDimFromDimSetID("Dimension Set ID", "Shortcut Dimension 1 Code", "Shortcut Dimension 2 Code"); + end; } field(28; "Shortcut Dimension 1 Code"; Code[20]) { @@ -241,8 +252,6 @@ table 6214 "Sustainability Jnl. Line" TableRelation = "Dimension Value".Code where("Global Dimension No." = const(1), Blocked = const(false)); trigger OnValidate() - var - DimMgt: Codeunit DimensionManagement; begin DimMgt.ValidateShortcutDimValues(1, "Shortcut Dimension 1 Code", "Dimension Set ID"); end; @@ -254,8 +263,6 @@ table 6214 "Sustainability Jnl. Line" TableRelation = "Dimension Value".Code where("Global Dimension No." = const(2), Blocked = const(false)); trigger OnValidate() - var - DimMgt: Codeunit DimensionManagement; begin DimMgt.ValidateShortcutDimValues(2, "Shortcut Dimension 2 Code", "Dimension Set ID"); end; @@ -294,6 +301,8 @@ table 6214 "Sustainability Jnl. Line" var SustainabilitySetup: Record "Sustainability Setup"; + DimMgt: Codeunit DimensionManagement; + JnlRecRefLbl: Label '%1 %2 %3', Locked = true; internal procedure SetupNewLine(PreviousLine: Record "Sustainability Jnl. Line") var @@ -320,7 +329,6 @@ table 6214 "Sustainability Jnl. Line" local procedure GetDefaultDimensionsFromAccount() var - DimMgt: Codeunit DimensionManagement; DefaultDimSource: List of [Dictionary of [Integer, Code[20]]]; begin "Shortcut Dimension 1 Code" := ''; @@ -329,4 +337,16 @@ table 6214 "Sustainability Jnl. Line" DimMgt.AddDimSource(DefaultDimSource, Database::"Sustainability Account", "Account No.", true); Validate("Dimension Set ID", DimMgt.GetRecDefaultDimID(Rec, CurrFieldNo, DefaultDimSource, "Source Code", "Shortcut Dimension 1 Code", "Shortcut Dimension 2 Code", 0, 0)); end; -} + + internal procedure ShowDimensions() IsChanged: Boolean + var + OldDimSetID: Integer; + begin + OldDimSetID := "Dimension Set ID"; + "Dimension Set ID" := DimMgt.EditDimensionSet( + Rec, "Dimension Set ID", StrSubstNo(JnlRecRefLbl, "Journal Template Name", "Journal Batch Name", "Line No."), + "Shortcut Dimension 1 Code", "Shortcut Dimension 2 Code"); + + IsChanged := OldDimSetID <> "Dimension Set ID"; + end; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Journal/SustainabilityJournal.Page.al b/Apps/W1/Sustainability/app/src/Journal/SustainabilityJournal.Page.al index 119fe06eef..20590cbc31 100644 --- a/Apps/W1/Sustainability/app/src/Journal/SustainabilityJournal.Page.al +++ b/Apps/W1/Sustainability/app/src/Journal/SustainabilityJournal.Page.al @@ -5,6 +5,7 @@ using Microsoft.Sustainability.Ledger; using Microsoft.Sustainability.Account; using Microsoft.Sustainability.Calculation; using Microsoft.Finance.Dimension; +using System.Utilities; page 6219 "Sustainability Journal" { @@ -284,6 +285,9 @@ page 6219 "Sustainability Journal" } area(FactBoxes) { + part(ErrorMessagesPart; "Error Messages Part") + { + } part(CategoryFactBox; "Sustain. Category FactBox") { SubPageLink = Code = field("Account Category"); @@ -349,14 +353,8 @@ page 6219 "Sustainability Journal" ToolTip = 'View or edit dimensions, such as area, project, or department, that you can assign to the journal and analyze transaction history.'; trigger OnAction() - var - DimMgt: Codeunit DimensionManagement; - DimensionCaptionLbl: Label '%1 %2 %3', Locked = true; begin - Rec.Validate("Dimension Set ID", DimMgt.EditDimensionSet(Rec, Rec."Dimension Set ID", - StrSubstNo(DimensionCaptionLbl, Rec."Journal Template Name", Rec."Journal Batch Name", Rec."Line No."), - Rec."Shortcut Dimension 1 Code", Rec."Shortcut Dimension 2 Code")); - + Rec.ShowDimensions(); CurrPage.SaveRecord(); end; } @@ -370,21 +368,35 @@ page 6219 "Sustainability Journal" ToolTip = 'Finalize the document or journal by posting the amounts and quantities to the related accounts in your company books.'; ShortCutKey = 'F9'; + trigger OnAction() + begin + if IsRecurringView then + Codeunit.Run(Codeunit::"Sustainability Recur Jnl.-Post", Rec) + else + Codeunit.Run(Codeunit::"Sustainability Jnl.-Post", Rec); + end; + } + action(CheckLines) + { + Image = CheckJournal; + ToolTip = 'Check all journal lines for errors.'; + trigger OnAction() var - SustainabilityPostMgt: Codeunit "Sustainability Post Mgt"; + TempErrorMessages: Record "Error Message" temporary; + SustainabilityJnlCheck: Codeunit "Sustainability Jnl.-Check"; begin - if SustainabilityPostMgt.CheckJournalLinesWithErrorCollect(Rec) then - SustainabilityPostMgt.PostSustainabilityJournalLines(Rec, IsRecurringView); + SustainabilityJnlCheck.CheckAllJournalLinesWithErrorCollect(Rec, TempErrorMessages); - CurrPage.Update(false); + if not TempErrorMessages.IsEmpty() then + Page.RunModal(Page::"Error Messages", TempErrorMessages); end; } action(Recalculate) { Caption = 'Recalculate'; Image = Calculate; - ToolTip = 'Calculate the emission of the journal line.'; + ToolTip = 'Recalculate the emission of the journal line.'; trigger OnAction() var @@ -403,6 +415,7 @@ page 6219 "Sustainability Journal" group(Category_Process) { actionref(Post_Promoted; Post) { } + actionref(CheckLines_Promoted; CheckLines) { } } group(Category_Category10) { @@ -434,6 +447,17 @@ page 6219 "Sustainability Journal" DimMgt.GetShortcutDimensions(Rec."Dimension Set ID", ShortcutDimCode); end; + trigger OnAfterGetCurrRecord() + var + TempErrorMessages: Record "Error Message" temporary; + SustainabilityJnlCheck: Codeunit "Sustainability Jnl.-Check"; + begin + SustainabilityJnlCheck.CheckSustainabilityJournalLineWithErrorCollect(Rec, TempErrorMessages); + + CurrPage.ErrorMessagesPart.Page.SetRecords(TempErrorMessages); + CurrPage.ErrorMessagesPart.Page.Update(false); + end; + trigger OnInit() begin SetDimensionVisibility(); @@ -459,7 +483,6 @@ page 6219 "Sustainability Journal" Rec.SetRange("Journal Batch Name", SustainabilityJnlBatch.Name); Rec.SetRange("Journal Template Name", SustainabilityJnlBatch."Journal Template Name"); Rec.FilterGroup(0); - if Rec.Find('-') then; end; local procedure SetDimensionVisibility() diff --git a/Apps/W1/Sustainability/app/src/Journal/SustainabilityJournalMgt.Codeunit.al b/Apps/W1/Sustainability/app/src/Journal/SustainabilityJournalMgt.Codeunit.al index 299c0f53c9..ae7ea1d0b0 100644 --- a/Apps/W1/Sustainability/app/src/Journal/SustainabilityJournalMgt.Codeunit.al +++ b/Apps/W1/Sustainability/app/src/Journal/SustainabilityJournalMgt.Codeunit.al @@ -6,19 +6,8 @@ using Microsoft.Sustainability.Account; codeunit 6211 "Sustainability Journal Mgt." { Access = Public; - Permissions = - tabledata "Sustainability Jnl. Template" = ri, - tabledata "Sustainability Jnl. Batch" = ri, - tabledata "No. Series" = i; - /// - /// Insert the default Sustainability Journal Template, with Primary Key set to `GENERAL`. - /// Should only be used to initialize a new environment. - /// - /// Specifies whether the default template is recurring. - /// The created template. - /// If the default template already exists. - procedure InitializeDefaultTemplate(IsRecurring: Boolean): Record "Sustainability Jnl. Template" + local procedure InitializeDefaultTemplate(IsRecurring: Boolean): Record "Sustainability Jnl. Template" var SustainabilityJnlTemplate: Record "Sustainability Jnl. Template"; begin @@ -54,30 +43,22 @@ codeunit 6211 "Sustainability Journal Mgt." NoSeriesLine.Validate("Starting No.", '000010'); NoSeriesLine.Validate("Ending No.", '999990'); NoSeriesLine.Validate("Increment-by No.", 1); - NoSeriesLine.Validate("Allow Gaps in Nos.", false); + NoSeriesLine.Validate(Implementation, Enum::"No. Series Implementation"::Normal); NoSeriesLine.Validate("Line No.", 1000); NoSeriesLine.Insert(true); exit(NoSeriesCode); end; - /// - /// Insert the default Sustainability Journal Batch, with Primary Key set to `DEFAULT`. - /// Should only be used to initialize a new environment. - /// - /// Specifies the name of the template to initialize the Batch with. - /// Specifies whether the default batch is recurring. - /// The created batch. - /// If the default batch already exists. - procedure InitializeDefaultBatch(TemplateName: Code[10]; IsRecurring: Boolean): Record "Sustainability Jnl. Batch" + local procedure InitializeDefaultBatch(TemplateName: Code[10]; IsRecurring: Boolean): Record "Sustainability Jnl. Batch" var SustainabilityJnlBatch: Record "Sustainability Jnl. Batch"; NoSeriesCode: Code[20]; begin if IsRecurring then - NoSeriesCode := InitializeDefaultNoSeries(GetRecurringNoSeriesCode(), RecurringNoSeriesDescriptionLbl) + NoSeriesCode := InitializeDefaultNoSeries(RecurringNoSeriesTok, RecurringNoSeriesDescriptionLbl) else - NoSeriesCode := InitializeDefaultNoSeries(GetSustainabilityNoSeriesCode(), SustainabilityNoSeriesDescriptionLbl); + NoSeriesCode := InitializeDefaultNoSeries(SustainabilityNoSeriesTok, SustainabilityNoSeriesDescriptionLbl); SustainabilityJnlBatch.Validate("Journal Template Name", TemplateName); SustainabilityJnlBatch.Validate(Name, DefaultBatchTok); @@ -88,30 +69,14 @@ codeunit 6211 "Sustainability Journal Mgt." exit(SustainabilityJnlBatch); end; - procedure GetSustainabilityNoSeriesCode(): Code[20] - begin - exit(SustainabilityNoSeriesTok); - end; - - procedure GetRecurringNoSeriesCode(): Code[20] - begin - exit(RecurringNoSeriesTok); - end; - internal procedure GetDocumentNo(IsPreviousDocumentNoValid: Boolean; SustainabilityJnlBatch: Record "Sustainability Jnl. Batch"; PreviousDocumentNo: Code[20]; PostingDate: Date): Code[20] var - NoSeriesLine: Record "No. Series Line"; - NoSeriesMgt: Codeunit NoSeriesManagement; + NoSeriesBatch: Codeunit "No. Series - Batch"; begin if SustainabilityJnlBatch."No Series" <> '' then begin if not IsPreviousDocumentNoValid then - exit(NoSeriesMgt.TryGetNextNo(SustainabilityJnlBatch."No Series", PostingDate)) - else begin - NoSeriesMgt.FindNoSeriesLine(NoSeriesLine, SustainabilityJnlBatch."No Series", PostingDate); - // TODO: need to check if the ending is integer otherwise runtime error - NoSeriesMgt.IncrementNoText(PreviousDocumentNo, NoSeriesLine."Increment-by No."); - exit(PreviousDocumentNo); - end + exit(NoSeriesBatch.PeekNextNo(SustainabilityJnlBatch."No Series", PostingDate)); + exit(NoSeriesBatch.SimulateGetNextNo(SustainabilityJnlBatch."No Series", PostingDate, PreviousDocumentNo)); end else if PreviousDocumentNo = '' then exit('') @@ -122,7 +87,7 @@ codeunit 6211 "Sustainability Journal Mgt." /// /// Get a Sustainability Journal Batch. /// If more than one Template exists, the user will be prompted to select one. - /// If no Template exists, a default one will be created. + /// If no Template/Batch exists, a default one will be created. /// /// Specifies whether the template is recurring. procedure GetASustainabilityJournalBatch(IsRecurring: Boolean): Record "Sustainability Jnl. Batch" diff --git a/Apps/W1/Sustainability/app/src/Ledger/SustainabilityLedgerEntry.Table.al b/Apps/W1/Sustainability/app/src/Ledger/SustainabilityLedgerEntry.Table.al index 9a37dde040..8339eace59 100644 --- a/Apps/W1/Sustainability/app/src/Ledger/SustainabilityLedgerEntry.Table.al +++ b/Apps/W1/Sustainability/app/src/Ledger/SustainabilityLedgerEntry.Table.al @@ -125,7 +125,7 @@ table 6216 "Sustainability Ledger Entry" } field(22; "Country/Region Code"; Code[10]) { - Caption = 'Country or Region Code'; + Caption = 'Country/Region Code'; TableRelation = "Country/Region"; } field(23; "Responsibility Center"; Code[10]) @@ -146,10 +146,14 @@ table 6216 "Sustainability Ledger Entry" { Caption = 'Expiration Date'; } - field(27; "Dimension Set ID"; Integer) + field(480; "Dimension Set ID"; Integer) { Caption = 'Dimension Set ID'; TableRelation = "Dimension Set Entry"; + trigger OnLookup() + begin + ShowDimensions(); + end; } field(28; "Global Dimension 1 Code"; Code[20]) { @@ -279,4 +283,12 @@ table 6216 "Sustainability Ledger Entry" var SustainabilitySetup: Record "Sustainability Setup"; + EntryRecIDLbl: Label '%1 %2', Locked = true; + + local procedure ShowDimensions() + var + DimMgt: Codeunit DimensionManagement; + begin + DimMgt.ShowDimensionSet("Dimension Set ID", StrSubstNo(EntryRecIDLbl, TableCaption(), "Entry No.")); + end; } \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Permissions/SustainabilityAdmin.permissionset.al b/Apps/W1/Sustainability/app/src/Permissions/SustainabilityAdmin.permissionset.al new file mode 100644 index 0000000000..1186e2b316 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Permissions/SustainabilityAdmin.permissionset.al @@ -0,0 +1,18 @@ +namespace Microsoft.Sustainability; + +using Microsoft.Sustainability.Setup; +using Microsoft.Sustainability.Account; + +permissionset 6212 "Sustainability Admin" +{ + Assignable = true; + Caption = 'Sustainability - Admin'; + + IncludedPermissionSets = "Sustainability Edit"; + + Permissions = + tabledata "Sustainability Setup" = M, + tabledata "Sustainability Account" = IMD, + tabledata "Sustain. Account Category" = IMD, + tabledata "Sustain. Account Subcategory" = IMD; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Permissions/SustainabilityEdit.permissionset.al b/Apps/W1/Sustainability/app/src/Permissions/SustainabilityEdit.permissionset.al index 37f69d26c0..fe03344516 100644 --- a/Apps/W1/Sustainability/app/src/Permissions/SustainabilityEdit.permissionset.al +++ b/Apps/W1/Sustainability/app/src/Permissions/SustainabilityEdit.permissionset.al @@ -2,24 +2,17 @@ namespace Microsoft.Sustainability; using Microsoft.Sustainability.Journal; using Microsoft.Sustainability.Ledger; -using Microsoft.Sustainability.Account; -using Microsoft.Sustainability.Setup; permissionset 6213 "Sustainability Edit" { - Access = Internal; Assignable = true; Caption = 'Sustainability - Edit'; IncludedPermissionSets = "Sustainability Read"; Permissions = - tabledata "Sustainability Account" = IMD, - tabledata "Sustain. Account Category" = IMD, - tabledata "Sustain. Account Subcategory" = IMD, tabledata "Sustainability Jnl. Template" = IMD, tabledata "Sustainability Jnl. Batch" = IMD, tabledata "Sustainability Jnl. Line" = IMD, - tabledata "Sustainability Ledger Entry" = I, - tabledata "Sustainability Setup" = M; + tabledata "Sustainability Ledger Entry" = I; } \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Permissions/SustainabilityObjects.permissionset.al b/Apps/W1/Sustainability/app/src/Permissions/SustainabilityObjects.permissionset.al index f04cbc8c86..475eef4efd 100644 --- a/Apps/W1/Sustainability/app/src/Permissions/SustainabilityObjects.permissionset.al +++ b/Apps/W1/Sustainability/app/src/Permissions/SustainabilityObjects.permissionset.al @@ -5,6 +5,7 @@ using Microsoft.Sustainability.Ledger; using Microsoft.Sustainability.Calculation; using Microsoft.Sustainability.Posting; using Microsoft.Sustainability.Account; +using Microsoft.Sustainability.Reports; using Microsoft.Sustainability.Setup; permissionset 6210 "Sustainability - Objects" @@ -45,5 +46,8 @@ permissionset 6210 "Sustainability - Objects" codeunit "Sustainability Post Mgt" = X, codeunit "Sustainability Jnl.-Check" = X, codeunit "Sustainability Calculation" = X, - codeunit "Sustainability Calc. Mgt." = X; + codeunit "Sustainability Calc. Mgt." = X, + report "Emission By Category" = X, + report "Emission Per Facility" = X, + report "Total Emissions" = X; } \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Permissions/d365BasicSustainability.PermissionsetExt.al b/Apps/W1/Sustainability/app/src/Permissions/d365BasicSustainability.PermissionsetExt.al index 47d0c027ed..31c54dfc64 100644 --- a/Apps/W1/Sustainability/app/src/Permissions/d365BasicSustainability.PermissionsetExt.al +++ b/Apps/W1/Sustainability/app/src/Permissions/d365BasicSustainability.PermissionsetExt.al @@ -1,4 +1,8 @@ -permissionsetextension 6214 "D365 Basic Sustainability" extends "D365 BASIC" +namespace Microsoft.Sustainability; + +using System.Security.AccessControl; + +permissionsetextension 6215 "D365 BASIC Sustainability" extends "D365 BASIC" { - IncludedPermissionSets = "Sustainability View"; + IncludedPermissionSets = "Sustainability Edit"; } \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Permissions/d365BusFullaccessSustainability.permissionsetExt.al b/Apps/W1/Sustainability/app/src/Permissions/d365BusFullaccessSustainability.permissionsetExt.al new file mode 100644 index 0000000000..52fed99ab1 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Permissions/d365BusFullaccessSustainability.permissionsetExt.al @@ -0,0 +1,8 @@ +namespace Microsoft.Sustainability; + +using System.Security.AccessControl; + +permissionsetextension 6210 "D365 BUS FULL ACCESS Sustainability" extends "D365 BUS FULL ACCESS" +{ + IncludedPermissionSets = "Sustainability Admin"; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Permissions/d365ReadSustainability.PermissionsetExt.al b/Apps/W1/Sustainability/app/src/Permissions/d365ReadSustainability.PermissionsetExt.al index ac59254a72..7ccf0f14c5 100644 --- a/Apps/W1/Sustainability/app/src/Permissions/d365ReadSustainability.PermissionsetExt.al +++ b/Apps/W1/Sustainability/app/src/Permissions/d365ReadSustainability.PermissionsetExt.al @@ -1,3 +1,7 @@ +namespace Microsoft.Sustainability; + +using System.Security.AccessControl; + permissionsetextension 6216 "D365 READ Sustainability" extends "D365 READ" { IncludedPermissionSets = "Sustainability Read"; diff --git a/Apps/W1/Sustainability/app/src/Permissions/d365TeamMemberSustainability.PermissionsetExt.al b/Apps/W1/Sustainability/app/src/Permissions/d365TeamMemberSustainability.PermissionsetExt.al index 7c7ceb44b0..f2198dfb2b 100644 --- a/Apps/W1/Sustainability/app/src/Permissions/d365TeamMemberSustainability.PermissionsetExt.al +++ b/Apps/W1/Sustainability/app/src/Permissions/d365TeamMemberSustainability.PermissionsetExt.al @@ -1,4 +1,8 @@ -permissionsetextension 6217 "D365 TeamMember Sustainability" extends "D365 TEAM MEMBER" +namespace Microsoft.Sustainability; + +using System.Security.AccessControl; + +permissionsetextension 6211 "D365 TEAM MEMBER Sustainability" extends "D365 TEAM MEMBER" { - IncludedPermissionSets = "Sustainability View"; + IncludedPermissionSets = "Sustainability Edit"; } \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Posting/SustainabilityJnlCheck.Codeunit.al b/Apps/W1/Sustainability/app/src/Posting/SustainabilityJnlCheck.Codeunit.al index 949a63ee0d..a0390bc7ce 100644 --- a/Apps/W1/Sustainability/app/src/Posting/SustainabilityJnlCheck.Codeunit.al +++ b/Apps/W1/Sustainability/app/src/Posting/SustainabilityJnlCheck.Codeunit.al @@ -5,27 +5,12 @@ using Microsoft.Sustainability.Journal; using Microsoft.Sustainability.Setup; using Microsoft.Finance.Dimension; using Microsoft.Sustainability.Calculation; +using System.Utilities; codeunit 6216 "Sustainability Jnl.-Check" { Access = Internal; TableNo = "Sustainability Jnl. Line"; - Permissions = - tabledata "Sustainability Jnl. Line" = r, - tabledata "Sustainability Jnl. Batch" = r, - tabledata "Sustainability Account" = r; - - trigger OnRun() - begin - Rec.ReadIsolation := IsolationLevel::ReadUncommitted; - - CheckCommonConditionsBeforePosting(Rec); - - if Rec.FindSet() then - repeat - CheckSustainabilityJournalLine(Rec); - until Rec.Next() = 0; - end; procedure CheckCommonConditionsBeforePosting(var SustainabilityJnlLine: Record "Sustainability Jnl. Line") begin @@ -40,6 +25,26 @@ codeunit 6216 "Sustainability Jnl.-Check" Error(SustainabilityJournalBatchMismatchErr); end; + [ErrorBehavior(ErrorBehavior::Collect)] + procedure CheckSustainabilityJournalLineWithErrorCollect(SustainabilityJnlLine: Record "Sustainability Jnl. Line"; var TempErrorMessages: Record "Error Message" temporary) + var + ErrorMessageManagement: Codeunit "Error Message Management"; + begin + if not TryCheckJournalLine(SustainabilityJnlLine) then + ErrorMessageManagement.InsertTempLineErrorMessage(TempErrorMessages, SustainabilityJnlLine.RecordId(), Database::"Sustainability Jnl. Line", 0, GetLastErrorText(), GetLastErrorCallStack()); + + ErrorMessageManagement.CollectErrors(TempErrorMessages); + end; + + [ErrorBehavior(ErrorBehavior::Collect)] + procedure CheckAllJournalLinesWithErrorCollect(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; var TempErrorMessages: Record "Error Message" temporary) + begin + if SustainabilityJnlLine.FindSet() then + repeat + CheckSustainabilityJournalLineWithErrorCollect(SustainabilityJnlLine, TempErrorMessages); + until SustainabilityJnlLine.Next() = 0; + end; + procedure CheckSustainabilityJournalLine(SustainabilityJnlLine: Record "Sustainability Jnl. Line") var SustainabilityAccount: Record "Sustainability Account"; @@ -50,20 +55,29 @@ codeunit 6216 "Sustainability Jnl.-Check" SustainabilityJnlLine.TestField(Description, ErrorInfo.Create()); SustainabilityJnlLine.TestField("Unit of Measure", ErrorInfo.Create()); - if SustainabilityAccount.Get(SustainabilityJnlLine."Account No.") then begin - SustainabilityAccount.CheckAccountReadyForPosting(); - SustainabilityAccount.TestField("Direct Posting", ErrorInfo.Create()); - SustainabilityJournalMgt.CheckScopeMatchWithBatch(SustainabilityJnlLine); - end else - SustainabilityJnlLine.TestField("Account No.", ErrorInfo.Create()); + TestRequiredFieldsFromSetupForJnlLine(SustainabilityJnlLine); + + SustainabilityAccount.Get(SustainabilityJnlLine."Account No."); + SustainabilityAccount.CheckAccountReadyForPosting(); + SustainabilityAccount.TestField("Direct Posting", ErrorInfo.Create()); + SustainabilityJournalMgt.CheckScopeMatchWithBatch(SustainabilityJnlLine); TestEmissionCalculationAndAmount(SustainabilityJnlLine); - TestRequiredFieldsFromSetupForJnlLine(SustainabilityJnlLine); - TestDimensionsForJnlLine(SustainabilityJnlLine); end; + [TryFunction] + local procedure TryCheckJournalLine(SustainabilityJnlLine: Record "Sustainability Jnl. Line") + var + SustainabilityJnlCheck: Codeunit "Sustainability Jnl.-Check"; + begin + if SustainabilityJnlLine."Line No." = 0 then + exit; + + SustainabilityJnlCheck.CheckSustainabilityJournalLine(SustainabilityJnlLine); + end; + local procedure TestEmissionCalculationAndAmount(SustainabilityJnlLine: Record "Sustainability Jnl. Line") var SustainabilityCalcMgt: Codeunit "Sustainability Calc. Mgt."; diff --git a/Apps/W1/Sustainability/app/src/Posting/SustainabilityJnlPost.Codeunit.al b/Apps/W1/Sustainability/app/src/Posting/SustainabilityJnlPost.Codeunit.al index 80752acbc5..2dc7b3a080 100644 --- a/Apps/W1/Sustainability/app/src/Posting/SustainabilityJnlPost.Codeunit.al +++ b/Apps/W1/Sustainability/app/src/Posting/SustainabilityJnlPost.Codeunit.al @@ -6,96 +6,69 @@ using Microsoft.Foundation.NoSeries; codeunit 6213 "Sustainability Jnl.-Post" { TableNo = "Sustainability Jnl. Line"; - Permissions = - tabledata "Sustainability Jnl. Line" = rd, - tabledata "Sustainability Jnl. Batch" = r; trigger OnRun() var SustainabilityPostMgt: Codeunit "Sustainability Post Mgt"; - IsManualNo: Boolean; + Window: Dialog; begin Rec.LockTable(); - // sort journal lines by Document No. to ensure that the No. Series is processed in the correct order - Rec.SetCurrentKey("Document No."); + if GuiAllowed() then + Window.Open(SustainabilityPostMgt.GetStartPostingProgressMessage()); - IsManualNo := CheckAndFindIfManualNoBeforePosting(Rec); + CheckJournalLinesBeforePosting(Rec, Window); - if not IsManualNo then - ProcessNoSeriesOnJournalLines(Rec); - - if Rec.FindSet() then - repeat - SustainabilityPostMgt.InsertLedgerEntry(Rec); - until Rec.Next() = 0; + ProcessLines(Rec, Window); Rec.DeleteAll(true); + + if GuiAllowed() then + Window.Close(); end; - // Could be replaced by running codeunit "Check Sustainability Jnl. Line", but need to check for manual No. Series - local procedure CheckAndFindIfManualNoBeforePosting(var SustainabilityJnlLine: Record "Sustainability Jnl. Line") IsManualNo: Boolean + local procedure CheckJournalLinesBeforePosting(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; var DialogInstance: Dialog) var - SustainabilityJnlBatch: Record "Sustainability Jnl. Batch"; SustainabilityJnlCheck: Codeunit "Sustainability Jnl.-Check"; - NoSeriesMgt: Codeunit NoSeriesManagement; - PreviousDocumentNo: Code[20]; + SustainabilityPostMgt: Codeunit "Sustainability Post Mgt"; begin SustainabilityJnlCheck.CheckCommonConditionsBeforePosting(SustainabilityJnlLine); - SustainabilityJnlBatch.Get(SustainabilityJnlLine."Journal Template Name", SustainabilityJnlLine."Journal Batch Name"); - if SustainabilityJnlLine.FindSet() then repeat - if IsNoSeriesLineChanged(SustainabilityJnlBatch."No Series", SustainabilityJnlLine."Posting Date", NoSeriesMgt) then - PreviousDocumentNo := ''; - - if (PreviousDocumentNo = '') or (SustainabilityJnlLine."Document No." <> PreviousDocumentNo) then - if not IsManualNo then - IsManualNo := (SustainabilityJnlLine."Document No." <> NoSeriesMgt.GetNextNo(SustainabilityJnlBatch."No Series", SustainabilityJnlLine."Posting Date", false)); - - PreviousDocumentNo := SustainabilityJnlLine."Document No."; + if GuiAllowed() then + DialogInstance.Update(1, SustainabilityPostMgt.GetCheckJournalLineProgressMessage(SustainabilityJnlLine."Line No.")); SustainabilityJnlCheck.CheckSustainabilityJournalLine(SustainabilityJnlLine); until SustainabilityJnlLine.Next() = 0; - - if IsManualNo then - NoSeriesMgt.TestManual(SustainabilityJnlBatch."No Series"); end; - local procedure ProcessNoSeriesOnJournalLines(var SustainabilityJnlLine: Record "Sustainability Jnl. Line") + local procedure ProcessLines(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; var DialogInstance: Dialog) var - NoSeriesMgt: Codeunit NoSeriesManagement; + SustainabilityJnlBatch: Record "Sustainability Jnl. Batch"; SustainabilityPostMgt: Codeunit "Sustainability Post Mgt"; - NoSeriesCode: Code[20]; + NoSeriesBatch: Codeunit "No. Series - Batch"; PreviousDocumentNo: Code[20]; begin - NoSeriesCode := SustainabilityPostMgt.GetNoSeriesFromJournalLine(SustainabilityJnlLine); + SustainabilityJnlBatch.Get(SustainabilityJnlLine."Journal Template Name", SustainabilityJnlLine."Journal Batch Name"); + PreviousDocumentNo := ''; if SustainabilityJnlLine.FindSet() then repeat - if IsNoSeriesLineChanged(NoSeriesCode, SustainabilityJnlLine."Posting Date", NoSeriesMgt) then - PreviousDocumentNo := ''; + if GuiAllowed() then + DialogInstance.Update(1, SustainabilityPostMgt.GetProgressingLineMessage(SustainabilityJnlLine."Line No.")); - if (PreviousDocumentNo = '') or (SustainabilityJnlLine."Document No." <> PreviousDocumentNo) then - if SustainabilityJnlLine."Document No." <> NoSeriesMgt.GetNextNo(NoSeriesCode, SustainabilityJnlLine."Posting Date", true) then - Error(ManualNoSeriesFoundDuringProcessingErr); + if PreviousDocumentNo <> SustainabilityJnlLine."Document No." then + if SustainabilityJnlLine."Document No." = NoSeriesBatch.PeekNextNo(SustainabilityJnlBatch."No Series", SustainabilityJnlLine."Posting Date") then + NoSeriesBatch.GetNextNo(SustainabilityJnlBatch."No Series", SustainabilityJnlLine."Posting Date") + else + NoSeriesBatch.TestManual(SustainabilityJnlBatch."No Series", SustainabilityJnlLine."Document No."); PreviousDocumentNo := SustainabilityJnlLine."Document No."; + + SustainabilityPostMgt.InsertLedgerEntry(SustainabilityJnlLine); until SustainabilityJnlLine.Next() = 0; - end; - local procedure IsNoSeriesLineChanged(NoSeriesCode: Code[20]; PostingDate: Date; var NoSeriesMgtInstance: Codeunit NoSeriesManagement): Boolean - var - NoSeriesLine: Record "No. Series Line"; - begin - if NoSeriesMgtInstance.FindNoSeriesLine(NoSeriesLine, NoSeriesCode, PostingDate) then - exit(not NoSeriesMgtInstance.IsCurrentNoSeriesLine(NoSeriesLine)) - else - Error(NoSeriesLineNotFoundErr, NoSeriesCode, PostingDate); + NoSeriesBatch.SaveState(); end; - - var - NoSeriesLineNotFoundErr: Label 'No. Series Line not found for the No. Series Code %1 and Posting Date %2.', Comment = '%1 = No. Series Code, %2 = Posting Date'; - ManualNoSeriesFoundDuringProcessingErr: Label 'Manual No. Series found during processing.'; } \ 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 f05a837e9a..ecb8fce4be 100644 --- a/Apps/W1/Sustainability/app/src/Posting/SustainabilityPostMgt.Codeunit.al +++ b/Apps/W1/Sustainability/app/src/Posting/SustainabilityPostMgt.Codeunit.al @@ -2,16 +2,11 @@ namespace Microsoft.Sustainability.Posting; using Microsoft.Sustainability.Journal; using Microsoft.Sustainability.Ledger; -using System.Utilities; using Microsoft.Sustainability.Account; codeunit 6212 "Sustainability Post Mgt" { Access = Internal; - Permissions = - tabledata "Sustainability Jnl. Line" = r, - tabledata "Sustainability Jnl. Batch" = r, - tabledata "Sustainability Ledger Entry" = i; procedure InsertLedgerEntry(SustainabilityJnlLine: Record "Sustainability Jnl. Line") var @@ -21,6 +16,9 @@ codeunit 6212 "Sustainability Post Mgt" // AutoIncrement requires the PK to be empty SustainabilityLedgerEntry."Entry No." := 0; + SustainabilityJnlLine.CalcFields("Account Name"); + SustainabilityLedgerEntry."Account Name" := SustainabilityJnlLine."Account Name"; + SustainabilityLedgerEntry.TransferFields(SustainabilityJnlLine); CopyDataFromAccountCategory(SustainabilityLedgerEntry, SustainabilityJnlLine."Account Category"); @@ -31,41 +29,19 @@ codeunit 6212 "Sustainability Post Mgt" SustainabilityLedgerEntry.Insert(true); end; - procedure GetNoSeriesFromJournalLine(SustainabilityJnlLine: Record "Sustainability Jnl. Line"): Code[20] - var - SustainabilityJnlBatch: Record "Sustainability Jnl. Batch"; + internal procedure GetStartPostingProgressMessage(): Text begin - SustainabilityJnlBatch.Get(SustainabilityJnlLine."Journal Template Name", SustainabilityJnlLine."Journal Batch Name"); - exit(SustainabilityJnlBatch."No Series"); + exit(PostingSustainabilityJournalLbl); end; - [ErrorBehavior(ErrorBehavior::Collect)] - procedure CheckJournalLinesWithErrorCollect(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"): Boolean - var - TempErrorMessages: Record "Error Message" temporary; - ErrorMessageManagement: Codeunit "Error Message Management"; + internal procedure GetCheckJournalLineProgressMessage(LineNo: Integer): Text begin - if not Codeunit.Run(Codeunit::"Sustainability Jnl.-Check", SustainabilityJnlLine) then - ErrorMessageManagement.InsertTempLineErrorMessage(TempErrorMessages, SustainabilityJnlLine.RecordId(), Database::"Sustainability Jnl. Line", 0, GetLastErrorText(), GetLastErrorCallStack()); - - ErrorMessageManagement.CollectErrors(TempErrorMessages); - - if not TempErrorMessages.IsEmpty() then begin - Page.RunModal(Page::"Error Messages", TempErrorMessages); - exit(false); - end; - - exit(true); + exit(StrSubstNo(CheckSustainabilityJournalLineLbl, LineNo)); end; - procedure PostSustainabilityJournalLines(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; IsRecurring: Boolean) + internal procedure GetProgressingLineMessage(LineNo: Integer): Text begin - if IsRecurring then - Codeunit.Run(Codeunit::"Sustainability Recur Jnl.-Post", SustainabilityJnlLine) - else - Codeunit.Run(Codeunit::"Sustainability Jnl.-Post", SustainabilityJnlLine); - - Message(SuccessfulPostingLbl); + exit(StrSubstNo(ProcessingLineLbl, LineNo)); end; local procedure CopyDataFromAccountCategory(var SustainabilityLedgerEntry: Record "Sustainability Ledger Entry"; CategoryCode: Code[20]) @@ -94,5 +70,7 @@ codeunit 6212 "Sustainability Post Mgt" end; var - SuccessfulPostingLbl: Label 'The journal lines have been posted successfully.'; + PostingSustainabilityJournalLbl: Label 'Posting Sustainability Journal Lines: \ #1', Comment = '#1 = sub-process progress message'; + CheckSustainabilityJournalLineLbl: Label 'Checking Sustainability Journal Line: %1', Comment = '%1 = Line No.'; + ProcessingLineLbl: Label 'Processing Line: %1', Comment = '%1 = Line No.'; } \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Posting/SustainabilityRecurJnlPost.Codeunit.al b/Apps/W1/Sustainability/app/src/Posting/SustainabilityRecurJnlPost.Codeunit.al index 5229db4163..754ec38e4d 100644 --- a/Apps/W1/Sustainability/app/src/Posting/SustainabilityRecurJnlPost.Codeunit.al +++ b/Apps/W1/Sustainability/app/src/Posting/SustainabilityRecurJnlPost.Codeunit.al @@ -6,40 +6,53 @@ using Microsoft.Foundation.NoSeries; codeunit 6214 "Sustainability Recur Jnl.-Post" { TableNo = "Sustainability Jnl. Line"; - Permissions = - tabledata "Sustainability Jnl. Line" = rm, - tabledata "Sustainability Jnl. Batch" = r; trigger OnRun() var + SustainabilityJnlBatch: Record "Sustainability Jnl. Batch"; SustainabilityPostMgt: Codeunit "Sustainability Post Mgt"; - NoSeriesMgt: Codeunit NoSeriesManagement; - NoSeriesCode: Code[20]; + NoSeriesBatch: Codeunit "No. Series - Batch"; + Window: Dialog; begin Rec.LockTable(); - CheckAndMarkRecurringLinesBeforePosting(Rec); + if GuiAllowed() then + Window.Open(SustainabilityPostMgt.GetStartPostingProgressMessage()); - NoSeriesCode := SustainabilityPostMgt.GetNoSeriesFromJournalLine(Rec); + CheckAndMarkRecurringLinesBeforePosting(Rec, Window); + + SustainabilityJnlBatch.Get(Rec."Journal Template Name", Rec."Journal Batch Name"); if Rec.FindSet() then repeat - Rec.Validate("Document No.", NoSeriesMgt.DoGetNextNo(NoSeriesCode, Rec."Posting Date", true, false)); + if GuiAllowed() then + Window.Update(1, SustainabilityPostMgt.GetProgressingLineMessage(Rec."Line No.")); + + + Rec.Validate("Document No.", NoSeriesBatch.GetNextNo(SustainabilityJnlBatch."No Series", Rec."Posting Date")); SustainabilityPostMgt.InsertLedgerEntry(Rec); ProcessRecurringJournalLine(Rec); until Rec.Next() = 0; + + NoSeriesBatch.SaveState(); + + if GuiAllowed() then + Window.Close(); end; - // Could be replaced by running codeunit "Check Sustainability Jnl. Line", but need to check for recurring specific fields - local procedure CheckAndMarkRecurringLinesBeforePosting(var SustainabilityJnlLine: Record "Sustainability Jnl. Line") + local procedure CheckAndMarkRecurringLinesBeforePosting(var SustainabilityJnlLine: Record "Sustainability Jnl. Line"; var DialogInstance: Dialog) var SustainabilityJnlCheck: Codeunit "Sustainability Jnl.-Check"; + SustainabilityPostMgt: Codeunit "Sustainability Post Mgt"; begin SustainabilityJnlCheck.CheckCommonConditionsBeforePosting(SustainabilityJnlLine); if SustainabilityJnlLine.FindSet() then repeat + if GuiAllowed() then + DialogInstance.Update(1, SustainabilityPostMgt.GetCheckJournalLineProgressMessage(SustainabilityJnlLine."Line No.")); + // Posting Date needs to be checked before IsExpiredJournalLine is called SustainabilityJnlLine.TestField("Posting Date"); @@ -55,7 +68,7 @@ codeunit 6214 "Sustainability Recur Jnl.-Post" SustainabilityJnlLine.MarkedOnly(true); if SustainabilityJnlLine.IsEmpty() then - Error(AllRecurringLinesExpiredErr); + Error(AllRecurringLinesExpiredErr, SustainabilityJnlLine.FieldCaption("Expiration Date"), SustainabilityJnlLine.FieldCaption("Posting Date")); end; local procedure ProcessRecurringJournalLine(var SustainabilityJnlLine: Record "Sustainability Jnl. Line") @@ -86,5 +99,5 @@ codeunit 6214 "Sustainability Recur Jnl.-Post" end; var - AllRecurringLinesExpiredErr: Label 'All recurring lines are expired, please check the Expiration Date and Posting Date set on each recurring journal lines.'; + AllRecurringLinesExpiredErr: Label 'All recurring lines are expired, please check the %1 and %2 set on each recurring journal lines.', Comment = '%1 = Expiration Date Field Caption, %2 = Posting Date Field Caption'; } \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Reports/EmissionByCategory.Report.al b/Apps/W1/Sustainability/app/src/Reports/EmissionByCategory.Report.al new file mode 100644 index 0000000000..9adfa1af4b --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Reports/EmissionByCategory.Report.al @@ -0,0 +1,125 @@ +namespace Microsoft.Sustainability.Reports; + +using Microsoft.Sustainability.Ledger; +using Microsoft.Sustainability.Setup; +using Microsoft.Sustainability.Account; + +report 6210 "Emission By Category" +{ + DefaultLayout = Excel; + ExcelLayout = './src/Reports/EmissionByCategory.xlsx'; + RDLCLayout = './src/Reports/EmissionByCategory.rdlc'; + ApplicationArea = Basic, Suite; + Caption = 'Emission By Category'; + UsageCategory = ReportsAndAnalysis; + DataAccessIntent = ReadOnly; + + dataset + { + dataitem("Sustainability Ledger Entry"; "Sustainability Ledger Entry") + { + DataItemTableView = sorting("Entry No."); + RequestFilterFields = "Posting Date", "Account Category", "Account No."; + column(PeriodFilter; StrSubstNo(PeriodLbl, SustLedgDateFilter)) + { + } + column(CompanyName; CompanyProperty.DisplayName()) + { + } + column(ShowDetails; ShowDetails) + { + } + column(Account_Category; "Account Category") + { + IncludeCaption = true; + } + column(Account_Category_Description; SustainAccountCategory.Description) + { + IncludeCaption = true; + } + column(Posting_Date; Format("Posting Date")) + { + } + column(Posting_Date_Caption; FieldCaption("Posting Date")) + { + } + column(Document_Type; "Document Type") + { + IncludeCaption = true; + } + column(Document_No_; "Document No.") + { + IncludeCaption = true; + } + column(Account_No_; "Account No.") + { + IncludeCaption = true; + } + column(Account_Name; "Account Name") + { + IncludeCaption = true; + } + column(Description; Description) + { + IncludeCaption = true; + } + column(Emission_Scope; "Emission Scope") + { + IncludeCaption = true; + } + column(Country_Region_Code; "Country/Region Code") + { + IncludeCaption = true; + } + column(Unit_of_Measure; ReportingUOMCode) + { + } + column(UnitOfMeasureCaption; FieldCaption("Unit of Measure")) + { + } + column(Emission_CO2; "Emission CO2") + { + IncludeCaption = true; + } + column(Emission_CH4; "Emission CH4") + { + IncludeCaption = true; + } + column(Emission_N2O; "Emission N2O") + { + IncludeCaption = true; + } + trigger OnAfterGetRecord() + begin + if not SustainAccountCategory.Get("Account Category") then + Clear(SustainAccountCategory); + + if UseReportingUOMFactor then begin + "Emission CO2" := Round("Emission CO2" * ReportingUOMFactor, RoundingPrecission, RoundingDirection); + "Emission CH4" := Round("Emission CH4" * ReportingUOMFactor, RoundingPrecission, RoundingDirection); + "Emission N2O" := Round("Emission N2O" * ReportingUOMFactor, RoundingPrecission, RoundingDirection); + end; + end; + } + } + labels + { + EmissionByCategory = 'Emission By Category'; + PageCaption = 'Page'; + } + trigger OnPreReport() + var + SustainabilitySetup: Record "Sustainability Setup"; + begin + SustLedgDateFilter := "Sustainability Ledger Entry".GetFilter("Posting Date"); + SustainabilitySetup.GetReportingParameters(ReportingUOMCode, UseReportingUOMFactor, ReportingUOMFactor, RoundingDirection, RoundingPrecission); + end; + + var + SustainAccountCategory: Record "Sustain. Account Category"; + ReportingUOMCode: Code[10]; + SustainabilityAccountName, SustLedgDateFilter, RoundingDirection : Text; + ShowDetails, UseReportingUOMFactor : Boolean; + ReportingUOMFactor, RoundingPrecission : Decimal; + PeriodLbl: Label 'Period: %1', Comment = '%1 - period filter'; +} \ No newline at end of file diff --git a/Apps/W1/Sustainability/app/src/Reports/EmissionByCategory.rdlc b/Apps/W1/Sustainability/app/src/Reports/EmissionByCategory.rdlc new file mode 100644 index 0000000000..2862746d67 --- /dev/null +++ b/Apps/W1/Sustainability/app/src/Reports/EmissionByCategory.rdlc @@ -0,0 +1,2300 @@ + + + 0 + + + + SQL + + + None + b969666f-b3cf-4531-be9d-88981134d032 + + + + + + + + + + + 0.66455in + + + 0.57638in + + + 1.05139in + + + 0.67638in + + + 0.48268in + + + 1.91239in + + + 0.53333in + + + 0.76805in + + + 0.07874in + + + 1.04305in + + + 0.07874in + + + 1.04305in + + + 0.07874in + + + 1.04305in + + + + + 0.19685in + + + + + true + true + + + + + =Fields!Posting_Date_Caption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Account_No_Caption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Account_NameCaption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Document_TypeCaption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Document_No_Caption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!DescriptionCaption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Country_Region_CodeCaption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Fields!UnitOfMeasureCaption.Value + + + + + + + Textbox25 + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Emission_CO2Caption.Value + + + + + + + Textbox11 + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Emission_CH4Caption.Value + + + + + + + Textbox2 + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Emission_N2OCaption.Value + + + + + + + Textbox10 + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + 0.19685in + + + + + true + true + + + + + =Fields!Account_Category.Value + + + + + + + + =Fields!Account_Category_Description.Value + + + + + + 2pt + 2pt + 2pt + 2pt + + + 8 + + + + + + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Textbox118 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Textbox117 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Textbox116 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + 0.19685in + + + + + true + + + + + =Fields!Posting_Date.Value + + + + + + =iif(Code.SetRowColor(Code.GetRowColor() + 1) = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Account_No_.Value + + + + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Account_Name.Value + + + + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Document_Type.Value + + + + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Document_No_.Value + + + + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Description.Value + + + + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Fields!Country_Region_Code.Value + + + + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Unit_of_Measure.Value + + + + + + + Unit_of_Measure + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Emission_CO2.Value + + + + + + + Emission_CO2 + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Emission_CH4.Value + + + + + + + Emission_CH4 + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Emission_N2O.Value + + + + + + + Emission_N2O + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + 0.19685in + + + + + true + true + + + + + =Fields!Account_Category.Value + + + + + + + + =Fields!Account_Category_Description.Value + + + + + + 2pt + 2pt + 2pt + 2pt + + + 8 + + + + + + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Sum(Fields!Emission_CO2.Value) + + + + + + + Textbox94 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Sum(Fields!Emission_CH4.Value) + + + + + + + Textbox95 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Sum(Fields!Emission_N2O.Value) + + + + + + + Textbox84 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + After + true + true + + + + + =Fields!Account_Category.Value + + + + + =Fields!Emission_Scope.Value + + + + + After + true + true + + + + + + Before + + + + + + true + true + DataSet_Result + 0.125in + 0in + 0.7874in + 10.03052in + + + + + + 1.3061in + + + + + + + 1cm + 14.85cm + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =Fields!PeriodFilter.Value + + + + + + + 0.46315in + 0.5cm + 14.85cm + 1 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =Fields!CompanyName.Value + + + + + + + 0.66in + 0.5cm + 14.85cm + 2 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =Globals!ExecutionTime + + + + + + + 6.88091in + 0.5cm + 8cm + 3 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =Parameters!PageCaption.Value & " " & Globals!PageNumber & " / " & Globals!TotalPages + + + + + + + 0.19685in + 6.88091in + 0.5cm + 8cm + 4 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =User!UserID + + + + + + + 0.3937in + 6.88091in + 0.5cm + 8cm + 5 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + + + + + 8.5in + 11in + 0.3937in + 0.3937in + 0.59055in + 0.49213in + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Account_NameCaption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!DescriptionCaption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Country_Region_CodeCaption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Fields!UnitOfMeasureCaption.Value + + + + + + + Textbox25 + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Emission_CO2Caption.Value + + + + + + + Textbox11 + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Emission_CH4Caption.Value + + + + + + + Textbox2 + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Emission_N2OCaption.Value + + + + + + + Textbox10 + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + 0.19685in + + + + + true + true + + + + + =Fields!Responsibility_Center.Value + + + + + + + + =Fields!Responsibility_Center_Name.Value + + + + + + 2pt + 2pt + 2pt + 2pt + + + 5 + + + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Textbox118 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Textbox117 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Textbox116 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + 0.19685in + + + + + true + + + + + =Fields!Account_No_.Value + + + + + + =iif(Code.SetRowColor(Code.GetRowColor() + 1) = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Account_Name.Value + + + + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Description.Value + + + + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Fields!Country_Region_Code.Value + + + + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Unit_of_Measure.Value + + + + + + + Unit_of_Measure + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Emission_CO2.Value + + + + + + + Emission_CO2 + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Emission_CH4.Value + + + + + + + Emission_CH4 + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Emission_N2O.Value + + + + + + + Emission_N2O + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + 0.19685in + + + + + true + true + + + + + =Fields!Responsibility_Center.Value + + + + + + + + =Fields!Responsibility_Center_Name.Value + + + + + + 2pt + 2pt + 2pt + 2pt + + + 5 + + + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Sum(Fields!Emission_CO2.Value) + + + + + + + Textbox94 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Sum(Fields!Emission_CH4.Value) + + + + + + + Textbox95 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Sum(Fields!Emission_N2O.Value) + + + + + + + Textbox84 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + + + + + + + + + + + + + + + + + + + + After + true + true + + + + + =Fields!Responsibility_Center.Value + + + + + =Fields!Emission_Scope.Value + + + + + After + true + true + + + + + + Before + + + + + + true + true + DataSet_Result + 0.125in + 0in + 0.7874in + 7.34302in + + + + + + 1.3061in + + + + + + + 1cm + 9.262cm + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =Fields!PeriodFilter.Value + + + + + + + 0.46315in + 0.5cm + 9.262cm + 1 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =Fields!CompanyName.Value + + + + + + + 0.66in + 0.5cm + 9.262cm + 2 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =Globals!ExecutionTime + + + + + + + 5.66008in + 0.5cm + 4.27467cm + 3 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =Parameters!PageCaption.Value & " " & Globals!PageNumber & " / " & Globals!TotalPages + + + + + + + 0.21074in + 5.66008in + 0.5cm + 4.27467cm + 4 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =User!UserID + + + + + + + 0.40759in + 5.66008in + 0.5cm + 4.27467cm + 5 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + + + + + 0.59055in + 0.49213in + 0.3937in + 0.3937in + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Account_No_Caption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Fields!Posting_Date_Caption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Document_TypeCaption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Document_No_Caption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!DescriptionCaption.Value + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Fields!UnitOfMeasureCaption.Value + + + + + + + Textbox25 + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Emission_CO2Caption.Value + + + + + + + Textbox11 + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Emission_CH4Caption.Value + + + + + + + Textbox2 + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Parameters!Emission_N2OCaption.Value + + + + + + + Textbox10 + + + + Black + + 1pt + + 2pt + 2pt + 2pt + 2pt + + + + + + + + 0.19685in + + + + + true + true + + + + + =Fields!Emission_Scope.Value + + + + + + 2pt + 2pt + 2pt + 2pt + + + 7 + + + + + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Textbox118 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Textbox117 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Textbox116 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + 0.19685in + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Fields!Account_No_.Value + + + + + + + + =Fields!Account_Name.Value + + + + + + 2pt + 2pt + 2pt + 2pt + + + 6 + + + + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Textbox113 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Textbox114 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + + Textbox115 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + 0.19685in + + + + + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Posting_Date.Value + + + + + + =iif(Code.SetRowColor(Code.GetRowColor() + 1) = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Document_Type.Value + + + + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Document_No_.Value + + + + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Description.Value + + + + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Unit_of_Measure.Value + + + + + + + Unit_of_Measure + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Emission_CO2.Value + + + + + + + Emission_CO2 + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Emission_CH4.Value + + + + + + + Emission_CH4 + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + + + + + =Fields!Emission_N2O.Value + + + + + + + Emission_N2O + + + =iif(Code.GetRowColor() = TRUE, "#EBEBEB", "White") + 2pt + 2pt + 2pt + 2pt + + + + + + + + 0.19685in + + + + + true + true + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Fields!Account_No_.Value + + + + + + + + =Fields!Account_Name.Value + + + + + + 2pt + 2pt + 2pt + 2pt + + + 6 + + + + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Sum(Fields!Emission_CO2.Value) + + + + + + + Textbox101 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Sum(Fields!Emission_CH4.Value) + + + + + + + Textbox102 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Sum(Fields!Emission_N2O.Value) + + + + + + + Textbox103 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + 0.19685in + + + + + true + true + + + + + =Fields!Emission_Scope.Value + + + + + + 2pt + 2pt + 2pt + 2pt + + + 7 + + + + + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Sum(Fields!Emission_CO2.Value) + + + + + + + Textbox94 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Sum(Fields!Emission_CH4.Value) + + + + + + + Textbox95 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + + + + + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + true + true + + + + + =Sum(Fields!Emission_N2O.Value) + + + + + + + Textbox84 + + + 2pt + 2pt + 2pt + 2pt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + After + true + true + + + + + =Fields!Emission_Scope.Value + + + + + =Fields!Emission_Scope.Value + + + + + After + true + true + + + + + =Fields!Account_No_.Value + + + + + =Fields!Account_No_.Value + + + + + + =Not(Fields!ShowDetails.Value) + + After + true + true + + + + + =Not(Fields!ShowDetails.Value) + + + + Before + + + + + Before + + + + + + true + true + DataSet_Result + 0.125in + 0in + 1.1811in + 10.03052in + + + + + + 1.3061in + + + + + + + 1cm + 14.85cm + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =Fields!PeriodFilter.Value + + + + + + + 0.46315in + 0.5cm + 14.85cm + 1 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =Fields!CompanyName.Value + + + + + + + 0.66in + 0.5cm + 14.85cm + 2 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =Globals!ExecutionTime + + + + + + + 6.88091in + 0.5cm + 8cm + 3 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =Parameters!PageCaption.Value & " " & Globals!PageNumber & " / " & Globals!TotalPages + + + + + + + 0.19685in + 6.88091in + 0.5cm + 8cm + 4 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + true + + + + + =User!UserID + + + + + + + 0.3937in + 6.88091in + 0.5cm + 8cm + 5 + + + Middle + 2pt + 2pt + 2pt + 2pt + + + + + + + + 8.5in + 11in + 0.3937in + 0.3937in + 0.59055in + 0.49213in +