diff --git a/.github/AL-Go-Settings.json b/.github/AL-Go-Settings.json index 293252e5ff..8dc7cf12cd 100644 --- a/.github/AL-Go-Settings.json +++ b/.github/AL-Go-Settings.json @@ -6,7 +6,7 @@ "runs-on": "windows-latest", "cacheImageName": "", "UsePsSession": false, - "artifact": "https://bcinsider-fvh2ekdjecfjd6gk.b02.azurefd.net/sandbox/28.0.45539.0/base", + "artifact": "https://bcinsider-fvh2ekdjecfjd6gk.b02.azurefd.net/sandbox/28.0.45946.0/base", "country": "base", "useProjectDependencies": true, "repoVersion": "28.0", diff --git a/Apps/AT/ContosoCoffeeDemoDatasetAT/app/DemoData/ContosoATLocalization.Codeunit.al b/Apps/AT/ContosoCoffeeDemoDatasetAT/app/DemoData/ContosoATLocalization.Codeunit.al index 16faf3f2b0..a98c9430a7 100644 --- a/Apps/AT/ContosoCoffeeDemoDatasetAT/app/DemoData/ContosoATLocalization.Codeunit.al +++ b/Apps/AT/ContosoCoffeeDemoDatasetAT/app/DemoData/ContosoATLocalization.Codeunit.al @@ -36,7 +36,7 @@ codeunit 11157 "Contoso AT Localization" if Module = Enum::"Contoso Demo Data Module"::"Human Resources Module" then HumanResource(ContosoDemoDataLevel); - UnBindSubscriptionDemoData(Module); + UnBindSubscriptionDemoData(ContosoDemoDataLevel, Module); end; local procedure HumanResource(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") @@ -159,7 +159,8 @@ codeunit 11157 "Contoso AT Localization" Enum::"Contoso Demo Data Module"::Inventory: begin BindSubscription(CreateInvPostingSetupAT); - BindSubscription(CreateItemAT); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemAT); BindSubscription(CreateLoactionAT); end; Enum::"Contoso Demo Data Module"::Purchase: @@ -186,7 +187,7 @@ codeunit 11157 "Contoso AT Localization" end; - local procedure UnBindSubscriptionDemoData(Module: Enum "Contoso Demo Data Module") + local procedure UnBindSubscriptionDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateResourceAT: Codeunit "Create Resource AT"; CreateCurrencyExcRate: Codeunit "Create Currency Ex. Rate AT"; @@ -231,7 +232,8 @@ codeunit 11157 "Contoso AT Localization" Enum::"Contoso Demo Data Module"::Inventory: begin UnbindSubscription(CreateInvPostingSetupAT); - UnbindSubscription(CreateItemAT); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnbindSubscription(CreateItemAT); UnbindSubscription(CreateLoactionAT); end; Enum::"Contoso Demo Data Module"::Purchase: diff --git a/Apps/AT/IntrastatAT/app/AppResources/AT_DataExchDefMap.xml b/Apps/AT/IntrastatAT/app/AppResources/AT_DataExchDefMap.xml index eb1df24bea..d323755e3a 100644 --- a/Apps/AT/IntrastatAT/app/AppResources/AT_DataExchDefMap.xml +++ b/Apps/AT/IntrastatAT/app/AppResources/AT_DataExchDefMap.xml @@ -33,8 +33,8 @@ - - + + diff --git a/Apps/AT/IntrastatAT/app/src/IntrastatReportManagementAT.Codeunit.al b/Apps/AT/IntrastatAT/app/src/IntrastatReportManagementAT.Codeunit.al index af93e9dd71..3ccc25ef24 100644 --- a/Apps/AT/IntrastatAT/app/src/IntrastatReportManagementAT.Codeunit.al +++ b/Apps/AT/IntrastatAT/app/src/IntrastatReportManagementAT.Codeunit.al @@ -159,6 +159,6 @@ codeunit 11150 IntrastatReportManagementAT Def3DPartyTradeVATNoLbl: Label 'QV999999999999', Locked = true; DefUnknowVATNoLbl: Label 'QV999999999999', Locked = true; UnknownCountryVATNoLbl: Label '999999999999', Locked = true; - DataExchangeXMLTxt: Label 'TRIMALLRemoves all spaces5&#032;0000000.00', + DataExchangeXMLTxt: Label 'TRIMALLRemoves all spaces5&#032;0000000.00', Locked = true; // will be replaced with file import when available } \ No newline at end of file diff --git a/Apps/AU/ContosoCoffeeDemoDatasetAU/app/DemoData/AUContosoLocalization.Codeunit.al b/Apps/AU/ContosoCoffeeDemoDatasetAU/app/DemoData/AUContosoLocalization.Codeunit.al index 177db861e4..b9cc270a41 100644 --- a/Apps/AU/ContosoCoffeeDemoDatasetAU/app/DemoData/AUContosoLocalization.Codeunit.al +++ b/Apps/AU/ContosoCoffeeDemoDatasetAU/app/DemoData/AUContosoLocalization.Codeunit.al @@ -215,7 +215,8 @@ codeunit 17131 "AU Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin BindSubscription(CreateAULocation); - BindSubscription(CreateAUItem); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateAUItem); end; Enum::"Contoso Demo Data Module"::Bank: begin @@ -286,7 +287,8 @@ codeunit 17131 "AU Contoso Localization" end; Enum::"Contoso Demo Data Module"::Inventory: begin - UnbindSubscription(CreateAUItem); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnbindSubscription(CreateAUItem); UnbindSubscription(CreateAULocation); end; Enum::"Contoso Demo Data Module"::Purchase: diff --git a/Apps/AU/EDocument_AU/demo data/app.json b/Apps/AU/EDocument_AU/demo data/app.json index af6118c8f9..6f498e6495 100644 --- a/Apps/AU/EDocument_AU/demo data/app.json +++ b/Apps/AU/EDocument_AU/demo data/app.json @@ -39,6 +39,9 @@ ], "screenshots": [], "platform": "28.0.0.0", + "features": [ + "TranslationFile" + ], "idRanges": [ { "from": 17211, diff --git a/Apps/BE/ContosoCoffeeDemoDatasetBE/app/DemoData/ContosoBELocalization.Codeunit.al b/Apps/BE/ContosoCoffeeDemoDatasetBE/app/DemoData/ContosoBELocalization.Codeunit.al index d20ae258c8..ecd9b2d335 100644 --- a/Apps/BE/ContosoCoffeeDemoDatasetBE/app/DemoData/ContosoBELocalization.Codeunit.al +++ b/Apps/BE/ContosoCoffeeDemoDatasetBE/app/DemoData/ContosoBELocalization.Codeunit.al @@ -43,7 +43,7 @@ codeunit 11355 "Contoso BE Localization" if Module = Enum::"Contoso Demo Data Module"::CRM then CRMModule(ContosoDemoDataLevel); - UnBindSubscriptionDemoData(Module); + UnBindSubscriptionDemoData(ContosoDemoDataLevel, Module); end; local procedure FixedAssetModule(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") @@ -205,7 +205,8 @@ codeunit 11355 "Contoso BE Localization" Enum::"Contoso Demo Data Module"::Inventory: begin BindSubscription(CreateInvPostingSetupBE); - BindSubscription(CreateItemBE); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemBE); BindSubscription(CreateLoactionBE); end; Enum::"Contoso Demo Data Module"::Purchase: @@ -228,7 +229,7 @@ codeunit 11355 "Contoso BE Localization" end; end; - local procedure UnBindSubscriptionDemoData(Module: Enum "Contoso Demo Data Module") + local procedure UnBindSubscriptionDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateResourceBE: Codeunit "Create Resource BE"; CreateCurrencyExcRate: Codeunit "Create Currency Ex. Rate BE"; @@ -273,7 +274,8 @@ codeunit 11355 "Contoso BE Localization" Enum::"Contoso Demo Data Module"::Inventory: begin UnbindSubscription(CreateInvPostingSetupBE); - UnbindSubscription(CreateItemBE); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnbindSubscription(CreateItemBE); UnbindSubscription(CreateLoactionBE); end; Enum::"Contoso Demo Data Module"::Purchase: diff --git a/Apps/BE/IntrastatBE/app/AppResources/BE_DataExchDefMapRcptS.xml b/Apps/BE/IntrastatBE/app/AppResources/BE_DataExchDefMapRcptS.xml index 3c3d4dcb2f..3e855e7914 100644 --- a/Apps/BE/IntrastatBE/app/AppResources/BE_DataExchDefMapRcptS.xml +++ b/Apps/BE/IntrastatBE/app/AppResources/BE_DataExchDefMapRcptS.xml @@ -37,7 +37,7 @@ - + diff --git a/Apps/BE/IntrastatBE/app/AppResources/BE_DataExchDefMapShptE.xml b/Apps/BE/IntrastatBE/app/AppResources/BE_DataExchDefMapShptE.xml index df17b21a24..ace6a87985 100644 --- a/Apps/BE/IntrastatBE/app/AppResources/BE_DataExchDefMapShptE.xml +++ b/Apps/BE/IntrastatBE/app/AppResources/BE_DataExchDefMapShptE.xml @@ -41,7 +41,7 @@ - + diff --git a/Apps/BE/IntrastatBE/app/AppResources/BE_DataExchDefMapShptS.xml b/Apps/BE/IntrastatBE/app/AppResources/BE_DataExchDefMapShptS.xml index f754537bb9..5842570bed 100644 --- a/Apps/BE/IntrastatBE/app/AppResources/BE_DataExchDefMapShptS.xml +++ b/Apps/BE/IntrastatBE/app/AppResources/BE_DataExchDefMapShptS.xml @@ -39,7 +39,7 @@ - + diff --git a/Apps/BE/IntrastatBE/app/src/IntrastatReportManagementBE.Codeunit.al b/Apps/BE/IntrastatBE/app/src/IntrastatReportManagementBE.Codeunit.al index f7b168f6c5..43feb3d373 100644 --- a/Apps/BE/IntrastatBE/app/src/IntrastatReportManagementBE.Codeunit.al +++ b/Apps/BE/IntrastatBE/app/src/IntrastatReportManagementBE.Codeunit.al @@ -431,18 +431,18 @@ codeunit 11346 IntrastatReportManagementBE EnterpriseNoNotValidErr: Label 'The enterprise number in Company Information is not valid.'; DataExchangeXMLRcptSmpP1Txt: Label '', Locked = true; // will be replaced with file import when available - DataExchangeXMLRcptSmpP2Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=', + DataExchangeXMLRcptSmpP2Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=', Locked = true; // will be replaced with file import when available DataExchangeXMLRcptExtP1Txt: Label '', Locked = true; // will be replaced with file import when available - DataExchangeXMLRcptExtP2Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=', + DataExchangeXMLRcptExtP2Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=', Locked = true; // will be replaced with file import when available DataExchangeXMLShptSmpP1Txt: Label '', Locked = true; // will be replaced with file import when available - DataExchangeXMLShptSmpP2Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=', + DataExchangeXMLShptSmpP2Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=', Locked = true; // will be replaced with file import when available DataExchangeXMLShptExtP1Txt: Label '', Locked = true; // will be replaced with file import when available - DataExchangeXMLShptExtP2Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=', + DataExchangeXMLShptExtP2Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=', Locked = true; // will be replaced with file import when available } \ No newline at end of file diff --git a/Apps/CA/ContosoCoffeeDemoDatasetCA/app/DemoData/CAContosoLocalization.Codeunit.al b/Apps/CA/ContosoCoffeeDemoDatasetCA/app/DemoData/CAContosoLocalization.Codeunit.al index 82ea0e6d3c..013b30002c 100644 --- a/Apps/CA/ContosoCoffeeDemoDatasetCA/app/DemoData/CAContosoLocalization.Codeunit.al +++ b/Apps/CA/ContosoCoffeeDemoDatasetCA/app/DemoData/CAContosoLocalization.Codeunit.al @@ -225,7 +225,8 @@ codeunit 27054 "CA Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin BindSubscription(CreateCAItemJnlTemplate); - BindSubscription(CreateCAItem); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateCAItem); BindSubscription(CreateCAItemCharge); BindSubscription(CreateCALocation); end; @@ -290,7 +291,8 @@ codeunit 27054 "CA Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin UnBindSubscription(CreateCAItemJnlTemplate); - UnBindSubscription(CreateCAItem); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnBindSubscription(CreateCAItem); UnBindSubscription(CreateCAItemCharge); UnBindSubscription(CreateCALocation); end; diff --git a/Apps/CA/EDocument_CA/demo data/app.json b/Apps/CA/EDocument_CA/demo data/app.json index 93253f7a28..5083801913 100644 --- a/Apps/CA/EDocument_CA/demo data/app.json +++ b/Apps/CA/EDocument_CA/demo data/app.json @@ -39,6 +39,9 @@ ], "screenshots": [], "platform": "28.0.0.0", + "features": [ + "TranslationFile" + ], "idRanges": [ { "from": 11505, diff --git a/Apps/CZ/ContosoCoffeeDemoDatasetCZ/app/DemoData/ContosoCZLocalization.Codeunit.al b/Apps/CZ/ContosoCoffeeDemoDatasetCZ/app/DemoData/ContosoCZLocalization.Codeunit.al index 1b86fcedec..7f467c3628 100644 --- a/Apps/CZ/ContosoCoffeeDemoDatasetCZ/app/DemoData/ContosoCZLocalization.Codeunit.al +++ b/Apps/CZ/ContosoCoffeeDemoDatasetCZ/app/DemoData/ContosoCZLocalization.Codeunit.al @@ -303,7 +303,8 @@ codeunit 31215 "Contoso CZ Localization" end; Enum::"Contoso Demo Data Module"::Inventory: begin - BindSubscription(CreateItemCZ); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemCZ); BindSubscription(CreateInvtPostingSetupCZ); BindSubscription(CreateItemChargeCZ); end; @@ -381,7 +382,8 @@ codeunit 31215 "Contoso CZ Localization" end; Enum::"Contoso Demo Data Module"::Inventory: begin - UnbindSubscription(CreateItemCZ); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnbindSubscription(CreateItemCZ); UnbindSubscription(CreateInvtPostingSetupCZ); UnbindSubscription(CreateItemChargeCZ); end; diff --git a/Apps/CZ/ContosoCoffeeDemoDatasetCZ/app/DemoData/Finance/1. Setup Data/CreateVATPostingGroupsCZ.Codeunit.al b/Apps/CZ/ContosoCoffeeDemoDatasetCZ/app/DemoData/Finance/1. Setup Data/CreateVATPostingGroupsCZ.Codeunit.al index c75894b810..60ae4e905b 100644 --- a/Apps/CZ/ContosoCoffeeDemoDatasetCZ/app/DemoData/Finance/1. Setup Data/CreateVATPostingGroupsCZ.Codeunit.al +++ b/Apps/CZ/ContosoCoffeeDemoDatasetCZ/app/DemoData/Finance/1. Setup Data/CreateVATPostingGroupsCZ.Codeunit.al @@ -35,6 +35,7 @@ codeunit 31189 "Create Vat Posting Groups CZ" if ContosoCoffeeDemoDataSetup."Company Type" = ContosoCoffeeDemoDataSetup."Company Type"::"Sales Tax" then exit; + ContosoPostingSetupCZ.SetOverwriteData(true); ContosoPostingSetupCZ.InsertVATPostingSetup('', NOVAT(), NOVAT(), 0, Enum::"Tax Calculation Type"::"Normal VAT", '', false, "VAT Rate CZL"::" "); ContosoPostingSetupCZ.InsertVATPostingSetup('', VAT12I(), VAT12I(), 0, Enum::"Tax Calculation Type"::"Normal VAT", '', false, "VAT Rate CZL"::Reduced); ContosoPostingSetupCZ.InsertVATPostingSetup('', VAT12S(), VAT12S(), 0, Enum::"Tax Calculation Type"::"Normal VAT", '', false, "VAT Rate CZL"::Reduced); @@ -57,6 +58,7 @@ codeunit 31189 "Create Vat Posting Groups CZ" ContosoPostingSetupCZ.InsertVATPostingSetup(CreateVATPostingGroups.Export(), VAT12S(), VAT12S(), 12, Enum::"Tax Calculation Type"::"Normal VAT", '', false, "VAT Rate CZL"::Reduced); ContosoPostingSetupCZ.InsertVATPostingSetup(CreateVATPostingGroups.Export(), VAT21I(), VAT21I(), 0, Enum::"Tax Calculation Type"::"Normal VAT", '', false, "VAT Rate CZL"::Base); ContosoPostingSetupCZ.InsertVATPostingSetup(CreateVATPostingGroups.Export(), VAT21S(), VAT21S(), 21, Enum::"Tax Calculation Type"::"Normal VAT", '', false, "VAT Rate CZL"::Base); + ContosoPostingSetupCZ.SetOverwriteData(false); end; procedure UpdateVATPostingSetup() diff --git a/Apps/CZ/IntrastatCZ/app/AppResources/CZ_DataExchDefMap.xml b/Apps/CZ/IntrastatCZ/app/AppResources/CZ_DataExchDefMap.xml index 82c98ea91b..d3658befda 100644 --- a/Apps/CZ/IntrastatCZ/app/AppResources/CZ_DataExchDefMap.xml +++ b/Apps/CZ/IntrastatCZ/app/AppResources/CZ_DataExchDefMap.xml @@ -88,7 +88,7 @@ - + diff --git a/Apps/CZ/IntrastatCZ/app/src/Codeunits/IntrastatReportManagementCZ.Codeunit.al b/Apps/CZ/IntrastatCZ/app/src/Codeunits/IntrastatReportManagementCZ.Codeunit.al index 0c6775424d..f58175d663 100644 --- a/Apps/CZ/IntrastatCZ/app/src/Codeunits/IntrastatReportManagementCZ.Codeunit.al +++ b/Apps/CZ/IntrastatCZ/app/src/Codeunits/IntrastatReportManagementCZ.Codeunit.al @@ -85,7 +85,7 @@ codeunit 31302 IntrastatReportManagementCZ TempBlob: Codeunit "Temp Blob"; XMLOutStream: OutStream; XMLInStream: InStream; - DataExchangeXMLTxt: Label 'INT_STAT_MONTHTransforming intrastat Statistics Period to month.432000000INT_STAT_YEARTransforming intrastat Statistics Period to year.1100000000INT_ARRIVALDISPATCHTransforming intrastat "Receipt" type to letter ''A'' and "Shipment" type to letter ''D''.1100000000TRIMALLRemoves all spaces5&#032;00000000INT_ITEMDESCShorten the item description to the required length.4180000000INT_ROUNDTOINTGTONERound to integer when the decimal is greater than 1.1100000000INT_ROUNDTOINTGTONERound to integer when the decimal is greater than 1.1100000000INT_ROUNDTOINTRound to integer and take into account the rounding direction setting in intrastat report setup.1100000000', + DataExchangeXMLTxt: Label 'INT_STAT_MONTHTransforming intrastat Statistics Period to month.432000000INT_STAT_YEARTransforming intrastat Statistics Period to year.1100000000INT_ARRIVALDISPATCHTransforming intrastat "Receipt" type to letter ''A'' and "Shipment" type to letter ''D''.1100000000TRIMALLRemoves all spaces5&#032;00000000INT_ITEMDESCShorten the item description to the required length.4180000000INT_ROUNDTOINTGTONERound to integer when the decimal is greater than 1.1100000000INT_ROUNDTOINTGTONERound to integer when the decimal is greater than 1.1100000000INT_ROUNDTOINTRound to integer and take into account the rounding direction setting in intrastat report setup.1100000000', Locked = true; // will be replaced with file import when available begin if DataExchDef.Get(DefaultDataExchDefCodeLbl) then diff --git a/Apps/DE/EDocumentDE/app/src/XRechnung/ExportXRechnungDocument.Codeunit.al b/Apps/DE/EDocumentDE/app/src/XRechnung/ExportXRechnungDocument.Codeunit.al index e812e3367d..e5b7895848 100644 --- a/Apps/DE/EDocumentDE/app/src/XRechnung/ExportXRechnungDocument.Codeunit.al +++ b/Apps/DE/EDocumentDE/app/src/XRechnung/ExportXRechnungDocument.Codeunit.al @@ -956,12 +956,14 @@ codeunit 13916 "Export XRechnung Document" Database::"Sales Invoice Header": begin HeaderRecordRef.SetTable(SalesInvoiceHeader); - PEPPOLMgt.FindNextSalesInvoiceRec(SalesInvoiceHeader, SalesHeader, 1); + SalesHeader.TransferFields(SalesInvoiceHeader); + SalesHeader."Document Type" := SalesHeader."Document Type"::Invoice; end; Database::"Sales Cr.Memo Header": begin HeaderRecordRef.SetTable(SalesCrMemoHeader); - PEPPOLMgt.FindNextSalesCreditMemoRec(SalesCrMemoHeader, SalesHeader, 1); + SalesHeader.TransferFields(SalesCrMemoHeader); + SalesHeader."Document Type" := SalesHeader."Document Type"::"Credit Memo"; end; end; PEPPOLMgt.GeneratePDFAttachmentAsAdditionalDocRef( diff --git a/Apps/DE/IntrastatDE/app/AppResources/DE_DataExchDefMap.xml b/Apps/DE/IntrastatDE/app/AppResources/DE_DataExchDefMap.xml index 163643202a..b89d24ffd4 100644 --- a/Apps/DE/IntrastatDE/app/AppResources/DE_DataExchDefMap.xml +++ b/Apps/DE/IntrastatDE/app/AppResources/DE_DataExchDefMap.xml @@ -140,10 +140,10 @@ - + - + @@ -374,7 +374,7 @@ - + diff --git a/Apps/DE/IntrastatDE/app/src/IntrastatReportManagementDE.Codeunit.al b/Apps/DE/IntrastatDE/app/src/IntrastatReportManagementDE.Codeunit.al index 54b33e1581..d0337be900 100644 --- a/Apps/DE/IntrastatDE/app/src/IntrastatReportManagementDE.Codeunit.al +++ b/Apps/DE/IntrastatDE/app/src/IntrastatReportManagementDE.Codeunit.al @@ -474,11 +474,11 @@ codeunit 11029 IntrastatReportManagementDE Locked = true; // will be replaced with file import when available DataExchangeXMLP3Txt: Label '', Locked = true; // will be replaced with file import when available - DataExchangeXMLP4Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer', + DataExchangeXMLP4Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer', Locked = true; // will be replaced with file import when available DataExchangeXMLP5Txt: Label '1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=TRANSACTIONACODETransaction A Code41100000.00TRANSACTIONBCODETransaction B Code42100000.00', Locked = true; // will be replaced with file import when available - DataExchangeXMLP6Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14', + DataExchangeXMLP6Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer1400ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14', Locked = true; // will be replaced with file import when available DataExchangeXMLP7Txt: Label '00ALPHANUM_ONLY00001.00=TRANSACTIONACODETransaction A Code41100000.00TRANSACTIONBCODETransaction B Code42100000.00', Locked = true; // will be replaced with file import when available diff --git a/Apps/DK/C52012DataMigration/app/src/items/C5ItemMigrator.Codeunit.al b/Apps/DK/C52012DataMigration/app/src/items/C5ItemMigrator.Codeunit.al index 757e54bdea..d1e56d8aa4 100644 --- a/Apps/DK/C52012DataMigration/app/src/items/C5ItemMigrator.Codeunit.al +++ b/Apps/DK/C52012DataMigration/app/src/items/C5ItemMigrator.Codeunit.al @@ -5,10 +5,11 @@ namespace Microsoft.DataMigration.C5; -using Microsoft.Foundation.Company; using Microsoft.Inventory.BOM; +#if CLEAN27 using Microsoft.Pricing.Asset; using Microsoft.Pricing.Source; +#endif using System.Integration; codeunit 1867 "C5 Item Migrator" @@ -447,18 +448,8 @@ codeunit 1867 "C5 Item Migrator" until C5InvenPrice.Next() = 0; end; +#if not CLEAN27 local procedure CreateSalesLineDiscountIfNeeded(C5InvenCustDisc: Record "C5 InvenCustDisc") - var - CompanyInfo: Record "Company Information"; - begin - CompanyInfo.Get(); - if CompanyInfo."Pricing Implementation" = CompanyInfo."Pricing Implementation"::"Extended Pricing" then - CreateSalesLineDiscountIfNeededExtended(C5InvenCustDisc) - else - CreateSalesLineDiscountIfNeededBasic(C5InvenCustDisc); - end; - - local procedure CreateSalesLineDiscountIfNeededBasic(C5InvenCustDisc: Record "C5 InvenCustDisc") var SalesTypeToSet: Option Customer,"Customer Disc. Group","All Customers",Campaign; TypeToSet: Option Item,"Item Disc. Group"; @@ -499,8 +490,8 @@ codeunit 1867 "C5 Item Migrator" C5InvenCustDisc.ItemRelation, C5InvenCustDisc.Rate_); end; - - local procedure CreateSalesLineDiscountIfNeededExtended(C5InvenCustDisc: Record "C5 InvenCustDisc") +#else + local procedure CreateSalesLineDiscountIfNeeded(C5InvenCustDisc: Record "C5 InvenCustDisc") var SalesTypeToSet: Enum "Price Source Type"; TypeToSet: Enum "Price Asset Type"; @@ -542,6 +533,7 @@ codeunit 1867 "C5 Item Migrator" C5InvenCustDisc.Rate_, 0); end; +#endif local procedure CreateNavCustDiscGroupIfNeeded(C5CustDiscountGroupCode: Code[10]) var @@ -566,6 +558,25 @@ codeunit 1867 "C5 Item Migrator" UninitializedItemDataMigrationFacade.CreateItemDiscGroupIfNeeded(C5DiscountGroupCode, GroupDescription); end; +#if not CLEAN27 + local procedure CreateNavSalesPriceIfNeeded(C5InvenPrice: Record "C5 InvenPrice") + var + SalesType: Option Customer,"Customer Price Group","All Customers",Campaign; + begin + CreateCustomerPriceGroupIfNeeded(C5InvenPrice.PriceGroup); + + UninitializedItemDataMigrationFacade.CreateSalesPriceIfNeeded( + SalesType::"Customer Price Group", + C5InvenPrice.PriceGroup, + C5InvenPrice.ItemNumber, + C5InvenPrice.Price, + C5InvenPrice.Currency, + 0D, + '', + 0, + ''); + end; +#else local procedure CreateNavSalesPriceIfNeeded(C5InvenPrice: Record "C5 InvenPrice") var SalesType: Enum "Price Source Type"; @@ -581,6 +592,7 @@ codeunit 1867 "C5 Item Migrator" '', '', 0, C5InvenPrice.Price); end; +#endif local procedure CreateCustomerPriceGroupIfNeeded(C5InvenPriceGroupTxt: Code[10]): Code[10] var diff --git a/Apps/DK/C52012DataMigration/test/src/C5ItemMigratorTest.Codeunit.al b/Apps/DK/C52012DataMigration/test/src/C5ItemMigratorTest.Codeunit.al index f7d3dc5914..5da9c525c6 100644 --- a/Apps/DK/C52012DataMigration/test/src/C5ItemMigratorTest.Codeunit.al +++ b/Apps/DK/C52012DataMigration/test/src/C5ItemMigratorTest.Codeunit.al @@ -239,7 +239,12 @@ codeunit 148005 "C5 Item Migrator Test" DefaultDimension: Record "Default Dimension"; DimensionValue: Record "Dimension Value"; CustomerDiscountGroup: Record "Customer Discount Group"; +#if not CLEAN27 + SalesLineDiscount: Record "Sales Line Discount"; + SalesPrice: Record "Sales Price"; +#else PriceListLine: Record "Price List Line"; +#endif CustomerPriceGroup: Record "Customer Price Group"; GenJournalLine: Record "Gen. Journal Line"; C5InvenBom: Record "C5 InvenBOM"; @@ -253,10 +258,17 @@ codeunit 148005 "C5 Item Migrator Test" CustomerDiscountGroup.DeleteAll(); Vendor.DeleteAll(); TariffNumber.DeleteAll(); +#if not CLEAN27 + SalesLineDiscount.DeleteAll(); +#endif ItemTrackingCode.DeleteAll(); DefaultDimension.DeleteAll(); DimensionValue.DeleteAll(); +#if not CLEAN27 + SalesPrice.DeleteAll(); +#else PriceListLine.DeleteAll(); +#endif CustomerPriceGroup.DeleteAll(); GenJournalLine.DeleteAll(); C5InvenBom.DeleteAll(); @@ -481,7 +493,12 @@ codeunit 148005 "C5 Item Migrator Test" ItemTrackingCode: Record "Item Tracking Code"; DefaultDimension: Record "Default Dimension"; CustomerDiscountGroup: Record "Customer Discount Group"; +#if not CLEAN27 + SalesLineDiscount: Record "Sales Line Discount"; + SalesPrice: Record "Sales Price"; +#else PriceListLine: Record "Price List Line"; +#endif CustomerPriceGroup: Record "Customer Price Group"; GenProductPostingSetup: Record "General Posting Setup"; InventoryPostingSetup: Record "Inventory Posting Setup"; @@ -512,12 +529,21 @@ codeunit 148005 "C5 Item Migrator Test" Assert.AreEqual('Super amazing discount cust', CustomerDiscountGroup.Description, 'CustomerDiscountGroup.Description'); // check inven cust disc +#if not CLEAN27 + SalesLineDiscount.SetRange(Type, SalesLineDiscount.Type::Item); + SalesLineDiscount.SetRange(Code, ItemNumTxt); + SalesLineDiscount.SetRange("Sales Type", SalesLineDiscount."Sales Type"::"Customer Disc. Group"); + SalesLineDiscount.SetRange("Sales Code", 'SuperC'); + SalesLineDiscount.SetRange("Line Discount %", 12.1); + Assert.IsFalse(SalesLineDiscount.IsEmpty(), 'The discount was not created.'); +#else PriceListLine.SetRange("Asset Type", "Price Asset Type"::Item); PriceListLine.SetRange("Asset No.", ItemNumTxt); PriceListLine.SetRange("Source Type", "Price Source Type"::"Customer Disc. Group"); PriceListLine.SetRange("Source No.", 'SuperC'); PriceListLine.SetRange("Line Discount %", 12.1); Assert.IsFalse(PriceListLine.IsEmpty(), 'The discount was not created.'); +#endif Assert.AreEqual(Item."Costing Method"::FIFO, Item."Costing Method", 'Costing Method incorrect'); Assert.AreEqual(111.11, Item."Unit Cost", 'Unit Cost incorrect'); @@ -559,6 +585,14 @@ codeunit 148005 "C5 Item Migrator Test" Assert.IsTrue(Item.PreventNegativeInventory(), 'PreventNegativeInventory incorrect'); // check price is created +#if not CLEAN27 + SalesPrice.SetRange("Sales Code", 'PREMIUM'); + SalesPrice.SetRange("Sales Type", SalesPrice."Sales Type"::"Customer Price Group"); + SalesPrice.SetRange("Item No.", ItemNumTxt); + SalesPrice.SetRange("Unit Price", 1600.80); + SalesPrice.SetRange("Currency Code", 'EUR'); + Assert.IsFalse(SalesPrice.IsEmpty(), 'The price was not created.'); +#else PriceListLine.SetRange("Source No.", 'PREMIUM'); PriceListLine.SetRange("Source Type", "Price Source Type"::"Customer Price Group"); PriceListLine.SetRange("Asset Type", "Price Asset Type"::Item); @@ -566,6 +600,7 @@ codeunit 148005 "C5 Item Migrator Test" PriceListLine.SetRange("Unit Price", 1600.80); PriceListLine.SetRange("Currency Code", 'EUR'); Assert.IsFalse(PriceListLine.IsEmpty(), 'The discount was not created.'); +#endif // check customer price group is created CustomerPriceGroup.Get('Premium'); diff --git a/Apps/DK/ContosoCoffeeDemoDatasetDK/app/DemoData/DKContosoLocalization.Codeunit.al b/Apps/DK/ContosoCoffeeDemoDatasetDK/app/DemoData/DKContosoLocalization.Codeunit.al index 4463b1b7f0..62853f2c0b 100644 --- a/Apps/DK/ContosoCoffeeDemoDatasetDK/app/DemoData/DKContosoLocalization.Codeunit.al +++ b/Apps/DK/ContosoCoffeeDemoDatasetDK/app/DemoData/DKContosoLocalization.Codeunit.al @@ -45,7 +45,7 @@ codeunit 13750 "DK Contoso Localization" if Module = Enum::"Contoso Demo Data Module"::"Human Resources Module" then HumanResource(ContosoDemoDataLevel); - UnBindSubscriptionDemoData(Module); + UnBindSubscriptionDemoData(ContosoDemoDataLevel, Module); end; local procedure HumanResource(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") @@ -198,7 +198,8 @@ codeunit 13750 "DK Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin BindSubscription(CreateInvPostingSetupDK); - BindSubscription(CreateItemDK); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemDK); BindSubscription(CreateLocationDK); end; Enum::"Contoso Demo Data Module"::Purchase: @@ -226,7 +227,7 @@ codeunit 13750 "DK Contoso Localization" end; - local procedure UnBindSubscriptionDemoData(Module: Enum "Contoso Demo Data Module") + local procedure UnBindSubscriptionDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreatePostingGroupsDK: Codeunit "Create Posting Groups DK"; CreateAnalysisViewDK: Codeunit "Create Analysis View DK"; @@ -280,7 +281,8 @@ codeunit 13750 "DK Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin UnBindSubscription(CreateInvPostingSetupDK); - UnBindSubscription(CreateItemDK); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnBindSubscription(CreateItemDK); UnBindSubscription(CreateLocationDK); end; Enum::"Contoso Demo Data Module"::Purchase: diff --git a/Apps/DK/EDocument_DK/demo data/app.json b/Apps/DK/EDocument_DK/demo data/app.json index cfb44325ef..79a02fa88b 100644 --- a/Apps/DK/EDocument_DK/demo data/app.json +++ b/Apps/DK/EDocument_DK/demo data/app.json @@ -39,6 +39,9 @@ ], "screenshots": [], "platform": "28.0.0.0", + "features": [ + "TranslationFile" + ], "idRanges": [ { "from": 13670, diff --git a/Apps/DK/ElectronicVATDeclarationDK/app/src/Engine/Communication/ElecVATDeclHttpComm.Codeunit.al b/Apps/DK/ElectronicVATDeclarationDK/app/src/Engine/Communication/ElecVATDeclHttpComm.Codeunit.al index d6590cecf4..fd18d7fb72 100644 --- a/Apps/DK/ElectronicVATDeclarationDK/app/src/Engine/Communication/ElecVATDeclHttpComm.Codeunit.al +++ b/Apps/DK/ElectronicVATDeclarationDK/app/src/Engine/Communication/ElecVATDeclHttpComm.Codeunit.al @@ -83,13 +83,15 @@ codeunit 13605 "Elec. VAT Decl. Http Comm." implements "Elec. VAT Decl. Communic ErrorNode: XmlNode; ErrorCode: Integer; ResponseText: Text; + CustomDimensions: Dictionary of [Text, Text]; begin Response.Content.ReadAs(ResponseText); if not ElecVATDeclXml.TryGetErrorNodeFromResponseText(ResponseText, ErrorNode) then exit; Evaluate(ErrorCode, ErrorNode.AsXmlElement().InnerText()); - FeatureTelemetry.LogError('0000LR0', FeatureNameTxt, StrSubstNo(ErrorTemplateErr, ErrorCode, ''), ''); + CustomDimensions.Add('ErrorCode', Format(ErrorCode)); + FeatureTelemetry.LogError('0000LR0', FeatureNameTxt, StrSubstNo(ErrorTemplateErr, ErrorCode, ''), '', '', CustomDimensions); case ErrorCode of 4801: Error(ErrorTemplateErr, ErrorCode, Error4801Err); diff --git a/Apps/DK/ElectronicVATDeclarationDK/app/src/Engine/VATReportFramework/ElecVATDeclCheckStatus.Codeunit.al b/Apps/DK/ElectronicVATDeclarationDK/app/src/Engine/VATReportFramework/ElecVATDeclCheckStatus.Codeunit.al index bc57b2ca43..8183eac8ab 100644 --- a/Apps/DK/ElectronicVATDeclarationDK/app/src/Engine/VATReportFramework/ElecVATDeclCheckStatus.Codeunit.al +++ b/Apps/DK/ElectronicVATDeclarationDK/app/src/Engine/VATReportFramework/ElecVATDeclCheckStatus.Codeunit.al @@ -15,6 +15,7 @@ codeunit 13620 "Elec. VAT Decl. Check Status" ElecVATDeclAcceptedTxt: Label 'Electronic VAT Declaration was accepted with this response', Locked = true; ElecVATDeclRejectedTxt: Label 'Electronic VAT Declaration was rejected with this response', Locked = true; EvelVATDeclResponseRcvdTxt: Label 'Electronic VAT Declaration response received', Locked = true; + CheckStatusOnRunTxt: Label 'Check VAT Return Status OnRun', Locked = true; trigger OnRun() var @@ -25,6 +26,7 @@ codeunit 13620 "Elec. VAT Decl. Check Status" ResponseText: Text; TransactionID: Code[100]; begin + FeatureTelemetry.LogUsage('0000RIW', FeatureNameTxt, CheckStatusOnRunTxt); TransactionID := ElecVATDeclCommunication.GetTransactionIDForVATReturn(Rec."No."); Response := ElecVATDeclSKATAPI.CheckVATReturnStatus(TransactionID); ResponseText := Response.GetResponseBodyAsText(); diff --git a/Apps/DK/ElectronicVATDeclarationDK/app/src/Engine/VATReportFramework/ElecVATDeclSubmit.Codeunit.al b/Apps/DK/ElectronicVATDeclarationDK/app/src/Engine/VATReportFramework/ElecVATDeclSubmit.Codeunit.al index afa56e9ff9..711c2d0798 100644 --- a/Apps/DK/ElectronicVATDeclarationDK/app/src/Engine/VATReportFramework/ElecVATDeclSubmit.Codeunit.al +++ b/Apps/DK/ElectronicVATDeclarationDK/app/src/Engine/VATReportFramework/ElecVATDeclSubmit.Codeunit.al @@ -13,6 +13,7 @@ codeunit 13613 "Elec. VAT Decl. Submit" SubmissionSuccessfulMsg: Label 'VAT Return draft submitted successfully. You need confirm the draft as final on skat.dk website.'; FeatureNameTxt: Label 'Electronic VAT Declaration DK', Locked = true; VATReturnSubmittedTxt: Label 'VAT Return Created', Locked = true; + SubmitVATReturnOnRunTxt: Label 'Submit VAT Return OnRun', Locked = true; trigger OnRun() var @@ -20,6 +21,7 @@ codeunit 13613 "Elec. VAT Decl. Submit" SubmissionTempBlob: Codeunit "Temp Blob"; HttpResponse: Interface "Elec. VAT Decl. Response"; begin + FeatureTelemetry.LogUsage('0000RIX', FeatureNameTxt, SubmitVATReturnOnRunTxt); HttpResponse := ElecVATDeclSKATAPI.SubmitVATReturn(Rec, SubmissionTempBlob); GetDeeplink(HttpResponse); ElecVATDeclArchiving.ArchiveSubmissionMessageBlob(SubmissionTempBlob, Rec); diff --git a/Apps/ES/ContosoCoffeeDemoDatasetES/app/DemoData/ESContosoLocalization.Codeunit.al b/Apps/ES/ContosoCoffeeDemoDatasetES/app/DemoData/ESContosoLocalization.Codeunit.al index e7bb4896af..0210cc85e4 100644 --- a/Apps/ES/ContosoCoffeeDemoDatasetES/app/DemoData/ESContosoLocalization.Codeunit.al +++ b/Apps/ES/ContosoCoffeeDemoDatasetES/app/DemoData/ESContosoLocalization.Codeunit.al @@ -198,7 +198,8 @@ codeunit 10824 "ES Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin BindSubscription(CreateESLocation); - BindSubscription(CreateESItem); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateESItem); end; Enum::"Contoso Demo Data Module"::Bank: begin @@ -264,7 +265,8 @@ codeunit 10824 "ES Contoso Localization" end; Enum::"Contoso Demo Data Module"::Inventory: begin - UnbindSubscription(CreateESItem); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnbindSubscription(CreateESItem); UnbindSubscription(CreateESLocation); end; Enum::"Contoso Demo Data Module"::Purchase: diff --git a/Apps/ES/EDocumentES/demo data/3.Transactions/CreateDemoEDocsES.Codeunit.al b/Apps/ES/EDocumentES/demo data/3.Transactions/CreateDemoEDocsES.Codeunit.al new file mode 100644 index 0000000000..6e97b95a66 --- /dev/null +++ b/Apps/ES/EDocumentES/demo data/3.Transactions/CreateDemoEDocsES.Codeunit.al @@ -0,0 +1,115 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.DemoData.Localization; + +using Microsoft.DemoData.Common; +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.Jobs; +using Microsoft.DemoData.Purchases; +using Microsoft.eServices.EDocument.DemoData; +using Microsoft.eServices.EDocument.Processing.Import.Purchase; +using Microsoft.Purchases.Document; + +codeunit 10888 "Create Demo E-Docs ES" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + var + ContosoInboundEDocument: Codeunit "Contoso Inbound E-Document"; + + trigger OnRun() + begin + GenerateContosoInboundEDocuments(); + end; + + procedure GetShipmentDHLInvoiceDescription(): Text[100] + var + ShipmentDHLLbl: Label 'Shipment', MaxLength = 100; + begin + exit(ShipmentDHLLbl); + end; + + local procedure GenerateContosoInboundEDocuments() + var + CreateVendor: Codeunit "Create Vendor"; + CreateESGLAccounts: Codeunit "Create ES GL Accounts"; + CreateCommonUnitOfMeasure: Codeunit "Create Common Unit Of Measure"; + CreateEDocumentMasterData: Codeunit "Create E-Document Master Data"; + CreateJobItem: Codeunit "Create Job Item"; + CreateAllocationAccount: Codeunit "Create Allocation Account"; + CreateDeferralTemplate: Codeunit "Create Deferral Template"; + EDocSamplePurchaseInvoice: Codeunit "E-Doc Sample Purchase Invoice"; + AccountingServicesJanuaryLbl: Label 'Accounting support period: January', MaxLength = 100; + AccountingServicesFebruaryLbl: Label 'Accounting support period: February', MaxLength = 100; + AccountingServicesMarchLbl: Label 'Accounting support period: March', MaxLength = 100; + AccountingServicesDecemberLbl: Label 'Accounting support period: December', MaxLength = 100; + AccountingServicesMayLbl: Label 'Accounting support period: May', MaxLength = 100; + SavedWorkDate, SampleInvoiceDate : Date; + begin + SavedWorkDate := WorkDate(); + SampleInvoiceDate := EDocSamplePurchaseInvoice.GetSampleInvoicePostingDate(); + WorkDate(SampleInvoiceDate); + ContosoInboundEDocument.AddEDocPurchaseHeader(CreateVendor.EUGraphicDesign(), SampleInvoiceDate, '245'); + ContosoInboundEDocument.AddEDocPurchaseLine( + Enum::"Purchase Line Type"::"Allocation Account", CreateAllocationAccount.Licenses(), + CreateAllocationAccount.LicensesDescription(), 6, 500, CreateDeferralTemplate.DeferralCode1Y(), ''); + ContosoInboundEDocument.Generate(); + + ContosoInboundEDocument.AddEDocPurchaseHeader(CreateVendor.DomesticFirstUp(), SampleInvoiceDate, '1419', 252); + ContosoInboundEDocument.AddEDocPurchaseLine( + Enum::"Purchase Line Type"::"G/L Account", CreateESGLAccounts.ProfessionalAdvisoryServices(), + AccountingServicesJanuaryLbl, 6, 200, '', CreateCommonUnitOfMeasure.Hour()); + ContosoInboundEDocument.Generate(); + + ContosoInboundEDocument.AddEDocPurchaseHeader(CreateVendor.DomesticFirstUp(), SampleInvoiceDate, '1425', 798); + ContosoInboundEDocument.AddEDocPurchaseLine( + Enum::"Purchase Line Type"::"G/L Account", CreateESGLAccounts.ProfessionalAdvisoryServices(), + AccountingServicesFebruaryLbl, 19, 200, '', CreateCommonUnitOfMeasure.Hour()); + ContosoInboundEDocument.Generate(); + + ContosoInboundEDocument.AddEDocPurchaseHeader(CreateVendor.DomesticFirstUp(), SampleInvoiceDate, '1437', 84); + ContosoInboundEDocument.AddEDocPurchaseLine( + Enum::"Purchase Line Type"::"G/L Account", CreateESGLAccounts.ProfessionalAdvisoryServices(), + AccountingServicesMarchLbl, 2, 200, '', CreateCommonUnitOfMeasure.Hour()); + ContosoInboundEDocument.Generate(); + + ContosoInboundEDocument.AddEDocPurchaseHeader(CreateVendor.DomesticFirstUp(), SampleInvoiceDate, '1479', 672); + ContosoInboundEDocument.AddEDocPurchaseLine( + Enum::"Purchase Line Type"::"G/L Account", CreateESGLAccounts.ProfessionalAdvisoryServices(), + AccountingServicesMayLbl, 16, 200, '', CreateCommonUnitOfMeasure.Hour()); + ContosoInboundEDocument.Generate(); + + ContosoInboundEDocument.AddEDocPurchaseHeader(CreateVendor.DomesticFirstUp(), SampleInvoiceDate, '1456', 294); + ContosoInboundEDocument.AddEDocPurchaseLine( + Enum::"Purchase Line Type"::"G/L Account", CreateESGLAccounts.ProfessionalAdvisoryServices(), + AccountingServicesDecemberLbl, 7, 200, '', CreateCommonUnitOfMeasure.Hour()); + ContosoInboundEDocument.Generate(); + + ContosoInboundEDocument.AddEDocPurchaseHeader(CreateVendor.ExportFabrikam(), SampleInvoiceDate, 'F12938'); + ContosoInboundEDocument.AddEDocPurchaseLine( + Enum::"Purchase Line Type"::Item, CreateEDocumentMasterData.WholeDecafBeansColombia(), + '', 50, 5, '', CreateCommonUnitOfMeasure.Piece()); + ContosoInboundEDocument.AddEDocPurchaseLine( + Enum::"Purchase Line Type"::Item, CreateJobItem.ItemConsumable(), + '', 50, 65, '', CreateCommonUnitOfMeasure.Piece()); + ContosoInboundEDocument.AddEDocPurchaseLine( + Enum::"Purchase Line Type"::"G/L Account", CreateESGLAccounts.Transportation(), + GetShipmentDHLInvoiceDescription(), 1, 60, '', ''); + ContosoInboundEDocument.Generate(); + + ContosoInboundEDocument.AddEDocPurchaseHeader(CreateVendor.DomesticWorldImporter(), SampleInvoiceDate, '000982', 8368.5); + ContosoInboundEDocument.AddEDocPurchaseLine( + Enum::"Purchase Line Type"::Item, CreateEDocumentMasterData.SmartGrindHome(), + '', 100, 299, '', CreateCommonUnitOfMeasure.Piece()); + ContosoInboundEDocument.AddEDocPurchaseLine( + Enum::"Purchase Line Type"::Item, CreateEDocumentMasterData.PrecisionGrindHome(), + '', 50, 199, '', CreateCommonUnitOfMeasure.Piece()); + ContosoInboundEDocument.Generate(); + WorkDate(SavedWorkDate); + end; + +} diff --git a/Apps/ES/EDocumentES/demo data/3.Transactions/CreateEDocSampleInvES.Codeunit.al b/Apps/ES/EDocumentES/demo data/3.Transactions/CreateEDocSampleInvES.Codeunit.al new file mode 100644 index 0000000000..344e2d85b6 --- /dev/null +++ b/Apps/ES/EDocumentES/demo data/3.Transactions/CreateEDocSampleInvES.Codeunit.al @@ -0,0 +1,57 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.DemoData.Localization; + +using Microsoft.DemoData.Common; +using Microsoft.DemoData.Finance; +using Microsoft.DemoData.Jobs; +using Microsoft.DemoData.Purchases; +using Microsoft.eServices.EDocument.DemoData; +using Microsoft.eServices.EDocument.Processing.Import.Purchase; +using Microsoft.Purchases.Document; + +codeunit 10889 "Create EDoc Sample Inv. ES" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + var + EDocSamplePurchaseInvoice: Codeunit "E-Doc Sample Purchase Invoice"; + CreateVendor: Codeunit "Create Vendor"; + CreateEDocumentMasterData: Codeunit "Create E-Document Master Data"; + CreateJobItem: Codeunit "Create Job Item"; + CreateCommonUnitOfMeasure: Codeunit "Create Common Unit Of Measure"; + CreateDemoEDocsES: Codeunit "Create Demo E-Docs ES"; + CreateAllocationAccount: Codeunit "Create Allocation Account"; + + trigger OnRun() + var + YearlyLicenstCostLbl: Label 'Yearly license cost mapped to a G/L account'; + BasicCoffeeEquipmentLbl: Label 'Basic coffee equipment mapped to vendor''s Item References'; + CoffeeBeansAndPartsLbl: Label 'Coffee beans and parts with shipping cost that needs human intervention'; + begin + EDocSamplePurchaseInvoice.AddInvoice(CreateVendor.ExportFabrikam(), '108239', CoffeeBeansAndPartsLbl); + EDocSamplePurchaseInvoice.AddLine( + Enum::"Purchase Line Type"::Item, CreateEDocumentMasterData.WholeDecafBeansColombia(), '', 50, 180, '', CreateCommonUnitOfMeasure.Piece()); + EDocSamplePurchaseInvoice.AddLine( + Enum::"Purchase Line Type"::Item, CreateJobItem.ItemConsumable(), '', 50, 65, '', CreateCommonUnitOfMeasure.Piece()); + EDocSamplePurchaseInvoice.AddLine( + Enum::"Purchase Line Type"::" ", '', CreateDemoEDocsES.GetShipmentDHLInvoiceDescription(), 1, 60, '', CreateCommonUnitOfMeasure.Piece()); + EDocSamplePurchaseInvoice.Generate(); + + EDocSamplePurchaseInvoice.AddInvoice(CreateVendor.DomesticWorldImporter(), '108240', BasicCoffeeEquipmentLbl, 8368.5); + EDocSamplePurchaseInvoice.AddLine( + Enum::"Purchase Line Type"::Item, CreateEDocumentMasterData.SmartGrindHome(), '', 100, 299, '', CreateCommonUnitOfMeasure.Piece()); + EDocSamplePurchaseInvoice.AddLine( + Enum::"Purchase Line Type"::Item, CreateEDocumentMasterData.PrecisionGrindHome(), '', 50, 199, '', CreateCommonUnitOfMeasure.Piece()); + EDocSamplePurchaseInvoice.Generate(); + + EDocSamplePurchaseInvoice.AddInvoice(CreateVendor.EUGraphicDesign(), '108426', YearlyLicenstCostLbl); + EDocSamplePurchaseInvoice.AddLine( + Enum::"Purchase Line Type"::" ", '', CreateAllocationAccount.LicensesDescription(), 1, 5000, '', CreateCommonUnitOfMeasure.Piece()); + EDocSamplePurchaseInvoice.Generate(); + end; +} diff --git a/Apps/ES/EDocumentES/demo data/EDocDemodataES.Codeunit.al b/Apps/ES/EDocumentES/demo data/EDocDemodataES.Codeunit.al new file mode 100644 index 0000000000..58455e08da --- /dev/null +++ b/Apps/ES/EDocumentES/demo data/EDocDemodataES.Codeunit.al @@ -0,0 +1,34 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace Microsoft.DemoData.Localization; + +using Microsoft.DemoTool; + +codeunit 10891 "EDoc. Demodata ES" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Contoso Demo Tool", 'OnAfterGeneratingDemoData', '', false, false)] + local procedure LocalizationContosoDemoData(Module: Enum "Contoso Demo Data Module"; ContosoDemoDataLevel: Enum "Contoso Demo Data Level") + begin + if Module <> Enum::"Contoso Demo Data Module"::"E-Document Contoso Module" then + exit; + EDocumentModule(ContosoDemoDataLevel); + end; + + local procedure EDocumentModule(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") + begin + case ContosoDemoDataLevel of + Enum::"Contoso Demo Data Level"::"Transactional Data": + begin + Codeunit.Run(Codeunit::"Create Demo E-Docs ES"); + Codeunit.Run(Codeunit::"Create EDoc Sample Inv. ES"); + end; + end; + end; +} diff --git a/Apps/ES/EDocumentES/demo data/ExtensionLogo.png b/Apps/ES/EDocumentES/demo data/ExtensionLogo.png new file mode 100644 index 0000000000..79a3aa399d Binary files /dev/null and b/Apps/ES/EDocumentES/demo data/ExtensionLogo.png differ diff --git a/Apps/ES/EDocumentES/demo data/app.json b/Apps/ES/EDocumentES/demo data/app.json new file mode 100644 index 0000000000..5da159297d --- /dev/null +++ b/Apps/ES/EDocumentES/demo data/app.json @@ -0,0 +1,58 @@ +{ + "id": "c9caa020-da92-4c37-b01c-00231acb1471", + "name": "E-Document Core Demo Data ES", + "publisher": "Microsoft", + "brief": "The Dynamics 365 Business Central E-Documents module enables different models of electronic invoicing, available for additional localizations.", + "description": "Business Central's E-Documents module is the foundation layer for all e-invoicing standards covering most common processes, but it can be used for other electronic documents. The module is easily extendable with the country-based e-invoicing apps. The E-Documents apps covers both sales and purchase processes and can have different lifecycles from standard invoices in Business Central.", + "version": "28.0.0.0", + "privacyStatement": "https://go.microsoft.com/fwlink/?LinkId=724009", + "EULA": "https://go.microsoft.com/fwlink/?linkid=2009120", + "help": "https://go.microsoft.com/fwlink/?linkid=2204541", + "url": "https://go.microsoft.com/fwlink/?LinkId=724011", + "logo": "ExtensionLogo.png", + "contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?linkid=2206603", + "dependencies": [ + { + "id": "e1d97edc-c239-46b4-8d84-6368bdf67c8b", + "name": "E-Document Core", + "publisher": "Microsoft", + "version": "28.0.0.0" + }, + { + "id": "de0dddf3-9917-430d-8d20-6e7679a08500", + "name": "E-Document Core Demo Data", + "publisher": "Microsoft", + "version": "28.0.0.0" + }, + { + "id": "5a0b41e9-7a42-4123-d521-2265186cfb31", + "name": "Contoso Coffee Demo Dataset", + "publisher": "Microsoft", + "version": "28.0.0.0" + }, + { + "id": "5b0a41a1-7b42-4123-a521-2265186cfb31", + "name": "Contoso Coffee Demo Dataset (ES)", + "publisher": "Microsoft", + "version": "28.0.0.0" + } + ], + "screenshots": [], + "platform": "28.0.0.0", + "features": [ + "TranslationFile" + ], + "idRanges": [ + { + "from": 10886, + "to": 10891 + } + ], + "resourceExposurePolicy": { + "allowDebugging": true, + "allowDownloadingSource": true, + "includeSourceInSymbolFile": true + }, + "application": "28.0.0.0", + "target": "OnPrem" +} diff --git a/Apps/ES/IntrastatES/app/AppResources/ES_DataExchDefMap.xml b/Apps/ES/IntrastatES/app/AppResources/ES_DataExchDefMap.xml index 5693464b7b..0c357d1474 100644 --- a/Apps/ES/IntrastatES/app/AppResources/ES_DataExchDefMap.xml +++ b/Apps/ES/IntrastatES/app/AppResources/ES_DataExchDefMap.xml @@ -17,7 +17,7 @@ - + EUCOUNTRYCODELOOKUP EU Country Lookup @@ -37,7 +37,7 @@ - + diff --git a/Apps/ES/IntrastatES/app/src/IntrastatReportManagementES.Codeunit.al b/Apps/ES/IntrastatES/app/src/IntrastatReportManagementES.Codeunit.al index 95df58d767..7b9490ca3a 100644 --- a/Apps/ES/IntrastatES/app/src/IntrastatReportManagementES.Codeunit.al +++ b/Apps/ES/IntrastatES/app/src/IntrastatReportManagementES.Codeunit.al @@ -139,6 +139,6 @@ codeunit 10790 IntrastatReportManagementES DefPrivatePersonVATNoLbl: Label 'QV999999999999', Locked = true; Def3DPartyTradeVATNoLbl: Label 'QV999999999999', Locked = true; DefUnknowVATNoLbl: Label 'QV999999999999', Locked = true; - DataExchangeXMLTxt: Label 'EUCOUNTRYCODELOOKUPEU Country Lookup13&#032;0091710.00TRIMALLRemoves all spaces5&#032;0000000.00EUCOUNTRYCODELOOKUPEU Country Lookup13&#032;0091710.00FIRSTCHARGet first character411TRIMALL00000.00TRIMALLRemoves all spaces5&#032;0000000.00', + DataExchangeXMLTxt: Label 'EUCOUNTRYCODELOOKUPEU Country Lookup13&#032;0091710.00TRIMALLRemoves all spaces5&#032;0000000.00EUCOUNTRYCODELOOKUPEU Country Lookup13&#032;0091710.00FIRSTCHARGet first character411TRIMALL00000.00TRIMALLRemoves all spaces5&#032;0000000.00', Locked = true; // will be replaced with file import when available } \ No newline at end of file diff --git a/Apps/FI/ContosoCoffeeDemoDatasetFI/app/DemoData/FIContosoLocalization.Codeunit.al b/Apps/FI/ContosoCoffeeDemoDatasetFI/app/DemoData/FIContosoLocalization.Codeunit.al index 6e2737eb2a..ac92959dd8 100644 --- a/Apps/FI/ContosoCoffeeDemoDatasetFI/app/DemoData/FIContosoLocalization.Codeunit.al +++ b/Apps/FI/ContosoCoffeeDemoDatasetFI/app/DemoData/FIContosoLocalization.Codeunit.al @@ -43,7 +43,7 @@ codeunit 13414 "FI Contoso Localization" if Module = Enum::"Contoso Demo Data Module"::Finance then FinanceModule(ContosoDemoDataLevel); - UnBindSubscriptionDemoData(Module); + UnBindSubscriptionDemoData(ContosoDemoDataLevel, Module); end; local procedure FoundationModule(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") @@ -110,7 +110,7 @@ codeunit 13414 "FI Contoso Localization" end; [EventSubscriber(ObjectType::Codeunit, Codeunit::"Contoso Demo Tool", 'OnBeforeGeneratingDemoData', '', false, false)] - local procedure OnBeforeGeneratingDemoData(Module: Enum "Contoso Demo Data Module") + local procedure OnBeforeGeneratingDemoData(Module: Enum "Contoso Demo Data Module"; ContosoDemoDataLevel: Enum "Contoso Demo Data Level") var CreateCountryRegionFI: Codeunit "Create Country Region FI"; CreateLocationFI: Codeunit "Create Location FI"; @@ -154,7 +154,8 @@ codeunit 13414 "FI Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin BindSubscription(CreateInvPostingSetupFI); - BindSubscription(CreateItemFI); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemFI); BindSubscription(CreateLocationFI); end; Enum::"Contoso Demo Data Module"::Sales: @@ -191,7 +192,7 @@ codeunit 13414 "FI Contoso Localization" end; end; - local procedure UnBindSubscriptionDemoData(Module: Enum "Contoso Demo Data Module") + local procedure UnBindSubscriptionDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateCountryRegionFI: Codeunit "Create Country Region FI"; CreateLocationFI: Codeunit "Create Location FI"; @@ -236,7 +237,8 @@ codeunit 13414 "FI Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin UnBindSubscription(CreateInvPostingSetupFI); - UnBindSubscription(CreateItemFI); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnBindSubscription(CreateItemFI); UnBindSubscription(CreateLocationFI); end; Enum::"Contoso Demo Data Module"::Sales: diff --git a/Apps/FI/IntrastatFI/app/AppResources/FI_DataExchDefMapRcpt.xml b/Apps/FI/IntrastatFI/app/AppResources/FI_DataExchDefMapRcpt.xml index 7b88ec20ec..08ef1dcbed 100644 --- a/Apps/FI/IntrastatFI/app/AppResources/FI_DataExchDefMapRcpt.xml +++ b/Apps/FI/IntrastatFI/app/AppResources/FI_DataExchDefMapRcpt.xml @@ -20,7 +20,7 @@ - + TRIMALL @@ -43,7 +43,7 @@ - + diff --git a/Apps/FI/IntrastatFI/app/AppResources/FI_DataExchDefMapShpt.xml b/Apps/FI/IntrastatFI/app/AppResources/FI_DataExchDefMapShpt.xml index 63417a693e..a667acd83e 100644 --- a/Apps/FI/IntrastatFI/app/AppResources/FI_DataExchDefMapShpt.xml +++ b/Apps/FI/IntrastatFI/app/AppResources/FI_DataExchDefMapShpt.xml @@ -20,7 +20,7 @@ - + TRIMALL @@ -43,7 +43,7 @@ - + diff --git a/Apps/FI/IntrastatFI/app/src/IntrastatReportManagementFI.Codeunit.al b/Apps/FI/IntrastatFI/app/src/IntrastatReportManagementFI.Codeunit.al index 37531ec516..4ba7aff91c 100644 --- a/Apps/FI/IntrastatFI/app/src/IntrastatReportManagementFI.Codeunit.al +++ b/Apps/FI/IntrastatFI/app/src/IntrastatReportManagementFI.Codeunit.al @@ -181,11 +181,11 @@ codeunit 13406 "Intrastat Report Management FI" DefPrivatePersonVATNoLbl: Label 'QV999999999999', Locked = true; Def3DPartyTradeVATNoLbl: Label 'QV999999999999', Locked = true; DefUnknowVATNoLbl: Label 'QV999999999999', Locked = true; - DataExchangeRcptXMLP1Txt: Label 'TRIMALLRemoves all spaces5&#032;0000000.00ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14&#032;00ALPHANUM_ONLY00001.00=', + DataExchangeRcptXMLP1Txt: Label 'TRIMALLRemoves all spaces5&#032;0000000.00ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14&#032;00ALPHANUM_ONLY00001.00=', Locked = true; // will be replaced with file import when available DataExchangeRcptXMLP2Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDUPTOINTRound up to integer14&#032;00ALPHANUM_ONLY00001.00>ADDVALUEIFNOTEMPTYAdd value it source text is not empty6^.+AAE0000000.00BLANKZEROBlank Zero6^0$00ADDVALUEIFNOTEMPTY00000.00ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14&#032;00ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14&#032;00ALPHANUM_ONLY00001.00=', Locked = true; // will be replaced with file import when available - DataExchangeShptXMLP1Txt: Label 'TRIMALLRemoves all spaces5&#032;0000000.00ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14&#032;00ALPHANUM_ONLY00001.00=', + DataExchangeShptXMLP1Txt: Label 'TRIMALLRemoves all spaces5&#032;0000000.00ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14&#032;00ALPHANUM_ONLY00001.00=', Locked = true; // will be replaced with file import when available DataExchangeShptXMLP2Txt: Label 'ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDUPTOINTRound up to integer14&#032;00ALPHANUM_ONLY00001.00>ADDVALUEIFNOTEMPTYAdd value it source text is not empty6^.+AAE0000000.00BLANKZEROBlank Zero6^0$00ADDVALUEIFNOTEMPTY00000.00ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14&#032;00ALPHANUM_ONLY00001.00=ALPHANUM_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14&#032;00ALPHANUM_ONLY00001.00=', Locked = true; // will be replaced with file import when available diff --git a/Apps/FR/ContosoCoffeeDemoDatasetFR/app/DemoData/ContosoFRLocalization.Codeunit.al b/Apps/FR/ContosoCoffeeDemoDatasetFR/app/DemoData/ContosoFRLocalization.Codeunit.al index a037931047..bf669bdc9d 100644 --- a/Apps/FR/ContosoCoffeeDemoDatasetFR/app/DemoData/ContosoFRLocalization.Codeunit.al +++ b/Apps/FR/ContosoCoffeeDemoDatasetFR/app/DemoData/ContosoFRLocalization.Codeunit.al @@ -44,7 +44,7 @@ codeunit 10864 "Contoso FR Localization" if Module = Enum::"Contoso Demo Data Module"::"Human Resources Module" then HumanResourceModule(ContosoDemoDataLevel); - UnBindSubscriptionDemoData(Module); + UnBindSubscriptionDemoData(ContosoDemoDataLevel, Module); end; local procedure FoundationModule(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") @@ -123,7 +123,7 @@ codeunit 10864 "Contoso FR Localization" end; [EventSubscriber(ObjectType::Codeunit, Codeunit::"Contoso Demo Tool", 'OnBeforeGeneratingDemoData', '', false, false)] - local procedure OnBeforeGeneratingDemoData(Module: Enum "Contoso Demo Data Module") + local procedure OnBeforeGeneratingDemoData(Module: Enum "Contoso Demo Data Module"; ContosoDemoDataLevel: Enum "Contoso Demo Data Level") var CreateResourceFR: Codeunit "Create Resource FR"; CreateVATPostingGrpFR: Codeunit "Create VAT Posting Grp FR"; @@ -162,7 +162,8 @@ codeunit 10864 "Contoso FR Localization" BindSubscription(CreateFAPostingGrpFR); Enum::"Contoso Demo Data Module"::Inventory: begin - BindSubscription(CreateItemFR); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemFR); BindSubscription(CreateLocationFR); end; Enum::"Contoso Demo Data Module"::Purchase: @@ -182,7 +183,7 @@ codeunit 10864 "Contoso FR Localization" end; end; - local procedure UnBindSubscriptionDemoData(Module: Enum "Contoso Demo Data Module") + local procedure UnBindSubscriptionDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateResourceFR: Codeunit "Create Resource FR"; CreateVATPostingGrpFR: Codeunit "Create VAT Posting Grp FR"; @@ -221,7 +222,8 @@ codeunit 10864 "Contoso FR Localization" UnbindSubscription(CreateFAPostingGrpFR); Enum::"Contoso Demo Data Module"::Inventory: begin - UnbindSubscription(CreateItemFR); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnbindSubscription(CreateItemFR); UnbindSubscription(CreateLocationFR); end; Enum::"Contoso Demo Data Module"::Purchase: diff --git a/Apps/GB/EDocument_GB/demo data/app.json b/Apps/GB/EDocument_GB/demo data/app.json index 15ac6f3bf7..266ba5cbbf 100644 --- a/Apps/GB/EDocument_GB/demo data/app.json +++ b/Apps/GB/EDocument_GB/demo data/app.json @@ -39,6 +39,9 @@ ], "screenshots": [], "platform": "28.0.0.0", + "features": [ + "TranslationFile" + ], "idRanges": [ { "from": 10545, diff --git a/Apps/GB/GovTalk/app/src/Codeunits/FeatureGovTalk.Codeunit.al b/Apps/GB/GovTalk/app/src/Codeunits/FeatureGovTalk.Codeunit.al index e6f4ea07a3..1c774b50aa 100644 --- a/Apps/GB/GovTalk/app/src/Codeunits/FeatureGovTalk.Codeunit.al +++ b/Apps/GB/GovTalk/app/src/Codeunits/FeatureGovTalk.Codeunit.al @@ -7,9 +7,7 @@ namespace Microsoft.Finance.VAT.GovTalk; using Microsoft.Finance.VAT.Reporting; using Microsoft.Foundation.Company; using Microsoft.Foundation.Navigate; -using Microsoft.Foundation.Reporting; using System.Environment.Configuration; -using System.Reflection; using System.Upgrade; codeunit 10526 "Feature - GovTalk" implements "Feature Data Update" @@ -24,7 +22,6 @@ codeunit 10526 "Feature - GovTalk" implements "Feature Data Update" var TempDocumentEntry: Record "Document Entry" temporary; - GovTalkApplicationAppIdTok: Label '{80672d74-d90a-4eb0-8f90-5b9bcea58dca}', Locked = true; DescriptionTxt: Label 'Existing records in GB BaseApp fields will be copied to GovTalk App fields'; procedure IsDataUpdateRequired(): Boolean; @@ -202,87 +199,5 @@ codeunit 10526 "Feature - GovTalk" implements "Feature Data Update" if not DataUpgradeExecuted then UpgradeTag.SetSkippedUpgrade(UpgTagGovTalk.GetGovTalkUpgradeTag(), true); end; - - procedure SetDefaultReportLayouts() - begin - SetDefaultReportLayout(Report::"EC Sales List"); - end; - - local procedure SetDefaultReportLayout(ReportID: Integer) - var - SelectedReportLayoutList: Record "Report Layout List"; - begin - SelectedReportLayoutList.SetRange("Report ID", ReportID); - SelectedReportLayoutList.SetRange(Name, 'GBlocalizationLayout'); - SelectedReportLayoutList.SetRange("Application ID", GovTalkApplicationAppIdTok); - if SelectedReportLayoutList.FindFirst() then - SetDefaultReportLayoutSelection(SelectedReportLayoutList); - SelectedReportLayoutList.Reset(); - end; - - local procedure SetDefaultReportLayoutSelection(SelectedReportLayoutList: Record "Report Layout List") - var - ReportLayoutSelection: Record "Report Layout Selection"; - CustomDimensions: Dictionary of [Text, Text]; - EmptyGuid: Guid; - SelectedCompany: Text[30]; - begin - SelectedCompany := CopyStr(CompanyName, 1, MaxStrLen(SelectedCompany)); - AddLayoutSelection(SelectedReportLayoutList, EmptyGuid, SelectedCompany); - if ReportLayoutSelection.get(SelectedReportLayoutList."Report ID", SelectedCompany) then begin - ReportLayoutSelection.Type := GetReportLayoutSelectionCorrespondingEnum(SelectedReportLayoutList); - ReportLayoutSelection.Modify(true); - end else begin - ReportLayoutSelection."Report ID" := SelectedReportLayoutList."Report ID"; - ReportLayoutSelection."Company Name" := SelectedCompany; - ReportLayoutSelection."Custom Report Layout Code" := ''; - ReportLayoutSelection.Type := GetReportLayoutSelectionCorrespondingEnum(SelectedReportLayoutList); - ReportLayoutSelection.Insert(true); - end; - - InitReportLayoutListDimensions(SelectedReportLayoutList, CustomDimensions); - AddReportLayoutDimensionsAction('SetDefault', CustomDimensions); - end; - - local procedure AddLayoutSelection(SelectedReportLayoutList: Record "Report Layout List"; UserId: Guid; SelectedCompany: Text[30]): Boolean - var - TenantReportLayoutSelection: Record "Tenant Report Layout Selection"; - begin - TenantReportLayoutSelection.Init(); - TenantReportLayoutSelection."App ID" := SelectedReportLayoutList."Application ID"; - TenantReportLayoutSelection."Company Name" := SelectedCompany; - TenantReportLayoutSelection."Layout Name" := SelectedReportLayoutList."Name"; - TenantReportLayoutSelection."Report ID" := SelectedReportLayoutList."Report ID"; - TenantReportLayoutSelection."User ID" := UserId; - - if not TenantReportLayoutSelection.Insert(true) then - TenantReportLayoutSelection.Modify(true); - end; - - local procedure GetReportLayoutSelectionCorrespondingEnum(SelectedReportLayoutList: Record "Report Layout List"): Integer - begin - case SelectedReportLayoutList."Layout Format" of - - SelectedReportLayoutList."Layout Format"::RDLC: - exit(0); - SelectedReportLayoutList."Layout Format"::Word: - exit(1); - SelectedReportLayoutList."Layout Format"::Excel: - exit(3); - SelectedReportLayoutList."Layout Format"::Custom: - exit(4); - end - end; - - local procedure InitReportLayoutListDimensions(ReportLayoutList: Record "Report Layout List"; var CustomDimensions: Dictionary of [Text, Text]) - begin - CustomDimensions.Set('ReportId', Format(ReportLayoutList."Report ID")); - CustomDimensions.Set('LayoutName', ReportLayoutList."Name"); - end; - - local procedure AddReportLayoutDimensionsAction(Action: Text; var CustomDimensions: Dictionary of [Text, Text]) - begin - CustomDimensions.Add('Action', Action); - end; } #endif \ No newline at end of file diff --git a/Apps/GB/GovTalk/app/src/Codeunits/GovTalkHelperProcedures.Codeunit.al b/Apps/GB/GovTalk/app/src/Codeunits/GovTalkHelperProcedures.Codeunit.al new file mode 100644 index 0000000000..116176c1cc --- /dev/null +++ b/Apps/GB/GovTalk/app/src/Codeunits/GovTalkHelperProcedures.Codeunit.al @@ -0,0 +1,164 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Finance.VAT.GovTalk; + +using Microsoft.Finance.VAT.Reporting; +using Microsoft.Foundation.Reporting; +using System.Environment.Configuration; +using System.Reflection; + +codeunit 10561 "GovTalk Helper Procedures" +{ + Access = Internal; + + var + GovTalkApplicationAppIdTok: Label '{80672d74-d90a-4eb0-8f90-5b9bcea58dca}', Locked = true; + + procedure TransferRecords(SourceTableId: Integer; TargetTableId: Integer) + var + SourceField: Record Field; + SourceRecRef: RecordRef; + TargetRecRef: RecordRef; + TargetFieldRef: FieldRef; + SourceFieldRef: FieldRef; + SourceFieldRefNo: Integer; + begin + SourceRecRef.Open(SourceTableId, false); + TargetRecRef.Open(TargetTableId, false); + + if SourceRecRef.IsEmpty() then + exit; + + if SourceRecRef.FindSet() then + repeat + Clear(SourceField); + SourceField.SetRange(TableNo, SourceTableId); + SourceField.SetRange(Class, SourceField.Class::Normal); + SourceField.SetRange(Enabled, true); + if SourceField.Findset() then + repeat + SourceFieldRefNo := SourceField."No."; + SourceFieldRef := SourceRecRef.Field(SourceFieldRefNo); + TargetFieldRef := TargetRecRef.Field(SourceFieldRefNo); + TargetFieldRef.VALUE := SourceFieldRef.VALUE; + until SourceField.Next() = 0; + TargetRecRef.Insert(); + until SourceRecRef.Next() = 0; + SourceRecRef.Close(); + TargetRecRef.Close(); + end; + + procedure UpgradeVATReportHeaderStatus() + var + VATReportHeader: Record "VAT Report Header"; + begin + if VATReportHeader.FindSet() then + repeat + if VATReportHeader.Status.AsInteger() = 7 then + VATReportHeader.Status := VATReportHeader.Status::"Part. Accepted"; + VATReportHeader.Modify(); + until VATReportHeader.Next() = 0; + end; + + procedure TransferFields(TableId: Integer; SourceFieldNo: Integer; TargetFieldNo: Integer) + var + RecRef: RecordRef; + TargetFieldRef: FieldRef; + SourceFieldRef: FieldRef; + begin + RecRef.Open(TableId, false); + SourceFieldRef := RecRef.Field(SourceFieldNo); + SourceFieldRef.SetFilter('<>%1', ''); + + if RecRef.FindSet() then + repeat + TargetFieldRef := RecRef.Field(TargetFieldNo); + TargetFieldRef.VALUE := SourceFieldRef.VALUE; + RecRef.Modify(false); + until RecRef.Next() = 0; + end; + + procedure SetDefaultReportLayouts() + begin + SetDefaultReportLayout(Report::"EC Sales List"); + end; + + local procedure SetDefaultReportLayout(ReportID: Integer) + var + SelectedReportLayoutList: Record "Report Layout List"; + begin + SelectedReportLayoutList.SetRange("Report ID", ReportID); + SelectedReportLayoutList.SetRange(Name, 'GBlocalizationLayout'); + SelectedReportLayoutList.SetRange("Application ID", GovTalkApplicationAppIdTok); + if SelectedReportLayoutList.FindFirst() then + SetDefaultReportLayoutSelection(SelectedReportLayoutList); + SelectedReportLayoutList.Reset(); + end; + + local procedure SetDefaultReportLayoutSelection(SelectedReportLayoutList: Record "Report Layout List") + var + ReportLayoutSelection: Record "Report Layout Selection"; + CustomDimensions: Dictionary of [Text, Text]; + EmptyGuid: Guid; + SelectedCompany: Text[30]; + begin + SelectedCompany := CopyStr(CompanyName, 1, MaxStrLen(SelectedCompany)); + AddLayoutSelection(SelectedReportLayoutList, EmptyGuid, SelectedCompany); + if ReportLayoutSelection.get(SelectedReportLayoutList."Report ID", SelectedCompany) then begin + ReportLayoutSelection.Type := GetReportLayoutSelectionCorrespondingEnum(SelectedReportLayoutList); + ReportLayoutSelection.Modify(true); + end else begin + ReportLayoutSelection."Report ID" := SelectedReportLayoutList."Report ID"; + ReportLayoutSelection."Company Name" := SelectedCompany; + ReportLayoutSelection."Custom Report Layout Code" := ''; + ReportLayoutSelection.Type := GetReportLayoutSelectionCorrespondingEnum(SelectedReportLayoutList); + ReportLayoutSelection.Insert(true); + end; + + InitReportLayoutListDimensions(SelectedReportLayoutList, CustomDimensions); + AddReportLayoutDimensionsAction('SetDefault', CustomDimensions); + end; + + local procedure AddLayoutSelection(SelectedReportLayoutList: Record "Report Layout List"; UserId: Guid; SelectedCompany: Text[30]): Boolean + var + TenantReportLayoutSelection: Record "Tenant Report Layout Selection"; + begin + TenantReportLayoutSelection.Init(); + TenantReportLayoutSelection."App ID" := SelectedReportLayoutList."Application ID"; + TenantReportLayoutSelection."Company Name" := SelectedCompany; + TenantReportLayoutSelection."Layout Name" := SelectedReportLayoutList."Name"; + TenantReportLayoutSelection."Report ID" := SelectedReportLayoutList."Report ID"; + TenantReportLayoutSelection."User ID" := UserId; + + if not TenantReportLayoutSelection.Insert(true) then + TenantReportLayoutSelection.Modify(true); + end; + + local procedure GetReportLayoutSelectionCorrespondingEnum(SelectedReportLayoutList: Record "Report Layout List"): Integer + begin + case SelectedReportLayoutList."Layout Format" of + + SelectedReportLayoutList."Layout Format"::RDLC: + exit(0); + SelectedReportLayoutList."Layout Format"::Word: + exit(1); + SelectedReportLayoutList."Layout Format"::Excel: + exit(3); + SelectedReportLayoutList."Layout Format"::Custom: + exit(4); + end + end; + + local procedure InitReportLayoutListDimensions(ReportLayoutList: Record "Report Layout List"; var CustomDimensions: Dictionary of [Text, Text]) + begin + CustomDimensions.Set('ReportId', Format(ReportLayoutList."Report ID")); + CustomDimensions.Set('LayoutName', ReportLayoutList."Name"); + end; + + local procedure AddReportLayoutDimensionsAction(Action: Text; var CustomDimensions: Dictionary of [Text, Text]) + begin + CustomDimensions.Add('Action', Action); + end; +} \ No newline at end of file diff --git a/Apps/GB/GovTalk/app/src/Codeunits/InstallGovTalk.Codeunit.al b/Apps/GB/GovTalk/app/src/Codeunits/InstallGovTalk.Codeunit.al new file mode 100644 index 0000000000..dfc6115998 --- /dev/null +++ b/Apps/GB/GovTalk/app/src/Codeunits/InstallGovTalk.Codeunit.al @@ -0,0 +1,58 @@ +#if CLEAN27 +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Finance.VAT.GovTalk; + +using Microsoft.Finance.VAT.Reporting; +using Microsoft.Foundation.Company; +using System.Upgrade; + +codeunit 10560 "Install GovTalk" +{ + Access = Internal; + Subtype = Install; + + var + UpgradeTag: Codeunit "Upgrade Tag"; + UpgTagGovTalk: Codeunit "Upg. Tag GovTalk"; + + trigger OnInstallAppPerCompany() + var + CurrentModuleInfo: ModuleInfo; + begin + NavApp.GetCurrentModuleInfo(CurrentModuleInfo); + if CurrentModuleInfo.AppVersion().Major() < 30 then + exit; + + InstallGovTalk(); + end; + + local procedure InstallGovTalk() + var + GovTalkHelperProcedures: Codeunit "GovTalk Helper Procedures"; + GovTalkMessageTableId: Integer; + GovTalkMessagePartsTableId: Integer; + GovTalkSetupTableId: Integer; + begin + if UpgradeTag.HasUpgradeTag(UpgTagGovTalk.GetGovTalkUpgradeTag()) then + exit; + + GovTalkHelperProcedures.TransferFields(Database::"Company Information", 10507, 10509); // 10507 - the existing field "Branch Number", 10509 - the new field "Branch Number GB"; + GovTalkHelperProcedures.TransferFields(Database::"ECSL VAT Report Line", 10500, 10502); // 10500 - the existing field "Line Status", 10502 - the new field "Line Status GB"; + GovTalkHelperProcedures.TransferFields(Database::"ECSL VAT Report Line", 10501, 10503); // 10501 - the existing field "XML Part Id", 10503 - the new field "XML Part Id GB"; + GovTalkHelperProcedures.TransferFields(Database::"VAT Reports Configuration", 10500, 10501); // 10500 - the existing field "Content Max Lines", 10501 - the new field "Content Max Lines GB"; + GovTalkMessageTableId := 10520; + GovTalkMessagePartsTableId := 10524; + GovTalkSetupTableId := 10523; + GovTalkHelperProcedures.TransferRecords(GovTalkMessageTableId, Database::"GovTalk Message"); + GovTalkHelperProcedures.TransferRecords(GovTalkMessagePartsTableId, Database::"GovTalk Msg. Parts"); + GovTalkHelperProcedures.TransferRecords(GovTalkSetupTableId, Database::"Gov Talk Setup"); + GovTalkHelperProcedures.UpgradeVATReportHeaderStatus(); + GovTalkHelperProcedures.SetDefaultReportLayouts(); + + UpgradeTag.SetUpgradeTag(UpgTagGovTalk.GetGovTalkUpgradeTag()); + end; +} +#endif \ No newline at end of file diff --git a/Apps/GB/GovTalk/app/src/Codeunits/UpgTagGovTalk.Codeunit.al b/Apps/GB/GovTalk/app/src/Codeunits/UpgTagGovTalk.Codeunit.al index 959d0d82ae..33194ef6bf 100644 --- a/Apps/GB/GovTalk/app/src/Codeunits/UpgTagGovTalk.Codeunit.al +++ b/Apps/GB/GovTalk/app/src/Codeunits/UpgTagGovTalk.Codeunit.al @@ -1,4 +1,3 @@ -#if not CLEAN27 // ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. @@ -9,9 +8,6 @@ using System.Upgrade; codeunit 10588 "Upg. Tag GovTalk" { - ObsoleteReason = 'Feature GovTalk will be enabled by default in version 30.0.'; - ObsoleteState = Pending; - ObsoleteTag = '27.0'; Access = Internal; [EventSubscriber(ObjectType::Codeunit, Codeunit::"Upgrade Tag", 'OnGetPerCompanyUpgradeTags', '', false, false)] @@ -24,5 +20,4 @@ codeunit 10588 "Upg. Tag GovTalk" begin exit('MS-581204-GovTalkUpgradeTag-20250710'); end; -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/Apps/GB/GovTalk/app/src/Codeunits/UpgradeGovTalk.Codeunit.al b/Apps/GB/GovTalk/app/src/Codeunits/UpgradeGovTalk.Codeunit.al index f8025b51fe..7a1d24a941 100644 --- a/Apps/GB/GovTalk/app/src/Codeunits/UpgradeGovTalk.Codeunit.al +++ b/Apps/GB/GovTalk/app/src/Codeunits/UpgradeGovTalk.Codeunit.al @@ -1,4 +1,4 @@ -#if not CLEAN27 +#if CLEAN27 // ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. @@ -7,7 +7,6 @@ namespace Microsoft.Finance.VAT.GovTalk; using Microsoft.Finance.VAT.Reporting; using Microsoft.Foundation.Company; -using System.Reflection; using System.Upgrade; codeunit 10587 "Upgrade GovTalk" @@ -32,91 +31,28 @@ codeunit 10587 "Upgrade GovTalk" local procedure UpgradeGovTalk() var - FeatureGovTalk: Codeunit "Feature - GovTalk"; + GovTalkHelperProcedures: Codeunit "GovTalk Helper Procedures"; + GovTalkMessageTableId: Integer; + GovTalkMessagePartsTableId: Integer; + GovTalkSetupTableId: Integer; begin if UpgradeTag.HasUpgradeTag(UpgTagGovTalk.GetGovTalkUpgradeTag()) then exit; - TransferFields(Database::"Company Information", 10509, 10507); // 10509 - the new field "Branch Number GB", 10507; the existing field "Branch Number"; - TransferFields(Database::"ECSL VAT Report Line", 10502, 10500); // 10502 - the new field "Line Status GB", 10500; the existing field "Line Status"; - TransferFields(Database::"ECSL VAT Report Line", 10503, 10501); // 10503 - the new field "XML Part Id GB", 10501; the existing field "XML Part Id"; - TransferFields(Database::"VAT Reports Configuration", 10501, 10500); // 10501 - the new field "Content Max Lines GB", 10500; the existing field "Content Max Lines"; -#pragma warning disable AL0797 - TransferRecords(Database::"GovTalkMessage", Database::"GovTalk Message"); -#pragma warning restore AL0797 - TransferRecords(Database::"GovTalk Message Parts", Database::"GovTalk Msg. Parts"); -#pragma warning disable AL0797 - TransferRecords(Database::"GovTalk Setup", Database::"Gov Talk Setup"); -#pragma warning restore AL0797 - UpgradeVATReportHeaderStatus(); - FeatureGovTalk.SetDefaultReportLayouts(); + GovTalkHelperProcedures.TransferFields(Database::"Company Information", 10507, 10509); // 10507 - the existing field "Branch Number", 10509 - the new field "Branch Number GB"; + GovTalkHelperProcedures.TransferFields(Database::"ECSL VAT Report Line", 10500, 10502); // 10500 - the existing field "Line Status", 10502 - the new field "Line Status GB"; + GovTalkHelperProcedures.TransferFields(Database::"ECSL VAT Report Line", 10501, 10503); // 10501 - the existing field "XML Part Id", 10503 - the new field "XML Part Id GB"; + GovTalkHelperProcedures.TransferFields(Database::"VAT Reports Configuration", 10500, 10501); // 10500 - the existing field "Content Max Lines", 10501 - the new field "Content Max Lines GB"; + GovTalkMessageTableId := 10520; + GovTalkMessagePartsTableId := 10524; + GovTalkSetupTableId := 10523; + GovTalkHelperProcedures.TransferRecords(GovTalkMessageTableId, Database::"GovTalk Message"); + GovTalkHelperProcedures.TransferRecords(GovTalkMessagePartsTableId, Database::"GovTalk Msg. Parts"); + GovTalkHelperProcedures.TransferRecords(GovTalkSetupTableId, Database::"Gov Talk Setup"); + GovTalkHelperProcedures.UpgradeVATReportHeaderStatus(); + GovTalkHelperProcedures.SetDefaultReportLayouts(); UpgradeTag.SetUpgradeTag(UpgTagGovTalk.GetGovTalkUpgradeTag()); end; - - local procedure TransferRecords(SourceTableId: Integer; TargetTableId: Integer) - var - SourceField: Record Field; - SourceRecRef: RecordRef; - TargetRecRef: RecordRef; - TargetFieldRef: FieldRef; - SourceFieldRef: FieldRef; - SourceFieldRefNo: Integer; - begin - SourceRecRef.Open(SourceTableId, false); - TargetRecRef.Open(TargetTableId, false); - - if SourceRecRef.IsEmpty() then - exit; - - SourceRecRef.FindSet(); - - repeat - Clear(SourceField); - SourceField.SetRange(TableNo, SourceTableId); - SourceField.SetRange(Class, SourceField.Class::Normal); - SourceField.SetRange(Enabled, true); - if SourceField.Findset() then - repeat - SourceFieldRefNo := SourceField."No."; - SourceFieldRef := SourceRecRef.Field(SourceFieldRefNo); - TargetFieldRef := TargetRecRef.Field(SourceFieldRefNo); - TargetFieldRef.VALUE := SourceFieldRef.VALUE; - until SourceField.Next() = 0; - TargetRecRef.Insert(); - until SourceRecRef.Next() = 0; - SourceRecRef.Close(); - TargetRecRef.Close(); - end; - - local procedure UpgradeVATReportHeaderStatus() - var - VATReportHeader: Record "VAT Report Header"; - begin - if VATReportHeader.FindSet() then - repeat - if VATReportHeader.Status.AsInteger() = 7 then - VATReportHeader.Status := VATReportHeader.Status::"Part. Accepted"; - VATReportHeader.Modify(); - until VATReportHeader.Next() = 0; - end; - - local procedure TransferFields(TableId: Integer; SourceFieldNo: Integer; TargetFieldNo: Integer) - var - RecRef: RecordRef; - TargetFieldRef: FieldRef; - SourceFieldRef: FieldRef; - begin - RecRef.Open(TableId, false); - SourceFieldRef := RecRef.Field(SourceFieldNo); - SourceFieldRef.SetFilter('<>%1', ''); - - if RecRef.FindSet() then - repeat - TargetFieldRef := RecRef.Field(TargetFieldNo); - TargetFieldRef.VALUE := SourceFieldRef.VALUE; - RecRef.Modify(false); - until RecRef.Next() = 0; - end; } #endif \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/ExtensionLogo.png b/Apps/GB/IdealPostcodes/app/ExtensionLogo.png new file mode 100644 index 0000000000..fbd8df877b Binary files /dev/null and b/Apps/GB/IdealPostcodes/app/ExtensionLogo.png differ diff --git a/Apps/GB/IdealPostcodes/app/Permissions/d365basicidealpostcodes.permissionsetext.al b/Apps/GB/IdealPostcodes/app/Permissions/d365basicidealpostcodes.permissionsetext.al new file mode 100644 index 0000000000..1b25cb5c06 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/Permissions/d365basicidealpostcodes.permissionsetext.al @@ -0,0 +1,12 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Security.AccessControl; + +permissionsetextension 9412 "D365 BASIC - IdealPostcodes" extends "D365 BASIC" +{ + IncludedPermissionSets = "IdealPostcodes View"; +} diff --git a/Apps/GB/IdealPostcodes/app/Permissions/d365basicisvidealpostcodes.permissionsetext.al b/Apps/GB/IdealPostcodes/app/Permissions/d365basicisvidealpostcodes.permissionsetext.al new file mode 100644 index 0000000000..a2100d835a --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/Permissions/d365basicisvidealpostcodes.permissionsetext.al @@ -0,0 +1,12 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Security.AccessControl; + +permissionsetextension 9411 "D365 BASIC ISV - IdealPostcodes" extends "D365 BASIC ISV" +{ + IncludedPermissionSets = "IdealPostcodes View"; +} diff --git a/Apps/GB/IdealPostcodes/app/Permissions/d365busfullidealpostcodes.permissionsetext.al b/Apps/GB/IdealPostcodes/app/Permissions/d365busfullidealpostcodes.permissionsetext.al new file mode 100644 index 0000000000..1a5974a7de --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/Permissions/d365busfullidealpostcodes.permissionsetext.al @@ -0,0 +1,12 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Security.AccessControl; + +permissionsetextension 9410 "D365 BUS FULL IdealPostcodes" extends "D365 BUS FULL ACCESS" +{ + IncludedPermissionSets = "IdealPostcodes View"; +} diff --git a/Apps/GB/IdealPostcodes/app/Permissions/d365buspremiumidealpostcodes.permissionsetext.al b/Apps/GB/IdealPostcodes/app/Permissions/d365buspremiumidealpostcodes.permissionsetext.al new file mode 100644 index 0000000000..bfe8cd6b02 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/Permissions/d365buspremiumidealpostcodes.permissionsetext.al @@ -0,0 +1,12 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Security.AccessControl; + +permissionsetextension 9409 "D365 BUS PREMIUM - IdealPostcodes" extends "D365 BUS PREMIUM" +{ + IncludedPermissionSets = "IdealPostcodes View"; +} diff --git a/Apps/GB/IdealPostcodes/app/Permissions/d365fullidealpostcodes.permissionsetext.al b/Apps/GB/IdealPostcodes/app/Permissions/d365fullidealpostcodes.permissionsetext.al new file mode 100644 index 0000000000..fa9f7139f2 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/Permissions/d365fullidealpostcodes.permissionsetext.al @@ -0,0 +1,12 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Security.AccessControl; + +permissionsetextension 9408 "D365 FULL - IdealPostcodes" extends "D365 FULL ACCESS" +{ + IncludedPermissionSets = "IdealPostcodes View"; +} diff --git a/Apps/GB/IdealPostcodes/app/Permissions/d365readidealpostcodes.permissionsetext.al b/Apps/GB/IdealPostcodes/app/Permissions/d365readidealpostcodes.permissionsetext.al new file mode 100644 index 0000000000..4cc4fdb5cf --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/Permissions/d365readidealpostcodes.permissionsetext.al @@ -0,0 +1,12 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Security.AccessControl; + +permissionsetextension 9407 "D365 READ - IdealPostcodes" extends "D365 READ" +{ + IncludedPermissionSets = "IdealPostcodes Read"; +} diff --git a/Apps/GB/IdealPostcodes/app/Permissions/d365teammidealpostcodes.permissionsetext.al b/Apps/GB/IdealPostcodes/app/Permissions/d365teammidealpostcodes.permissionsetext.al new file mode 100644 index 0000000000..91de244b81 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/Permissions/d365teammidealpostcodes.permissionsetext.al @@ -0,0 +1,12 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Security.AccessControl; + +permissionsetextension 9406 "D365 TEAM M. IdealPostcodes" extends "D365 TEAM MEMBER" +{ + IncludedPermissionSets = "IdealPostcodes Read"; +} diff --git a/Apps/GB/IdealPostcodes/app/Permissions/idealpostcodeslocal.permissionsetext.al b/Apps/GB/IdealPostcodes/app/Permissions/idealpostcodeslocal.permissionsetext.al new file mode 100644 index 0000000000..624fe533cf --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/Permissions/idealpostcodeslocal.permissionsetext.al @@ -0,0 +1,12 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Security.AccessControl; + +permissionsetextension 9404 "IdealPostcodes Local" extends LOCAL +{ + IncludedPermissionSets = "IdealPostcodes View"; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/Permissions/idealpostcodeslocalread.permissionsetext.al b/Apps/GB/IdealPostcodes/app/Permissions/idealpostcodeslocalread.permissionsetext.al new file mode 100644 index 0000000000..c8af27761d --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/Permissions/idealpostcodeslocalread.permissionsetext.al @@ -0,0 +1,12 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Security.AccessControl; + +permissionsetextension 9405 "IdealPostcodes Local Read" extends "LOCAL READ" +{ + IncludedPermissionSets = "IdealPostcodes Read"; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/Permissions/idealpostcodesread.permissionset.al b/Apps/GB/IdealPostcodes/app/Permissions/idealpostcodesread.permissionset.al new file mode 100644 index 0000000000..026b5a31d2 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/Permissions/idealpostcodesread.permissionset.al @@ -0,0 +1,10 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +permissionset 9400 "IdealPostcodes Read" +{ + Permissions = tabledata "IPC Config" = R; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/Permissions/idealpostcodesview.permissionset.al b/Apps/GB/IdealPostcodes/app/Permissions/idealpostcodesview.permissionset.al new file mode 100644 index 0000000000..fb74ab9704 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/Permissions/idealpostcodesview.permissionset.al @@ -0,0 +1,11 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +permissionset 9401 "IdealPostcodes View" +{ + IncludedPermissionSets = "IdealPostcodes Read"; + Permissions = tabledata "IPC Config" = IMD; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/Permissions/intcloudidealpostcodes.permissionsetext.al b/Apps/GB/IdealPostcodes/app/Permissions/intcloudidealpostcodes.permissionsetext.al new file mode 100644 index 0000000000..422d1b4a80 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/Permissions/intcloudidealpostcodes.permissionsetext.al @@ -0,0 +1,12 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Security.AccessControl; + +permissionsetextension 9402 "Int. Cloud - IdealPostcodes" extends "INTELLIGENT CLOUD" +{ + IncludedPermissionSets = "IdealPostcodes View"; +} diff --git a/Apps/GB/IdealPostcodes/app/app.json b/Apps/GB/IdealPostcodes/app/app.json new file mode 100644 index 0000000000..45364a1ee3 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/app.json @@ -0,0 +1,40 @@ +{ + "id": "c62d3f56-16a4-484f-878a-330583985eeb", + "name": "IdealPostcodes", + "publisher": "Microsoft", + "brief": "Get accurate addresses in United Kingdom based on post codes", + "description": "This extension connects to an external service to verify and get the correct address based on a local address database. Whenever you specify a customer, vendor, contact, or any address in the United Kingdom, this extension helps you make verify that you got the right address.", + "version": "28.0.0.0", + "privacyStatement": "https://go.microsoft.com/fwlink/?LinkId=724009", + "EULA": "https://go.microsoft.com/fwlink/?linkid=2009120", + "help": "https://go.microsoft.com/fwlink/?LinkId=724009", + "url": "https://go.microsoft.com/fwlink/?LinkId=724011", + "contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?LinkId=724009", + "logo": "ExtensionLogo.png", + "dependencies": [], + "idRanges": [ + { + "from": 9400, + "to": 9415 + } + ], + "internalsVisibleTo": [ + { + "id": "5cd5fc9e-9760-467c-adfb-35ff35ee4cce", + "name": "IdealPostcodes Tests", + "publisher": "Microsoft" + } + ], + "features": [ + "TranslationFile" + ], + "resourceExposurePolicy": { + "allowDebugging": true, + "allowDownloadingSource": true, + "includeSourceInSymbolFile": true + }, + "screenshots": [], + "platform": "28.0.0.0", + "target": "Cloud", + "application": "28.0.0.0" +} diff --git a/Apps/GB/IdealPostcodes/app/ext/IPCBankAccountCard.PageExt.al b/Apps/GB/IdealPostcodes/app/ext/IPCBankAccountCard.PageExt.al new file mode 100644 index 0000000000..ec6f21dfc7 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/ext/IPCBankAccountCard.PageExt.al @@ -0,0 +1,107 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.Bank.BankAccount; + +pageextension 9402 "IPC Bank Account Card" extends "Bank Account Card" +{ + layout + { + modify(Address) + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Post Code") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Country/Region Code") + { + trigger OnBeforeValidate() + begin + HandleAddressLookupVisibility(); + end; + } + addfirst(Communication) + { + group(Control1040007_IdealPostcodes) + { + ShowCaption = false; + Visible = AddressLookupTextEnabled; + field(LookupAddress_IdealPostcodes; LookupAddressLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + ShowPostcodeLookup(true); + end; + } + } + } + moveafter("Address 2"; City, CountyGroup) + } + + actions + { + addlast(processing) + { + action(LookupPostcode) + { + ApplicationArea = All; + Image = Find; + Enabled = AddressLookupTextEnabled; + Caption = 'Lookup Address'; + ToolTip = 'Search for address using postcode provider'; + + trigger OnAction() + begin + ShowPostcodeLookup(true); + end; + } + } + } + + var + IPCAddressLookupHelper: Codeunit "IPC Address Lookup Helper"; + AddressLookupTextEnabled: Boolean; + LookupAddressLbl: Label 'Lookup address from postcode'; + + trigger OnAfterGetCurrRecord() + begin + HandleAddressLookupVisibility(); + end; + + local procedure HandleAddressLookupVisibility() + begin + AddressLookupTextEnabled := CurrPage.Editable() and IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code"); + end; + + local procedure ShowPostcodeLookup(UpdatePage: Boolean) + var + BankAccount: Record "Bank Account"; + RecRef: RecordRef; + begin + if not IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code") then + exit; + + CurrPage.SaveRecord(); + BankAccount.Copy(Rec); + RecRef.GetTable(BankAccount); + IPCAddressLookupHelper.LookupAndUpdateAddress(RecRef, Rec.FieldNo(Address), Rec.FieldNo("Address 2"), Rec.FieldNo(City), Rec.FieldNo("Post Code"), Rec.FieldNo(County), Rec.FieldNo("Country/Region Code")); + RecRef.SetTable(BankAccount); + BankAccount.Modify(); + + if UpdatePage then begin + CurrPage.SetRecord(BankAccount); + CurrPage.Update(); + end; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/ext/IPCCompanyInformation.PageExt.al b/Apps/GB/IdealPostcodes/app/ext/IPCCompanyInformation.PageExt.al new file mode 100644 index 0000000000..42d5556063 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/ext/IPCCompanyInformation.PageExt.al @@ -0,0 +1,179 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.Foundation.Company; + +pageextension 9403 "IPC Company Information" extends "Company Information" +{ + layout + { + modify(Address) + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Post Code") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + ShowPostcodeLookupForAddress(false); + end; + } + modify("Country/Region Code") + { + trigger OnBeforeValidate() + begin + HandleAddressLookupVisibility(); + end; + } + modify("Ship-to Post Code") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + ShowPostcodeLookupForShipToAddress(false); + end; + } + modify("Ship-to Country/Region Code") + { + trigger OnBeforeValidate() + begin + HandleAddressLookupVisibility(); + end; + } + modify("Ship-to Address") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + addfirst(Shipping) + { + group(Control1040016_GB) + { + ShowCaption = false; + Visible = ShipToAddressLookupTextEnabled; + field(LookupShipToAddress_IdealPostcodes; LookupShipToAddressLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + ShowPostcodeLookupForShipToAddress(true); + end; + } + } + } + addfirst(Communication) + { + group(General_IdealPostCodes) + { + ShowCaption = false; + Visible = AddressLookupTextEnabled; + field(LookupAddress_IdealPostcodes; LookupAddressLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + ShowPostcodeLookupForAddress(true); + end; + } + } + } + } + actions + { + addlast(processing) + { + action(LookupPostcode) + { + ApplicationArea = All; + Image = Find; + Enabled = AddressLookupTextEnabled; + Caption = 'Lookup Address'; + ToolTip = 'Search for address using postcode provider'; + + trigger OnAction() + begin + ShowPostcodeLookupForAddress(true); + end; + } + action(LookupShipToPostcode) + { + ApplicationArea = All; + Image = Find; + Enabled = ShipToAddressLookupTextEnabled; + Caption = 'Lookup Ship-to Address'; + ToolTip = 'Search for ship-to address using postcode provider'; + + trigger OnAction() + begin + ShowPostcodeLookupForShipToAddress(true); + end; + } + } + } + + var + IPCAddressLookupHelper: Codeunit "IPC Address Lookup Helper"; + AddressLookupTextEnabled: Boolean; + ShipToAddressLookupTextEnabled: Boolean; + LookupAddressLbl: Label 'Lookup address from postcode'; + LookupShipToAddressLbl: Label 'Lookup ship-to address from postcode'; + + trigger OnAfterGetCurrRecord() + begin + HandleAddressLookupVisibility(); + end; + + local procedure HandleAddressLookupVisibility() + begin + AddressLookupTextEnabled := CurrPage.Editable() and IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code"); + ShipToAddressLookupTextEnabled := CurrPage.Editable() and IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Ship-to Country/Region Code"); + end; + + local procedure ShowPostcodeLookupForAddress(UpdatePage: Boolean) + var + CompanyInformation: Record "Company Information"; + RecRef: RecordRef; + begin + if not IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code") then + exit; + + CurrPage.SaveRecord(); + CompanyInformation.Copy(Rec); + RecRef.GetTable(CompanyInformation); + IPCAddressLookupHelper.LookupAndUpdateAddress(RecRef, Rec.FieldNo(Address), Rec.FieldNo("Address 2"), Rec.FieldNo(City), Rec.FieldNo("Post Code"), Rec.FieldNo(County), Rec.FieldNo("Country/Region Code")); + RecRef.SetTable(CompanyInformation); + + if UpdatePage then begin + CurrPage.SetRecord(CompanyInformation); + CurrPage.Update(); + end; + end; + + local procedure ShowPostcodeLookupForShipToAddress(UpdatePage: Boolean) + var + RecRef: RecordRef; + begin + if not IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Ship-to Country/Region Code") then + exit; + CurrPage.SaveRecord(); + RecRef.GetTable(Rec); + IPCAddressLookupHelper.LookupAndUpdateAddress(RecRef, Rec.FieldNo("Ship-to Address"), Rec.FieldNo("Ship-to Address 2"), Rec.FieldNo("Ship-to City"), Rec.FieldNo("Ship-to Post Code"), Rec.FieldNo("Ship-to County"), Rec.FieldNo("Ship-to Country/Region Code")); + RecRef.SetTable(Rec); + + if UpdatePage then begin + Rec.Modify(); + CurrPage.Update(true); + end; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/ext/IPCContactAltAddressCard.PageExt.al b/Apps/GB/IdealPostcodes/app/ext/IPCContactAltAddressCard.PageExt.al new file mode 100644 index 0000000000..69c1346e35 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/ext/IPCContactAltAddressCard.PageExt.al @@ -0,0 +1,106 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.CRM.Contact; + +pageextension 9404 "IPC Contact Alt. Address Card" extends "Contact Alt. Address Card" +{ + layout + { + modify(Address) + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Post Code") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Country/Region Code") + { + trigger OnBeforeValidate() + begin + HandleAddressLookupVisibility(); + end; + } + addfirst(General) + { + group(General_IdealPostCodes) + { + ShowCaption = false; + Visible = AddressLookupTextEnabled; + field(LookupAddress_IdealPostcodes; LookupAddressLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + ShowPostcodeLookup(true); + end; + } + } + } + moveafter("Address 2"; "Post Code", City) + } + + actions + { + addlast(processing) + { + action(LookupPostcode) + { + ApplicationArea = All; + Image = Find; + Enabled = AddressLookupTextEnabled; + Caption = 'Lookup Address'; + ToolTip = 'Search for address using postcode provider'; + + trigger OnAction() + begin + ShowPostcodeLookup(true); + end; + } + } + } + + var + IPCAddressLookupHelper: Codeunit "IPC Address Lookup Helper"; + AddressLookupTextEnabled: Boolean; + LookupAddressLbl: Label 'Lookup address from postcode'; + + trigger OnAfterGetCurrRecord() + begin + HandleAddressLookupVisibility(); + end; + + local procedure HandleAddressLookupVisibility() + begin + AddressLookupTextEnabled := CurrPage.Editable() and IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code"); + end; + + local procedure ShowPostcodeLookup(UpdatePage: Boolean) + var + ContactAltAddress: Record "Contact Alt. Address"; + RecRef: RecordRef; + begin + if not IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code") then + exit; + + CurrPage.SaveRecord(); + ContactAltAddress.Copy(Rec); + RecRef.GetTable(ContactAltAddress); + IPCAddressLookupHelper.LookupAndUpdateAddress(RecRef, Rec.FieldNo(Address), Rec.FieldNo("Address 2"), Rec.FieldNo(City), Rec.FieldNo("Post Code"), Rec.FieldNo(County), Rec.FieldNo("Country/Region Code")); + RecRef.SetTable(ContactAltAddress); + + if UpdatePage then begin + CurrPage.SetRecord(ContactAltAddress); + CurrPage.Update(); + end; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/ext/IPCContactCard.PageExt.al b/Apps/GB/IdealPostcodes/app/ext/IPCContactCard.PageExt.al new file mode 100644 index 0000000000..81ec1d9f56 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/ext/IPCContactCard.PageExt.al @@ -0,0 +1,105 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.CRM.Contact; + +pageextension 9405 "IPC Contact Card" extends "Contact Card" +{ + layout + { + modify(Address) + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Post Code") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Country/Region Code") + { + trigger OnBeforeValidate() + begin + HandleAddressLookupVisibility(); + end; + } + addfirst(Control37) + { + group(Control1040001_IdealPostcodes) + { + ShowCaption = false; + Visible = AddressLookupTextEnabled; + field(LookupAddress_IdealPostcodes; LookupAddressLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + ShowPostcodeLookup(true); + end; + } + } + } + moveafter("Address 2"; "Country/Region Code") + } + + actions + { + addlast(processing) + { + action(LookupPostcode) + { + ApplicationArea = All; + Image = Find; + Enabled = AddressLookupTextEnabled; + Caption = 'Lookup Address'; + ToolTip = 'Search for address using postcode provider'; + + trigger OnAction() + begin + ShowPostcodeLookup(true); + end; + } + } + } + + var + IPCAddressLookupHelper: Codeunit "IPC Address Lookup Helper"; + AddressLookupTextEnabled: Boolean; + LookupAddressLbl: Label 'Lookup address from postcode'; + + trigger OnAfterGetCurrRecord() + begin + HandleAddressLookupVisibility(); + end; + + local procedure HandleAddressLookupVisibility() + begin + AddressLookupTextEnabled := CurrPage.Editable() and IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code"); + end; + + local procedure ShowPostcodeLookup(UpdatePage: Boolean) + var + Contact: Record Contact; + RecRef: RecordRef; + begin + if not IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code") then + exit; + + Contact.Copy(Rec); + RecRef.GetTable(Contact); + IPCAddressLookupHelper.LookupAndUpdateAddress(RecRef, Rec.FieldNo(Address), Rec.FieldNo("Address 2"), Rec.FieldNo(City), Rec.FieldNo("Post Code"), Rec.FieldNo(County), Rec.FieldNo("Country/Region Code")); + RecRef.SetTable(Contact); + + if UpdatePage then begin + CurrPage.SetRecord(Contact); + CurrPage.Update(); + end; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/ext/IPCCustomerBankAccountCard.PageExt.al b/Apps/GB/IdealPostcodes/app/ext/IPCCustomerBankAccountCard.PageExt.al new file mode 100644 index 0000000000..de9eb20ed8 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/ext/IPCCustomerBankAccountCard.PageExt.al @@ -0,0 +1,107 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.Sales.Customer; + +pageextension 9406 "IPC Customer Bank Account Card" extends "Customer Bank Account Card" +{ + layout + { + modify(Address) + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Post Code") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Country/Region Code") + { + trigger OnBeforeValidate() + begin + HandleAddressLookupVisibility(); + end; + } + addafter(Name) + { + group(Control1040004_IdealPostcodes) + { + ShowCaption = false; + Visible = AddressLookupTextEnabled; + field(LookupAddress_IdealPostcodes; LookupAddressLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + ShowPostcodeLookup(true); + end; + } + } + } + moveafter(Contact; "Post Code") + moveafter(City; CountyGroup) + } + + actions + { + addlast(processing) + { + action(LookupPostcode) + { + ApplicationArea = All; + Image = Find; + Enabled = AddressLookupTextEnabled; + Caption = 'Lookup Address'; + ToolTip = 'Search for address using postcode provider'; + + trigger OnAction() + begin + ShowPostcodeLookup(true); + end; + } + } + } + + var + IPCAddressLookupHelper: Codeunit "IPC Address Lookup Helper"; + AddressLookupTextEnabled: Boolean; + LookupAddressLbl: Label 'Lookup address from postcode'; + + trigger OnAfterGetCurrRecord() + begin + HandleAddressLookupVisibility(); + end; + + local procedure HandleAddressLookupVisibility() + begin + AddressLookupTextEnabled := CurrPage.Editable() and IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code"); + end; + + local procedure ShowPostcodeLookup(UpdatePage: Boolean) + var + CustomerBankAccount: Record "Customer Bank Account"; + RecRef: RecordRef; + begin + if not IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code") then + exit; + + CurrPage.SaveRecord(); + CustomerBankAccount.Copy(Rec); + RecRef.GetTable(CustomerBankAccount); + IPCAddressLookupHelper.LookupAndUpdateAddress(RecRef, Rec.FieldNo(Address), Rec.FieldNo("Address 2"), Rec.FieldNo(City), Rec.FieldNo("Post Code"), Rec.FieldNo(County), Rec.FieldNo("Country/Region Code")); + RecRef.SetTable(CustomerBankAccount); + + if UpdatePage then begin + CurrPage.SetRecord(CustomerBankAccount); + CurrPage.Update(); + end; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/ext/IPCCustomerCard.PageExt.al b/Apps/GB/IdealPostcodes/app/ext/IPCCustomerCard.PageExt.al new file mode 100644 index 0000000000..ca4afd55a4 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/ext/IPCCustomerCard.PageExt.al @@ -0,0 +1,105 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.Sales.Customer; + +pageextension 9407 "IPC Customer Card" extends "Customer Card" +{ + layout + { + modify(Address) + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Post Code") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Country/Region Code") + { + trigger OnBeforeValidate() + begin + HandleAddressLookupVisibility(); + end; + } + addfirst("Address & Contact") + { + group(Control1040004_IdealPostcodes) + { + ShowCaption = false; + Visible = AddressLookupTextEnabled; + field(LookupAddress_IdealPostcodes; LookupAddressLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + ShowPostcodeLookup(true); + end; + } + } + } + } + + actions + { + addlast(processing) + { + action(LookupPostcode) + { + ApplicationArea = All; + Image = Find; + Enabled = AddressLookupTextEnabled; + Caption = 'Lookup Address'; + ToolTip = 'Search for address using postcode provider'; + + trigger OnAction() + begin + ShowPostcodeLookup(true); + end; + } + } + } + + var + IPCAddressLookupHelper: Codeunit "IPC Address Lookup Helper"; + AddressLookupTextEnabled: Boolean; + LookupAddressLbl: Label 'Lookup address from postcode'; + + trigger OnAfterGetCurrRecord() + begin + HandleAddressLookupVisibility(); + end; + + local procedure HandleAddressLookupVisibility() + begin + AddressLookupTextEnabled := CurrPage.Editable() and IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code"); + end; + + local procedure ShowPostcodeLookup(UpdatePage: Boolean) + var + Customer: Record Customer; + RecRef: RecordRef; + begin + if not IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code") then + exit; + + CurrPage.SaveRecord(); + Customer.Copy(Rec); + RecRef.GetTable(Customer); + IPCAddressLookupHelper.LookupAndUpdateAddress(RecRef, Rec.FieldNo(Address), Rec.FieldNo("Address 2"), Rec.FieldNo(City), Rec.FieldNo("Post Code"), Rec.FieldNo(County), Rec.FieldNo("Country/Region Code")); + RecRef.SetTable(Customer); + + if UpdatePage then begin + CurrPage.SetRecord(Customer); + CurrPage.Update(); + end; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/ext/IPCEmployeeCard.PageExt.al b/Apps/GB/IdealPostcodes/app/ext/IPCEmployeeCard.PageExt.al new file mode 100644 index 0000000000..8766e4c505 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/ext/IPCEmployeeCard.PageExt.al @@ -0,0 +1,106 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.HumanResources.Employee; + +pageextension 9408 "IPC Employee Card" extends "Employee Card" +{ + layout + { + modify(Address) + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Post Code") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Country/Region Code") + { + trigger OnBeforeValidate() + begin + HandleAddressLookupVisibility(); + end; + } + addfirst(Control13) + { + group(Control1040007_IdealPostcodes) + { + ShowCaption = false; + Visible = AddressLookupTextEnabled; + field(LookupAddress_IdealPostcodes; LookupAddressLbl) + { + ApplicationArea = BasicHR; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + ShowPostcodeLookup(true); + end; + } + } + } + } + + actions + { + addlast(processing) + { + action(LookupPostcode) + { + ApplicationArea = All; + Image = Find; + Enabled = AddressLookupTextEnabled; + Caption = 'Lookup Address'; + ToolTip = 'Search for address using postcode provider'; + + trigger OnAction() + begin + ShowPostcodeLookup(true); + end; + } + } + } + + var + IPCAddressLookupHelper: Codeunit "IPC Address Lookup Helper"; + AddressLookupTextEnabled: Boolean; + LookupAddressLbl: Label 'Lookup address from postcode'; + + trigger OnAfterGetCurrRecord() + begin + HandleAddressLookupVisibility(); + end; + + local procedure HandleAddressLookupVisibility() + begin + AddressLookupTextEnabled := CurrPage.Editable() and IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code"); + end; + + local procedure ShowPostcodeLookup(UpdatePage: Boolean) + var + Employee: Record Employee; + RecRef: RecordRef; + begin + if not IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code") then + exit; + + CurrPage.SaveRecord(); + Employee.Copy(Rec); + RecRef.GetTable(Employee); + IPCAddressLookupHelper.LookupAndUpdateAddress(RecRef, Rec.FieldNo(Address), Rec.FieldNo("Address 2"), Rec.FieldNo(City), Rec.FieldNo("Post Code"), Rec.FieldNo(County), Rec.FieldNo("Country/Region Code")); + RecRef.SetTable(Employee); + Employee.Modify(); + + if UpdatePage then begin + CurrPage.SetRecord(Employee); + CurrPage.Update(); + end; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/ext/IPCLocationCard.PageExt.al b/Apps/GB/IdealPostcodes/app/ext/IPCLocationCard.PageExt.al new file mode 100644 index 0000000000..33fb481a66 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/ext/IPCLocationCard.PageExt.al @@ -0,0 +1,106 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.Inventory.Location; + +pageextension 9409 "IPC Location Card" extends "Location Card" +{ + layout + { + modify(Address) + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Post Code") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Country/Region Code") + { + trigger OnBeforeValidate() + begin + HandleAddressLookupVisibility(); + end; + } + addfirst(AddressDetails) + { + group(Control1040003_IdealPostcodes) + { + ShowCaption = false; + Visible = AddressLookupTextEnabled; + field(LookupAddress_IdealPostcodes; LookupAddressLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + ShowPostcodeLookup(true); + end; + } + } + } + moveafter(CountyGroup; "Post Code", "Country/Region Code") + } + + actions + { + addlast(processing) + { + action(LookupPostcode) + { + ApplicationArea = All; + Image = Find; + Enabled = AddressLookupTextEnabled; + Caption = 'Lookup Address'; + ToolTip = 'Search for address using postcode provider'; + + trigger OnAction() + begin + ShowPostcodeLookup(true); + end; + } + } + } + + var + IPCAddressLookupHelper: Codeunit "IPC Address Lookup Helper"; + AddressLookupTextEnabled: Boolean; + LookupAddressLbl: Label 'Lookup address from postcode'; + + trigger OnAfterGetCurrRecord() + begin + HandleAddressLookupVisibility(); + end; + + local procedure HandleAddressLookupVisibility() + begin + AddressLookupTextEnabled := CurrPage.Editable() and IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code"); + end; + + local procedure ShowPostcodeLookup(UpdatePage: Boolean) + var + Location: Record Location; + RecRef: RecordRef; + begin + if not IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code") then + exit; + + CurrPage.SaveRecord(); + Location.Copy(Rec); + RecRef.GetTable(Location); + IPCAddressLookupHelper.LookupAndUpdateAddress(RecRef, Rec.FieldNo(Address), Rec.FieldNo("Address 2"), Rec.FieldNo(City), Rec.FieldNo("Post Code"), Rec.FieldNo(County), Rec.FieldNo("Country/Region Code")); + RecRef.SetTable(Location); + + if UpdatePage then begin + CurrPage.SetRecord(Location); + CurrPage.Update(); + end; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/ext/IPCResourceCard.PageExt.al b/Apps/GB/IdealPostcodes/app/ext/IPCResourceCard.PageExt.al new file mode 100644 index 0000000000..a240fc62d9 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/ext/IPCResourceCard.PageExt.al @@ -0,0 +1,105 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.Projects.Resources.Resource; + +pageextension 9410 "IPC Resource Card" extends "Resource Card" +{ + layout + { + modify(Address) + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Post Code") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Country/Region Code") + { + trigger OnBeforeValidate() + begin + HandleAddressLookupVisibility(); + end; + } + addfirst("Personal Data") + { + group(Control1040003_IdealPostcodes) + { + ShowCaption = false; + Visible = AddressLookupTextEnabled; + field(LookupAddress_IdealPostcodes; LookupAddressLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + ShowPostcodeLookup(true); + end; + } + } + } + } + + actions + { + addlast(processing) + { + action(LookupPostcode) + { + ApplicationArea = All; + Image = Find; + Enabled = AddressLookupTextEnabled; + Caption = 'Lookup Address'; + ToolTip = 'Search for address using postcode provider'; + + trigger OnAction() + begin + ShowPostcodeLookup(true); + end; + } + } + } + + var + IPCAddressLookupHelper: Codeunit "IPC Address Lookup Helper"; + AddressLookupTextEnabled: Boolean; + LookupAddressLbl: Label 'Lookup address from postcode'; + + trigger OnAfterGetCurrRecord() + begin + HandleAddressLookupVisibility(); + end; + + local procedure HandleAddressLookupVisibility() + begin + AddressLookupTextEnabled := CurrPage.Editable() and IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code"); + end; + + local procedure ShowPostcodeLookup(UpdatePage: Boolean) + var + Resource: Record Resource; + RecRef: RecordRef; + begin + if not IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code") then + exit; + + CurrPage.SaveRecord(); + Resource.Copy(Rec); + RecRef.GetTable(Resource); + IPCAddressLookupHelper.LookupAndUpdateAddress(RecRef, Rec.FieldNo(Address), Rec.FieldNo("Address 2"), Rec.FieldNo(City), Rec.FieldNo("Post Code"), Rec.FieldNo(County), Rec.FieldNo("Country/Region Code")); + RecRef.SetTable(Resource); + + if UpdatePage then begin + CurrPage.SetRecord(Resource); + CurrPage.Update(); + end; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/ext/IPCShipToAddress.PageExt.al b/Apps/GB/IdealPostcodes/app/ext/IPCShipToAddress.PageExt.al new file mode 100644 index 0000000000..4f8fa3dddd --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/ext/IPCShipToAddress.PageExt.al @@ -0,0 +1,105 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.Sales.Customer; + +pageextension 9411 "IPC Ship-to Address" extends "Ship-to Address" +{ + layout + { + modify(Address) + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Post Code") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Country/Region Code") + { + trigger OnBeforeValidate() + begin + HandleAddressLookupVisibility(); + end; + } + addfirst(Control13) + { + group(Control1040006_IdealPostcodes) + { + ShowCaption = false; + Visible = AddressLookupTextEnabled; + field(LookupAddress_IdealPostcodes; LookupAddressLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + ShowPostcodeLookup(true); + end; + } + } + } + } + + actions + { + addlast(processing) + { + action(LookupPostcode) + { + ApplicationArea = All; + Image = Find; + Enabled = AddressLookupTextEnabled; + Caption = 'Lookup Address'; + ToolTip = 'Search for address using postcode provider'; + + trigger OnAction() + begin + ShowPostcodeLookup(true); + end; + } + } + } + + var + IPCAddressLookupHelper: Codeunit "IPC Address Lookup Helper"; + AddressLookupTextEnabled: Boolean; + LookupAddressLbl: Label 'Lookup address from postcode'; + + trigger OnAfterGetCurrRecord() + begin + HandleAddressLookupVisibility(); + end; + + local procedure HandleAddressLookupVisibility() + begin + AddressLookupTextEnabled := CurrPage.Editable() and IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code"); + end; + + local procedure ShowPostcodeLookup(UpdatePage: Boolean) + var + ShipToAddress: Record "Ship-to Address"; + RecRef: RecordRef; + begin + if not IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code") then + exit; + + CurrPage.SaveRecord(); + ShipToAddress.Copy(Rec); + RecRef.GetTable(ShipToAddress); + IPCAddressLookupHelper.LookupAndUpdateAddress(RecRef, Rec.FieldNo(Address), Rec.FieldNo("Address 2"), Rec.FieldNo(City), Rec.FieldNo("Post Code"), Rec.FieldNo(County), Rec.FieldNo("Country/Region Code")); + RecRef.SetTable(ShipToAddress); + + if UpdatePage then begin + CurrPage.SetRecord(ShipToAddress); + CurrPage.Update(); + end; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/ext/IPCVendorCard.PageExt.al b/Apps/GB/IdealPostcodes/app/ext/IPCVendorCard.PageExt.al new file mode 100644 index 0000000000..9d16acbc1a --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/ext/IPCVendorCard.PageExt.al @@ -0,0 +1,105 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.Purchases.Vendor; + +pageextension 9401 "IPC Vendor Card" extends "Vendor Card" +{ + layout + { + modify(Address) + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Post Code") + { + trigger OnBeforeValidate() + begin + IPCAddressLookupHelper.NotifyUserAboutAddressProviderCapabilities(); + end; + } + modify("Country/Region Code") + { + trigger OnBeforeValidate() + begin + HandleAddressLookupVisibility(); + end; + } + addfirst(AddressDetails) + { + group(Control1040003_IdealPostcodes) + { + ShowCaption = false; + Visible = AddressLookupTextEnabled; + field(LookupAddress_IdealPostcodes; LookupAddressLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + ShowPostcodeLookup(true); + end; + } + } + } + } + + actions + { + addlast(processing) + { + action(LookupPostcode) + { + ApplicationArea = All; + Image = Find; + Enabled = AddressLookupTextEnabled; + Caption = 'Lookup Address'; + ToolTip = 'Search for address using postcode provider'; + + trigger OnAction() + begin + ShowPostcodeLookup(true); + end; + } + } + } + + var + IPCAddressLookupHelper: Codeunit "IPC Address Lookup Helper"; + AddressLookupTextEnabled: Boolean; + LookupAddressLbl: Label 'Lookup address from postcode'; + + trigger OnAfterGetCurrRecord() + begin + HandleAddressLookupVisibility(); + end; + + local procedure HandleAddressLookupVisibility() + begin + AddressLookupTextEnabled := CurrPage.Editable() and IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code"); + end; + + local procedure ShowPostcodeLookup(UpdatePage: Boolean) + var + Vendor: Record Vendor; + RecRef: RecordRef; + begin + if not IPCAddressLookupHelper.ConfiguredAndSupportedForRecord(Rec."Country/Region Code") then + exit; + + CurrPage.SaveRecord(); + Vendor.Copy(Rec); + RecRef.GetTable(Vendor); + IPCAddressLookupHelper.LookupAndUpdateAddress(RecRef, Rec.FieldNo(Address), Rec.FieldNo("Address 2"), Rec.FieldNo(City), Rec.FieldNo("Post Code"), Rec.FieldNo(County), Rec.FieldNo("Country/Region Code")); + RecRef.SetTable(Vendor); + + if UpdatePage then begin + CurrPage.SetRecord(Vendor); + CurrPage.Update(); + end; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/src/IPCAddressLookup.Page.al b/Apps/GB/IdealPostcodes/app/src/IPCAddressLookup.Page.al new file mode 100644 index 0000000000..a17eb9df43 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/src/IPCAddressLookup.Page.al @@ -0,0 +1,74 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +page 9402 "IPC Address Lookup" +{ + PageType = List; + ApplicationArea = All; + SourceTable = "IPC Address Lookup"; + SourceTableTemporary = true; + Caption = 'Select Address'; + Editable = false; + + layout + { + area(Content) + { + repeater(Addresses) + { + field("Display Text"; Rec."Display Text") + { + ApplicationArea = All; + ToolTip = 'Specifies address information'; + } + field(Address; Rec.Address) + { + ApplicationArea = All; + ToolTip = 'Specifies street address'; + } + field(City; Rec.City) + { + ApplicationArea = All; + ToolTip = 'Specifies city or town'; + } + field("Post Code"; Rec."Post Code") + { + ApplicationArea = All; + ToolTip = 'Specifies post code'; + } + } + } + } + + actions + { + area(Processing) + { + action(Select) + { + ApplicationArea = All; + Caption = 'Select'; + Tooltip = 'Select'; + Image = Approve; + + trigger OnAction() + begin + CurrPage.Close(); + end; + } + } + } + + internal procedure SetRecords(var TempIPCAddressLookup: Record "IPC Address Lookup" temporary) + begin + if TempIPCAddressLookup.FindSet() then + repeat + Rec := TempIPCAddressLookup; + Rec.Insert(); + until TempIPCAddressLookup.Next() = 0; + end; + + internal procedure GetSelectedAddress(var SelectedAddress: Record "IPC Address Lookup") + begin + SelectedAddress := Rec; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/src/IPCAddressLookup.Table.al b/Apps/GB/IdealPostcodes/app/src/IPCAddressLookup.Table.al new file mode 100644 index 0000000000..0fe2785f8f --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/src/IPCAddressLookup.Table.al @@ -0,0 +1,65 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +table 9401 "IPC Address Lookup" +{ + TableType = Temporary; + Caption = 'IdealPostcodes Address Lookup'; + Access = Internal; + + fields + { + field(1; "Entry No."; Integer) + { + Caption = 'Entry No.'; + DataClassification = SystemMetadata; + } + field(2; "Address ID"; Text[100]) + { + Caption = 'Address ID'; + DataClassification = CustomerContent; + } + field(3; "Display Text"; Text[250]) + { + Caption = 'Display Text'; + DataClassification = EndUserIdentifiableInformation; + } + field(10; Address; Text[100]) + { + Caption = 'Address'; + DataClassification = EndUserIdentifiableInformation; + } + field(11; "Address 2"; Text[50]) + { + Caption = 'Address 2'; + DataClassification = EndUserIdentifiableInformation; + } + field(12; City; Text[30]) + { + Caption = 'City'; + DataClassification = EndUserIdentifiableInformation; + } + field(13; "Post Code"; Code[20]) + { + Caption = 'Post Code'; + DataClassification = EndUserIdentifiableInformation; + } + field(14; County; Text[30]) + { + Caption = 'County'; + DataClassification = EndUserIdentifiableInformation; + } + field(15; "Country/Region Code"; Code[10]) + { + Caption = 'Country/Region Code'; + DataClassification = EndUserIdentifiableInformation; + } + } + + keys + { + key(PK; "Entry No.") + { + Clustered = true; + } + } +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/src/IPCAddressLookupHelper.Codeunit.al b/Apps/GB/IdealPostcodes/app/src/IPCAddressLookupHelper.Codeunit.al new file mode 100644 index 0000000000..0e9e261bc2 --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/src/IPCAddressLookupHelper.Codeunit.al @@ -0,0 +1,194 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.Foundation.Address; +using System.Environment.Configuration; + +codeunit 9401 "IPC Address Lookup Helper" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + Permissions = tabledata "Post Code" = ri; + + var + AwarenessNotificationNameTxt: Label 'Notify the user of address provider capabilities.'; + AwarenessNotificationDescriptionTxt: Label 'Turns the user''s attention to the address provider capabilities.'; + UserDisabledNotificationTxt: Label 'The user disabled notification %1.', Locked = true; + AwarenessNotificationTxt: Label 'You can use an address provider to retrieve and validate addresses based on postcodes.'; + SetUpNotificationActionTxt: Label 'Set it up here.'; + DisableNotificationTxt: Label 'Disable this notification.'; + + procedure LookupAndUpdateAddress(var RecRef: RecordRef; AddressFieldNo: Integer; Address2FieldNo: Integer; CityFieldNo: Integer; PostCodeFieldNo: Integer; CountyFieldNo: Integer; CountryCodeFieldNo: Integer) + var + IPCManagement: Codeunit "IPC Management"; + Address: Text[100]; + Address2: Text[50]; + City: Text[30]; + PostCode: Code[20]; + County: Text[30]; + CountryCode: Code[10]; + begin + // Get current values + Address := CopyStr(GetFieldValue(RecRef, AddressFieldNo), 1, MaxStrLen(Address)); + Address2 := CopyStr(GetFieldValue(RecRef, Address2FieldNo), 1, MaxStrLen(Address2)); + City := CopyStr(GetFieldValue(RecRef, CityFieldNo), 1, MaxStrLen(City)); + PostCode := CopyStr(GetFieldValue(RecRef, PostCodeFieldNo), 1, MaxStrLen(PostCode)); + County := CopyStr(GetFieldValue(RecRef, CountyFieldNo), 1, MaxStrLen(County)); + CountryCode := CopyStr(GetFieldValue(RecRef, CountryCodeFieldNo), 1, MaxStrLen(CountryCode)); + + // Perform lookup + IPCManagement.LookupAddress(Address, Address2, City, PostCode, County, CountryCode); + + // Update record + SetFieldValue(RecRef, AddressFieldNo, Address); + SetFieldValue(RecRef, Address2FieldNo, Address2); + SetFieldValue(RecRef, CityFieldNo, City); + SetFieldValue(RecRef, PostCodeFieldNo, PostCode); + SetFieldValue(RecRef, CountyFieldNo, County); + SetFieldValue(RecRef, CountryCodeFieldNo, CountryCode); + + CreateNewPostcodeIfNotExists(City, PostCode, County, CountryCode); + end; + + local procedure CreateNewPostcodeIfNotExists(City: Text[30]; PostCodeValue: Code[20]; County: Text[30]; CountryRegionCode: Code[10]) + var + PostCode: Record "Post Code"; + begin + if (City = '') or (PostCodeValue = '') then + exit; + + // Entered postcode already exists + PostCode.SetRange(Code, PostCodeValue); + PostCode.SetRange(City, City); + if not PostCode.IsEmpty() then + exit; + + // Otherwise create one + PostCode.Init(); + PostCode.Code := PostCodeValue; + PostCode.City := City; + PostCode."Search City" := UpperCase(City); + PostCode."Country/Region Code" := CountryRegionCode; + PostCode.County := County; + PostCode.Insert(); + end; + + procedure SupportedCountryOrRegionCode(CountryOrRegionCode: Code[10]): Boolean + begin + exit(CountryOrRegionCode in ['GB', 'UK', 'IE', 'NL', 'SG', '']); + end; + + [EventSubscriber(ObjectType::Page, Page::"My Notifications", 'OnInitializingNotificationWithDefaultState', '', false, false)] + local procedure OnInitializingNotificationWithDefaultState(); + var + MyNotifications: Record "My Notifications"; + begin + MyNotifications.InsertDefault(GetAwarenessNotificationId(), AwarenessNotificationNameTxt, AwarenessNotificationDescriptionTxt, true); + end; + + procedure NotifyUserAboutAddressProviderCapabilities() + var + MyNotifications: Record "My Notifications"; + IPCProvider: Codeunit "IPC Provider"; + PostCodeServiceManager: Codeunit "Postcode Service Manager"; + AwarenessNotification: Notification; + IsConfigured: Boolean; + begin + if not MyNotifications.IsEnabled(GetAwarenessNotificationId()) then + exit; + + PostCodeServiceManager.IsServiceConfigured(IPCProvider.GetServiceKey(), IsConfigured); + if IsConfigured then + exit; + + AwarenessNotification.Id(GetAwarenessNotificationId()); + AwarenessNotification.SetData('NotificationId', GetAwarenessNotificationId()); + AwarenessNotification.Message(AwarenessNotificationTxt); + AwarenessNotification.AddAction(SetUpNotificationActionTxt, Codeunit::"IPC Address Lookup Helper", 'NotificationOnConfigure'); + AwarenessNotification.AddAction(DisableNotificationTxt, Codeunit::"IPC Address Lookup Helper", 'DisableNotificationForUser'); + AwarenessNotification.Send(); + end; + + procedure GetAwarenessNotificationId(): Guid; + begin + exit('a5480dd3-24d2-4540-9492-3cba865956d0'); + end; + + procedure DisableNotificationForUser(HostNotification: Notification) + var + MyNotifications: Record "My Notifications"; + NotificationId: Text; + begin + NotificationId := HostNotification.GetData('NotificationId'); + if MyNotifications.Get(UserId(), NotificationId) then + MyNotifications.Disable(NotificationId) + else + MyNotifications.InsertDefault(NotificationId, GetNotificationName(NotificationId), GetNotificationDescription(NotificationId), false); + Session.LogMessage('0000RFJ', StrSubstNo(UserDisabledNotificationTxt, HostNotification.GetData('NotificationId')), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', 'IdealPostcodes'); + end; + + procedure NotificationOnConfigure(Notification: Notification) + begin + PAGE.Run(PAGE::"Postcode Configuration Page W1"); + DisableNotificationForUser(Notification); + end; + + procedure NotificationOnDontShowAgain(Notification: Notification) + begin + DisableNotificationForUser(Notification); + end; + + procedure ConfiguredAndSupportedForRecord(CountryOrRegionCode: Code[10]): Boolean + var + IPCProvider: Codeunit "IPC Provider"; + PostCodeServiceManager: Codeunit "Postcode Service Manager"; + IsConfigured: Boolean; + begin + if not SupportedCountryOrRegionCode(CountryOrRegionCode) then + exit(false); + + PostCodeServiceManager.IsServiceConfigured(IPCProvider.GetServiceKey(), IsConfigured); + exit(IsConfigured); + end; + + local procedure GetNotificationName(NotificationId: Guid): Text[128]; + begin + case NotificationId of + GetAwarenessNotificationId(): + exit(AwarenessNotificationNameTxt); + end; + exit(''); + end; + + local procedure GetNotificationDescription(NotificationId: Guid): Text; + begin + case NotificationId of + GetAwarenessNotificationId(): + exit(AwarenessNotificationDescriptionTxt); + end; + exit(''); + end; + + local procedure GetFieldValue(RecRef: RecordRef; FieldNo: Integer): Text + var + FldRef: FieldRef; + begin + if TryGetField(RecRef, FieldNo, FldRef) then + exit(Format(FldRef.Value)); + exit(''); + end; + + local procedure SetFieldValue(RecRef: RecordRef; FieldNo: Integer; Value: Text) + var + FldRef: FieldRef; + begin + if TryGetField(RecRef, FieldNo, FldRef) then + FldRef.Value := Value; + end; + + local procedure TryGetField(RecRef: RecordRef; FieldNo: Integer; var FldRef: FieldRef): Boolean + begin + FldRef := RecRef.Field(FieldNo); + exit(FldRef.Number <> 0); + end; +} diff --git a/Apps/GB/IdealPostcodes/app/src/IPCConfig.Page.al b/Apps/GB/IdealPostcodes/app/src/IPCConfig.Page.al new file mode 100644 index 0000000000..1d38c3cdda --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/src/IPCConfig.Page.al @@ -0,0 +1,164 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Telemetry; + +page 9400 "IPC Config" +{ + PageType = Card; + ApplicationArea = All; + UsageCategory = Administration; + SourceTable = "IPC Config"; + Caption = 'IdealPostcodes Provider Setup'; + InsertAllowed = false; + DeleteAllowed = false; + + + layout + { + area(Content) + { + group(General) + { + Caption = 'General'; + + field("Enabled"; Rec."Enabled") + { + ApplicationArea = All; + ToolTip = 'Specifies whether the postcode provider is enabled or not.'; + + trigger OnValidate() + begin + ValidateApiKey(); + if not TermsAndCondsRead then + Error(ThirdPartyNoticeErr); + end; + } + field("API Key"; APIKeyText) + { + ApplicationArea = Basic, Suite; + Caption = 'API Key'; + ToolTip = 'Specifies the API Key for IdealPostcodes'; + ExtendedDatatype = Masked; + + trigger OnValidate() + var + APIKeySecretTxt: SecretText; + begin + APIKeySecretTxt := ConvertToSecretText(APIKeyText); + Rec.SaveAPIKeyAsSecret(Rec."API Key", APIKeySecretTxt); + UpdateAPIField(); + end; + } + field(TermsAndConditions; TermsAndCondsLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + ToolTip = 'Specifies the terms and conditions for using the IdealPostcodes service'; + + trigger OnDrillDown() + begin + HyperLink(TermsAndCondsUrlTok); + TermsAndCondsRead := true; + end; + } + field(GetAPIKey; GetAPIKeyLbl) + { + ApplicationArea = Basic, Suite; + Editable = false; + ShowCaption = false; + + trigger OnDrillDown() + begin + HyperLink(APIKeyUrlTok); + end; + } + } + } + } + + actions + { + area(Processing) + { + action(TestConnection) + { + ApplicationArea = All; + Caption = 'Test Connection'; + Image = TestReport; + ToolTip = 'Test the connection to the postcode API'; + + trigger OnAction() + var + CustomPostcodeMgt: Codeunit "IPC Management"; + begin + CustomPostcodeMgt.TestConnection(); + end; + } + } + } + + trigger OnAfterGetRecord() + begin + UpdateAPIField(); + end; + + trigger OnQueryClosePage(CloseAction: Action): Boolean + begin + if CloseAction = ACTION::Cancel then + exit(true); + + if not TermsAndCondsRead then + if Rec.Enabled then + Message(ThirdPartyNoticeMsg); + + exit(true); + end; + + [NonDebuggable] + local procedure ConvertToSecretText(InputText: Text): SecretText + begin + exit(SecretStrSubstNo(InputText)) + end; + + var + [NonDebuggable] + APIKeyText: Text; + TermsAndCondsRead: Boolean; + APIKeyUrlTok: Label 'https://ideal-postcodes.co.uk/pricing', Locked = true; + GetAPIKeyLbl: Label 'Get API Key'; + EmptyAPIKeyErr: Label 'You must specify an API Key.'; + ThirdPartyNoticeMsg: Label 'You are accessing a third-party website and service. You should review the third-party''s terms and privacy policy.'; + ThirdPartyNoticeErr: Label 'You must review the third-party''s terms and privacy policy.'; + TermsAndCondsLbl: Label 'Terms and conditions'; + TermsAndCondsUrlTok: Label 'https://terms.ideal-postcodes.co.uk/', Locked = true; + + local procedure UpdateAPIField() + begin + if IsNullGuid(Rec."API Key") then + APIKeyText := '' + else + APIKeyText := '****************'; + end; + + local procedure ValidateApiKey() + begin + if APIKeyText = '' then + Error(EmptyAPIKeyErr); + end; + + trigger OnOpenPage() + var + FeatureTelemetry: Codeunit "Feature Telemetry"; + begin + FeatureTelemetry.LogUptake('0000RFB', 'IdealPostcodes', Enum::"Feature Uptake Status"::Discovered); + Rec.Reset(); + if not Rec.Get() then begin + TermsAndCondsRead := false; + Rec.Init(); + Rec."Primary Key" := ''; + Rec.Insert(); + end else + TermsAndCondsRead := Rec."Enabled"; + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/src/IPCConfig.Table.al b/Apps/GB/IdealPostcodes/app/src/IPCConfig.Table.al new file mode 100644 index 0000000000..eef3200c4f --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/src/IPCConfig.Table.al @@ -0,0 +1,79 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Telemetry; + +table 9402 "IPC Config" +{ + DataClassification = CustomerContent; + Caption = 'IdealPostcodes Configuration'; + Access = Internal; + + fields + { + field(1; "Primary Key"; Code[10]) + { + Caption = 'Primary Key'; + DataClassification = SystemMetadata; + } + field(2; "API Key"; Guid) + { + Caption = 'API Key'; + DataClassification = CustomerContent; + } + field(4; "Enabled"; Boolean) + { + Caption = 'Enabled'; + DataClassification = CustomerContent; + } + } + + keys + { + key(PK; "Primary Key") + { + Clustered = true; + } + } + + var + EndpointBaseUrlTxt: Label 'https://api.ideal-postcodes.co.uk/v1', Locked = true; + + internal procedure GetAPIPasswordAsSecret(APIKeyGUID: Guid): SecretText + var + APIPassword: SecretText; + begin + if IsNullGuid(APIKeyGUID) or not IsolatedStorage.Get(APIKeyGUID, Datascope::Company, APIPassword) then + exit(APIPassword); + + exit(APIPassword); + end; + + internal procedure SaveAPIKeyAsSecret(var APIKeyGUID: Guid; APIKeyValue: SecretText) + var + FeatureTelemetry: Codeunit "Feature Telemetry"; + begin + if not IsNullGuid(APIKeyGUID) and (APIKeyValue.IsEmpty()) then begin + if IsolatedStorage.Contains(APIKeyGUID, Datascope::Company) then + IsolatedStorage.Delete(APIKeyGUID, Datascope::Company); + Clear(Rec."API Key"); + end else begin + if IsNullGuid(Rec."API Key") or not IsolatedStorage.Contains(APIKeyGUID, Datascope::Company) then begin + APIKeyGuid := Format(CreateGuid()); + Rec."API Key" := APIKeyGuid; + end; + if not EncryptionEnabled() then + IsolatedStorage.Set(APIKeyGUID, APIKeyValue, Datascope::Company) + else + IsolatedStorage.SetEncrypted(APIKeyGUID, APIKeyValue, Datascope::Company); + + FeatureTelemetry.LogUptake('0000RFC', 'IdealPostcodes', Enum::"Feature Uptake Status"::"Set up"); + FeatureTelemetry.LogUptake('0000RFD', 'IdealPostcodes', Enum::"Feature Uptake Status"::Used); + end; + Modify(); + end; + + internal procedure APIEndpoint(): Text[250] + begin + exit(EndpointBaseUrlTxt); + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/src/IPCManagement.Codeunit.al b/Apps/GB/IdealPostcodes/app/src/IPCManagement.Codeunit.al new file mode 100644 index 0000000000..c6f6964a6a --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/src/IPCManagement.Codeunit.al @@ -0,0 +1,240 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using System.Reflection; +using System.Telemetry; + +codeunit 9400 "IPC Management" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + var + ConfigNotSetupErr: Label 'The IdealPostcodes Provider is not configured. Set up the API key in the IdealPostcodes Provider Setup page.'; + ConnectionSuccessMsg: Label 'Connection test was successful.'; + ConnectionFailedErr: Label 'Connection test failed.'; + NoResultsMsg: Label 'No addresses found for the given postcode.'; + ApiKeyConfigErr: Label 'API Key is not configured.'; + ResponseDetailsTxt: Label 'Received response %1 %2.', Comment = '%1 - Status code, %2 - Reason phrase.'; + UnsuccessfulAddressSearchTxt: Label 'Unsuccessful address search. Response %1 %2.', Comment = '%1 - Status code, %2 - Reason phrase.', Locked = true; + + [NonDebuggable] + procedure SearchAddress(SearchText: Text; var TempIPCAddressLookup: Record "IPC Address Lookup" temporary; var StatusCode: Integer; var ReasonPhrase: Text): Boolean + var + Config: Record "IPC Config"; + TypeHelper: Codeunit "Type Helper"; + FeatureTelemetry: Codeunit "Feature Telemetry"; + HttpClient: HttpClient; + HttpResponse: HttpResponseMessage; + ResponseText: Text; + RequestUrl: Text; + begin + if not GetConfiguration(Config) then + Error(ConfigNotSetupErr); + + if not Config.Enabled then + exit(false); + + FeatureTelemetry.LogUptake('0000RFE', 'IdealPostcodes', Enum::"Feature Uptake Status"::Used); + RequestUrl := Config.APIEndpoint() + '/postcodes/' + TypeHelper.UriEscapeDataString(SearchText); + HttpClient.DefaultRequestHeaders().Add('Authorization', SecretStrSubstNo('IDEALPOSTCODES api_key="%1"', Config.GetAPIPasswordAsSecret(Config."API Key"))); + HttpClient.DefaultRequestHeaders().Add('Accept-Encoding', 'utf-8'); + HttpClient.DefaultRequestHeaders().Add('Accept', 'application/json'); + + if HttpClient.Get(RequestUrl, HttpResponse) then begin + StatusCode := HttpResponse.HttpStatusCode(); + ReasonPhrase := HttpResponse.ReasonPhrase(); + if HttpResponse.IsSuccessStatusCode() then begin + HttpResponse.Content.ReadAs(ResponseText); + ParseAddressResponse(ResponseText, TempIPCAddressLookup); + exit(not TempIPCAddressLookup.IsEmpty()); + end; + end; + exit(false); + end; + + [NonDebuggable] + procedure GetAddressDetails(AddressId: Text; var TempIPCAddressLookup: Record "IPC Address Lookup" temporary; var ReasonCode: Integer; var ReasonPhrase: Text) + var + Config: Record "IPC Config"; + TypeHelper: Codeunit "Type Helper"; + FeatureTelemetry: Codeunit "Feature Telemetry"; + HttpClient: HttpClient; + HttpResponse: HttpResponseMessage; + ResponseText: Text; + RequestUrl: Text; + begin + if not GetConfiguration(Config) then + Error(ConfigNotSetupErr); + + if not Config.Enabled then + exit; + + FeatureTelemetry.LogUptake('0000RFF', 'IdealPostcodes', Enum::"Feature Uptake Status"::Used); + RequestUrl := Config.APIEndpoint() + '/' + TypeHelper.UriEscapeDataString(AddressId); + HttpClient.DefaultRequestHeaders().Add('Authorization', SecretStrSubstNo('IDEALPOSTCODES api_key="%1"', Config.GetAPIPasswordAsSecret(Config."API Key"))); + + if HttpClient.Get(RequestUrl, HttpResponse) then begin + ReasonCode := HttpResponse.HttpStatusCode(); + ReasonPhrase := HttpResponse.ReasonPhrase(); + if HttpResponse.IsSuccessStatusCode then begin + HttpResponse.Content.ReadAs(ResponseText); + ParseAddressDetail(ResponseText, TempIPCAddressLookup); + end; + end; + end; + + procedure LookupAddress(var Address: Text[100]; var Address2: Text[50]; var City: Text[30]; var PostCode: Code[20]; var County: Text[30]; var CountryCode: Code[10]) + var + TempIPCAddressLookup: Record "IPC Address Lookup" temporary; + TempSelectedIPCAddressLookup: Record "IPC Address Lookup" temporary; + AddressLookupPage: Page "IPC Address Lookup"; + SearchText, ReasonPhrase : Text; + StatusCode: Integer; + begin + SearchText := PostCode; + if SearchText = '' then + SearchText := City; + + if SearchText = '' then + exit; + + if not SearchAddress(SearchText, TempIPCAddressLookup, StatusCode, ReasonPhrase) then begin + case StatusCode of + 404, 200: + Message(NoResultsMsg); + else + Message(ResponseDetailsTxt, StatusCode, ReasonPhrase); + end; + Session.LogMessage('0000RFS', StrSubstNo(UnsuccessfulAddressSearchTxt, StatusCode, ReasonPhrase), Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', 'IdealPostcodes'); + end; + + AddressLookupPage.SetRecords(TempIPCAddressLookup); + AddressLookupPage.LookupMode(true); + + if AddressLookupPage.RunModal() = Action::LookupOK then begin + AddressLookupPage.GetSelectedAddress(TempSelectedIPCAddressLookup); + Address := TempSelectedIPCAddressLookup.Address; + Address2 := TempSelectedIPCAddressLookup."Address 2"; + City := TempSelectedIPCAddressLookup.City; + PostCode := TempSelectedIPCAddressLookup."Post Code"; + County := TempSelectedIPCAddressLookup.County; + CountryCode := TempSelectedIPCAddressLookup."Country/Region Code"; + end; + end; + + local procedure GetConfiguration(var Config: Record "IPC Config"): Boolean + begin + if Config.Get() then + exit(true); + exit(false); + end; + + local procedure ParseAddressResponse(ResponseText: Text; var TempIPCAddressLookup: Record "IPC Address Lookup" temporary) + var + JsonObject: JsonObject; + JsonArray: JsonArray; + JsonToken: JsonToken; + i: Integer; + begin + TempIPCAddressLookup.DeleteAll(); + + if JsonObject.ReadFrom(ResponseText) then + if JsonObject.Get('result', JsonToken) then begin + JsonArray := JsonToken.AsArray(); + + for i := 0 to JsonArray.Count - 1 do begin + JsonArray.Get(i, JsonToken); + AddAddressToBuffer(JsonToken.AsObject(), TempIPCAddressLookup, i + 1); + end; + end; + end; + + local procedure AddAddressToBuffer(AddressJson: JsonObject; var TempIPCAddressLookup: Record "IPC Address Lookup" temporary; EntryNo: Integer) + begin + TempIPCAddressLookup.Init(); + TempIPCAddressLookup."Entry No." := EntryNo; + TempIPCAddressLookup."Address ID" := CopyStr(GetJsonValue(AddressJson, 'id'), 1, MaxStrLen(TempIPCAddressLookup."Address ID")); + TempIPCAddressLookup.Address := CopyStr(GetJsonValue(AddressJson, 'line_1'), 1, MaxStrLen(TempIPCAddressLookup.Address)); + TempIPCAddressLookup."Address 2" := CopyStr(GetJsonValue(AddressJson, 'line_2'), 1, MaxStrLen(TempIPCAddressLookup."Address 2")); + TempIPCAddressLookup.City := CopyStr(GetJsonValue(AddressJson, 'post_town'), 1, MaxStrLen(TempIPCAddressLookup.City)); + TempIPCAddressLookup."Post Code" := CopyStr(GetJsonValue(AddressJson, 'postcode'), 1, MaxStrLen(TempIPCAddressLookup."Post Code")); + TempIPCAddressLookup.County := CopyStr(GetJsonValue(AddressJson, 'county'), 1, MaxStrLen(TempIPCAddressLookup.County)); + TempIPCAddressLookup."Country/Region Code" := CopyStr(GetJsonValue(AddressJson, 'country_iso_2'), 1, MaxStrLen(TempIPCAddressLookup."Country/Region Code")); + + // Create display text + TempIPCAddressLookup."Display Text" := TempIPCAddressLookup.Address; + if TempIPCAddressLookup.City <> '' then + TempIPCAddressLookup."Display Text" += ', ' + TempIPCAddressLookup.City; + if TempIPCAddressLookup."Post Code" <> '' then + TempIPCAddressLookup."Display Text" += ' ' + TempIPCAddressLookup."Post Code"; + + TempIPCAddressLookup.Insert(); + end; + + local procedure ParseAddressDetail(ResponseText: Text; var TempIPCAddressLookup: Record "IPC Address Lookup") + var + JsonObject: JsonObject; + begin + if JsonObject.ReadFrom(ResponseText) then begin + TempIPCAddressLookup.Init(); + TempIPCAddressLookup.Address := CopyStr(GetJsonValue(JsonObject, 'address'), 1, MaxStrLen(TempIPCAddressLookup.Address)); + TempIPCAddressLookup."Address 2" := CopyStr(GetJsonValue(JsonObject, 'address2'), 1, MaxStrLen(TempIPCAddressLookup."Address 2")); + TempIPCAddressLookup.City := CopyStr(GetJsonValue(JsonObject, 'city'), 1, MaxStrLen(TempIPCAddressLookup.City)); + TempIPCAddressLookup."Post Code" := CopyStr(GetJsonValue(JsonObject, 'postcode'), 1, MaxStrLen(TempIPCAddressLookup."Post Code")); + TempIPCAddressLookup.County := CopyStr(GetJsonValue(JsonObject, 'county'), 1, MaxStrLen(TempIPCAddressLookup.County)); + TempIPCAddressLookup."Country/Region Code" := CopyStr(GetJsonValue(JsonObject, 'country_code'), 1, MaxStrLen(TempIPCAddressLookup."Country/Region Code")); + end; + + // Create display text + TempIPCAddressLookup."Display Text" := TempIPCAddressLookup.Address; + if TempIPCAddressLookup.City <> '' then + TempIPCAddressLookup."Display Text" += ', ' + TempIPCAddressLookup.City; + if TempIPCAddressLookup."Post Code" <> '' then + TempIPCAddressLookup."Display Text" += ' ' + TempIPCAddressLookup."Post Code"; + end; + + local procedure GetJsonValue(JsonObject: JsonObject; KeyName: Text): Text + var + JsonToken: JsonToken; + begin + if JsonObject.Get(KeyName, JsonToken) then + if not JsonToken.AsValue().IsNull then + exit(JsonToken.AsValue().AsText()); + exit(''); + end; + + procedure TestConnection() + var + Config: Record "IPC Config"; + TempIPCAddressLookup: Record "IPC Address Lookup" temporary; + StatusCode: Integer; + ReasonPhrase: Text; + begin + if not GetConfiguration(Config) then + Error(ConfigNotSetupErr); + + if IsNullGuid(Config."API Key") then + Error(ApiKeyConfigErr); + + if Config.GetAPIPasswordAsSecret(Config."API Key").IsEmpty() then + Error(ApiKeyConfigErr); + + SearchAddress('SW1A 2AE', TempIPCAddressLookup, StatusCode, ReasonPhrase); + if StatusCode <> 200 then + Message(ConnectionFailedErr + ' ' + StrSubstNo(ResponseDetailsTxt, StatusCode, ReasonPhrase)) + else + Message(ConnectionSuccessMsg); + exit; + end; + + procedure IsConfigured(): Boolean + var + Config: Record "IPC Config"; + begin + if not GetConfiguration(Config) then + exit(false); + + exit(Config.Enabled and not IsNullGuid(Config."API Key")); + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/app/src/IPCProvider.Codeunit.al b/Apps/GB/IdealPostcodes/app/src/IPCProvider.Codeunit.al new file mode 100644 index 0000000000..f08a6535dd --- /dev/null +++ b/Apps/GB/IdealPostcodes/app/src/IPCProvider.Codeunit.al @@ -0,0 +1,167 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes; + +using Microsoft.Foundation.Address; +using Microsoft.Utilities; + +codeunit 9403 "IPC Provider" +{ + Access = Internal; + InherentEntitlements = X; + InherentPermissions = X; + + var + MyServiceKeyTok: Label 'IDEAL_POSTCODE_POSTCODE_SERVICE', Locked = true; + MyServiceNameLbl: Label 'IdealPostcodes'; + ServiceConnectionNameLbl: Label 'Postcode Service'; + RetrieveAddressDetailsErr: Label 'Failed to retrieve address details.'; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Postcode Service Manager", 'OnDiscoverPostcodeServices', '', false, false)] + local procedure OnDiscoverPostcodeServices(var TempServiceListNameValueBuffer: Record "Name/Value Buffer" temporary) + begin + TempServiceListNameValueBuffer.Init(); + TempServiceListNameValueBuffer.ID := TempServiceListNameValueBuffer.Count + 1; + TempServiceListNameValueBuffer.Name := MyServiceNameLbl; + TempServiceListNameValueBuffer.Value := MyServiceKeyTok; + TempServiceListNameValueBuffer.Insert(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Postcode Service Manager", 'OnCheckIsServiceConfigured', '', false, false)] + local procedure OnCheckIsServiceConfigured(ServiceKey: Text; var IsConfigured: Boolean) + var + IdealPostcodesConfig: Record "IPC Config"; + begin + if ServiceKey <> MyServiceKeyTok then + exit; + + if not IdealPostcodesConfig.Get() then begin + IsConfigured := false; + exit; + end; + + if not IdealPostcodesConfig.Enabled then begin + IsConfigured := false; + exit; + end; + + if IsNullGuid(IdealPostcodesConfig."API Key") then begin + IsConfigured := false; + exit; + end; + + if IdealPostcodesConfig.GetAPIPasswordAsSecret(IdealPostcodesConfig."API Key").IsEmpty() then begin + IsConfigured := false; + exit; + end; + + IsConfigured := true; + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Postcode Service Manager", 'OnShowConfigurationPage', '', false, false)] + local procedure OnShowConfigurationPage(ServiceKey: Text; var Successful: Boolean) + var + IPCConfig: Record "IPC Config"; + IPCConfigPage: Page "IPC Config"; + begin + if ServiceKey <> MyServiceKeyTok then + exit; + + Successful := IPCConfigPage.RunModal() = ACTION::OK; + Successful := IPCConfig.FindFirst(); + Successful := Successful and not IsNullGuid(IPCConfig."API Key") and IPCConfig.Enabled; + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Postcode Service Manager", 'OnRetrieveAddressList', '', false, false)] + local procedure OnRetrieveAddressList(ServiceKey: Text; TempEnteredAutocompleteAddress: Record "Autocomplete Address" temporary; var TempAddressListNameValueBuffer: Record "Name/Value Buffer" temporary; var IsSuccessful: Boolean; var ErrorMsg: Text) + var + TempIPCAddressLookup: Record "IPC Address Lookup" temporary; + IPCManagement: Codeunit "IPC Management"; + SearchText, ReasonPhrase : Text; + LastId, StatusCode : Integer; + begin + if ServiceKey <> MyServiceKeyTok then + exit; + + LastId := 0; + if TempAddressListNameValueBuffer.FindLast() then + LastId := TempAddressListNameValueBuffer.ID; + + if TempEnteredAutocompleteAddress.Postcode <> '' then + SearchText := TempEnteredAutocompleteAddress.PostCode + else + SearchText := TempEnteredAutocompleteAddress.City; + + if SearchText = '' then + exit; + + if not IPCManagement.SearchAddress(SearchText, TempIPCAddressLookup, StatusCode, ReasonPhrase) then + exit; + + TempIPCAddressLookup.Reset(); + if TempIPCAddressLookup.FindSet() then + repeat + LastId += 1; + TempAddressListNameValueBuffer.Init(); + TempAddressListNameValueBuffer.ID := LastId; + TempAddressListNameValueBuffer.Name := TempIPCAddressLookup."Address ID"; + TempAddressListNameValueBuffer.Value := TempIPCAddressLookup."Display Text"; + TempAddressListNameValueBuffer.Insert(); + until TempIPCAddressLookup.Next() = 0; + + IsSuccessful := true; + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Postcode Service Manager", 'OnRetrieveAddress', '', false, false)] + local procedure OnRetrieveAddress(ServiceKey: Text; TempEnteredAutocompleteAddress: Record "Autocomplete Address" temporary; TempSelectedAddressNameValueBuffer: Record "Name/Value Buffer" temporary; var TempAutocompleteAddress: Record "Autocomplete Address" temporary; var IsSuccessful: Boolean; var ErrorMsg: Text) + var + TempIPCAddressLookup: Record "IPC Address Lookup" temporary; + IPCManagement: Codeunit "IPC Management"; + StatusCode: Integer; + ReasonPhrase: Text; + begin + if ServiceKey <> MyServiceKeyTok then + exit; + + IPCManagement.GetAddressDetails(TempSelectedAddressNameValueBuffer.Name, TempIPCAddressLookup, StatusCode, ReasonPhrase); + IsSuccessful := TempIPCAddressLookup."Display Text" <> ''; + if not IsSuccessful then begin + ErrorMsg := RetrieveAddressDetailsErr; + exit; + end; + + TempAutocompleteAddress.Address := TempIPCAddressLookup.Address; + TempAutocompleteAddress."Address 2" := TempIPCAddressLookup."Address 2"; + TempAutocompleteAddress.City := TempIPCAddressLookup.City; + TempAutocompleteAddress."Postcode" := TempIPCAddressLookup."Post Code"; + TempAutocompleteAddress.County := TempIPCAddressLookup.County; + TempAutocompleteAddress."Country / Region" := TempIPCAddressLookup."Country/Region Code"; + IsSuccessful := true; + end; + + [EventSubscriber(ObjectType::Table, Database::"Service Connection", 'OnRegisterServiceConnection', '', false, false)] + local procedure RegisterServiceOnRegisterServiceConnection(var ServiceConnection: Record "Service Connection") + var + PostcodeServiceConfig: Record "Postcode Service Config"; + PostcodeServiceManager: Codeunit "Postcode Service Manager"; + Configured: Boolean; + begin + PostcodeServiceManager.IsServiceConfigured(GetServiceKey(), Configured); + if Configured then + ServiceConnection.Status := ServiceConnection.Status::Enabled + else + ServiceConnection.Status := ServiceConnection.Status::Disabled; + + if not PostcodeServiceConfig.FindFirst() then begin + PostcodeServiceConfig.Init(); + PostcodeServiceConfig.Insert(); + PostcodeServiceConfig.SaveServiceKey('Disabled'); + end; + + ServiceConnection.InsertServiceConnection(ServiceConnection, PostcodeServiceConfig.RecordId, + ServiceConnectionNameLbl, '', PAGE::"Postcode Configuration Page W1"); + end; + + procedure GetServiceKey(): Text + begin + exit(MyServiceKeyTok); + end; +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/test/.resources/SearchAddress_TESTPOSTCODE.json b/Apps/GB/IdealPostcodes/test/.resources/SearchAddress_TESTPOSTCODE.json new file mode 100644 index 0000000000..8b76f565b9 --- /dev/null +++ b/Apps/GB/IdealPostcodes/test/.resources/SearchAddress_TESTPOSTCODE.json @@ -0,0 +1,22 @@ +{ + "result": [ + { + "id": "1", + "line_1": "ADDRESS-1", + "line_2": "ADDRESS 2-1", + "post_town": "CITY", + "postcode": "TESTPOSTCODE", + "county": "COUNTY", + "country_iso_2": "GB" + }, + { + "id": "2", + "line_1": "ADDRESS", + "line_2": "ADDRESS 2", + "post_town": "CITY", + "postcode": "TESTPOSTCODE", + "county": "COUNTY", + "country_iso_2": "GB" + } +] +} \ No newline at end of file diff --git a/Apps/GB/IdealPostcodes/test/ExtensionLogo.png b/Apps/GB/IdealPostcodes/test/ExtensionLogo.png new file mode 100644 index 0000000000..fbd8df877b Binary files /dev/null and b/Apps/GB/IdealPostcodes/test/ExtensionLogo.png differ diff --git a/Apps/GB/IdealPostcodes/test/app.json b/Apps/GB/IdealPostcodes/test/app.json new file mode 100644 index 0000000000..553dc23c5b --- /dev/null +++ b/Apps/GB/IdealPostcodes/test/app.json @@ -0,0 +1,59 @@ +{ + "id": "5cd5fc9e-9760-467c-adfb-35ff35ee4cce", + "name": "IdealPostcodes Tests", + "publisher": "Microsoft", + "brief": "Tests for the IdealPostcodes extension.", + "description": "Tests for the IdealPostcodes extension.", + "version": "28.0.0.0", + "privacyStatement": "https://go.microsoft.com/fwlink/?LinkId=724009", + "EULA": "https://go.microsoft.com/fwlink/?linkid=2009120", + "help": "https://go.microsoft.com/fwlink/?LinkId=724011", + "url": "https://go.microsoft.com/fwlink/?LinkId=724011", + "contextSensitiveHelpUrl": "https://go.microsoft.com/fwlink/?LinkId=724011", + "logo": "ExtensionLogo.png", + "dependencies": [ + { + "id": "c62d3f56-16a4-484f-878a-330583985eeb", + "name": "IdealPostcodes", + "publisher": "Microsoft", + "version": "28.0.0.0" + }, + { + "id": "5d86850b-0d76-4eca-bd7b-951ad998e997", + "name": "Tests-TestLibraries", + "publisher": "Microsoft", + "version": "28.0.0.0" + }, + { + "id": "5095f467-0a01-4b99-99d1-9ff1237d286f", + "publisher": "Microsoft", + "name": "Library Variable Storage", + "version": "28.0.0.0" + } + ], + "features": [ + "TranslationFile" + ], + "screenshots": [], + "platform": "28.0.0.0", + "idRanges": [ + { + "from": 139500, + "to": 139899 + }, + { + "from": 148000, + "to": 148499 + } + ], + "resourceFolders": [ + ".resources" + ], + "target": "OnPrem", + "resourceExposurePolicy": { + "allowDebugging": false, + "allowDownloadingSource": true, + "includeSourceInSymbolFile": true + }, + "application": "28.0.0.0" +} diff --git a/Apps/GB/IdealPostcodes/test/src/TestIdealPostcodesPages.Codeunit.al b/Apps/GB/IdealPostcodes/test/src/TestIdealPostcodesPages.Codeunit.al new file mode 100644 index 0000000000..2ed9b5f3a8 --- /dev/null +++ b/Apps/GB/IdealPostcodes/test/src/TestIdealPostcodesPages.Codeunit.al @@ -0,0 +1,1894 @@ +namespace Microsoft.Foundation.Address.IdealPostcodes.Test; + +using Microsoft.Bank.BankAccount; +using Microsoft.CRM.Contact; +using Microsoft.Foundation.Address; +using Microsoft.Foundation.Address.IdealPostcodes; +using Microsoft.Foundation.Company; +using Microsoft.HumanResources.Employee; +using Microsoft.Inventory.Location; +using Microsoft.Projects.Resources.Resource; +using Microsoft.Purchases.Vendor; +using Microsoft.Sales.Customer; + +codeunit 148121 "Test IdealPostcodes Pages" +{ + Subtype = Test; + TestType = IntegrationTest; + TestPermissions = Disabled; + + trigger OnRun() + begin + end; + + var + Assert: Codeunit Assert; + LibraryLowerPermissions: Codeunit "Library - Lower Permissions"; + LibraryHR: Codeunit "Library - Human Resource"; + LibraryPurchase: Codeunit "Library - Purchase"; + LibraryRandom: Codeunit "Library - Random"; + LibrarySales: Codeunit "Library - Sales"; + PostcodeDummyService: Codeunit "Postcode Dummy Service"; + Initialized: Boolean; + LookupTextTok: Label 'Lookup Text', Locked = true; + RetrievedInvalidValueTok: Label 'Retrieved field value is incorrect.', Locked = true; + + [Test] + [Scope('OnPrem')] + procedure TestBankAccountLookupHiddenInViewMode() + var + BankAccountCard: TestPage "Bank Account Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetSalesDocsCreate(); + + // [WHEN] customer card is viewed + BankAccountCard.OpenView(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(BankAccountCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestBankAccountrLookupHidenInEditModeServiceNotConfigured() + var + BankAccountCard: TestPage "Bank Account Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + + // [WHEN] customer card is opened + BankAccountCard.OpenEdit(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(BankAccountCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + Teardown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestBankAccountLookupVisibleInEditModeGBCountry() + var + BankAccountCard: TestPage "Bank Account Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + + // [WHEN] customer card is opened and country is set to GB + BankAccountCard.OpenEdit(); + BankAccountCard."Country/Region Code".Value('GB'); + + // [THEN] postcode lookup action is visible + Assert.IsTrue(BankAccountCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(true, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestBankAccountLookupVisibleInEditModeNonGBCountry() + var + BankAccountCard: TestPage "Bank Account Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + + // [WHEN] customer card is opened and country is set to something other than GB + BankAccountCard.OpenEdit(); + BankAccountCard."Country/Region Code".Value('SI'); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(BankAccountCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchScenarioModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestBankAccountScenarioSuccess() + var + BankAccountCard: TestPage "Bank Account Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at bank account page and successful: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Selects 3rd + // 4. Values are populated + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + + // [WHEN] we assume successful process, copying fields + BankAccountCard.OpenEdit(); + BankAccountCard."Country/Region Code".Value(''); + BankAccountCard."Post Code".Value('TESTPOSTCODE'); + BankAccountCard.LookupAddress_IdealPostcodes.DrillDown(); // trigger postcode search + // PostcodeSearchScenario page handler takes over and inputs postcode + + // [THEN] we should get our data + Assert.AreEqual('ADDRESS', BankAccountCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('ADDRESS 2', BankAccountCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', BankAccountCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('CITY', BankAccountCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('GB', BankAccountCard."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchCancelModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestBankAccountScenarioCancel() + var + BankAccountCard: TestPage "Bank Account Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at bank account page but canceled: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Cancel the window + // 4. Values are left empty + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + + // [GIVEN] ensure blank address fields + BankAccountCard.OpenEdit(); + BankAccountCard.Address.Value(''); + BankAccountCard."Address 2".Value(''); + BankAccountCard.City.Value(''); + BankAccountCard."Country/Region Code".Value(''); + BankAccountCard."Post Code".Value('TESTPOSTCODE'); + + // [WHEN] trigger postcode search + BankAccountCard.LookupAddress_IdealPostcodes.DrillDown(); + // PostcodeSearch cancel page handler takes over and cancels the process + + // [THEN] address fields should stay blank + Assert.AreEqual('', BankAccountCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', BankAccountCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', BankAccountCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('', BankAccountCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', BankAccountCard."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestCustomerLookupHiddenInViewMode() + var + CustomerCard: TestPage "Customer Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + + // [WHEN] customer card is viewed + CustomerCard.OpenView(); + + // [THEN] Lookup address option is hidden + Assert.IsFalse(CustomerCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestCustomerLookupHidenInEditModeServiceNotConfigured() + var + CustomerCard: TestPage "Customer Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] customer card is opened + CustomerCard.OpenEdit(); + + // [THEN] Lookup address option is hidden + Assert.IsFalse(CustomerCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestCustomerLookupVisibleInEditModeGBCountry() + var + CustomerCard: TestPage "Customer Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] customer card is opened and country is set to GB + CustomerCard.OpenEdit(); + CustomerCard."Country/Region Code".Value('GB'); + + // [THEN] Lookup address option is visible + Assert.IsTrue(CustomerCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(true, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestCustomerLookupVisibleInEditModeNonGBCountry() + var + CustomerCard: TestPage "Customer Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] customer card is opened and country is set to something other than GB + CustomerCard.OpenEdit(); + CustomerCard."Country/Region Code".Value('SI'); + + // [THEN] lookup text is visible, postcode lookup field is visible + Assert.IsFalse(CustomerCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchScenarioModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestCustomerScenarioSuccess() + var + CustomerCard: TestPage "Customer Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at customer page and successful: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Selects 3rd + // 4. Values are populated + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] we assume successful process, copying fields + CustomerCard.OpenEdit(); + CustomerCard."Country/Region Code".Value(''); + CustomerCard."Post Code".Value('TESTPOSTCODE'); + CustomerCard.LookupAddress_IdealPostcodes.DrillDown(); // trigger postcode search + // PostcodeSearchScenario page handler takes over and inputs postcode + + // [THEN] we should get our data + Assert.AreEqual('ADDRESS', CustomerCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('ADDRESS 2', CustomerCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', CustomerCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('CITY', CustomerCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('GB', CustomerCard."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchCancelModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestCustomerScenarioCancel() + var + CustomerCard: TestPage "Customer Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at customer page but canceled: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Cancel the window + // 4. Values are left empty + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetCustomerEdit(); + + // [GIVEN] ensure blank address fields + CustomerCard.OpenEdit(); + CustomerCard.Address.Value(''); + CustomerCard."Address 2".Value(''); + CustomerCard.City.Value(''); + CustomerCard."Country/Region Code".Value(''); + CustomerCard."Post Code".Value('TESTPOSTCODE'); + + // [WHEN] trigger postcode search + CustomerCard.LookupAddress_IdealPostcodes.DrillDown(); + // PostcodeSearch cancel page handler takes over and cancels the process + + // [THEN] address fields should stay blank + Assert.AreEqual('', CustomerCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', CustomerCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', CustomerCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('', CustomerCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', CustomerCard."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestEmployeeLookupHiddenInViewMode() + var + EmployeeCard: TestPage "Employee Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetO365HRView(); + + // [WHEN] customer card is viewed + EmployeeCard.OpenView(); + + // [THEN] Lookup address option is hidden + Assert.IsFalse(EmployeeCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestEmployeeLookupHidenInEditModeServiceNotConfigured() + var + EmployeeCard: TestPage "Employee Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetO365HREdit(); + + // [WHEN] customer card is opened + EmployeeCard.OpenEdit(); + + // [THEN] Lookup address option is hidden + Assert.IsFalse(EmployeeCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestEmployeeLookupVisibleInEditModeGBCountry() + var + EmployeeCard: TestPage "Employee Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetO365HREdit(); + + // [WHEN] customer card is opened and country is set to GB + EmployeeCard.OpenEdit(); + EmployeeCard."Country/Region Code".Value('GB'); + + // [THEN] Lookup address option is visible + Assert.IsTrue(EmployeeCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(true, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestEmployeeLookupVisibleInEditModeNonGBCountry() + var + EmployeeCard: TestPage "Employee Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetO365HREdit(); + + // [WHEN] customer card is opened and country is set to something other than GB + EmployeeCard.OpenEdit(); + EmployeeCard."Country/Region Code".Value('SI'); + + // [THEN] lookup text is visible, postcode lookup field is visible + Assert.IsFalse(EmployeeCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchScenarioModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestEmployeeScenarioSuccess() + var + PostCode: Record "Post Code"; + EmployeeCard: TestPage "Employee Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at customer page and successful: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Selects 3rd + // 4. Values are populated + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetO365HREdit(); + + // [WHEN] we assume successful process, copying fields + EmployeeCard.OpenEdit(); + EmployeeCard."Country/Region Code".Value(''); + EmployeeCard."Post Code".Value('TESTPOSTCODE'); + EmployeeCard.LookupAddress_IdealPostcodes.DrillDown(); // trigger postcode search + // PostcodeSearchScenario page handler takes over and inputs postcode + + // [THEN] we should get our data + Assert.AreEqual('ADDRESS', EmployeeCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('ADDRESS 2', EmployeeCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', EmployeeCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('CITY', EmployeeCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('GB', EmployeeCard."Country/Region Code".Value, RetrievedInvalidValueTok); + PostCode.SetRange(Code, 'TESTPOSTCODE'); + Assert.IsFalse(PostCode.IsEmpty(), 'Postcode record was not created.'); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchCancelModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestEmployeeScenarioCancel() + var + PostCode: Record "Post Code"; + EmployeeCard: TestPage "Employee Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at customer page but canceled: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Cancel the window + // 4. Values are left empty + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetO365HREdit(); + + // [GIVEN] ensure blank address fields + EmployeeCard.OpenEdit(); + EmployeeCard.Address.Value(''); + EmployeeCard."Address 2".Value(''); + EmployeeCard.City.Value(''); + EmployeeCard."Country/Region Code".Value(''); + + // [WHEN] trigger postcode search via validate + EmployeeCard."Post Code".Value('TESTPOSTCODE'); + EmployeeCard.LookupAddress_IdealPostcodes.DrillDown(); + // PostcodeSearch cancel page handler takes over and cancels the process + + // [THEN] address fields should stay blank + Assert.AreEqual('', EmployeeCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', EmployeeCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', EmployeeCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('', EmployeeCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', EmployeeCard."Country/Region Code".Value, RetrievedInvalidValueTok); + PostCode.SetRange(Code, 'TESTPOSTCODE'); + Assert.IsTrue(PostCode.IsEmpty(), 'Postcode record was unexpectedly created.'); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + EmployeeCard.Close(); + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestShipToAddressLookupHiddenInViewMode() + var + ShiptoAddress: TestPage "Ship-to Address"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetCustomerView(); + + // [WHEN] customer card is viewed + ShiptoAddress.OpenView(); + + // [THEN] regular postcode fields are visible instead of lookup fields + Assert.IsFalse(ShiptoAddress.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestShipToAddressLookupHidenInEditModeServiceNotConfigured() + var + ShiptoAddress: TestPage "Ship-to Address"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] customer card is opened + ShiptoAddress.OpenEdit(); + ShiptoAddress.New(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(ShiptoAddress.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestShipToAddressLookupVisibleInEditModeGBCountry() + var + Customer: Record Customer; + ShiptoAddressRec: Record "Ship-to Address"; + ShiptoAddress: TestPage "Ship-to Address"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibrarySales.CreateCustomer(Customer); + LibrarySales.CreateShipToAddress(ShiptoAddressRec, Customer."No."); + + // [WHEN] customer card is opened and country is set to GB + ShiptoAddress.OpenEdit(); + ShiptoAddress.GoToRecord(ShiptoAddressRec); + ShiptoAddress."Country/Region Code".Value('GB'); + + // [THEN] postcode lookup action is visible + Assert.IsTrue(ShiptoAddress.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(true, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestShipToAddressLookupVisibleInEditModeNonGBCountry() + var + Customer: Record Customer; + ShiptoAddressRec: Record "Ship-to Address"; + ShiptoAddress: TestPage "Ship-to Address"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibrarySales.CreateCustomer(Customer); + LibrarySales.CreateShipToAddress(ShiptoAddressRec, Customer."No."); + + // [WHEN] customer card is opened and country is set to GB + ShiptoAddress.OpenEdit(); + ShiptoAddress.GoToRecord(ShiptoAddressRec); + ShiptoAddress."Country/Region Code".Value('GB'); + ShiptoAddress."Country/Region Code".Value('SI'); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(ShiptoAddress.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchScenarioModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestShipToAddressScenarioSuccess() + var + Customer: Record Customer; + ShipToAddressRec: Record "Ship-to Address"; + ShiptoAddress: TestPage "Ship-to Address"; + begin + // [SCENARIO] Postcode auto complete is initiated at ship to address page and successful: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Selects 3rd + // 4. Values are populated + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibrarySales.CreateCustomer(Customer); + LibrarySales.CreateShipToAddress(ShipToAddressRec, Customer."No."); + + // [WHEN] we assume successful process, copying fields + ShiptoAddress.OpenEdit(); + ShiptoAddress.GoToRecord(ShipToAddressRec); + ShiptoAddress."Country/Region Code".Value(''); + ShiptoAddress."Post Code".Value('TESTPOSTCODE'); + ShiptoAddress.LookupAddress_IdealPostcodes.DrillDown(); // trigger postcode search + // PostcodeSearchScenario page handler takes over and inputs postcode + + // [THEN] we should get our data + Assert.AreEqual('ADDRESS', ShiptoAddress.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('ADDRESS 2', ShiptoAddress."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', ShiptoAddress."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('CITY', ShiptoAddress.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('GB', ShiptoAddress."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchCancelModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestShipToAddressScenarioCancel() + var + Customer: Record Customer; + ShiptoAddressRec: Record "Ship-to Address"; + ShiptoAddress: TestPage "Ship-to Address"; + begin + // [SCENARIO] Postcode auto complete is initiated at ship to address page but canceled: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Cancel the window + // 4. Values are left empty + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibrarySales.CreateCustomer(Customer); + LibrarySales.CreateShipToAddress(ShiptoAddressRec, Customer."No."); + + // [GIVEN] ensure blank address fields + ShiptoAddress.OpenEdit(); + ShiptoAddress.GoToRecord(ShiptoAddressRec); + ShiptoAddress.Address.Value(''); + ShiptoAddress."Address 2".Value(''); + ShiptoAddress.City.Value(''); + ShiptoAddress."Country/Region Code".Value(''); + ShiptoAddress."Post Code".Value('TESTPOSTCODE'); + + // [WHEN] trigger postcode search + ShiptoAddress.LookupAddress_IdealPostcodes.DrillDown(); + // PostcodeSearch cancel page handler takes over and cancels the process + + // [THEN] address fields should stay blank + Assert.AreEqual('', ShiptoAddress.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', ShiptoAddress."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', ShiptoAddress."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('', ShiptoAddress.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', ShiptoAddress."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestLocationLookupHiddenInViewMode() + var + LocationCard: TestPage "Location Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is viewed + LocationCard.OpenView(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(LocationCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestLocationLookupHidenInEditModeServiceNotConfigured() + var + LocationCard: TestPage "Location Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is opened + LocationCard.OpenEdit(); + LocationCard.New(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(LocationCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestLocationLookupVisibleInEditModeGBCountry() + var + LocationCard: TestPage "Location Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is opened and country is set to GB + LocationCard.OpenEdit(); + LocationCard.New(); + LocationCard."Country/Region Code".Value('GB'); + + // [THEN] postcode lookup action is visible + Assert.IsTrue(LocationCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(true, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestLocationLookupVisibleInEditModeNonGBCountry() + var + LocationCard: TestPage "Location Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is opened and country is set to something other than GB + LocationCard.OpenEdit(); + LocationCard.New(); + LocationCard."Country/Region Code".Value('SI'); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(LocationCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchScenarioModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestLocationScenarioSuccess() + var + Location: Record Location; + LocationCard: TestPage "Location Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at location page and successful: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Selects 3rd + // 4. Values are populated + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] we assume successful process, copying fields + LocationCard.OpenEdit(); + LocationCard.New(); + LocationCard.Code.Value(LibraryRandom.RandText(10)); + LocationCard."Country/Region Code".Value(''); + LocationCard."Post Code".Value('TESTPOSTCODE'); + LocationCard.LookupAddress_IdealPostcodes.DrillDown(); // trigger postcode search + // PostcodeSearchScenario page handler takes over and inputs postcode + + // [THEN] we should get our data + Assert.AreEqual('ADDRESS', LocationCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('ADDRESS 2', LocationCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', LocationCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('CITY', LocationCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('GB', LocationCard."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + Location.Get(LocationCard.Code.Value); + LocationCard.Close(); + Location.Delete(); + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchCancelModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestLocationScenarioCancel() + var + LocationCard: TestPage "Location Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at location page but canceled: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Cancel the window + // 4. Values are left empty + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [GIVEN] ensure blank address fields + LocationCard.OpenEdit(); + LocationCard.New(); + LocationCard.Code.Value(LibraryRandom.RandText(10)); + LocationCard.Address.Value(''); + LocationCard."Address 2".Value(''); + LocationCard.City.Value(''); + LocationCard."Country/Region Code".Value(''); + LocationCard."Post Code".Value('TESTPOSTCODE'); + + // [WHEN] trigger postcode search + LocationCard.LookupAddress_IdealPostcodes.DrillDown(); + // PostcodeSearch cancel page handler takes over and cancels the process + + // [THEN] address fields should stay blank + Assert.AreEqual('', LocationCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', LocationCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', LocationCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('', LocationCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', LocationCard."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + LocationCard.Close(); + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestResourceLookupHiddenInViewMode() + var + ResourceCard: TestPage "Resource Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is viewed + ResourceCard.OpenView(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(ResourceCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestResourceLookupHidenInEditModeServiceNotConfigured() + var + ResourceCard: TestPage "Resource Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is opened + ResourceCard.OpenEdit(); + ResourceCard.New(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(ResourceCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestResourceLookupVisibleInEditModeServiceConfigured() + var + ResourceCard: TestPage "Resource Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is opened + ResourceCard.OpenEdit(); + ResourceCard.New(); + + // [THEN] postcode lookup action is visible + Assert.IsTrue(ResourceCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(true, LookupTextTok)); + + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchScenarioModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TesResourceScenarioSuccess() + var + Resource: Record Resource; + ResourceCard: TestPage "Resource Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at resource page and successful: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Selects 3rd + // 4. Values are populated + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] we assume successful process, copying fields + ResourceCard.OpenEdit(); + ResourceCard.New(); + ResourceCard."Country/Region Code".Value(''); + ResourceCard."Post Code".Value('TESTPOSTCODE'); + ResourceCard.LookupAddress_IdealPostcodes.DrillDown(); // trigger postcode search + // PostcodeSearchScenario page handler takes over and inputs postcode + + // [THEN] we should get our data + Assert.AreEqual('ADDRESS', ResourceCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('ADDRESS 2', ResourceCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', ResourceCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('CITY', ResourceCard.City.Value, RetrievedInvalidValueTok); + + Resource.Get(ResourceCard."No.".Value); + ResourceCard.Close(); + Resource.Delete(); + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchCancelModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestResourceScenarioCancel() + var + Resource: Record Resource; + ResourceCard: TestPage "Resource Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at resource page but canceled: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Cancel the window + // 4. Values are left empty + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [GIVEN] ensure blank address fields + ResourceCard.OpenEdit(); + ResourceCard.New(); + ResourceCard.Address.Value(''); + ResourceCard."Address 2".Value(''); + ResourceCard.City.Value(''); + ResourceCard."Country/Region Code".Value(''); + ResourceCard."Post Code".Value('TESTPOSTCODE'); + + // [WHEN] trigger postcode search + ResourceCard.LookupAddress_IdealPostcodes.DrillDown(); + // PostcodeSearch cancel page handler takes over and cancels the process + + // [THEN] address fields should stay blank + Assert.AreEqual('', ResourceCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', ResourceCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', ResourceCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('', ResourceCard.City.Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + Resource.Get(ResourceCard."No.".Value); + ResourceCard.Close(); + Resource.Delete(); + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestContactLookupHiddenInViewMode() + var + ContactCard: TestPage "Contact Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] customer card is viewed + ContactCard.OpenView(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(ContactCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestContactLookupHidenInEditModeServiceNotConfigured() + var + ContactCard: TestPage "Contact Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] customer card is opened + ContactCard.OpenEdit(); + ContactCard.New(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(ContactCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestContactLookupVisibleInEditModeGBCountry() + var + ContactCard: TestPage "Contact Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] customer card is opened and country is set to GB + ContactCard.OpenEdit(); + ContactCard.New(); + ContactCard."Country/Region Code".Value('GB'); + + // [THEN] postcode lookup action is visible + Assert.IsTrue(ContactCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(true, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestContactLookupVisibleInEditModeNonGBCountry() + var + Contact: Record Contact; + ContactCard: TestPage "Contact Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + + // [WHEN] customer card is opened and country is set to something other than GB + ContactCard.OpenEdit(); + ContactCard.New(); + ContactCard."Country/Region Code".Value('SI'); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(ContactCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + Contact.Get(ContactCard."No.".Value); + ContactCard.Close(); + Contact.Delete(); + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchScenarioModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestContactScenarioSuccess() + var + ContactCard: TestPage "Contact Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at contact page and successful: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Selects 3rd + // 4. Values are populated + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + + // [WHEN] we assume successful process, copying fields + ContactCard.OpenEdit(); + ContactCard.New(); + ContactCard."Country/Region Code".Value(''); + ContactCard."Post Code".Value('TESTPOSTCODE'); + ContactCard.LookupAddress_IdealPostcodes.DrillDown(); // trigger postcode search + // PostcodeSearchScenario page handler takes over and inputs postcode + + // [THEN] we should get our data + Assert.AreEqual('ADDRESS', ContactCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('ADDRESS 2', ContactCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', ContactCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('CITY', ContactCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('GB', ContactCard."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + ContactCard.Close(); + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchCancelModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestContactScenarioCancel() + var + ContactCard: TestPage "Contact Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at contact page but canceled: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Cancel the window + // 4. Values are left empty + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + + // [GIVEN] ensure blank address fields + ContactCard.OpenEdit(); + ContactCard.New(); + ContactCard.Address.Value(''); + ContactCard."Address 2".Value(''); + ContactCard.City.Value(''); + ContactCard."Country/Region Code".Value(''); + ContactCard."Post Code".Value('TESTPOSTCODE'); + + // [WHEN] trigger postcode search + ContactCard.LookupAddress_IdealPostcodes.DrillDown(); + // PostcodeSearch cancel page handler takes over and cancels the process + + // [THEN] address fields should stay blank + Assert.AreEqual('', ContactCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', ContactCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', ContactCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('', ContactCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', ContactCard."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + ContactCard.Close(); + Teardown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestContactAltAddrLookupHiddenInViewMode() + var + ContactAltAddressCard: TestPage "Contact Alt. Address Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] customer card is viewed + ContactAltAddressCard.OpenView(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(ContactAltAddressCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestContactAltAddrLookupHidenInEditModeServiceNotConfigured() + var + ContactAltAddressCard: TestPage "Contact Alt. Address Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] customer card is opened + ContactAltAddressCard.OpenEdit(); + ContactAltAddressCard.New(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(ContactAltAddressCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestContactAltAddrLookupVisibleInEditModeGBCountry() + var + ContactAltAddressCard: TestPage "Contact Alt. Address Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] customer card is opened and country is set to GB + ContactAltAddressCard.OpenEdit(); + ContactAltAddressCard.New(); + ContactAltAddressCard."Country/Region Code".Value('GB'); + + // [THEN] postcode lookup action is visible + Assert.IsTrue(ContactAltAddressCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(true, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestContactAltAddrLookupVisibleInEditModeNonGBCountry() + var + ContactAltAddressCard: TestPage "Contact Alt. Address Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] customer card is opened and country is set to something other than GB + ContactAltAddressCard.OpenEdit(); + ContactAltAddressCard.New(); + ContactAltAddressCard."Country/Region Code".Value('SI'); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(ContactAltAddressCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchScenarioModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestContactAltAddrScenarioSuccess() + var + ContactAltAddressCard: TestPage "Contact Alt. Address Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at contact alternative address page and successful: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Selects 3rd + // 4. Values are populated + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetCustomerEdit(); + + // [WHEN] we assume successful process, copying fields + ContactAltAddressCard.OpenEdit(); + ContactAltAddressCard.New(); + ContactAltAddressCard.Code.Value(LibraryRandom.RandText(10)); + ContactAltAddressCard."Country/Region Code".Value(''); + ContactAltAddressCard."Post Code".Value('TESTPOSTCODE'); + ContactAltAddressCard.LookupAddress_IdealPostcodes.DrillDown(); // trigger postcode search + // PostcodeSearchScenario page handler takes over and inputs postcode + + // [THEN] we should get our data + Assert.AreEqual('ADDRESS', ContactAltAddressCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('ADDRESS 2', ContactAltAddressCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', ContactAltAddressCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('CITY', ContactAltAddressCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('GB', ContactAltAddressCard."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchCancelModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestContactAltAddrScenarioCancel() + var + ContactAltAddressCard: TestPage "Contact Alt. Address Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at contact alternative address page but canceled: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Cancel the window + // 4. Values are left empty + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetCustomerEdit(); + + // [GIVEN] ensure blank address fields + ContactAltAddressCard.OpenEdit(); + ContactAltAddressCard.Code.Value(LibraryRandom.RandText(10)); + ContactAltAddressCard.Address.Value(''); + ContactAltAddressCard."Address 2".Value(''); + ContactAltAddressCard.City.Value(''); + ContactAltAddressCard."Country/Region Code".Value(''); + ContactAltAddressCard."Post Code".Value('TESTPOSTCODE'); + + // [WHEN] trigger postcode search + ContactAltAddressCard.LookupAddress_IdealPostcodes.DrillDown(); + // PostcodeSearch cancel page handler takes over and cancels the process + + // [THEN] address fields should stay blank + Assert.AreEqual('', ContactAltAddressCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', ContactAltAddressCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', ContactAltAddressCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('', ContactAltAddressCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', ContactAltAddressCard."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestCompanyInformationLookupHiddenInViewMode() + var + CompanyInformation: TestPage "Company Information"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is viewed + CompanyInformation.OpenView(); + + // [THEN] lookup link should be visible + Assert.IsFalse(CompanyInformation.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestCompanyInformationLookupHidenInEditModeServiceNotConfigured() + var + CompanyInformation: TestPage "Company Information"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is opened + CompanyInformation.OpenEdit(); + + // [THEN] lookup link should be visible + Assert.IsFalse(CompanyInformation.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestCompanyInformationLookupVisibleInEditModeGBCountry() + var + CompanyInformation: TestPage "Company Information"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is opened and country is set to GB + CompanyInformation.OpenEdit(); + CompanyInformation."Country/Region Code".Value('GB'); + + // [THEN] lookup link should be visible + Assert.IsTrue(CompanyInformation.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(true, LookupTextTok)); + + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestCompanyInformationLookupVisibleInEditModeNonGBCountry() + var + CompanyInformation: TestPage "Company Information"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is opened and country is set to something other than GB + CompanyInformation.OpenEdit(); + CompanyInformation."Country/Region Code".Value('SI'); + + // [THEN] lookup link should be visible + Assert.IsFalse(CompanyInformation.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestCompanyInformationShipToLookupHiddenInViewMode() + var + CompanyInformation: TestPage "Company Information"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is viewed + CompanyInformation.OpenView(); + + // [THEN] lookup link should be visible + Assert.IsFalse(CompanyInformation.LookupShipToAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestCompanyInformationShipToLookupHidenInEditModeServiceNotConfigured() + var + CompanyInformation: TestPage "Company Information"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is opened + CompanyInformation.OpenEdit(); + + // [THEN] lookup link should be visible + Assert.IsFalse(CompanyInformation.LookupShipToAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestCompanyInformationShipToLookupVisibleInEditModeBlankCountry() + var + CompanyInformation: TestPage "Company Information"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is opened and country is set to blank + CompanyInformation.OpenEdit(); + CompanyInformation."Ship-to Country/Region Code".Value(''); + + // [THEN] lookup link should be visible + Assert.IsTrue(CompanyInformation.LookupShipToAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(true, LookupTextTok)); + + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestCompanyInformationShipToLookupVisibleInEditModeNonGBCountry() + var + CompanyInformation: TestPage "Company Information"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] customer card is opened and country is set to something other than GB + CompanyInformation.OpenEdit(); + CompanyInformation."Ship-to Country/Region Code".Value('SI'); + + // [THEN] lookup link should be visible + Assert.IsFalse(CompanyInformation.LookupShipToAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchScenarioModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestCompanyInformationShipToScenarioSuccess() + var + CompanyInformation: TestPage "Company Information"; + begin + // [SCENARIO] Postcode auto complete is initiated at company infromation (ship to) page and successful: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Selects 3rd + // 4. Values are populated + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [WHEN] we assume successful process, copying fields + CompanyInformation.OpenEdit(); + CompanyInformation."Ship-to Country/Region Code".Value(''); + CompanyInformation."Ship-to Post Code".Value('TESTPOSTCODE'); + CompanyInformation.LookupShipToAddress_IdealPostcodes.DrillDown(); // trigger postcode search + // PostcodeSearchScenario page handler takes over and inputs postcode + + // [THEN] we should get our data + Assert.AreEqual('ADDRESS', CompanyInformation."Ship-to Address".Value, RetrievedInvalidValueTok); + Assert.AreEqual('ADDRESS 2', CompanyInformation."Ship-to Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', CompanyInformation."Ship-to Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('CITY', CompanyInformation."Ship-to City".Value, RetrievedInvalidValueTok); + Assert.AreEqual('GB', CompanyInformation."Ship-to Country/Region Code".Value, RetrievedInvalidValueTok); + + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchCancelModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestCompanyInformationShipToScenarioCancel() + var + CompanyInformation: TestPage "Company Information"; + begin + // [SCENARIO] Postcode auto complete is initiated at company infromation (ship to) page but canceled: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Cancel the window + // 4. Values are left empty + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetO365BusFull(); + + // [GIVEN] ensure blank address fields + CompanyInformation.OpenEdit(); + CompanyInformation."Ship-to Address".Value(''); + CompanyInformation."Ship-to Address 2".Value(''); + CompanyInformation."Ship-to City".Value(''); + CompanyInformation."Ship-to Country/Region Code".Value(''); + CompanyInformation."Ship-to Post Code".Value('TESTPOSTCODE'); + + // [WHEN] trigger postcode search + CompanyInformation.LookupShipToAddress_IdealPostcodes.DrillDown(); + // PostcodeSearch cancel page handler takes over and cancels the process + + // [THEN] address fields should stay blank + Assert.AreEqual('', CompanyInformation."Ship-to Address".Value, RetrievedInvalidValueTok); + Assert.AreEqual('', CompanyInformation."Ship-to Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', CompanyInformation."Ship-to Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('', CompanyInformation."Ship-to City".Value, RetrievedInvalidValueTok); + Assert.AreEqual('', CompanyInformation."Ship-to Country/Region Code".Value, RetrievedInvalidValueTok); + + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestVendorLookupHiddenInViewMode() + var + VendorCard: TestPage "Vendor Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + + // [WHEN] customer card is viewed + VendorCard.OpenView(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(VendorCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestVendorLookupHidenInEditModeServiceNotConfigured() + var + VendorCard: TestPage "Vendor Card"; + begin + // [GIVEN] postcode service is not configured + // - Unbind dummy service so it won't raise an error + Initialize(); + TearDown(); // unbind dummy service + LibraryLowerPermissions.SetVendorEdit(); + + // [WHEN] customer card is opened + VendorCard.OpenEdit(); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(VendorCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + end; + + [Test] + [Scope('OnPrem')] + procedure TestVendorLookupVisibleInEditModeGBCountry() + var + VendorCard: TestPage "Vendor Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetVendorEdit(); + + // [WHEN] customer card is opened and country is set to GB + VendorCard.OpenEdit(); + VendorCard."Country/Region Code".Value('GB'); + + // [THEN] postcode lookup action is visible + Assert.IsTrue(VendorCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(true, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [Scope('OnPrem')] + procedure TestVendorLookupVisibleInEditModeNonGBCountry() + var + VendorCard: TestPage "Vendor Card"; + begin + // [GIVEN] postcode service is configured + Initialize(); + LibraryLowerPermissions.SetVendorEdit(); + + // [WHEN] customer card is opened and country is set to something other than GB + VendorCard.OpenEdit(); + VendorCard."Country/Region Code".Value('SI'); + + // [THEN] postcode lookup action is visible + Assert.IsFalse(VendorCard.LookupAddress_IdealPostcodes.Visible(), ErrorMsgGenerator(false, LookupTextTok)); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchScenarioModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestVendorScenarioSuccess() + var + VendorCard: TestPage "Vendor Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at vendor page and successful: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Selects 3rd + // 4. Values are populated + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetVendorEdit(); + + // [WHEN] we assume successful process, copying fields + VendorCard.OpenEdit(); + VendorCard."Country/Region Code".Value(''); + VendorCard."Post Code".Value('TESTPOSTCODE'); + VendorCard.LookupAddress_IdealPostcodes.DrillDown(); // trigger postcode search + // PostcodeSearchScenario page handler takes over and inputs postcode + + // [THEN] we should get our data + Assert.AreEqual('ADDRESS', VendorCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('ADDRESS 2', VendorCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', VendorCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('CITY', VendorCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('GB', VendorCard."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + [Test] + [HandlerFunctions('PostcodeSearchCancelModalPageHandler,IdealPostCodesHttpClientHandler')] + [Scope('OnPrem')] + procedure TestVendorScenarioCancel() + var + VendorCard: TestPage "Vendor Card"; + begin + // [SCENARIO] Postcode auto complete is initiated at vendor page but canceled: + // 1. User clicks postcode lookup + // 2. Enters a valid postcode with multiple results + // 3. Cancel the window + // 4. Values are left empty + + // [GIVEN] + // - Service is configured + // - Retrieve a result with one address, so that values are + // automatically set + Initialize(); + LibraryLowerPermissions.SetVendorEdit(); + + // [GIVEN] ensure blank address fields + VendorCard.OpenEdit(); + VendorCard.Address.Value(''); + VendorCard."Address 2".Value(''); + VendorCard.City.Value(''); + VendorCard."Country/Region Code".Value(''); + VendorCard."Post Code".Value('TESTPOSTCODE'); + + // [WHEN] trigger postcode search + VendorCard.LookupAddress_IdealPostcodes.DrillDown(); + // PostcodeSearch cancel page handler takes over and cancels the process + + // [THEN] address fields should stay blank + Assert.AreEqual('', VendorCard.Address.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', VendorCard."Address 2".Value, RetrievedInvalidValueTok); + Assert.AreEqual('TESTPOSTCODE', VendorCard."Post Code".Value, RetrievedInvalidValueTok); + Assert.AreEqual('', VendorCard.City.Value, RetrievedInvalidValueTok); + Assert.AreEqual('', VendorCard."Country/Region Code".Value, RetrievedInvalidValueTok); + + LibraryLowerPermissions.SetO365BusFull(); // for cleanup + TearDown(); + end; + + local procedure Initialize() + var + PostcodeServiceConfig: Record "Postcode Service Config"; + CountryRegion: Record "Country/Region"; + Customer: Record Customer; + Vendor: Record Vendor; + Employee: Record Employee; + IPCConfig: Record "IPC Config"; + PostCode: Record "Post Code"; + BankAccount: Record "Bank Account"; + LibraryERM: Codeunit "Library - ERM"; + APIKeyGuid: Guid; + MyServiceKeyTok: Label 'IDEAL_POSTCODE_POSTCODE_SERVICE', Locked = true; + begin + UnbindSubscription(PostcodeDummyService); + BindSubscription(PostcodeDummyService); + + PostCode.SetRange(Code, 'TESTPOSTCODE'); + PostCode.DeleteAll(); + + if BankAccount.IsEmpty() then + LibraryERM.CreateBankAccount(BankAccount); + + if Customer.IsEmpty() then + LibrarySales.CreateCustomer(Customer); + + if Vendor.IsEmpty() then + LibraryPurchase.CreateVendor(Vendor); + + if Employee.IsEmpty() then + LibraryHR.CreateEmployee(Employee); + + if not CountryRegion.Get('GB') then begin + CountryRegion.Init(); + CountryRegion.Code := 'GB'; + CountryRegion.Name := 'Great Britain'; + CountryRegion.Insert(); + end; + + if not CountryRegion.Get('SI') then begin + CountryRegion.Init(); + CountryRegion.Code := 'SI'; + CountryRegion.Name := 'Slovenia'; + CountryRegion.Insert(); + end; + + PostcodeServiceConfig.DeleteAll(); + + PostcodeServiceConfig.Init(); + PostcodeServiceConfig.Insert(); + PostcodeServiceConfig.SaveServiceKey(MyServiceKeyTok); + if not IPCConfig.Get() then begin + IPCConfig.Init(); + IPCConfig.Enabled := true; + ApiKeyGuid := CreateGuid(); + IPCConfig."API Key" := ApiKeyGuid; + IPCConfig.Insert(); + IPCConfig.SaveAPIKeyAsSecret(ApiKeyGuid, SecretStrSubstNo('apikey')); + end else begin + IPCConfig.Enabled := true; + ApiKeyGuid := CreateGuid(); + IPCConfig."API Key" := ApiKeyGuid; + IPCConfig.Modify(); + IPCConfig.SaveAPIKeyAsSecret(ApiKeyGuid, SecretStrSubstNo('apikey')); + end; + Commit(); + Initialized := true; + end; + + [Scope('OnPrem')] + procedure Teardown() + var + PostcodeServiceConfig: Record "Postcode Service Config"; + IPCConfig: Record "IPC Config"; + begin + UnbindSubscription(PostcodeDummyService); + PostcodeServiceConfig.DeleteAll(); + IPCConfig.DeleteAll(); + Commit(); + Initialized := false; + end; + + local procedure ErrorMsgGenerator(Visible: Boolean; FieldName: Text): Text + var + ErrorMsg: Text; + ServiceConfigured: Boolean; + begin + ErrorMsg := FieldName + ' should be '; + ServiceConfigured := Initialized; // Bound indirectly indicates if the service is configured + + if Visible then + ErrorMsg := ErrorMsg + 'VISIBLE' + else + ErrorMsg := ErrorMsg + 'HIDDEN'; + + ErrorMsg := ErrorMsg + ' if service is '; + + if ServiceConfigured then + ErrorMsg := ErrorMsg + 'configured' + else + ErrorMsg := ErrorMsg + 'NOT configured'; + + ErrorMsg := ErrorMsg + '.'; + exit(ErrorMsg); + end; + + [ModalPageHandler] + [Scope('OnPrem')] + procedure PostcodeSearchScenarioModalPageHandler(var IPCAddressLookup: TestPage "IPC Address Lookup") + begin + IPCAddressLookup."Post Code".Value('TESTPOSTCODE'); + IPCAddressLookup.OK().Invoke(); + end; + + [ModalPageHandler] + [Scope('OnPrem')] + procedure PostcodeSearchCancelModalPageHandler(var IPCAddressLookup: TestPage "IPC Address Lookup") + begin + IPCAddressLookup.Cancel().Invoke(); + end; + + [HttpClientHandler] + procedure IdealPostCodesHttpClientHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean + var + IPCConfig: Record "IPC Config"; + URLTxt: Text; + InStream: InStream; + ResourceName: Text; + begin + URLTxt := IPCConfig.APIEndpoint(); + case Request.Path of + URLTxt + '/postcodes/TESTPOSTCODE': + ResourceName := 'SearchAddress_TESTPOSTCODE.json'; + else + exit(true); + end; + + NavApp.GetResource(ResourceName, InStream); + Response.Content.WriteFrom(InStream); + Response.HttpStatusCode := 200; + exit(false); + end; + +} diff --git a/Apps/GB/IdealPostcodes/test/src/TestNegativeOutcomes.Codeunit.al b/Apps/GB/IdealPostcodes/test/src/TestNegativeOutcomes.Codeunit.al new file mode 100644 index 0000000000..fa0f47499e --- /dev/null +++ b/Apps/GB/IdealPostcodes/test/src/TestNegativeOutcomes.Codeunit.al @@ -0,0 +1,165 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Foundation.Address.IdealPostcodes.Test; + +using Microsoft.Foundation.Address; +using Microsoft.Foundation.Address.IdealPostcodes; +using System.TestLibraries.Utilities; + +codeunit 148119 "Test Negative Outcomes" +{ + // version Test,W1,All + + Subtype = Test; + TestType = IntegrationTest; + + var + Assert: Codeunit "Assert"; + LibraryVariableStorage: Codeunit "Library - Variable Storage"; + PostcodeServiceManager: Codeunit "Postcode Service Manager"; + LibraryLowerPermissions: Codeunit "Library - Lower Permissions"; + MyServiceKeyTok: Label 'IDEAL_POSTCODE_POSTCODE_SERVICE', Locked = true; + + [Test] + [HandlerFunctions('ConfigPageHandler')] + procedure TestOpenConfigPageBlankAPIShow() + var + Successful: Boolean; + begin + // [GIVEN] + LibraryLowerPermissions.SetO365BusFull(); + Initialize(); + + LibraryVariableStorage.Enqueue('You must specify an API Key.'); + LibraryVariableStorage.Enqueue('You must specify an API Key.'); + + // [WHEN] request to open a page, error is also thrown because of an empty API key, ignore it + PostcodeServiceManager.ShowConfigurationPage('IDEAL_POSTCODE_POSTCODE_SERVICE', Successful); + + // [THEN] a page is open, otherwise we have an unused handler + end; + + [Test] + procedure TestIsConfiguredNoAPIKey() + var + Successful: Boolean; + begin + // [GIVEN] + LibraryLowerPermissions.SetO365BusFull(); + Initialize(); + + // [WHEN] request to open a page is made + PostcodeServiceManager.IsServiceConfigured('IDEAL_POSTCODE_POSTCODE_SERVICE', Successful); + + // [THEN] API key is not set to result should be false + Assert.IsFalse(Successful, 'API key is not set so service should not respond as configured'); + end; + + [Test] + procedure TestIsConfiguredWithAPIKey() + var + IPCConfig: Record "IPC Config"; + Successful: Boolean; + ApiKeyGuid: Guid; + begin + // [GIVEN] + LibraryLowerPermissions.SetO365BusFull(); + Initialize(); + IPCConfig.FINDFIRST(); + IPCConfig.Enabled := true; + ApiKeyGuid := CreateGuid(); + IPCConfig.SaveAPIKeyAsSecret(ApiKeyGuid, SecretStrSubstNo('apikey')); + IPCConfig."API Key" := ApiKeyGuid; + IPCConfig.MODIFY(); + + // [WHEN] request to open a page is made + PostcodeServiceManager.IsServiceConfigured('IDEAL_POSTCODE_POSTCODE_SERVICE', Successful); + + // [THEN] API key is not set to result should be false + Assert.IsTrue(Successful, 'Service should be active, as endpoint url and api key are set'); + + // Cleanup + CLEAR(IPCConfig."API Key"); + IPCConfig.MODIFY(); + end; + + [Test] + procedure TestConfigPageInputedAPIKey() + var + IPCConfig: Record "IPC Config"; + IPCConfigPage: TestPage "IPC Config"; + begin + // [GIVEN] we have an empty API Key + LibraryLowerPermissions.SetO365BusFull(); + Initialize(); + // [WHEN] we assign a value to it + IPCConfigPage.OPENEDIT(); + IPCConfigPage."API Key".VALUE('VALUE'); + + // [THEN] GUID should not be null for encrypted API Key in table + IPCConfig.FINDFIRST(); + Assert.IsFalse(ISNULLGUID(IPCConfig."API Key"), 'Encrypted API Key was stored incorectly'); + end; + + [Test] + procedure TestConfigPageTermsAndConditionsNotice() + var + IPCConfig: TestPage "IPC Config"; + begin + // [GIVEN] Empty configuration + LibraryLowerPermissions.SetO365BusFull(); + + // Expected message + Initialize(); + LibraryVariableStorage.Enqueue( + 'You are accessing a third-party website and service. You should review the third-party''s terms and privacy policy.'); + + // [WHEN] Open and close the dialog box + IPCConfig.OPENEDIT(); + IPCConfig."API Key".VALUE('KEY'); // Doesn't matter what + IPCConfig.TermsAndConditions.ACTIVATE(); // Make sure the field exists + IPCConfig.OK().INVOKE(); + + // [THEN] Message dialog should appear. + end; + + local procedure Initialize() + var + IPCConfig: Record "IPC Config"; + PostcodeServiceConfig: Record "Postcode Service Config"; + begin + Clear(LibraryVariableStorage); + Clear(PostcodeServiceManager); + + PostcodeServiceConfig.DeleteAll(); + IPCConfig.DeleteAll(); + Commit(); + + // Create IdealPostcodes Config and Postcode config + if IPCConfig.IsEmpty() then begin + PostcodeServiceConfig.Init(); + PostcodeServiceConfig.Insert(); + PostcodeServiceConfig.SaveServiceKey(MyServiceKeyTok); + + IPCConfig.Init(); + IPCConfig.Insert(); + Commit(); + end; + + // Active service in Postcode Service Manager + end; + + [ModalPageHandler] + procedure ConfigPageHandler(var IPCConfig: TestPage "IPC Config") + begin + IPCConfig.OK().Invoke() + end; + + [MessageHandler] + procedure MessageHandler(Message: Text[1024]) + begin + Assert.AreEqual(LibraryVariableStorage.DequeueText(), Message, 'Incorrect error was shown.'); + end; +} diff --git a/Apps/GB/IntrastatGB/app/AppResources/GB_DataExchDefMapRcpt.xml b/Apps/GB/IntrastatGB/app/AppResources/GB_DataExchDefMapRcpt.xml index 42b915c3e3..f55896ba03 100644 --- a/Apps/GB/IntrastatGB/app/AppResources/GB_DataExchDefMapRcpt.xml +++ b/Apps/GB/IntrastatGB/app/AppResources/GB_DataExchDefMapRcpt.xml @@ -30,12 +30,12 @@ - + - + diff --git a/Apps/GB/IntrastatGB/app/AppResources/GB_DataExchDefMapShpt.xml b/Apps/GB/IntrastatGB/app/AppResources/GB_DataExchDefMapShpt.xml index 8a8ca1e7b1..b2f952c239 100644 --- a/Apps/GB/IntrastatGB/app/AppResources/GB_DataExchDefMapShpt.xml +++ b/Apps/GB/IntrastatGB/app/AppResources/GB_DataExchDefMapShpt.xml @@ -32,12 +32,12 @@ - + - + diff --git a/Apps/GB/IntrastatGB/app/src/IntrastatReportManagementGB.Codeunit.al b/Apps/GB/IntrastatGB/app/src/IntrastatReportManagementGB.Codeunit.al index 8a34be2054..6973bc3242 100644 --- a/Apps/GB/IntrastatGB/app/src/IntrastatReportManagementGB.Codeunit.al +++ b/Apps/GB/IntrastatGB/app/src/IntrastatReportManagementGB.Codeunit.al @@ -116,8 +116,8 @@ codeunit 10501 "Intrastat Report Management GB" var IntrastatReportHeader2: Record "Intrastat Report Header"; - DataExchangeRcptTxt: Label 'TRIMALLRemoves all spaces5&#032;0000000.00', + DataExchangeRcptTxt: Label 'TRIMALLRemoves all spaces5&#032;0000000.00', Locked = true; // will be replaced with file import when available - DataExchangeShptTxt: Label 'TRIMALLRemoves all spaces5&#032;0000000.00LOOKUPINTRASTATCODELookup Intrastat Country Code130091710.00', + DataExchangeShptTxt: Label 'TRIMALLRemoves all spaces5&#032;0000000.00LOOKUPINTRASTATCODELookup Intrastat Country Code130091710.00', Locked = true; // will be replaced with file import when available } \ No newline at end of file diff --git a/Apps/GB/ReportsGB/app/src/Codeunits/FeatureReportsGB.Codeunit.al b/Apps/GB/ReportsGB/app/src/Codeunits/FeatureReportsGB.Codeunit.al index f2eb815bcf..a61fbc2b42 100644 --- a/Apps/GB/ReportsGB/app/src/Codeunits/FeatureReportsGB.Codeunit.al +++ b/Apps/GB/ReportsGB/app/src/Codeunits/FeatureReportsGB.Codeunit.al @@ -4,24 +4,13 @@ /// namespace Microsoft.Finance.VAT.Setup; -using Microsoft.Bank.Reports; -using Microsoft.CashFlow.Reports; -using Microsoft.FixedAssets.Reports; -using Microsoft.Foundation.Reporting; -using Microsoft.Purchases.Document; -using Microsoft.Purchases.History; -using Microsoft.Purchases.Reports; -using Microsoft.Sales.FinanceCharge; -using Microsoft.Sales.History; -using Microsoft.Sales.Reminder; -using Microsoft.Sales.Reports; using System.Environment.Configuration; -using System.Reflection; using System.Upgrade; codeunit 10580 "Feature - Reports GB" implements "Feature Data Update" { Access = Internal; + Permissions = TableData "Feature Data Update Status" = rm; InherentEntitlements = X; InherentPermissions = X; ObsoleteReason = 'Feature Reports GB will be enabled by default in version 30.0.'; @@ -30,7 +19,6 @@ codeunit 10580 "Feature - Reports GB" implements "Feature Data Update" var UpgTagReportsGB: Codeunit "Upg. Tag Reports GB"; - ReportsGBApplicationAppIdTok: Label '{a4417920-02d4-47fc-b6d2-3bcfdfe1e798}', Locked = true; DescriptionTxt: Label 'Report layouts will be updated to contain GB localization functionality'; procedure IsDataUpdateRequired(): Boolean @@ -50,12 +38,13 @@ codeunit 10580 "Feature - Reports GB" implements "Feature Data Update" procedure UpdateData(FeatureDataUpdateStatus: Record "Feature Data Update Status") var FeatureDataUpdateMgt: Codeunit "Feature Data Update Mgt."; + ReportsGBHelperProcedures: Codeunit "Reports GB Helper Procedures"; StartDateTime: DateTime; EndDateTime: DateTime; begin StartDateTime := CurrentDateTime; FeatureDataUpdateMgt.LogTask(FeatureDataUpdateStatus, 'Upgrade Reports GB', StartDateTime); - SetDefaultReportLayouts(); + ReportsGBHelperProcedures.SetDefaultReportLayouts(); EndDateTime := CurrentDateTime; FeatureDataUpdateMgt.LogTask(FeatureDataUpdateStatus, 'Upgrade Reports GB', EndDateTime); end; @@ -89,98 +78,5 @@ codeunit 10580 "Feature - Reports GB" implements "Feature Data Update" if not DataUpgradeExecuted then UpgradeTag.SetSkippedUpgrade(UpgTagReportsGB.GetReportsGBUpgradeTag(), true); end; - - procedure SetDefaultReportLayouts() - begin - SetDefaultReportLayout(Report::"Sales Document - Test"); - SetDefaultReportLayout(Report::"Purchase Document - Test"); - SetDefaultReportLayout(Report::Reminder); - SetDefaultReportLayout(Report::"Bank Account - List"); - SetDefaultReportLayout(Report::"Cash Flow Dimensions - Detail"); - SetDefaultReportLayout(Report::"Finance Charge Memo"); -#if not CLEAN28 - SetDefaultReportLayout(Report::"Fixed Asset - Projected Value"); -#endif - SetDefaultReportLayout(Report::"Purchase - Quote"); - SetDefaultReportLayout(Report::"Purchase - Receipt"); - SetDefaultReportLayout(Report::"Sales - Shipment"); - end; - - local procedure SetDefaultReportLayout(ReportID: Integer) - var - SelectedReportLayoutList: Record "Report Layout List"; - begin - SelectedReportLayoutList.SetRange("Report ID", ReportID); - SelectedReportLayoutList.SetRange(Name, 'GBlocalizationLayout'); - SelectedReportLayoutList.SetRange("Application ID", ReportsGBApplicationAppIdTok); - if SelectedReportLayoutList.FindFirst() then - SetDefaultReportLayoutSelection(SelectedReportLayoutList); - SelectedReportLayoutList.Reset(); - end; - - local procedure SetDefaultReportLayoutSelection(SelectedReportLayoutList: Record "Report Layout List") - var - ReportLayoutSelection: Record "Report Layout Selection"; - CustomDimensions: Dictionary of [Text, Text]; - EmptyGuid: Guid; - SelectedCompany: Text[30]; - begin - SelectedCompany := CopyStr(CompanyName, 1, MaxStrLen(SelectedCompany)); - AddLayoutSelection(SelectedReportLayoutList, EmptyGuid, SelectedCompany); - if ReportLayoutSelection.get(SelectedReportLayoutList."Report ID", SelectedCompany) then begin - ReportLayoutSelection.Type := GetReportLayoutSelectionCorrespondingEnum(SelectedReportLayoutList); - ReportLayoutSelection.Modify(true); - end else begin - ReportLayoutSelection."Report ID" := SelectedReportLayoutList."Report ID"; - ReportLayoutSelection."Company Name" := SelectedCompany; - ReportLayoutSelection."Custom Report Layout Code" := ''; - ReportLayoutSelection.Type := GetReportLayoutSelectionCorrespondingEnum(SelectedReportLayoutList); - ReportLayoutSelection.Insert(true); - end; - - InitReportLayoutListDimensions(SelectedReportLayoutList, CustomDimensions); - AddReportLayoutDimensionsAction('SetDefault', CustomDimensions); - end; - - local procedure AddLayoutSelection(SelectedReportLayoutList: Record "Report Layout List"; UserId: Guid; SelectedCompany: Text[30]): Boolean - var - TenantReportLayoutSelection: Record "Tenant Report Layout Selection"; - begin - TenantReportLayoutSelection.Init(); - TenantReportLayoutSelection."App ID" := SelectedReportLayoutList."Application ID"; - TenantReportLayoutSelection."Company Name" := SelectedCompany; - TenantReportLayoutSelection."Layout Name" := SelectedReportLayoutList."Name"; - TenantReportLayoutSelection."Report ID" := SelectedReportLayoutList."Report ID"; - TenantReportLayoutSelection."User ID" := UserId; - - if not TenantReportLayoutSelection.Insert(true) then - TenantReportLayoutSelection.Modify(true); - end; - - local procedure GetReportLayoutSelectionCorrespondingEnum(SelectedReportLayoutList: Record "Report Layout List"): Integer - begin - case SelectedReportLayoutList."Layout Format" of - - SelectedReportLayoutList."Layout Format"::RDLC: - exit(0); - SelectedReportLayoutList."Layout Format"::Word: - exit(1); - SelectedReportLayoutList."Layout Format"::Excel: - exit(3); - SelectedReportLayoutList."Layout Format"::Custom: - exit(4); - end - end; - - local procedure InitReportLayoutListDimensions(ReportLayoutList: Record "Report Layout List"; var CustomDimensions: Dictionary of [Text, Text]) - begin - CustomDimensions.Set('ReportId', Format(ReportLayoutList."Report ID")); - CustomDimensions.Set('LayoutName', ReportLayoutList."Name"); - end; - - local procedure AddReportLayoutDimensionsAction(Action: Text; var CustomDimensions: Dictionary of [Text, Text]) - begin - CustomDimensions.Add('Action', Action); - end; } #endif \ No newline at end of file diff --git a/Apps/GB/ReportsGB/app/src/Codeunits/InstallReportsGB.Codeunit.al b/Apps/GB/ReportsGB/app/src/Codeunits/InstallReportsGB.Codeunit.al new file mode 100644 index 0000000000..17a377697f --- /dev/null +++ b/Apps/GB/ReportsGB/app/src/Codeunits/InstallReportsGB.Codeunit.al @@ -0,0 +1,40 @@ +#if CLEAN27 +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Finance.VAT.Setup; + +using System.Upgrade; + +codeunit 10593 "Install Reports GB" +{ + Access = Internal; + Subtype = Install; + + var + UpgradeTag: Codeunit "Upgrade Tag"; + UpgTagReportsGB: Codeunit "Upg. Tag Reports GB"; + + trigger OnInstallAppPerCompany() + var + CurrentModuleInfo: ModuleInfo; + begin + NavApp.GetCurrentModuleInfo(CurrentModuleInfo); + if CurrentModuleInfo.AppVersion().Major() < 30 then + exit; + + InstallReportsGB(); + end; + + local procedure InstallReportsGB() + var + ReportsGBHelperProcedures: Codeunit "Reports GB Helper Procedures"; + begin + if UpgradeTag.HasUpgradeTag(UpgTagReportsGB.GetReportsGBUpgradeTag()) then + exit; + ReportsGBHelperProcedures.SetDefaultReportLayouts(); + UpgradeTag.SetUpgradeTag(UpgTagReportsGB.GetReportsGBUpgradeTag()); + end; +} +#endif \ No newline at end of file diff --git a/Apps/GB/ReportsGB/app/src/Codeunits/ReportsGBHelperProcedures.Codeunit.al b/Apps/GB/ReportsGB/app/src/Codeunits/ReportsGBHelperProcedures.Codeunit.al new file mode 100644 index 0000000000..879d80d04e --- /dev/null +++ b/Apps/GB/ReportsGB/app/src/Codeunits/ReportsGBHelperProcedures.Codeunit.al @@ -0,0 +1,123 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Finance.VAT.Setup; + +using Microsoft.Bank.Reports; +using Microsoft.CashFlow.Reports; +#if not CLEAN28 +using Microsoft.FixedAssets.Reports; +#endif +using Microsoft.Foundation.Reporting; +using Microsoft.Purchases.Document; +using Microsoft.Purchases.History; +using Microsoft.Purchases.Reports; +using Microsoft.Sales.FinanceCharge; +using Microsoft.Sales.History; +using Microsoft.Sales.Reminder; +using Microsoft.Sales.Reports; +using System.Environment.Configuration; +using System.Reflection; +codeunit 10592 "Reports GB Helper Procedures" +{ + Access = Internal; + + var + ReportsGBApplicationAppIdTok: Label '{a4417920-02d4-47fc-b6d2-3bcfdfe1e798}', Locked = true; + + procedure SetDefaultReportLayouts() + begin + SetDefaultReportLayout(Report::"Sales Document - Test"); + SetDefaultReportLayout(Report::"Purchase Document - Test"); + SetDefaultReportLayout(Report::Reminder); + SetDefaultReportLayout(Report::"Bank Account - List"); + SetDefaultReportLayout(Report::"Cash Flow Dimensions - Detail"); + SetDefaultReportLayout(Report::"Finance Charge Memo"); +#if not CLEAN28 +#pragma warning disable AL0432 + SetDefaultReportLayout(Report::"Fixed Asset - Projected Value"); +#pragma warning restore AL0432 +#endif + SetDefaultReportLayout(Report::"Purchase - Quote"); + SetDefaultReportLayout(Report::"Purchase - Receipt"); + SetDefaultReportLayout(Report::"Sales - Shipment"); + end; + + local procedure SetDefaultReportLayout(ReportID: Integer) + var + SelectedReportLayoutList: Record "Report Layout List"; + begin + SelectedReportLayoutList.SetRange("Report ID", ReportID); + SelectedReportLayoutList.SetRange(Name, 'GBlocalizationLayout'); + SelectedReportLayoutList.SetRange("Application ID", ReportsGBApplicationAppIdTok); + if SelectedReportLayoutList.FindFirst() then + SetDefaultReportLayoutSelection(SelectedReportLayoutList); + SelectedReportLayoutList.Reset(); + end; + + local procedure SetDefaultReportLayoutSelection(SelectedReportLayoutList: Record "Report Layout List") + var + ReportLayoutSelection: Record "Report Layout Selection"; + CustomDimensions: Dictionary of [Text, Text]; + EmptyGuid: Guid; + SelectedCompany: Text[30]; + begin + SelectedCompany := CopyStr(CompanyName, 1, MaxStrLen(SelectedCompany)); + AddLayoutSelection(SelectedReportLayoutList, EmptyGuid, SelectedCompany); + if ReportLayoutSelection.get(SelectedReportLayoutList."Report ID", SelectedCompany) then begin + ReportLayoutSelection.Type := GetReportLayoutSelectionCorrespondingEnum(SelectedReportLayoutList); + ReportLayoutSelection.Modify(true); + end else begin + ReportLayoutSelection."Report ID" := SelectedReportLayoutList."Report ID"; + ReportLayoutSelection."Company Name" := SelectedCompany; + ReportLayoutSelection."Custom Report Layout Code" := ''; + ReportLayoutSelection.Type := GetReportLayoutSelectionCorrespondingEnum(SelectedReportLayoutList); + ReportLayoutSelection.Insert(true); + end; + + InitReportLayoutListDimensions(SelectedReportLayoutList, CustomDimensions); + AddReportLayoutDimensionsAction('SetDefault', CustomDimensions); + end; + + local procedure AddLayoutSelection(SelectedReportLayoutList: Record "Report Layout List"; UserId: Guid; SelectedCompany: Text[30]): Boolean + var + TenantReportLayoutSelection: Record "Tenant Report Layout Selection"; + begin + TenantReportLayoutSelection.Init(); + TenantReportLayoutSelection."App ID" := SelectedReportLayoutList."Application ID"; + TenantReportLayoutSelection."Company Name" := SelectedCompany; + TenantReportLayoutSelection."Layout Name" := SelectedReportLayoutList."Name"; + TenantReportLayoutSelection."Report ID" := SelectedReportLayoutList."Report ID"; + TenantReportLayoutSelection."User ID" := UserId; + + if not TenantReportLayoutSelection.Insert(true) then + TenantReportLayoutSelection.Modify(true); + end; + + local procedure GetReportLayoutSelectionCorrespondingEnum(SelectedReportLayoutList: Record "Report Layout List"): Integer + begin + case SelectedReportLayoutList."Layout Format" of + + SelectedReportLayoutList."Layout Format"::RDLC: + exit(0); + SelectedReportLayoutList."Layout Format"::Word: + exit(1); + SelectedReportLayoutList."Layout Format"::Excel: + exit(3); + SelectedReportLayoutList."Layout Format"::Custom: + exit(4); + end + end; + + local procedure InitReportLayoutListDimensions(ReportLayoutList: Record "Report Layout List"; var CustomDimensions: Dictionary of [Text, Text]) + begin + CustomDimensions.Set('ReportId', Format(ReportLayoutList."Report ID")); + CustomDimensions.Set('LayoutName', ReportLayoutList."Name"); + end; + + local procedure AddReportLayoutDimensionsAction(Action: Text; var CustomDimensions: Dictionary of [Text, Text]) + begin + CustomDimensions.Add('Action', Action); + end; +} \ No newline at end of file diff --git a/Apps/GB/ReportsGB/app/src/Codeunits/UpgTagReportsGB.Codeunit.al b/Apps/GB/ReportsGB/app/src/Codeunits/UpgTagReportsGB.Codeunit.al index 1aeb33cba2..91d0636d96 100644 --- a/Apps/GB/ReportsGB/app/src/Codeunits/UpgTagReportsGB.Codeunit.al +++ b/Apps/GB/ReportsGB/app/src/Codeunits/UpgTagReportsGB.Codeunit.al @@ -1,4 +1,3 @@ -#if not CLEAN27 // ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. @@ -9,9 +8,6 @@ using System.Upgrade; codeunit 10583 "Upg. Tag Reports GB" { - ObsoleteReason = 'Feature Reports GB will be enabled by default in version 30.0.'; - ObsoleteState = Pending; - ObsoleteTag = '27.0'; Access = Internal; [EventSubscriber(ObjectType::Codeunit, Codeunit::"Upgrade Tag", 'OnGetPerCompanyUpgradeTags', '', false, false)] @@ -24,5 +20,4 @@ codeunit 10583 "Upg. Tag Reports GB" begin exit('MS-573191-ReportsGBUpgradeTag-20250602'); end; -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/Apps/GB/ReportsGB/app/src/Codeunits/UpgradeReportsGB.Codeunit.al b/Apps/GB/ReportsGB/app/src/Codeunits/UpgradeReportsGB.Codeunit.al index 139f5a51e3..47549287a9 100644 --- a/Apps/GB/ReportsGB/app/src/Codeunits/UpgradeReportsGB.Codeunit.al +++ b/Apps/GB/ReportsGB/app/src/Codeunits/UpgradeReportsGB.Codeunit.al @@ -1,4 +1,4 @@ -#if not CLEAN27 +#if CLEAN27 // ------------------------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. @@ -9,9 +9,6 @@ using System.Upgrade; codeunit 10582 "Upgrade Reports GB" { - ObsoleteReason = 'Feature Reports GB will be enabled by default in version 30.0.'; - ObsoleteState = Pending; - ObsoleteTag = '27.0'; Access = Internal; Subtype = Upgrade; @@ -32,11 +29,11 @@ codeunit 10582 "Upgrade Reports GB" local procedure UpgradeReportsGB() var - FeatureReportsGB: Codeunit "Feature - Reports GB"; + ReportsGBHelperProcedures: Codeunit "Reports GB Helper Procedures"; begin if UpgradeTag.HasUpgradeTag(UpgTagReportsGB.GetReportsGBUpgradeTag()) then exit; - FeatureReportsGB.SetDefaultReportLayouts(); + ReportsGBHelperProcedures.SetDefaultReportLayouts(); UpgradeTag.SetUpgradeTag(UpgTagReportsGB.GetReportsGBUpgradeTag()); end; } diff --git a/Apps/GB/UKPostcodeGetAddressIO/app/src/GetAddressioConfig.Page.al b/Apps/GB/UKPostcodeGetAddressIO/app/src/GetAddressioConfig.Page.al index 20d1237907..f4b7599b11 100644 --- a/Apps/GB/UKPostcodeGetAddressIO/app/src/GetAddressioConfig.Page.al +++ b/Apps/GB/UKPostcodeGetAddressIO/app/src/GetAddressioConfig.Page.al @@ -61,6 +61,27 @@ page 9142 "GetAddress.io Config" } } + actions + { + area(processing) + { + action(Disable) + { + ApplicationArea = All; + Image = Setup; + Caption = 'Disable'; + ToolTip = 'Disables the service by clearing the URL.'; + + trigger OnAction() + begin + Rec.EndpointURL := ''; + Rec.Modify(); + CurrPage.Update(); + end; + } + } + } + trigger OnAfterGetRecord() begin UpdateAPIField(); diff --git a/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeBusinessLogicGB.Codeunit.al b/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeBusinessLogicGB.Codeunit.al index ce3aae34b0..a46c5f8549 100644 --- a/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeBusinessLogicGB.Codeunit.al +++ b/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeBusinessLogicGB.Codeunit.al @@ -18,7 +18,7 @@ codeunit 9099 "Postcode Business Logic GB" var PostcodeServiceManager: Codeunit "Postcode Service Manager"; SavePostcode: Boolean; - UKPostcodeAutocompleteLbl: Label 'UK Postcode Service'; + UKPostcodeAutocompleteLbl: Label 'Postcode Service'; NoDataRetrievedErr: Label 'Postal code service did not return any results.'; SavePostcodeSet: Boolean; DiscoverabilityMessageMsg: Label 'You can retrieve and validate addresses based on postcodes.'; @@ -26,6 +26,7 @@ codeunit 9099 "Postcode Business Logic GB" DontShowAgainTok: Label 'Don''t show again'; NotificationIdTok: Label '3c379efc-509e-4f20-8c0e-e65f9d535a04', Locked = true; DisabledTok: Label 'Disabled', Locked = true; + ServiceNameTxt: Label 'GetAddress.io', Locked = true; procedure ShowLookupWindow(var TempEnteredAutocompleteAddress: Record "Autocomplete Address" temporary; ShowInputPage: Boolean; var TempAutocompleteAddress: Record "Autocomplete Address" temporary): Boolean var @@ -44,6 +45,11 @@ codeunit 9099 "Postcode Business Logic GB" // -- Address selection window opened with a list of possible addresses // - - Address selection is canceled => EXIT(FALSE), do not show postcode input page // - - Address selection is confirmed => set the address and EXIT(TRUE) + if not IsConfigured() then + exit; + + if PostcodeServiceManager.GetActiveService() <> ServiceNameTxt then + exit; if not ShowInputPage then TempEnteredAutocompleteAddress.Address := ''; @@ -112,11 +118,7 @@ codeunit 9099 "Postcode Business Logic GB" procedure NotificationOnConfigure(Notification: Notification) begin -#if not CLEAN28 - PAGE.Run(PAGE::"Postcode Configuration Page"); -#else - PAGE.Run(PAGE::"Postcode Configuration Page GB"); -#endif + PAGE.Run(PAGE::"Postcode Configuration Page W1"); DisableNotificationForUser(); end; @@ -126,8 +128,11 @@ codeunit 9099 "Postcode Business Logic GB" end; procedure IsConfigured(): Boolean + var + Configured: Boolean; begin - exit(PostcodeServiceManager.IsConfigured()); + PostcodeServiceManager.IsServiceConfigured(ServiceNameTxt, Configured); + exit(Configured); end; procedure SetSavePostcode(NewValue: Boolean) @@ -186,11 +191,7 @@ codeunit 9099 "Postcode Business Logic GB" local procedure ShowPostcodeInputFields(var Postcode: Text[20]; var DeliveryPoint: Text[100]): Boolean var -#if not CLEAN28 - PostcodeSearch: Page "Postcode Search"; -#else PostcodeSearch: Page "Postcode Search GB"; -#endif begin PostcodeSearch.SetValues(Postcode, ''); if PostcodeSearch.RunModal() = ACTION::Cancel then @@ -226,8 +227,10 @@ codeunit 9099 "Postcode Business Logic GB" local procedure RegisterServiceOnRegisterServiceConnection(var ServiceConnection: Record "Service Connection") var PostcodeServiceConfig: Record "Postcode Service Config"; + Configured: Boolean; begin - if PostcodeServiceManager.IsConfigured() then + PostcodeServiceManager.IsServiceConfigured(ServiceNameTxt, Configured); + if Configured then ServiceConnection.Status := ServiceConnection.Status::Enabled else ServiceConnection.Status := ServiceConnection.Status::Disabled; @@ -238,13 +241,8 @@ codeunit 9099 "Postcode Business Logic GB" PostcodeServiceConfig.SaveServiceKey('Disabled'); end; -#if not CLEAN28 - ServiceConnection.InsertServiceConnection(ServiceConnection, PostcodeServiceConfig.RecordId, - UKPostcodeAutocompleteLbl, '', PAGE::"Postcode Configuration Page"); -#else ServiceConnection.InsertServiceConnection(ServiceConnection, PostcodeServiceConfig.RecordId, - UKPostcodeAutocompleteLbl, '', PAGE::"Postcode Configuration Page GB"); -#endif + UKPostcodeAutocompleteLbl, '', PAGE::"Postcode Configuration Page W1"); end; } diff --git a/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeServiceGetAddressio.Codeunit.al b/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeServiceGetAddressio.Codeunit.al index f0e5224b89..3071ae334d 100644 --- a/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeServiceGetAddressio.Codeunit.al +++ b/Apps/GB/UKPostcodeGetAddressIO/app/src/PostcodeServiceGetAddressio.Codeunit.al @@ -16,7 +16,6 @@ codeunit 9092 "Postcode Service GetAddress.io" ServiceNameMsg: Label 'GetAddress.io', Locked = true; UKPostCodeFeatureNameTxt: Label 'GetAddress.io UK Postcodes', Locked = true; TechnicalErr: Label 'A technical error occurred while trying to reach the service.'; - WrongServiceErr: Label 'You must choose the getAddress.io service.'; ServiceUnavailableErr: Label 'The getAddress.io service is not available right now. Try again later.'; ExpiredTok: Label 'expired', Locked = true; PaymentTok: Label 'Payment Required', Locked = true; @@ -64,12 +63,8 @@ codeunit 9092 "Postcode Service GetAddress.io" FeatureTelemetry.LogUptake('0000FW5', UKPostCodeFeatureNameTxt, Enum::"Feature Uptake Status"::Used); // Check if we're the selected service - if ServiceKey <> ServiceIdentifierMsg then begin - ErrorMsg := WrongServiceErr; - IsSuccessful := false; - FeatureTelemetry.LogError('0000BUX', UKPostCodeFeatureNameTxt, 'Checking the selected service', ErrorMsg); + if ServiceKey <> ServiceIdentifierMsg then exit; - end; GetConfigAndIfNecessaryCreate(); diff --git a/Apps/IN/ContosoCoffeeDemoDatasetIN/app/DemoData/INContosoLocalization.Codeunit.al b/Apps/IN/ContosoCoffeeDemoDatasetIN/app/DemoData/INContosoLocalization.Codeunit.al index bc040a1fc3..382adce661 100644 --- a/Apps/IN/ContosoCoffeeDemoDatasetIN/app/DemoData/INContosoLocalization.Codeunit.al +++ b/Apps/IN/ContosoCoffeeDemoDatasetIN/app/DemoData/INContosoLocalization.Codeunit.al @@ -40,7 +40,7 @@ codeunit 19047 "IN Contoso Localization" if Module = Enum::"Contoso Demo Data Module"::Sales then SalesModule(ContosoDemoDataLevel); - UnBindSubscriptionDemoData(Module); + UnBindSubscriptionDemoData(ContosoDemoDataLevel, Module); end; local procedure PurchaseModule(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") @@ -170,7 +170,7 @@ codeunit 19047 "IN Contoso Localization" end; [EventSubscriber(ObjectType::Codeunit, Codeunit::"Contoso Demo Tool", 'OnBeforeGeneratingDemoData', '', false, false)] - local procedure OnBeforeGeneratingDemoData(Module: Enum "Contoso Demo Data Module") + local procedure OnBeforeGeneratingDemoData(Module: Enum "Contoso Demo Data Module"; ContosoDemoDataLevel: Enum "Contoso Demo Data Level") var CreateINItem: Codeunit "Create IN Item"; CreateINItemCharge: Codeunit "Create IN Item Charge"; @@ -205,7 +205,8 @@ codeunit 19047 "IN Contoso Localization" begin BindSubscription(CreateINItemCharge); BindSubscription(CreateINInvenPostingSetup); - BindSubscription(CreateINItem); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateINItem); BindSubscription(CreateINLocation) end; Enum::"Contoso Demo Data Module"::Sales: @@ -230,7 +231,7 @@ codeunit 19047 "IN Contoso Localization" end; end; - local procedure UnBindSubscriptionDemoData(Module: Enum "Contoso Demo Data Module") + local procedure UnBindSubscriptionDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateINItem: Codeunit "Create IN Item"; CreateINItemCharge: Codeunit "Create IN Item Charge"; @@ -265,7 +266,8 @@ codeunit 19047 "IN Contoso Localization" begin UnbindSubscription(CreateINItemCharge); UnbindSubscription(CreateINInvenPostingSetup); - UnbindSubscription(CreateINItem); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnbindSubscription(CreateINItem); UnbindSubscription(CreateINLocation) end; Enum::"Contoso Demo Data Module"::Sales: diff --git a/Apps/IN/INFADepreciation/app/src/codeunit/DeprCalculationSubscribers.codeunit.al b/Apps/IN/INFADepreciation/app/src/codeunit/DeprCalculationSubscribers.codeunit.al index 4c3e058435..1e8b37ed9c 100644 --- a/Apps/IN/INFADepreciation/app/src/codeunit/DeprCalculationSubscribers.codeunit.al +++ b/Apps/IN/INFADepreciation/app/src/codeunit/DeprCalculationSubscribers.codeunit.al @@ -141,7 +141,7 @@ codeunit 18632 "Depr Calculation Subscribers" end; if (DeprBook."FA Book Type" = DeprBook."FA Book Type"::"Income Tax") or (DeprBook."Fiscal Year 365 Days") then - NumberOfDays := CalculateDeprDays(FirstDeprDate, UntilDate); + NumberOfDays := DepreciationCalc.DeprDays(FirstDeprDate, UntilDate, Year365Days); OnAfterCalculateNumberofDays(FixedAsset, DeprBook, NumberofDays, FirstDeprDate, UntilDate, Year365Days); @@ -423,6 +423,23 @@ codeunit 18632 "Depr Calculation Subscribers" IsHandled := true; end; + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Calculate Normal Depreciation", 'OnAfterCalcDB1Amount', '', false, false)] + local procedure OnAfterCalcDB1Amount(DBPercent: Decimal; NumberOfDays: Integer; BookValue: Decimal; var Result: Decimal; FADepreciationBook: Record "FA Depreciation Book") + var + DeprBook: Record "Depreciation Book"; + begin + if not DeprBook.Get(FADepreciationBook."Depreciation Book Code") then + exit; + + if not (DeprBook."FA Book Type" = FADepreciationBook."FA Book Type"::"Income Tax") then + exit; + + if NumberOfDays <= DeprBook."Depr. Threshold Days" then + Result := -(BookValue * DBPercent / 200) + else + Result := -(BookValue * DBPercent / 100); + end; + [EventSubscriber(ObjectType::Codeunit, Codeunit::"FA Check Consistency", 'OnCheckNormalPostingOnAfterSetFALedgerEntryFilters', '', false, false)] local procedure CheckNormalPostingError(DepreciationBookCode: Code[10]; FANo: Code[20]) var @@ -481,17 +498,6 @@ codeunit 18632 "Depr Calculation Subscribers" AddDeprAmount += FALedgerEntry."Add. Depreciation Amount"; end; - local procedure CalculateDeprDays(StartingDate: Date; EndingDate: Date): Integer - begin - if EndingDate < StartingDate then - exit(0); - - if (StartingDate = 0D) or (EndingDate = 0D) then - exit(0); - - exit(1 + (EndingDate - StartingDate)); - end; - local procedure CreateDisposedError(DepreciationBookCode: Code[20]; FANo: Code[20]) var FixedAsset: Record "Fixed Asset"; diff --git a/Apps/IS/ContosoCoffeeDemoDatasetIS/app/DemoData/ISContosoLocalization.Codeunit.al b/Apps/IS/ContosoCoffeeDemoDatasetIS/app/DemoData/ISContosoLocalization.Codeunit.al index 4f241b07a3..959df34ef1 100644 --- a/Apps/IS/ContosoCoffeeDemoDatasetIS/app/DemoData/ISContosoLocalization.Codeunit.al +++ b/Apps/IS/ContosoCoffeeDemoDatasetIS/app/DemoData/ISContosoLocalization.Codeunit.al @@ -32,7 +32,7 @@ codeunit 14628 "IS Contoso Localization" if Module = Enum::"Contoso Demo Data Module"::Inventory then InventoryModule(ContosoDemoDataLevel); - UnBindSubscriptionDemoData(Module); + UnBindSubscriptionDemoData(ContosoDemoDataLevel, Module); end; local procedure FoundationModule(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") @@ -83,7 +83,7 @@ codeunit 14628 "IS Contoso Localization" end; [EventSubscriber(ObjectType::Codeunit, Codeunit::"Contoso Demo Tool", 'OnBeforeGeneratingDemoData', '', false, false)] - local procedure OnBeforeGeneratingDemoData(Module: Enum "Contoso Demo Data Module") + local procedure OnBeforeGeneratingDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateItemIS: Codeunit "Create Item IS"; CreateBankAccountIS: Codeunit "Create Bank Account IS"; @@ -107,7 +107,8 @@ codeunit 14628 "IS Contoso Localization" BindSubscription(CreateBankAccountIS); Enum::"Contoso Demo Data Module"::Inventory: begin - BindSubscription(CreateItemIS); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemIS); BindSubscription(CreateLocationIS) end; Enum::"Contoso Demo Data Module"::Sales: @@ -136,7 +137,7 @@ codeunit 14628 "IS Contoso Localization" end; end; - local procedure UnBindSubscriptionDemoData(Module: Enum "Contoso Demo Data Module") + local procedure UnBindSubscriptionDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateItemIS: Codeunit "Create Item IS"; CreateBankAccountIS: Codeunit "Create Bank Account IS"; @@ -160,7 +161,8 @@ codeunit 14628 "IS Contoso Localization" UnBindSubscription(CreateBankAccountIS); Enum::"Contoso Demo Data Module"::Inventory: begin - UnBindSubscription(CreateItemIS); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnBindSubscription(CreateItemIS); UnbindSubscription(CreateLocationIS); end; Enum::"Contoso Demo Data Module"::Sales: diff --git a/Apps/IT/ContosoCoffeeDemoDatasetIT/app/DemoData/ITContosoLocalization.Codeunit.al b/Apps/IT/ContosoCoffeeDemoDatasetIT/app/DemoData/ITContosoLocalization.Codeunit.al index dfc328aac7..4eaaef1ac8 100644 --- a/Apps/IT/ContosoCoffeeDemoDatasetIT/app/DemoData/ITContosoLocalization.Codeunit.al +++ b/Apps/IT/ContosoCoffeeDemoDatasetIT/app/DemoData/ITContosoLocalization.Codeunit.al @@ -38,7 +38,7 @@ codeunit 12251 "IT Contoso Localization" if Module = Enum::"Contoso Demo Data Module"::Analytics then AnalyticsModule(ContosoDemoDataLevel); - UnBindSubscriptionDemoData(Module); + UnBindSubscriptionDemoData(ContosoDemoDataLevel, Module); end; local procedure FoundationModule(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") @@ -132,7 +132,7 @@ codeunit 12251 "IT Contoso Localization" end; [EventSubscriber(ObjectType::Codeunit, Codeunit::"Contoso Demo Tool", 'OnBeforeGeneratingDemoData', '', false, false)] - local procedure OnBeforeGeneratingDemoData(Module: Enum "Contoso Demo Data Module") + local procedure OnBeforeGeneratingDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateLocationIT: Codeunit "Create Location IT"; CreateItemIT: Codeunit "Create Item IT"; @@ -162,7 +162,8 @@ codeunit 12251 "IT Contoso Localization" BindSubscription(CreateBankAccountIT); Enum::"Contoso Demo Data Module"::Inventory: begin - BindSubscription(CreateItemIT); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemIT); BindSubscription(CreateLocationIT); end; Enum::"Contoso Demo Data Module"::Sales: @@ -210,7 +211,7 @@ codeunit 12251 "IT Contoso Localization" end; end; - local procedure UnBindSubscriptionDemoData(Module: Enum "Contoso Demo Data Module") + local procedure UnBindSubscriptionDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateLocationIT: Codeunit "Create Location IT"; CreateItemIT: Codeunit "Create Item IT"; @@ -242,7 +243,8 @@ codeunit 12251 "IT Contoso Localization" UnbindSubscription(CreateNoSeriesIT); Enum::"Contoso Demo Data Module"::Inventory: begin - UnbindSubscription(CreateItemIT); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnbindSubscription(CreateItemIT); UnbindSubscription(CreateLocationIT); end; Enum::"Contoso Demo Data Module"::Sales: diff --git a/Apps/IT/EDocumentIT/demo data/app.json b/Apps/IT/EDocumentIT/demo data/app.json index 1d6f6618dc..1e1c2be0ee 100644 --- a/Apps/IT/EDocumentIT/demo data/app.json +++ b/Apps/IT/EDocumentIT/demo data/app.json @@ -39,6 +39,9 @@ ], "screenshots": [], "platform": "28.0.0.0", + "features": [ + "TranslationFile" + ], "idRanges": [ { "from": 12194, diff --git a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CPM.xml b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CPM.xml index d5a9e1cab0..dd4506981b 100644 --- a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CPM.xml +++ b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CPM.xml @@ -87,7 +87,7 @@ 0 - + diff --git a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CPQ.xml b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CPQ.xml index 9765a18b80..dab1ef0916 100644 --- a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CPQ.xml +++ b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CPQ.xml @@ -86,7 +86,7 @@ 0 - + diff --git a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CSM.xml b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CSM.xml index 61df302f5a..33c8af559e 100644 --- a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CSM.xml +++ b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CSM.xml @@ -86,7 +86,7 @@ 0 - + diff --git a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CSQ.xml b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CSQ.xml index acd93837d3..763f0df97a 100644 --- a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CSQ.xml +++ b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_CSQ.xml @@ -85,7 +85,7 @@ 0 - + diff --git a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NPM.xml b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NPM.xml index 3a8fc10944..02e5dfc677 100644 --- a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NPM.xml +++ b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NPM.xml @@ -48,7 +48,7 @@ - + diff --git a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NPQ.xml b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NPQ.xml index 8d41d09ae7..b3949a4be4 100644 --- a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NPQ.xml +++ b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NPQ.xml @@ -39,7 +39,7 @@ - + diff --git a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NSM.xml b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NSM.xml index 8470edbd61..78fa871a2e 100644 --- a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NSM.xml +++ b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NSM.xml @@ -47,7 +47,7 @@ - + diff --git a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NSQ.xml b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NSQ.xml index 7491efe5d0..feea300040 100644 --- a/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NSQ.xml +++ b/Apps/IT/IntrastatIT/app/AppResources/IT_DataExchDefMap_NSQ.xml @@ -38,7 +38,7 @@ - + diff --git a/Apps/IT/IntrastatIT/app/src/IntrastatReportManagementIT.Codeunit.al b/Apps/IT/IntrastatIT/app/src/IntrastatReportManagementIT.Codeunit.al index ab70264576..7544b42f28 100644 --- a/Apps/IT/IntrastatIT/app/src/IntrastatReportManagementIT.Codeunit.al +++ b/Apps/IT/IntrastatIT/app/src/IntrastatReportManagementIT.Codeunit.al @@ -1290,39 +1290,39 @@ codeunit 148121 "Intrastat Report Management IT" TotalInvoicedQty, TotalAmt : Decimal; TotalRoundedAmount, LineCount : Integer; PeriodAlreadyReportedQst: Label 'You''ve already submitted the report for this period.\Do you want to continue?'; - DataExchangeXMLNPMP1Txt: Label 'NUMBERSONLYNumbers Only6\D+0000000.000ALPHANUM_ONLYAlphanumeric Text Only700', + DataExchangeXMLNPMP1Txt: Label 'NUMBERSONLYNumbers Only6\D+0000000.000ALPHANUM_ONLYAlphanumeric Text Only700', Locked = true; // will be replaced with file import when available DataExchangeXMLNPMP2Txt: Label '00000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0FIRSTCHARFirst Character4&#032;1100000.000TRIMALLRemoves all spaces5&#032;0000000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0ROUNDTOINTWITHMIN1Round to Integer with minimal value equal to 16^0[,.].*100ROUNDTOINT00000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000', Locked = true; // will be replaced with file import when available DataExchangeXMLNPMP3Txt: Label 'ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0FIRSTCHARFirst Character4&#032;1100000.000FIRSTCHARFirst Character4&#032;1100000.000NUMBERSONLYFIRSTCHARNumbers Only First Character6\D+00FIRSTCHAR00000.000FIRST2CHARSFirst Two Characters41200000.000FIRST2CHARSFirst Two Characters41200000.000FIRST2CHARSFirst Two Characters41200000.000SECONDCHARSecond Character42100000.000', Locked = true; // will be replaced with file import when available - DataExchangeXMLNPQP1Txt: Label 'NUMBERSONLYNumbers Only 6\D+0000000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0ALPHANUM_ONLYAlphanumeric Text Only70000000.000', + DataExchangeXMLNPQP1Txt: Label 'NUMBERSONLYNumbers Only 6\D+0000000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0ALPHANUM_ONLYAlphanumeric Text Only70000000.000', Locked = true; // will be replaced with file import when available DataExchangeXMLNPQP2Txt: Label 'ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0FIRSTCHARFirst Character4&#032;1100000.000TRIMALLRemoves all spaces5&#032;0000000.000', Locked = true; // will be replaced with file import when available - DataExchangeXMLNSMP1Txt: Label 'NUMBERSONLYNumbers Only6\D+0000000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000', + DataExchangeXMLNSMP1Txt: Label 'NUMBERSONLYNumbers Only6\D+0000000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000', Locked = true; // will be replaced with file import when available DataExchangeXMLNSMP2Txt: Label 'ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0FIRSTCHARFirst Character4&#032;1100000.000TRIMALLRemoves all spaces5&#032;0000000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0ROUNDTOINTWITHMIN1Round to Integer with minimal value equal to 16^0[,.].*100ROUNDTOINT00000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY', Locked = true; // will be replaced with file import when available DataExchangeXMLNSMP3Txt: Label '00001.00=0FIRSTCHARFirst Character4&#032;1100000.000FIRSTCHARFirst Character4&#032;1100000.000NUMBERSONLYFIRSTCHARNumbers Only First Character6\D+00FIRSTCHAR00000.000FIRST2CHARSFirst Two Characters41200000.000FIRST2CHARSFirst Two Characters41200000.000SECONDCHARSecond Character42100000.000FIRST2CHARSFirst Two Characters41200000.000', Locked = true; // will be replaced with file import when available - DataExchangeXMLNSQP1Txt: Label 'NUMBERSONLYNumbers Only 6\D+0000000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0FIRSTCHARFirst Character4&#032;1100000.000', + DataExchangeXMLNSQP1Txt: Label 'NUMBERSONLYNumbers Only 6\D+0000000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0FIRSTCHARFirst Character4&#032;1100000.000', Locked = true; // will be replaced with file import when available DataExchangeXMLNSQP2Txt: Label 'TRIMALLRemoves all spaces5&#032;0000000.000', Locked = true; // will be replaced with file import when available DataExchangeXMLCPMP1Txt: Label 'NUMBERSONLYNumbers Only6\D+0000000.000SECOND2CHARSGets characters 3d and 4th charachters43200000.000FIRST2CHARSFirst Two Characters41200000.000', Locked = true; // will be replaced with file import when available - DataExchangeXMLCPMP2Txt: Label 'FIRSTCHARFirst Character4&#032;1100000.000GETAMOUNTSIGNGet Amount Sign6^\d+00FIRSTCHAR00000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0FIRSTCHARFirst Character4&#032;1100000.000TRIMALLRemoves all spaces5&#032;0000000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0', + DataExchangeXMLCPMP2Txt: Label 'FIRSTCHARFirst Character4&#032;1100000.000GETAMOUNTSIGNGet Amount Sign6^\d+00FIRSTCHAR00000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0FIRSTCHARFirst Character4&#032;1100000.000TRIMALLRemoves all spaces5&#032;0000000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0', Locked = true; // will be replaced with file import when available DataExchangeXMLCSMP1Txt: Label 'NUMBERSONLYNumbers Only6\D+0000000.000SECOND2CHARSGets characters 3d and 4th charachters43200000.000FIRST2CHARSFirst Two Characters41200000.000', Locked = true; // will be replaced with file import when available - DataExchangeXMLCSMP2Txt: Label 'FIRSTCHARFirst Character4&#032;1100000.000GETAMOUNTSIGNGet Amount Sign6^\d+00FIRSTCHAR00000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0FIRSTCHARFirst Character4&#032;1100000.000TRIMALLRemoves all spaces5&#032;0000000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0', + DataExchangeXMLCSMP2Txt: Label 'FIRSTCHARFirst Character4&#032;1100000.000GETAMOUNTSIGNGet Amount Sign6^\d+00FIRSTCHAR00000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0FIRSTCHARFirst Character4&#032;1100000.000TRIMALLRemoves all spaces5&#032;0000000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0', Locked = true; // will be replaced with file import when available - DataExchangeXMLCPQP1Txt: Label 'NUMBERSONLYNumbers Only6\D+0000000.000FOURTHCHARFourth Character44100000.000FIRST2CHARSFirst Two Characters41200000.000', + DataExchangeXMLCPQP1Txt: Label 'NUMBERSONLYNumbers Only6\D+0000000.000FOURTHCHARFourth Character44100000.000FIRST2CHARSFirst Two Characters41200000.000', Locked = true; // will be replaced with file import when available DataExchangeXMLCPQP2Txt: Label 'FIRSTCHARFirst Character4&#032;1100000.000GETAMOUNTSIGNGet Amount Sign6^\d+00FIRSTCHAR00000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0FIRSTCHARFirst Character4&#032;1100000.000TRIMALLRemoves all spaces5&#032;0000000.000', Locked = true; // will be replaced with file import when available - DataExchangeXMLCSQP1Txt: Label 'NUMBERSONLYNumbers Only6\D+0000000.000FOURTHCHARFourth Character44100000.000FIRST2CHARSFirst Two Characters41200000.000FIRSTCHARFirst Character4&#032;1100000.000', + DataExchangeXMLCSQP1Txt: Label 'NUMBERSONLYNumbers Only6\D+0000000.000FOURTHCHARFourth Character44100000.000FIRST2CHARSFirst Two Characters41200000.000FIRSTCHARFirst Character4&#032;1100000.000', Locked = true; // will be replaced with file import when available DataExchangeXMLCSQP2Txt: Label 'GETAMOUNTSIGNGet Amount Sign6^\d+00FIRSTCHAR00000.000ALPHANUM_ONLYAlphanumeric Text Only70000000.000ROUNDTOINTRound to Integer14&#032;00ALPHANUM_ONLY00001.00=0FIRSTCHARFirst Character4&#032;1100000.000TRIMALLRemoves all spaces5&#032;0000000.000', Locked = true; // will be replaced with file import when available diff --git a/Apps/MX/ContosoCoffeeDemoDatasetMX/app/DemoData/MXContosoLocalization.Codeunit.al b/Apps/MX/ContosoCoffeeDemoDatasetMX/app/DemoData/MXContosoLocalization.Codeunit.al index c29ffedcbe..ce596b8a88 100644 --- a/Apps/MX/ContosoCoffeeDemoDatasetMX/app/DemoData/MXContosoLocalization.Codeunit.al +++ b/Apps/MX/ContosoCoffeeDemoDatasetMX/app/DemoData/MXContosoLocalization.Codeunit.al @@ -32,7 +32,7 @@ codeunit 14108 "MX Contoso Localization" if Module = Enum::"Contoso Demo Data Module"::Bank then BankModule(ContosoDemoDataLevel); - UnBindSubscriptionDemoData(Module); + UnBindSubscriptionDemoData(ContosoDemoDataLevel, Module); end; local procedure FoundationModule(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") @@ -128,7 +128,8 @@ codeunit 14108 "MX Contoso Localization" BindSubscription(CreateBankAccountMX); Enum::"Contoso Demo Data Module"::Inventory: begin - BindSubscription(CreateItemMX); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemMX); BindSubscription(CreateLocationMX); BindSubscription(CreateInvPostingSetupMX); BindSubscription(CreateItemJournalTemplateMX); @@ -162,7 +163,7 @@ codeunit 14108 "MX Contoso Localization" end; end; - local procedure UnBindSubscriptionDemoData(Module: Enum "Contoso Demo Data Module") + local procedure UnBindSubscriptionDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateCurrencyExchRateMX: Codeunit "Create Currency Ex. Rate MX"; CreateAccScheduleLineMX: Codeunit "Create Acc. Schedule Line MX"; @@ -187,7 +188,8 @@ codeunit 14108 "MX Contoso Localization" UnbindSubscription(CreateBankAccountMX); Enum::"Contoso Demo Data Module"::Inventory: begin - UnbindSubscription(CreateItemMX); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnbindSubscription(CreateItemMX); UnbindSubscription(CreateLocationMX); UnbindSubscription(CreateInvPostingSetupMX); UnbindSubscription(CreateItemJournalTemplateMX); diff --git a/Apps/NL/ContosoCoffeeDemoDatasetNL/app/DemoData/NLContosoLocalization.Codeunit.al b/Apps/NL/ContosoCoffeeDemoDatasetNL/app/DemoData/NLContosoLocalization.Codeunit.al index f6ed998430..acb40c7f85 100644 --- a/Apps/NL/ContosoCoffeeDemoDatasetNL/app/DemoData/NLContosoLocalization.Codeunit.al +++ b/Apps/NL/ContosoCoffeeDemoDatasetNL/app/DemoData/NLContosoLocalization.Codeunit.al @@ -40,7 +40,7 @@ codeunit 11508 "NL Contoso Localization" if Module = Enum::"Contoso Demo Data Module"::Purchase then SalesModule(ContosoDemoDataLevel); - UnbindSubscriptionDemoData(Module); + UnbindSubscriptionDemoData(ContosoDemoDataLevel, Module); end; local procedure FoundationModule(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") @@ -195,7 +195,8 @@ codeunit 11508 "NL Contoso Localization" end; Enum::"Contoso Demo Data Module"::Inventory: begin - BindSubscription(CreateItemNL); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemNL); BindSubscription(CreateLocationNL); BindSubscription(CreateInvPostingSetupNL); end; @@ -216,7 +217,7 @@ codeunit 11508 "NL Contoso Localization" end; end; - local procedure UnbindSubscriptionDemoData(Module: Enum "Contoso Demo Data Module") + local procedure UnbindSubscriptionDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateLocationNL: Codeunit "Create Location NL"; CreateItemNL: Codeunit "Create Item NL"; @@ -262,7 +263,8 @@ codeunit 11508 "NL Contoso Localization" end; Enum::"Contoso Demo Data Module"::Inventory: begin - UnbindSubscription(CreateItemNL); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnbindSubscription(CreateItemNL); UnbindSubscription(CreateLocationNL); UnbindSubscription(CreateInvPostingSetupNL); end; diff --git a/Apps/NL/IntrastatNL/app/AppResources/NL_DataExchDefMap.xml b/Apps/NL/IntrastatNL/app/AppResources/NL_DataExchDefMap.xml index eecb05313f..4e31545461 100644 --- a/Apps/NL/IntrastatNL/app/AppResources/NL_DataExchDefMap.xml +++ b/Apps/NL/IntrastatNL/app/AppResources/NL_DataExchDefMap.xml @@ -52,7 +52,7 @@ 3 - + GETMONTH Get Month From Date diff --git a/Apps/NO/ContosoCoffeeDemoDatasetNO/app/DemoData/NOContosoLocalization.Codeunit.al b/Apps/NO/ContosoCoffeeDemoDatasetNO/app/DemoData/NOContosoLocalization.Codeunit.al index 787993b07a..5559a0b7ff 100644 --- a/Apps/NO/ContosoCoffeeDemoDatasetNO/app/DemoData/NOContosoLocalization.Codeunit.al +++ b/Apps/NO/ContosoCoffeeDemoDatasetNO/app/DemoData/NOContosoLocalization.Codeunit.al @@ -31,7 +31,7 @@ codeunit 10669 "NO Contoso Localization" if Module = Enum::"Contoso Demo Data Module"::Sales then SalesModule(ContosoDemoDataLevel); - UnBindSubscriptionDemoData(Module); + UnBindSubscriptionDemoData(ContosoDemoDataLevel, Module); end; local procedure FoundationModule(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") @@ -106,7 +106,8 @@ codeunit 10669 "NO Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin BindSubscription(CreateLocationNO); - BindSubscription(CreateItemNO); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemNO); end; Enum::"Contoso Demo Data Module"::Finance: begin @@ -143,7 +144,7 @@ codeunit 10669 "NO Contoso Localization" end; end; - local procedure UnBindSubscriptionDemoData(Module: Enum "Contoso Demo Data Module") + local procedure UnBindSubscriptionDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateItemNO: Codeunit "Create Item NO"; CreateCurrencyNO: Codeunit "Create Currency NO"; @@ -168,7 +169,8 @@ codeunit 10669 "NO Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin UnbindSubscription(CreateLocationNO); - UnBindSubscription(CreateItemNO); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnBindSubscription(CreateItemNO); end; Enum::"Contoso Demo Data Module"::Finance: begin diff --git a/Apps/NZ/ContosoCoffeeDemoDatasetNZ/app/DemoData/NZContosoLocalization.Codeunit.al b/Apps/NZ/ContosoCoffeeDemoDatasetNZ/app/DemoData/NZContosoLocalization.Codeunit.al index 72dcf9c947..0101d6a163 100644 --- a/Apps/NZ/ContosoCoffeeDemoDatasetNZ/app/DemoData/NZContosoLocalization.Codeunit.al +++ b/Apps/NZ/ContosoCoffeeDemoDatasetNZ/app/DemoData/NZContosoLocalization.Codeunit.al @@ -167,7 +167,8 @@ codeunit 17142 "NZ Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin BindSubscription(CreateNZLocation); - BindSubscription(CreateNZItem); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateNZItem); end; Enum::"Contoso Demo Data Module"::Bank: BindSubscription(CreateNZBankAccount); @@ -224,7 +225,8 @@ codeunit 17142 "NZ Contoso Localization" UnbindSubscription(CreateNZBankAccount); Enum::"Contoso Demo Data Module"::Inventory: begin - UnbindSubscription(CreateNZItem); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnbindSubscription(CreateNZItem); UnbindSubscription(CreateNZLocation); end; Enum::"Contoso Demo Data Module"::Purchase: diff --git a/Apps/NZ/EDocument_NZ/demo data/app.json b/Apps/NZ/EDocument_NZ/demo data/app.json index 3ba08c0431..7d59c17195 100644 --- a/Apps/NZ/EDocument_NZ/demo data/app.json +++ b/Apps/NZ/EDocument_NZ/demo data/app.json @@ -39,6 +39,9 @@ ], "screenshots": [], "platform": "28.0.0.0", + "features": [ + "TranslationFile" + ], "idRanges": [ { "from": 17211, diff --git a/Apps/SE/ContosoCoffeeDemoDatasetSE/app/DemoData/SEContosoLocalization.Codeunit.al b/Apps/SE/ContosoCoffeeDemoDatasetSE/app/DemoData/SEContosoLocalization.Codeunit.al index 44d9adb674..071881c65b 100644 --- a/Apps/SE/ContosoCoffeeDemoDatasetSE/app/DemoData/SEContosoLocalization.Codeunit.al +++ b/Apps/SE/ContosoCoffeeDemoDatasetSE/app/DemoData/SEContosoLocalization.Codeunit.al @@ -36,7 +36,7 @@ codeunit 11214 "SE Contoso Localization" if Module = Enum::"Contoso Demo Data Module"::Inventory then InventoryModule(ContosoDemoDataLevel); - UnBindSubscriptionDemoData(Module); + UnBindSubscriptionDemoData(ContosoDemoDataLevel, Module); end; local procedure FoundationModule(ContosoDemoDataLevel: Enum "Contoso Demo Data Level") @@ -142,7 +142,8 @@ codeunit 11214 "SE Contoso Localization" end; Enum::"Contoso Demo Data Module"::Inventory: begin - BindSubscription(CreateItemSE); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemSE); BindSubscription(CreateLocationSE); end; Enum::"Contoso Demo Data Module"::Sales: @@ -177,7 +178,7 @@ codeunit 11214 "SE Contoso Localization" end; end; - local procedure UnBindSubscriptionDemoData(Module: Enum "Contoso Demo Data Module") + local procedure UnBindSubscriptionDemoData(ContosoDemoDataLevel: Enum "Contoso Demo Data Level"; Module: Enum "Contoso Demo Data Module") var CreateLocationSE: Codeunit "Create Location SE"; CreateItemSE: Codeunit "Create Item SE"; @@ -206,7 +207,8 @@ codeunit 11214 "SE Contoso Localization" end; Enum::"Contoso Demo Data Module"::Inventory: begin - UnBindSubscription(CreateItemSE); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnBindSubscription(CreateItemSE); UnBindSubscription(CreateLocationSE); end; Enum::"Contoso Demo Data Module"::Sales: diff --git a/Apps/SE/IntrastatSE/app/src/IntrastatReportManagementSE.Codeunit.al b/Apps/SE/IntrastatSE/app/src/IntrastatReportManagementSE.Codeunit.al index 39b676a194..d7c31cc755 100644 --- a/Apps/SE/IntrastatSE/app/src/IntrastatReportManagementSE.Codeunit.al +++ b/Apps/SE/IntrastatSE/app/src/IntrastatReportManagementSE.Codeunit.al @@ -60,7 +60,7 @@ codeunit 11298 IntrastatReportManagementSE DefPrivatePersonVATNoLbl: Label 'QV999999999999', Locked = true; Def3DPartyTradeVATNoLbl: Label 'QV999999999999', Locked = true; DefUnknowVATNoLbl: Label 'QV999999999999', Locked = true; - DataExchangeXMLTxt: Label 'TRIMALLRemoves all spaces5&#032;0000000.00ALPHANUMERIC_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14&#032;00ALPHANUMERIC_ONLY00001.00=ALPHANUMERIC_ONLYAlphanumeric Text Only70000000.00ROUNDUPTOINTRound up to integer14&#032;00ALPHANUMERIC_ONLY00001.00>ALPHANUMERIC_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14&#032;00ALPHANUMERIC_ONLY00001.00=EUCOUNTRYCODELOOKUPEU Country Lookup13&#032;0091710.00', + DataExchangeXMLTxt: Label 'TRIMALLRemoves all spaces5&#032;0000000.00ALPHANUMERIC_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14&#032;00ALPHANUMERIC_ONLY00001.00=ALPHANUMERIC_ONLYAlphanumeric Text Only70000000.00ROUNDUPTOINTRound up to integer14&#032;00ALPHANUMERIC_ONLY00001.00>ALPHANUMERIC_ONLYAlphanumeric Text Only70000000.00ROUNDTOINTRound to integer14&#032;00ALPHANUMERIC_ONLY00001.00=EUCOUNTRYCODELOOKUPEU Country Lookup13&#032;0091710.00', Locked = true; // will be replaced with file import when available } \ No newline at end of file diff --git a/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/USContosoLocalization.Codeunit.al b/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/USContosoLocalization.Codeunit.al index 7608b7e050..2a7a6934fe 100644 --- a/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/USContosoLocalization.Codeunit.al +++ b/Apps/US/ContosoCoffeeDemoDatasetUS/app/DemoData/USContosoLocalization.Codeunit.al @@ -202,7 +202,8 @@ codeunit 11465 "US Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin BindSubscription(CreateItemJournalTemplateUS); - BindSubscription(CreateItemUS); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + BindSubscription(CreateItemUS); BindSubscription(CreateItemChargeUS); BindSubscription(CreateLocationUS); end; @@ -288,7 +289,8 @@ codeunit 11465 "US Contoso Localization" Enum::"Contoso Demo Data Module"::Inventory: begin UnbindSubscription(CreateItemJournalTemplateUS); - UnbindSubscription(CreateItemUS); + if ContosoDemoDataLevel = Enum::"Contoso Demo Data Level"::"Master Data" then + UnbindSubscription(CreateItemUS); UnbindSubscription(CreateItemChargeUS); UnbindSubscription(CreateLocationUS); end; diff --git a/Apps/US/EDocument_US/demo data/app.json b/Apps/US/EDocument_US/demo data/app.json index b158045912..fc8d32f58f 100644 --- a/Apps/US/EDocument_US/demo data/app.json +++ b/Apps/US/EDocument_US/demo data/app.json @@ -39,6 +39,9 @@ ], "screenshots": [], "platform": "28.0.0.0", + "features": [ + "TranslationFile" + ], "idRanges": [ { "from": 11501, diff --git a/Apps/W1/APIV2/app/src/pages/APIV2DimensionSetLines.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2DimensionSetLines.Page.al index c77403dca8..cfa46d617e 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2DimensionSetLines.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2DimensionSetLines.Page.al @@ -331,6 +331,8 @@ page 30022 "APIV2 - Dimension Set Lines" SalesCrMemoHeader.SetRange("Draft Cr. Memo SystemId", ParentIdFilter); if SalesCrMemoHeader.FindFirst() then exit(SalesCrMemoHeader."Dimension Set ID"); + if SalesCrMemoHeader.GetBySystemId(ParentIdFilter) then + exit(SalesCrMemoHeader."Dimension Set ID"); end; end; DimensionSetEntryBufferParentType::"Sales Invoice": @@ -510,6 +512,13 @@ page 30022 "APIV2 - Dimension Set Lines" SalesCrMemoHeader.Modify(true); exit; end; + if SalesCrMemoHeader.GetBySystemId(ParentIdFilter) then begin + SalesCrMemoHeader."Dimension Set ID" := DimensionManagement.GetDimensionSetID(TempDimensionSetEntry); + DimensionManagement.UpdateGlobalDimFromDimSetID( + SalesCrMemoHeader."Dimension Set ID", SalesCrMemoHeader."Shortcut Dimension 1 Code", SalesCrMemoHeader."Shortcut Dimension 2 Code"); + SalesCrMemoHeader.Modify(true); + exit; + end; end; end; DimensionSetEntryBufferParentType::"Sales Invoice": diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Inventory/3.Transactions/CreateItemJnlLine.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Inventory/3.Transactions/CreateItemJnlLine.Codeunit.al new file mode 100644 index 0000000000..bcd80de8dd --- /dev/null +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Inventory/3.Transactions/CreateItemJnlLine.Codeunit.al @@ -0,0 +1,63 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace Microsoft.DemoData.Inventory; + +using Microsoft.DemoTool.Helpers; +using Microsoft.Inventory.Journal; +using Microsoft.Inventory.Ledger; +using Microsoft.Inventory.Posting; + +codeunit 5538 "Create Item Jnl Line" +{ + InherentEntitlements = X; + InherentPermissions = X; + + trigger OnRun() + var + ItemJournalBatch: Record "Item Journal Batch"; + ItemJournalTemplate: Record "Item Journal Template"; + ItemJournalLine: Record "Item Journal Line"; + CreateItem: Codeunit "Create Item"; + ContosoItem: Codeunit "Contoso Item"; + ContosoUtilities: Codeunit "Contoso Utilities"; + CreateItemJournalTemplate: Codeunit "Create Item Journal Template"; + TemplateName, BatchName : Code[10]; + begin + ItemJournalTemplate.Get(CreateItemJournalTemplate.ItemJournalTemplate()); + ItemJournalBatch.Get(ItemJournalTemplate.Name, ContosoUtilities.GetDefaultBatchNameLbl()); + + BatchName := ItemJournalBatch.Name; + TemplateName := ItemJournalTemplate.Name; + + // Create 500 units for each item + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.AthensDesk(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.ParisGuestChairBlack(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.AthensMobilePedestal(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.LondonSwivelChairBlue(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.AntwerpConferenceTable(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.ConferenceBundle16(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.AmsterdamLamp(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.ConferenceBundle18(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.BerlingGuestChairYellow(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.GuestSection1(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.RomeGuestChairGreen(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.TokyoGuestChairBlue(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.ConferenceBundle28(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.MexicoSwivelChairBlack(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.ConferencePackage1(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.MunichSwivelChairYellow(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.MoscowSwivelChairRed(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.SeoulGuestChairRed(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.AtlantaWhiteboardBase(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + ContosoItem.InsertItemJournalLine(TemplateName, BatchName, CreateItem.SydneySwivelChairGreen(), '', Enum::"Item Ledger Entry Type"::"Positive Adjmt.", 500, '', ContosoUtilities.AdjustDate(19020601D)); + + // Post the journal lines + ItemJournalLine.SetRange("Journal Template Name", TemplateName); + ItemJournalLine.SetRange("Journal Batch Name", BatchName); + if ItemJournalLine.FindFirst() then + CODEUNIT.Run(CODEUNIT::"Item Jnl.-Post Batch", ItemJournalLine); + end; +} diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Inventory/InventoryModule.Codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Inventory/InventoryModule.Codeunit.al index c3ff9a34e5..4a2cf2b8f1 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Inventory/InventoryModule.Codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoData/Inventory/InventoryModule.Codeunit.al @@ -56,6 +56,7 @@ codeunit 5680 "Inventory Module" implements "Contoso Demo Data Module" procedure CreateTransactionalData() begin + Codeunit.Run(Codeunit::"Create Item Jnl Line"); Codeunit.Run(Codeunit::"Create Item Reference"); Codeunit.Run(Codeunit::"Create Nonstock Item"); Codeunit.Run(Codeunit::"Create Transfer Orders"); diff --git a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/GenerateContosoDemoData.codeunit.al b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/GenerateContosoDemoData.codeunit.al index 992a3e10fc..1fb2e2d03a 100644 --- a/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/GenerateContosoDemoData.codeunit.al +++ b/Apps/W1/ContosoCoffeeDemoDataset/app/DemoTool/GenerateContosoDemoData.codeunit.al @@ -22,7 +22,8 @@ codeunit 5279 "Generate Contoso Demo Data" JobQueueLogEntry: Record "Job Queue Log Entry"; begin // give time to update AssistedCompanySetupStatus with "Session ID" and "Task ID" - Sleep(500); + // also time to initialize permission systems in new company + Sleep(10 * 1000); if not CODEUNIT.Run(CODEUNIT::"Company Creation Contoso", Rec) then begin AssistedCompanySetupStatus.Get(CompanyName); diff --git a/Apps/W1/CrossEnvironmentIntercompany/app/src/pages/APIBufICInboxTransaction.Page.al b/Apps/W1/CrossEnvironmentIntercompany/app/src/pages/APIBufICInboxTransaction.Page.al index 91c544cd47..db38462dc5 100644 --- a/Apps/W1/CrossEnvironmentIntercompany/app/src/pages/APIBufICInboxTransaction.Page.al +++ b/Apps/W1/CrossEnvironmentIntercompany/app/src/pages/APIBufICInboxTransaction.Page.al @@ -1,5 +1,6 @@ namespace Microsoft.Intercompany.CrossEnvironment; +using Microsoft.Intercompany; using Microsoft.Intercompany.DataExchange; page 30423 "API Buf IC Inbox Transaction" @@ -42,16 +43,11 @@ page 30423 "API Buf IC Inbox Transaction" Caption = 'Intercompany Partner Code'; Editable = true; } -#if not CLEAN27 - field(sourceType; Rec."Source Type") + field(sourceType; LocalSourceType) { Caption = 'Source Type'; Editable = true; - ObsoleteReason = 'Replaced with IC Source Type for consistent naming.'; - ObsoleteState = Pending; - ObsoleteTag = '27.0'; } -#endif field(icSourceType; Rec."IC Source Type") { Caption = 'IC Source Type'; @@ -141,11 +137,15 @@ page 30423 "API Buf IC Inbox Transaction" trigger OnAfterGetRecord() begin -#if not CLEAN27 - SourceTypeIndex := Rec."Source Type"; -#else + case Rec."IC Source Type" of + Enum::"IC Transaction Source Type"::Journal: + LocalSourceType := LocalSourceType::Journal; + Enum::"IC Transaction Source Type"::"Sales Document": + LocalSourceType := LocalSourceType::"Sales Document"; + Enum::"IC Transaction Source Type"::"Purchase Document": + LocalSourceType := LocalSourceType::"Purchase Document"; + end; SourceTypeIndex := Rec."IC Source Type".AsInteger(); -#endif DocumentTypeOrdinal := Rec."Document Type".AsInteger(); TransactionSourceIndex := Rec."Transaction Source"; LineActionIndex := Rec."Line Action"; @@ -153,6 +153,7 @@ page 30423 "API Buf IC Inbox Transaction" end; var + LocalSourceType: Option Journal,"Sales Document","Purchase Document"; IDShouldBeSpecifiedErr: Label 'Operation ID should be specified'; ThereAreNoNotificationsForSpecifiedIDErr: Label 'There are no notifications for specified ID'; SourceTypeIndex, DocumentTypeOrdinal, TransactionSourceIndex, LineActionIndex, IcAccountTypeOrdinal : Integer; diff --git a/Apps/W1/CrossEnvironmentIntercompany/app/src/pages/APIHandledICInboxTrans.Page.al b/Apps/W1/CrossEnvironmentIntercompany/app/src/pages/APIHandledICInboxTrans.Page.al index a8038d9cb3..e752b2fff7 100644 --- a/Apps/W1/CrossEnvironmentIntercompany/app/src/pages/APIHandledICInboxTrans.Page.al +++ b/Apps/W1/CrossEnvironmentIntercompany/app/src/pages/APIHandledICInboxTrans.Page.al @@ -1,5 +1,6 @@ namespace Microsoft.Intercompany.CrossEnvironment; +using Microsoft.Intercompany; using Microsoft.Intercompany.Inbox; page 30400 "API - Handled IC Inbox Trans." @@ -40,16 +41,11 @@ page 30400 "API - Handled IC Inbox Trans." { Caption = 'Intercompany Partner Code'; } -#if not CLEAN27 - field(sourceType; Rec."Source Type") + field(sourceType; LocalSourceType) { Caption = 'Source Type'; Editable = true; - ObsoleteReason = 'Replaced with IC Source Type for consistent naming.'; - ObsoleteState = Pending; - ObsoleteTag = '27.0'; } -#endif field(icSourceType; Rec."IC Source Type") { Caption = 'IC Source Type'; @@ -117,16 +113,21 @@ page 30400 "API - Handled IC Inbox Trans." trigger OnAfterGetRecord() begin -#if not CLEAN27 - SourceTypeIndex := Rec."Source Type"; -#else + case Rec."IC Source Type" of + Enum::"IC Transaction Source Type"::Journal: + LocalSourceType := LocalSourceType::Journal; + Enum::"IC Transaction Source Type"::"Sales Document": + LocalSourceType := LocalSourceType::"Sales Document"; + Enum::"IC Transaction Source Type"::"Purchase Document": + LocalSourceType := LocalSourceType::"Purchase Document"; + end; SourceTypeIndex := Rec."IC Source Type".AsInteger(); -#endif DocumentTypeOrdinal := Rec."Document Type".AsInteger(); TransactionSourceIndex := Rec."Transaction Source"; StatusIndex := Rec."Status"; end; var + LocalSourceType: Option Journal,"Sales Document","Purchase Document"; SourceTypeIndex, DocumentTypeOrdinal, TransactionSourceIndex, StatusIndex, IcAccountTypeOrdinal : Integer; } \ No newline at end of file diff --git a/Apps/W1/CrossEnvironmentIntercompany/app/src/pages/APIICInboxTransactions.Page.al b/Apps/W1/CrossEnvironmentIntercompany/app/src/pages/APIICInboxTransactions.Page.al index 1637857845..abb754e9da 100644 --- a/Apps/W1/CrossEnvironmentIntercompany/app/src/pages/APIICInboxTransactions.Page.al +++ b/Apps/W1/CrossEnvironmentIntercompany/app/src/pages/APIICInboxTransactions.Page.al @@ -1,5 +1,6 @@ namespace Microsoft.Intercompany.CrossEnvironment; +using Microsoft.Intercompany; using Microsoft.Intercompany.Inbox; page 30411 "API - IC Inbox Transactions" @@ -39,16 +40,11 @@ page 30411 "API - IC Inbox Transactions" Caption = 'Intercompany Partner Code'; Editable = true; } -#if not CLEAN27 - field(sourceType; Rec."Source Type") + field(sourceType; LocalSourceType) { Caption = 'Source Type'; Editable = true; - ObsoleteReason = 'Replaced with IC Source Type for consistent naming.'; - ObsoleteState = Pending; - ObsoleteTag = '27.0'; } -#endif field(icSourceType; Rec."IC Source Type") { Caption = 'IC Source Type'; @@ -124,11 +120,15 @@ page 30411 "API - IC Inbox Transactions" } trigger OnAfterGetRecord() begin -#if not CLEAN27 - SourceTypeIndex := Rec."Source Type"; -#else + case Rec."IC Source Type" of + Enum::"IC Transaction Source Type"::Journal: + LocalSourceType := LocalSourceType::Journal; + Enum::"IC Transaction Source Type"::"Sales Document": + LocalSourceType := LocalSourceType::"Sales Document"; + Enum::"IC Transaction Source Type"::"Purchase Document": + LocalSourceType := LocalSourceType::"Purchase Document"; + end; SourceTypeIndex := Rec."IC Source Type".AsInteger(); -#endif DocumentTypeOrdinal := Rec."Document Type".AsInteger(); TransactionSourceIndex := Rec."Transaction Source"; LineActionIndex := Rec."Line Action"; @@ -136,5 +136,6 @@ page 30411 "API - IC Inbox Transactions" end; var + LocalSourceType: Option Journal,"Sales Document","Purchase Document"; SourceTypeIndex, DocumentTypeOrdinal, TransactionSourceIndex, LineActionIndex, IcAccountTypeOrdinal : Integer; } \ No newline at end of file diff --git a/Apps/W1/Intrastat/app/src/BaseAppExtensions/MasterData/IntrastatReportItem.TableExt.al b/Apps/W1/Intrastat/app/src/BaseAppExtensions/MasterData/IntrastatReportItem.TableExt.al index 2095d2cb74..b613d7d2fd 100644 --- a/Apps/W1/Intrastat/app/src/BaseAppExtensions/MasterData/IntrastatReportItem.TableExt.al +++ b/Apps/W1/Intrastat/app/src/BaseAppExtensions/MasterData/IntrastatReportItem.TableExt.al @@ -18,7 +18,7 @@ tableextension 4811 "Intrastat Report Item" extends Item TariffNumber: Record "Tariff Number"; IntrastatReportMgt: Codeunit IntrastatReportManagement; begin - if "Tariff No." <> '' then begin + if ("Tariff No." <> '') and ("No." <> '') then begin TariffNumber.Get("Tariff No."); if not (TariffNumber."Suppl. Unit of Measure" in ['', "Supplementary Unit of Measure"]) then begin if not ItemUOM.Get("No.", TariffNumber."Suppl. Unit of Measure") then begin diff --git a/Apps/W1/Intrastat/test/src/IntrastatReportTest.Codeunit.al b/Apps/W1/Intrastat/test/src/IntrastatReportTest.Codeunit.al index acfe07949a..3417f68128 100644 --- a/Apps/W1/Intrastat/test/src/IntrastatReportTest.Codeunit.al +++ b/Apps/W1/Intrastat/test/src/IntrastatReportTest.Codeunit.al @@ -4796,6 +4796,39 @@ codeunit 139550 "Intrastat Report Test" Assert.RecordIsNotEmpty(IntrastatReportLine); end; + [Test] + procedure WhenValidateTariffNoInItemTemplateThenAnErrorOccur() + var + ItemTempl: Record "Item Templ."; + TariffNo: Record "Tariff Number"; + UnitOfMeasure: Record "Unit of Measure"; + LibraryTemplates: Codeunit "Library - Templates"; + begin + // [SCENARIO 618166] When validating an item template in Business Central that contains a tariff number (Tariff No.) an error occurs + Initialize(); + + // [GIVEN] Create Item Unit of Measure + LibraryInventory.CreateUnitOfMeasureCode(UnitOfMeasure); + + // [GIVEN] Create Tariff Number + TariffNo.Init(); + TariffNo.Validate("No.", LibraryUtility.GenerateGUID()); + TariffNo.Validate("Supplementary Units", true); + TariffNo.SetSkipValidationLogic(true); + TariffNo.Validate("Suppl. Unit of Measure", UnitOfMeasure.Code); + TariffNo.Insert(true); + + // [GIVEN] Create Item Template + LibraryTemplates.CreateItemTemplateWithData(ItemTempl); + + //[WHEN] Select same Tariff No in created Item Template + ItemTempl.Validate("Tariff No.", TariffNo."No."); + ItemTempl.Modify(true); + + //[THEN] Tariff No selected successfully No error occur + Assert.AreEqual(TariffNo."No.", ItemTempl."Tariff No.", ''); + end; + local procedure Initialize() var LibraryERMCountryData: Codeunit "Library - ERM Country Data"; diff --git a/Apps/W1/LatePaymentPredictor/app/src/LPPUpdate.Codeunit.al b/Apps/W1/LatePaymentPredictor/app/src/LPPUpdate.Codeunit.al index 8f79bb9ac4..7a9b8a3004 100644 --- a/Apps/W1/LatePaymentPredictor/app/src/LPPUpdate.Codeunit.al +++ b/Apps/W1/LatePaymentPredictor/app/src/LPPUpdate.Codeunit.al @@ -29,14 +29,16 @@ codeunit 1957 "LPP Update" repeat if SalesInvoiceHeader.Get(CustomerLedgerEntries."Document No.") then begin LPMLInputData.SetRange(Number, CustomerLedgerEntries."Document No."); - LPMLInputData.FindFirst(); - if LPMLInputData."Is Late" then - CustomerLedgerEntries."Payment Prediction" := CustomerLedgerEntries."Payment Prediction"::Late - else - CustomerLedgerEntries."Payment Prediction" := CustomerLedgerEntries."Payment Prediction"::"On-Time"; - CustomerLedgerEntries."Prediction Confidence %" := Round(LPMLInputData.Confidence * 100, 1); - CustomerLedgerEntries."Prediction Confidence" := LPPredictionMgt.GetConfidenceOptionFromConfidencePercent(LPMLInputData.Confidence); - CustomerLedgerEntries.Modify(); + if LPMLInputData.FindFirst() then begin + if LPMLInputData."Is Late" then + CustomerLedgerEntries."Payment Prediction" := CustomerLedgerEntries."Payment Prediction"::Late + else + CustomerLedgerEntries."Payment Prediction" := CustomerLedgerEntries."Payment Prediction"::"On-Time"; + CustomerLedgerEntries."Prediction Confidence %" := Round(LPMLInputData.Confidence * 100, 1); + CustomerLedgerEntries."Prediction Confidence" := LPPredictionMgt.GetConfidenceOptionFromConfidencePercent(LPMLInputData.Confidence); + CustomerLedgerEntries.Modify(); + end else + Session.LogMessage('0000RH7', LPMLInputDataNotFoundTok, Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', TelemetryCategoryTok); end; until CustomerLedgerEntries.Next() = 0; LPMLInputData.DeleteAll(); @@ -45,4 +47,8 @@ codeunit 1957 "LPP Update" LPMachineLearningSetup."Last Feature Table Reset" := 0DT; // table will need to be rebuilt LPMachineLearningSetup.Modify(); end; + + var + TelemetryCategoryTok: Label 'LatePaymentML', Locked = true; + LPMLInputDataNotFoundTok: Label 'LP ML Input Data not found.', Locked = true; } \ No newline at end of file diff --git a/Apps/W1/MasterDataManagement/app/src/codeunits/MasterDataManagement.Codeunit.al b/Apps/W1/MasterDataManagement/app/src/codeunits/MasterDataManagement.Codeunit.al index 01138d8408..87c9871505 100644 --- a/Apps/W1/MasterDataManagement/app/src/codeunits/MasterDataManagement.Codeunit.al +++ b/Apps/W1/MasterDataManagement/app/src/codeunits/MasterDataManagement.Codeunit.al @@ -35,6 +35,7 @@ codeunit 7233 "Master Data Management" tabledata "Integration Table Mapping" = rimd, tabledata "Integration Synch. Job" = r, tabledata "Job Queue Entry" = rimd, + tabledata "Scheduled Task" = rm, tabledata "Master Data Management Setup" = rimd; var diff --git a/Apps/W1/ReviewGLEntries/app/src/codeunits/Upgrade.Codeunit.al b/Apps/W1/ReviewGLEntries/app/src/codeunits/Upgrade.Codeunit.al index c83d0e9d1e..931a8ffe5c 100644 --- a/Apps/W1/ReviewGLEntries/app/src/codeunits/Upgrade.Codeunit.al +++ b/Apps/W1/ReviewGLEntries/app/src/codeunits/Upgrade.Codeunit.al @@ -16,7 +16,7 @@ codeunit 22201 "Upgrade" local procedure FixGLEntryReviewLogWithReviewAmountZero() var - GLEntryReviewLog, GLEntryReviewLog2: Record "G/L Entry Review Log"; + GLEntryReviewLog, GLEntryReviewLog2 : Record "G/L Entry Review Log"; GlEntry: Record "G/L Entry"; UpgradeTag: Codeunit "Upgrade Tag"; begin @@ -40,24 +40,23 @@ codeunit 22201 "Upgrade" var GLEntryReviewEntry: Record "G/L Entry Review Entry"; GLEntryReviewLog: Record "G/L Entry Review Log"; - GlEntry: Record "G/L Entry"; + GLEntry: Record "G/L Entry"; UpgradeTag: Codeunit "Upgrade Tag"; + GLEntryReviewDataTransfer, GLEntryDataTransfer : DataTransfer; begin if UpgradeTag.HasUpgradeTag(UpgradeReviewGLEntryTag()) then exit; - if GLEntryReviewEntry.FindSet() then - repeat - GLEntryReviewLog.Init(); - GLEntryReviewLog."G/L Entry No." := GLEntryReviewEntry."G/L Entry No."; - GLEntryReviewLog."Reviewed Identifier" := GLEntryReviewEntry."Reviewed Identifier"; - GLEntryReviewLog."Reviewed By" := GLEntryReviewEntry."Reviewed By"; - if GlEntry.Get(GLEntryReviewEntry."G/L Entry No.") then begin - GLEntryReviewLog."G/L Account No." := GlEntry."G/L Account No."; - GLEntryReviewLog."Reviewed Amount" := GlEntry.Amount; - end; - GLEntryReviewLog.Insert(true); - until GLEntryReviewEntry.Next() = 0; + GLEntryReviewDataTransfer.SetTables(Database::"G/L Entry Review Entry", Database::"G/L Entry Review Log"); + GLEntryReviewDataTransfer.AddFieldValue(GLEntryReviewEntry.FieldNo("G/L Entry No."), GLEntryReviewLog.FieldNo("G/L Entry No.")); + GLEntryReviewDataTransfer.AddFieldValue(GLEntryReviewEntry.FieldNo("Reviewed Identifier"), GLEntryReviewLog.FieldNo("Reviewed Identifier")); + GLEntryReviewDataTransfer.AddFieldValue(GLEntryReviewEntry.FieldNo("Reviewed By"), GLEntryReviewLog.FieldNo("Reviewed By")); + GLEntryReviewDataTransfer.CopyRows(); + GLEntryDataTransfer.SetTables(Database::"G/L Entry", Database::"G/L Entry Review Log"); + GLEntryDataTransfer.AddJoin(GLEntry.FieldNo("Entry No."), GLEntryReviewLog.FieldNo("G/L Entry No.")); + GLEntryDataTransfer.AddFieldValue(GLEntry.FieldNo("G/L Account No."), GLEntryReviewLog.FieldNo("G/L Account No.")); + GLEntryDataTransfer.AddFieldValue(GLEntry.FieldNo(Amount), GLEntryReviewLog.FieldNo("Reviewed Amount")); + GLEntryDataTransfer.CopyFields(); UpgradeTag.SetUpgradeTag(UpgradeReviewGLEntryTag()); end; diff --git a/Build/Packages.json b/Build/Packages.json index 906720893a..bf7c798633 100644 --- a/Build/Packages.json +++ b/Build/Packages.json @@ -4,8 +4,9 @@ "Source": "NuGet.org" }, "AppBaselines-BCArtifacts": { - "Version": "27.4.45057", + "Version": "27.5.45926", "Source": "BCArtifacts", "_comment": "Used to fetch app baselines from BC artifacts" } } +