diff --git a/src/Apps/W1/Shopify/App/src/Companies/Codeunits/ShpfyCompanyExport.Codeunit.al b/src/Apps/W1/Shopify/App/src/Companies/Codeunits/ShpfyCompanyExport.Codeunit.al index f8a7a584c4..732063d6ac 100644 --- a/src/Apps/W1/Shopify/App/src/Companies/Codeunits/ShpfyCompanyExport.Codeunit.al +++ b/src/Apps/W1/Shopify/App/src/Companies/Codeunits/ShpfyCompanyExport.Codeunit.al @@ -122,6 +122,7 @@ codeunit 30284 "Shpfy Company Export" TaxRegistrationIdMapping: Interface "Shpfy Tax Registration Id Mapping"; CountyCodeTooLongErr: Text; PaymentTermsId: BigInteger; + ISOCountryCode: Code[10]; begin TempCompanyLocation := CompanyLocation; @@ -132,8 +133,20 @@ codeunit 30284 "Shpfy Company Export" CompanyLocation.City := Customer.City; CompanyLocation.Recipient := Customer.Name; + if (Customer."Country/Region Code" = '') and CompanyInformation.Get() then + Customer."Country/Region Code" := CompanyInformation."Country/Region Code"; + + // Get the ISO country code first, as it's needed for both the Shopify API and Tax Area lookups + // Tax Area table stores Shopify's ISO country codes (e.g., "GR" for Greece), + // while BC may use different codes (e.g., "EL" for Greece in EU/VIES contexts) + if CountryRegion.Get(Customer."Country/Region Code") then begin + CountryRegion.TestField("ISO Code"); + ISOCountryCode := CountryRegion."ISO Code"; + end else + ISOCountryCode := CopyStr(Customer."Country/Region Code", 1, MaxStrLen(ISOCountryCode)); + if Customer.County <> '' then begin - TaxArea.SetRange("Country/Region Code", Customer."Country/Region Code"); + TaxArea.SetRange("Country/Region Code", ISOCountryCode); if not TaxArea.IsEmpty() then case Shop."County Source" of Shop."County Source"::Code: @@ -142,7 +155,7 @@ codeunit 30284 "Shpfy Company Export" CountyCodeTooLongErr := StrSubstNo(CountyCodeTooLongLbl, Customer."No.", Customer.Name, StrLen(Customer.County), MaxStrLen(TaxArea."County Code"), Customer.County, Customer.FieldCaption(County)); Error(CountyCodeTooLongErr); end; - TaxArea.SetRange("Country/Region Code", Customer."Country/Region Code"); + TaxArea.SetRange("Country/Region Code", ISOCountryCode); TaxArea.SetRange("County Code", Customer.County); if TaxArea.FindFirst() then begin CompanyLocation."Province Code" := TaxArea."County Code"; @@ -151,7 +164,7 @@ codeunit 30284 "Shpfy Company Export" end; Shop."County Source"::Name: begin - TaxArea.SetRange("Country/Region Code", Customer."Country/Region Code"); + TaxArea.SetRange("Country/Region Code", ISOCountryCode); TaxArea.SetRange(County, Customer.County); if TaxArea.FindFirst() then begin CompanyLocation."Province Code" := TaxArea."County Code"; @@ -167,13 +180,7 @@ codeunit 30284 "Shpfy Company Export" end; end; - if (Customer."Country/Region Code" = '') and CompanyInformation.Get() then - Customer."Country/Region Code" := CompanyInformation."Country/Region Code"; - - if CountryRegion.Get(Customer."Country/Region Code") then begin - CountryRegion.TestField("ISO Code"); - CompanyLocation."Country/Region Code" := CountryRegion."ISO Code"; - end; + CompanyLocation."Country/Region Code" := ISOCountryCode; CompanyLocation."Phone No." := Customer."Phone No."; diff --git a/src/Apps/W1/Shopify/App/src/Customers/Codeunits/ShpfyCustomerExport.Codeunit.al b/src/Apps/W1/Shopify/App/src/Customers/Codeunits/ShpfyCustomerExport.Codeunit.al index 5043f72eb0..8b16ba09ad 100644 --- a/src/Apps/W1/Shopify/App/src/Customers/Codeunits/ShpfyCustomerExport.Codeunit.al +++ b/src/Apps/W1/Shopify/App/src/Customers/Codeunits/ShpfyCustomerExport.Codeunit.al @@ -102,6 +102,7 @@ codeunit 30116 "Shpfy Customer Export" #pragma warning restore AA0073 TaxArea: Record "Shpfy Tax Area"; CountyCodeTooLongErr: Text; + ISOCountryCode: Code[10]; begin xShopifyCustomer := ShopifyCustomer; xCustomerAddress := CustomerAddress; @@ -140,8 +141,17 @@ codeunit 30116 "Shpfy Customer Export" if (Customer."Country/Region Code" = '') and CompanyInformation.Get() then Customer."Country/Region Code" := CompanyInformation."Country/Region Code"; + // Get the ISO country code first, as it's needed for both the Shopify API and Tax Area lookups + // Tax Area table stores Shopify's ISO country codes (e.g., "GR" for Greece), + // while BC may use different codes (e.g., "EL" for Greece in EU/VIES contexts) + if CountryRegion.Get(Customer."Country/Region Code") then begin + CountryRegion.TestField("ISO Code"); + ISOCountryCode := CountryRegion."ISO Code"; + end else + ISOCountryCode := CopyStr(Customer."Country/Region Code", 1, MaxStrLen(ISOCountryCode)); + if Customer.County <> '' then begin - TaxArea.SetRange("Country/Region Code", Customer."Country/Region Code"); + TaxArea.SetRange("Country/Region Code", ISOCountryCode); if not TaxArea.IsEmpty() then case Shop."County Source" of Shop."County Source"::Code: @@ -150,7 +160,7 @@ codeunit 30116 "Shpfy Customer Export" CountyCodeTooLongErr := StrSubstNo(CountyCodeTooLongLbl, Customer."No.", Customer.Name, StrLen(Customer.County), MaxStrLen(TaxArea."County Code"), Customer.County, Customer.FieldCaption(County)); Error(CountyCodeTooLongErr); end; - TaxArea.SetRange("Country/Region Code", Customer."Country/Region Code"); + TaxArea.SetRange("Country/Region Code", ISOCountryCode); TaxArea.SetRange("County Code", Customer.County); if TaxArea.FindFirst() then begin CustomerAddress."Province Code" := TaxArea."County Code"; @@ -159,7 +169,7 @@ codeunit 30116 "Shpfy Customer Export" end; Shop."County Source"::Name: begin - TaxArea.SetRange("Country/Region Code", Customer."Country/Region Code"); + TaxArea.SetRange("Country/Region Code", ISOCountryCode); TaxArea.SetRange(County, Customer.County); if TaxArea.FindFirst() then begin CustomerAddress."Province Code" := TaxArea."County Code"; @@ -175,10 +185,7 @@ codeunit 30116 "Shpfy Customer Export" end; end; - if CountryRegion.Get(Customer."Country/Region Code") then begin - CountryRegion.TestField("ISO Code"); - CustomerAddress."Country/Region Code" := CountryRegion."ISO Code"; - end; + CustomerAddress."Country/Region Code" := ISOCountryCode; CustomerAddress.Phone := Customer."Phone No."; diff --git a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyExportTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyExportTest.Codeunit.al index b7fd88c45a..6dda1a7801 100644 --- a/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyExportTest.Codeunit.al +++ b/src/Apps/W1/Shopify/Test/Companies/ShpfyCompanyExportTest.Codeunit.al @@ -5,6 +5,7 @@ namespace Microsoft.Integration.Shopify.Test; +using Microsoft.Foundation.Address; using Microsoft.Foundation.PaymentTerms; using Microsoft.Integration.Shopify; using Microsoft.Sales.Customer; @@ -33,16 +34,29 @@ codeunit 139636 "Shpfy Company Export Test" procedure UnitTestFillInShopifyCustomerData() var Customer: Record Customer; + CountryRegion: Record "Country/Region"; ShopifyCompany: Record "Shpfy Company"; CompanyLocation: Record "Shpfy Company Location"; ShopifyShop: Record "Shpfy Shop"; Result: Boolean; ShopifyPaymentTermsId: BigInteger; + ExpectedCountryCode: Code[10]; begin // [SCENARIO] Convert an existing company record to a "Shpfy Company" and "Shpfy Company Location" record. // [GIVEN] Customer record Customer.FindFirst(); + + // [GIVEN] Ensure the customer's country has an ISO code set + if CountryRegion.Get(Customer."Country/Region Code") then begin + if CountryRegion."ISO Code" = '' then begin + CountryRegion."ISO Code" := CopyStr(Customer."Country/Region Code", 1, MaxStrLen(CountryRegion."ISO Code")); + CountryRegion.Modify(); + end; + ExpectedCountryCode := CountryRegion."ISO Code"; + end else + ExpectedCountryCode := CopyStr(Customer."Country/Region Code", 1, MaxStrLen(ExpectedCountryCode)); + ShopifyShop := InitializeTest.CreateShop(); ShopifyShop."Name Source" := Enum::"Shpfy Name Source"::CompanyName; ShopifyShop."Name 2 Source" := Enum::"Shpfy Name Source"::None; @@ -68,7 +82,7 @@ codeunit 139636 "Shpfy Company Export Test" LibraryAssert.AreEqual(Customer."Address 2", CompanyLocation."Address 2", 'Address 2'); LibraryAssert.AreEqual(Customer."Post Code", CompanyLocation.Zip, 'Post Code'); LibraryAssert.AreEqual(Customer.City, CompanyLocation.City, 'City'); - LibraryAssert.AreEqual(Customer."Country/Region Code", CompanyLocation."Country/Region Code", 'Country'); + LibraryAssert.AreEqual(ExpectedCountryCode, CompanyLocation."Country/Region Code", 'Country should be ISO code'); LibraryAssert.AreEqual(Customer.Name, CompanyLocation.Recipient, 'Recipient'); LibraryAssert.AreEqual(ShopifyPaymentTermsId, CompanyLocation."Shpfy Payment Terms Id", 'Payment Terms Id should be 0'); end; @@ -108,6 +122,7 @@ codeunit 139636 "Shpfy Company Export Test" procedure UnitTestFillInShopifyCustomerDataCounty() var Customer: Record Customer; + CountryRegion: Record "Country/Region"; CompanyLocation: Record "Shpfy Company Location"; ShopifyShop: Record "Shpfy Shop"; TaxArea: Record "Shpfy Tax Area"; @@ -115,16 +130,30 @@ codeunit 139636 "Shpfy Company Export Test" begin // [SCENARIO] County information is only sent to Shopify if the country has any provinces - // [GIVEN] Customer record + // [GIVEN] Customer record with country code 'US' that has ISO code 'US' Customer.FindFirst(); Customer."Country/Region Code" := 'US'; Customer."County" := 'CA'; Customer.Modify(); + // Ensure the US country has ISO code set + if not CountryRegion.Get('US') then begin + CountryRegion.Init(); + CountryRegion.Code := 'US'; + CountryRegion."ISO Code" := 'US'; + CountryRegion.Insert(); + end else begin + if CountryRegion."ISO Code" = '' then begin + CountryRegion."ISO Code" := 'US'; + CountryRegion.Modify(); + end; + end; + TaxArea."Country/Region Code" := 'US'; TaxArea.County := 'CA'; TaxArea."County Code" := 'CA'; - TaxArea.Insert(); + if not TaxArea.Insert() then + TaxArea.Modify(); ShopifyShop := InitializeTest.CreateShop(); ShopifyShop."Name Source" := Enum::"Shpfy Name Source"::CompanyName; @@ -149,6 +178,20 @@ codeunit 139636 "Shpfy Company Export Test" // [WHEN] Change the county to a country without provinces Customer."Country/Region Code" := 'DE'; Customer.Modify(); + + // Ensure the DE country has ISO code set + if not CountryRegion.Get('DE') then begin + CountryRegion.Init(); + CountryRegion.Code := 'DE'; + CountryRegion."ISO Code" := 'DE'; + CountryRegion.Insert(); + end else begin + if CountryRegion."ISO Code" = '' then begin + CountryRegion."ISO Code" := 'DE'; + CountryRegion.Modify(); + end; + end; + Clear(CompanyLocation); Result := CompanyExport.FillInShopifyCompanyLocation(Customer, CompanyLocation); @@ -158,6 +201,78 @@ codeunit 139636 "Shpfy Company Export Test" LibraryAssert.IsTrue(CompanyLocation."Province Name" = '', 'Province Name'); end; + [Test] + procedure UnitTestFillInShopifyCompanyLocationISOCountryCodeMapping() + var + Customer: Record Customer; + CountryRegion: Record "Country/Region"; + CompanyLocation: Record "Shpfy Company Location"; + ShopifyShop: Record "Shpfy Shop"; + TaxArea: Record "Shpfy Tax Area"; + Result: Boolean; + BCCountryCode: Code[10]; + ISOCountryCode: Code[10]; + begin + // [SCENARIO] When BC uses a different country code than the ISO standard (e.g., "EL" for Greece instead of "GR"), + // the Shopify connector should correctly map to the ISO code for Shopify API and Tax Area lookups. + + // [GIVEN] A country with BC code "EL" and ISO code "GR" (like Greece in EU/VIES context) + BCCountryCode := 'EL'; + ISOCountryCode := 'GR'; + + if not CountryRegion.Get(BCCountryCode) then begin + CountryRegion.Init(); + CountryRegion.Code := BCCountryCode; + CountryRegion.Name := 'Greece'; + CountryRegion."ISO Code" := ISOCountryCode; + CountryRegion.Insert(); + end else begin + CountryRegion."ISO Code" := ISOCountryCode; + CountryRegion.Modify(); + end; + + // [GIVEN] A Tax Area with country code "GR" (Shopify's ISO code) and province info + TaxArea.Init(); + TaxArea."Country/Region Code" := ISOCountryCode; + TaxArea.County := 'Attica'; + TaxArea."County Code" := 'I'; + if not TaxArea.Insert() then + TaxArea.Modify(); + + // [GIVEN] A customer with country code "EL" (BC code) and matching county + Customer.FindFirst(); + Customer."Country/Region Code" := BCCountryCode; + Customer.County := 'Attica'; + Customer.Modify(); + + // [GIVEN] Shop with County Source = Name + ShopifyShop := InitializeTest.CreateShop(); + ShopifyShop."Name Source" := Enum::"Shpfy Name Source"::CompanyName; + ShopifyShop."Name 2 Source" := Enum::"Shpfy Name Source"::None; + ShopifyShop."Contact Source" := Enum::"Shpfy Name Source"::None; + ShopifyShop."County Source" := Enum::"Shpfy County Source"::Name; + ShopifyShop."B2B Enabled" := true; + CompanyLocation.Init(); + + CompanyExport.SetShop(ShopifyShop); + + // [WHEN] Invoke FillInShopifyCompanyLocation + Result := CompanyExport.FillInShopifyCompanyLocation(Customer, CompanyLocation); + + // [THEN] The result is true + LibraryAssert.IsTrue(Result, 'Result should be true'); + + // [THEN] The country code is mapped to the ISO code "GR" (not the BC code "EL") + LibraryAssert.AreEqual(ISOCountryCode, CompanyLocation."Country/Region Code", 'Country/Region Code should be ISO code GR, not BC code EL'); + + // [THEN] The province information is correctly retrieved using the ISO country code + LibraryAssert.AreEqual('I', CompanyLocation."Province Code", 'Province Code should be found using ISO country code'); + LibraryAssert.AreEqual('Attica', CompanyLocation."Province Name", 'Province Name should be found using ISO country code'); + + // Cleanup + TaxArea.Delete(); + end; + local procedure Initialize() begin diff --git a/src/Apps/W1/Shopify/Test/Customers/ShpfyCustomerExportTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Customers/ShpfyCustomerExportTest.Codeunit.al index 8bee14df10..75a2b749a4 100644 --- a/src/Apps/W1/Shopify/Test/Customers/ShpfyCustomerExportTest.Codeunit.al +++ b/src/Apps/W1/Shopify/Test/Customers/ShpfyCustomerExportTest.Codeunit.al @@ -5,6 +5,7 @@ namespace Microsoft.Integration.Shopify.Test; +using Microsoft.Foundation.Address; using Microsoft.Integration.Shopify; using Microsoft.Sales.Customer; using System.TestLibraries.Utilities; @@ -18,6 +19,7 @@ codeunit 139568 "Shpfy Customer Export Test" var LibraryAssert: Codeunit "Library Assert"; CustomerExport: Codeunit "Shpfy Customer Export"; + Any: Codeunit Any; [Test] procedure UnitTestSpiltNameIntoFirstAndLastName() @@ -95,6 +97,7 @@ codeunit 139568 "Shpfy Customer Export Test" procedure UnitTestFillInShopifyCustomerDataCounty() var Customer: Record Customer; + CountryRegion: Record "Country/Region"; ShopifyCustomer: Record "Shpfy Customer"; CustomerAddress: Record "Shpfy Customer Address"; Shop: Record "Shpfy Shop"; @@ -104,16 +107,30 @@ codeunit 139568 "Shpfy Customer Export Test" begin // [SCENARIO] County information is only sent to Shopify if the country has any provinces - // [GIVEN] Customer record + // [GIVEN] Customer record with country code 'US' that has ISO code 'US' Customer.FindFirst(); Customer."Country/Region Code" := 'US'; Customer."County" := 'CA'; Customer.Modify(); + // Ensure the US country has ISO code set + if not CountryRegion.Get('US') then begin + CountryRegion.Init(); + CountryRegion.Code := 'US'; + CountryRegion."ISO Code" := 'US'; + CountryRegion.Insert(); + end else begin + if CountryRegion."ISO Code" = '' then begin + CountryRegion."ISO Code" := 'US'; + CountryRegion.Modify(); + end; + end; + TaxArea."Country/Region Code" := 'US'; TaxArea.County := 'CA'; TaxArea."County Code" := 'CA'; - TaxArea.Insert(); + if not TaxArea.Insert() then + TaxArea.Modify(); Shop := InitializeTest.CreateShop(); Shop."Name Source" := Enum::"Shpfy Name Source"::CompanyName; @@ -137,6 +154,20 @@ codeunit 139568 "Shpfy Customer Export Test" // [WHEN] Change the county to a country without provinces Customer."Country/Region Code" := 'DE'; Customer.Modify(); + + // Ensure the DE country has ISO code set + if not CountryRegion.Get('DE') then begin + CountryRegion.Init(); + CountryRegion.Code := 'DE'; + CountryRegion."ISO Code" := 'DE'; + CountryRegion.Insert(); + end else begin + if CountryRegion."ISO Code" = '' then begin + CountryRegion."ISO Code" := 'DE'; + CountryRegion.Modify(); + end; + end; + Clear(CustomerAddress); Clear(ShopifyCustomer); Result := CustomerExport.FillInShopifyCustomerData(Customer, ShopifyCustomer, CustomerAddress); @@ -146,4 +177,78 @@ codeunit 139568 "Shpfy Customer Export Test" LibraryAssert.IsTrue(CustomerAddress."Province Code" = '', 'Province Code'); LibraryAssert.IsTrue(CustomerAddress."Province Name" = '', 'Province Name'); end; + + [Test] + procedure UnitTestFillInShopifyCustomerDataISOCountryCodeMapping() + var + Customer: Record Customer; + CountryRegion: Record "Country/Region"; + ShopifyCustomer: Record "Shpfy Customer"; + CustomerAddress: Record "Shpfy Customer Address"; + Shop: Record "Shpfy Shop"; + TaxArea: Record "Shpfy Tax Area"; + InitializeTest: Codeunit "Shpfy Initialize Test"; + Result: Boolean; + BCCountryCode: Code[10]; + ISOCountryCode: Code[10]; + begin + // [SCENARIO] When BC uses a different country code than the ISO standard (e.g., "EL" for Greece instead of "GR"), + // the Shopify connector should correctly map to the ISO code for Shopify API and Tax Area lookups. + + // [GIVEN] A country with BC code "EL" and ISO code "GR" (like Greece in EU/VIES context) + BCCountryCode := 'EL'; + ISOCountryCode := 'GR'; + + if not CountryRegion.Get(BCCountryCode) then begin + CountryRegion.Init(); + CountryRegion.Code := BCCountryCode; + CountryRegion.Name := 'Greece'; + CountryRegion."ISO Code" := ISOCountryCode; + CountryRegion.Insert(); + end else begin + CountryRegion."ISO Code" := ISOCountryCode; + CountryRegion.Modify(); + end; + + // [GIVEN] A Tax Area with country code "GR" (Shopify's ISO code) and province info + TaxArea.Init(); + TaxArea."Country/Region Code" := ISOCountryCode; + TaxArea.County := 'Attica'; + TaxArea."County Code" := 'I'; + if not TaxArea.Insert() then + TaxArea.Modify(); + + // [GIVEN] A customer with country code "EL" (BC code) and matching county + Customer.FindFirst(); + Customer."Country/Region Code" := BCCountryCode; + Customer.County := 'Attica'; + Customer.Modify(); + + // [GIVEN] Shop with County Source = Name + Shop := InitializeTest.CreateShop(); + Shop."Name Source" := Enum::"Shpfy Name Source"::CompanyName; + Shop."Name 2 Source" := Enum::"Shpfy Name Source"::None; + Shop."Contact Source" := Enum::"Shpfy Name Source"::None; + Shop."County Source" := Enum::"Shpfy County Source"::Name; + ShopifyCustomer.Init(); + CustomerAddress.Init(); + + CustomerExport.SetShop(Shop); + + // [WHEN] Invoke FillInShopifyCustomerData + Result := CustomerExport.FillInShopifyCustomerData(Customer, ShopifyCustomer, CustomerAddress); + + // [THEN] The result is true + LibraryAssert.IsTrue(Result, 'Result should be true'); + + // [THEN] The country code is mapped to the ISO code "GR" (not the BC code "EL") + LibraryAssert.AreEqual(ISOCountryCode, CustomerAddress."Country/Region Code", 'Country/Region Code should be ISO code GR, not BC code EL'); + + // [THEN] The province information is correctly retrieved using the ISO country code + LibraryAssert.AreEqual('I', CustomerAddress."Province Code", 'Province Code should be found using ISO country code'); + LibraryAssert.AreEqual('Attica', CustomerAddress."Province Name", 'Province Name should be found using ISO country code'); + + // Cleanup + TaxArea.Delete(); + end; }