Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Shopify][BC Idea]: Enhancing Shopify Connector for Accurate Price Synchronization with Business Central based on Customer #26981

Merged
merged 6 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ page 30159 "Shpfy Catalogs"
ToolTip = 'Specifies the unique identifier for the catalog in Shopify.';
Editable = false;
}
field("Customer No."; Rec."Customer No.")
{
ApplicationArea = All;
Visible = false;
ToolTip = 'Specifies the customer''s no. When Customer No. is Selected: Parameters like ''Customer Discount Group'', ''Customer Price Group'', and ''Allow Line Discount'' on the customer card take precedence over catalog settings';
}
field(Name; Rec.Name)
{
ApplicationArea = All;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ table 30152 "Shpfy Catalog"
Caption = 'Sync Prices';
DataClassification = CustomerContent;
}
field(17; "Customer No."; Code[20])
{
Caption = 'Customer No.';
DataClassification = CustomerContent;
TableRelation = "Customer";
}
}
keys
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ codeunit 30182 "Shpfy Product Price Calc."
TaxLiable: Boolean;
VATCountryRegionCode: Code[10];
CustomerPriceGroup: Code[10];
CustomerNo: Code[20];
CustomerDiscGroup: Code[20];
CustomerPostingGroup: Code[20];
PricesIncludingVAT: Boolean;
Expand Down Expand Up @@ -91,22 +92,35 @@ codeunit 30182 "Shpfy Product Price Calc."
/// Create Temp Sales Header.
/// </summary>
local procedure CreateTempSalesHeader()
var
Customer: Record Customer;
begin
Clear(TempSalesHeader);
TempSalesHeader."Document Type" := TempSalesHeader."Document Type"::Quote;
TempSalesHeader."No." := Shop.Code;
TempSalesHeader."Sell-to Customer No." := Shop.Code;
TempSalesHeader."Bill-to Customer No." := Shop.Code;
if CustomerNo <> '' then begin
Customer.GET(CustomerNo);
TempSalesHeader."Sell-to Customer No." := CustomerNo;
TempSalesHeader."Bill-to Customer No." := CustomerNo;
TempSalesHeader."Customer Price Group" := Customer."Customer Price Group";
TempSalesHeader."Customer Disc. Group" := Customer."Customer Disc. Group";
TempSalesHeader."Allow Line Disc." := Customer."Allow Line Disc.";
end
else begin
TempSalesHeader."Sell-to Customer No." := Shop.Code;
TempSalesHeader."Bill-to Customer No." := Shop.Code;
TempSalesHeader."Customer Price Group" := CustomerPriceGroup;
TempSalesHeader."Customer Disc. Group" := CustomerDiscGroup;
TempSalesHeader."Allow Line Disc." := AllowLineDisc;
end;

TempSalesHeader."Gen. Bus. Posting Group" := GenBusPostingGroup;
TempSalesHeader."VAT Bus. Posting Group" := VATBusPostingGroup;
TempSalesHeader."Tax Area Code" := TaxAreaCode;
TempSalesHeader."Tax Liable" := TaxLiable;
TempSalesHeader."VAT Country/Region Code" := VATCountryRegionCode;
TempSalesHeader."Customer Price Group" := CustomerPriceGroup;
TempSalesHeader."Customer Disc. Group" := CustomerDiscGroup;
TempSalesHeader."Customer Posting Group" := CustomerPostingGroup;
TempSalesHeader."Prices Including VAT" := PricesIncludingVAT;
TempSalesHeader."Allow Line Disc." := AllowLineDisc;
TempSalesHeader.Validate("Document Date", WorkDate());
TempSalesHeader.Validate("Order Date", WorkDate());
TempSalesHeader.Validate("Currency Code", Shop."Currency Code");
Expand Down Expand Up @@ -206,6 +220,7 @@ codeunit 30182 "Shpfy Product Price Calc."
CustomerPostingGroup := ShopifyCatalog."Customer Posting Group";
PricesIncludingVAT := ShopifyCatalog."Prices Including VAT";
AllowLineDisc := ShopifyCatalog."Allow Line Disc.";
CustomerNo := ShopifyCatalog."Customer No.";
end;
end;
end;
Expand Down
238 changes: 238 additions & 0 deletions Apps/W1/Shopify/test/Catalogs/ShpfyCatalogPricesTest.Codeunit.al
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ codeunit 139646 "Shpfy Catalog Prices Test"

// [GIVEN] Update the Catalog."Customer Discount Group" field and set the catalog to the calculation codeunit.
Catalog."Customer Discount Group" := CustomerDiscountGroup.Code;
Catalog."Allow Line Disc." := true;
Catalog.Modify();
ProductPriceCalculation.SetShopAndCatalog(Shop, Catalog);

Expand All @@ -72,4 +73,241 @@ codeunit 139646 "Shpfy Catalog Prices Test"
// [THEN] InitPrice - InitDiscountPerc = Price
LibraryAssert.AreNearlyEqual(InitPrice * (1 - InitDiscountPerc / 100), Price, 0.01, 'Discount Price');
end;

[Test]
procedure UnitTestCalcCatalogPriceAllCustomers()
var
Shop: Record "Shpfy Shop";
LibrarySales: Codeunit "Library - Sales";
Catalog: Record "Shpfy Catalog";
ShopifyCompany: Record "Shpfy Company";
Item: Record Item;
CustomerDiscountGroup: Record "Customer Discount Group";
Customer: Record Customer;
InitializeTest: Codeunit "Shpfy Initialize Test";
ProductInitTest: Codeunit "Shpfy Product Init Test";
CatalogInitialize: Codeunit "Shpfy Catalog Initialize";
CompanyInitialize: Codeunit "Shpfy Company Initialize";
ProductPriceCalculation: Codeunit "Shpfy Product Price Calc.";
InitUnitCost: Decimal;
InitPrice: Decimal;
InitDiscountPerc: Decimal;
UnitCost: Decimal;
Price: Decimal;
ComparePrice: Decimal;
begin
// [GIVEN] Initializing test environment and creating necessary test records.
Shop := InitializeTest.CreateShop();
CompanyInitialize.CreateShopifyCompany(ShopifyCompany);
Catalog := CatalogInitialize.CreateCatalog(ShopifyCompany);
CatalogInitialize.CopyParametersFromShop(Catalog, Shop);
InitUnitCost := Any.DecimalInRange(10, 100, 1);
InitPrice := Any.DecimalInRange(2 * InitUnitCost, 4 * InitUnitCost, 1);
InitDiscountPerc := Any.DecimalInRange(5, 20, 1);
Item := ProductInitTest.CreateItem(Shop."Item Templ. Code", InitUnitCost, InitPrice);

// Creating a customer entry, though it is generic as discounts apply to all customers.
LibrarySales.CreateCustomer(Customer);

// [WHEN] Calculating initial prices without any discounts applied.
ProductPriceCalculation.SetShopAndCatalog(Shop, Catalog);
ProductPriceCalculation.CalcPrice(Item, '', '', UnitCost, Price, ComparePrice);

// [THEN] Confirm initial price calculations match expectations.
LibraryAssert.AreEqual(InitUnitCost, UnitCost, 'Initial unit cost should match expected.');
LibraryAssert.AreEqual(InitPrice, Price, 'Initial price should match expected before discount application.');

// [GIVEN] Updating the catalog to apply a universal discount to all customers.
#if CLEAN23
ProductInitTest.CreateAllCustomerPriceList(Shop.Code, Item."No.", InitPrice, InitDiscountPerc);
Catalog."Customer No." := Customer."No.";
Catalog.Modify();

// [WHEN] Recalculating prices after applying the discount.
ProductPriceCalculation.SetShopAndCatalog(Shop, Catalog);
ProductPriceCalculation.CalcPrice(Item, '', '', UnitCost, Price, ComparePrice);

// [THEN] Validate the results reflect the universal discount.
LibraryAssert.AreEqual(InitUnitCost, UnitCost, 'Unit cost should remain consistent after discount application.');
LibraryAssert.AreEqual(InitPrice, ComparePrice, 'Compare price should reflect the original price prior to any discounts.');
LibraryAssert.AreNearlyEqual(InitPrice * (1 - InitDiscountPerc / 100), Price, 0.01, 'The final price should accurately reflect the applied discount for all customers.');
#endif
end;

[Test]
procedure UnitTestCalcCustomerCatalogPrice()
var
Shop: Record "Shpfy Shop";
LibrarySales: Codeunit "Library - Sales";
Catalog: Record "Shpfy Catalog";
ShopifyCompany: Record "Shpfy Company";
Item: Record Item;
CustomerDiscountGroup: Record "Customer Discount Group";
Customer: Record Customer;
InitializeTest: Codeunit "Shpfy Initialize Test";
ProductInitTest: Codeunit "Shpfy Product Init Test";
CatalogInitialize: Codeunit "Shpfy Catalog Initialize";
CompanyInitialize: Codeunit "Shpfy Company Initialize";
ProductPriceCalculation: Codeunit "Shpfy Product Price Calc.";
InitUnitCost: Decimal;
InitPrice: Decimal;
InitDiscountPerc: Decimal;
UnitCost: Decimal;
Price: Decimal;
ComparePrice: Decimal;
CustDiscPerc: Decimal;
begin
// [GIVEN] Setting up the test environment: Shop, Catalog, Item, and Customer with specific pricing and discount.
Shop := InitializeTest.CreateShop();
CompanyInitialize.CreateShopifyCompany(ShopifyCompany);
Catalog := CatalogInitialize.CreateCatalog(ShopifyCompany);
CatalogInitialize.CopyParametersFromShop(Catalog, Shop);
InitUnitCost := Any.DecimalInRange(10, 100, 1);
InitPrice := Any.DecimalInRange(2 * InitUnitCost, 4 * InitUnitCost, 1);
CustDiscPerc := Any.DecimalInRange(5, 20, 1);
Item := ProductInitTest.CreateItem(Shop."Item Templ. Code", InitUnitCost, InitPrice);

// [WHEN] Calculating prices without and then with customer-specific discounts.
ProductPriceCalculation.SetShopAndCatalog(Shop, Catalog);
ProductPriceCalculation.CalcPrice(Item, '', '', UnitCost, Price, ComparePrice);
LibraryAssert.AreEqual(InitUnitCost, UnitCost, 'Verify initial unit cost matches setup.');
LibraryAssert.AreEqual(InitPrice, Price, 'Verify initial price matches setup before discount.');
#if CLEAN23
// Creating a customer entry, though it is generic as discounts apply to all customers.
LibrarySales.CreateCustomer(Customer);
// [GIVEN] Applying customer-specific discounts.
ProductInitTest.CreateCustomerPriceList(Shop.Code, Item."No.", InitPrice, CustDiscPerc, Customer);
Catalog."Customer No." := Customer."No.";
Catalog.Modify();
ProductPriceCalculation.SetShopAndCatalog(Shop, Catalog);

// [WHEN] Recalculating prices with customer-specific discounts.
ProductPriceCalculation.CalcPrice(Item, '', '', UnitCost, Price, ComparePrice);

// [THEN] Confirming pricing accuracy with applied discounts.
LibraryAssert.AreEqual(InitUnitCost, UnitCost, 'Unit cost should remain unchanged after applying discounts.');
LibraryAssert.AreEqual(InitPrice, ComparePrice, 'Compare price should reflect the original price pre-discount.');
LibraryAssert.AreNearlyEqual(InitPrice * (1 - CustDiscPerc / 100), Price, 0.01, 'Discounted price should be accurately calculated.');
#endif
end;

[Test]
procedure UnitTestCalcCustomerCatalogPriceAllCustomers()
var
Shop: Record "Shpfy Shop";
LibrarySales: Codeunit "Library - Sales";
Catalog: Record "Shpfy Catalog";
ShopifyCompany: Record "Shpfy Company";
Item: Record Item;
CustomerDiscountGroup: Record "Customer Discount Group";
Customer: Record Customer;
InitializeTest: Codeunit "Shpfy Initialize Test";
ProductInitTest: Codeunit "Shpfy Product Init Test";
CatalogInitialize: Codeunit "Shpfy Catalog Initialize";
CompanyInitialize: Codeunit "Shpfy Company Initialize";
ProductPriceCalculation: Codeunit "Shpfy Product Price Calc.";
InitUnitCost: Decimal;
InitPrice: Decimal;
InitPerc: Decimal;
CustDiscPerc: Decimal;
UnitCost: Decimal;
Price: Decimal;
ComparePrice: Decimal;
begin
// [GIVEN] Setting up shop, catalog, item, and customer-specific pricing.
Shop := InitializeTest.CreateShop();
CompanyInitialize.CreateShopifyCompany(ShopifyCompany);
Catalog := CatalogInitialize.CreateCatalog(ShopifyCompany);
CatalogInitialize.CopyParametersFromShop(Catalog, Shop);
InitUnitCost := Any.DecimalInRange(10, 100, 1);
InitPrice := Any.DecimalInRange(2 * InitUnitCost, 4 * InitUnitCost, 1);
CustDiscPerc := Any.DecimalInRange(5, 20, 1);
Item := ProductInitTest.CreateItem(Shop."Item Templ. Code", InitUnitCost, InitPrice);

// [WHEN] Calculating prices without discounts applied.
ProductPriceCalculation.SetShopAndCatalog(Shop, Catalog);
ProductPriceCalculation.CalcPrice(Item, '', '', UnitCost, Price, ComparePrice);

// [THEN] Verifying initial prices match expectations.
LibraryAssert.AreEqual(InitUnitCost, UnitCost, 'Initial unit cost should match.');
LibraryAssert.AreEqual(InitPrice, Price, 'Initial price should match before discount.');

#if CLEAN23
// Creating a customer entry, though it is generic as discounts apply to all customers.
LibrarySales.CreateCustomer(Customer);
// [GIVEN] Applying a universal discount for all customers.
ProductInitTest.CreateCustomerPriceList(Shop.Code, Item."No.", InitPrice, CustDiscPerc, Customer);
ProductInitTest.CreateAllCustomerPriceList(Shop.Code, Item."No.", InitPrice, InitPerc);
Catalog."Customer No." := Customer."No.";
Catalog.Modify();

// [WHEN] Recalculating prices with discounts.
ProductPriceCalculation.SetShopAndCatalog(Shop, Catalog);
ProductPriceCalculation.CalcPrice(Item, '', '', UnitCost, Price, ComparePrice);

// [THEN] Confirming discounts are accurately reflected in the final prices.
LibraryAssert.AreEqual(InitUnitCost, UnitCost, 'Unit cost should remain consistent.');
LibraryAssert.AreEqual(InitPrice, ComparePrice, 'Compare price should reflect initial pricing.');
LibraryAssert.AreNearlyEqual(InitPrice * (1 - CustDiscPerc / 100), Price, 0.01, 'Discounted price should be accurately calculated.');
#endif
end;

[Test]
procedure UnitTestCalcCustomerDiscountCatalogPrice()
var
Shop: Record "Shpfy Shop";
Catalog: Record "Shpfy Catalog";
LibrarySales: Codeunit "Library - Sales";
ShopifyCompany: Record "Shpfy Company";
Item: Record Item;
CustomerDiscountGroup: Record "Customer Discount Group";
InitializeTest: Codeunit "Shpfy Initialize Test";
ProductInitTest: Codeunit "Shpfy Product Init Test";
CatalogInitialize: Codeunit "Shpfy Catalog Initialize";
CompanyInitialize: Codeunit "Shpfy Company Initialize";
ProductPriceCalculation: Codeunit "Shpfy Product Price Calc.";
InitUnitCost: Decimal;
InitPrice: Decimal;
InitDiscountPerc: Decimal;
UnitCost: Decimal;
Price: Decimal;
ComparePrice: Decimal;
Customer: Record Customer;
begin
// [GIVEN] Creating shop, catalog, item, and setting customer discount details.
Shop := InitializeTest.CreateShop();
CompanyInitialize.CreateShopifyCompany(ShopifyCompany);
Catalog := CatalogInitialize.CreateCatalog(ShopifyCompany);
CatalogInitialize.CopyParametersFromShop(Catalog, Shop);
InitUnitCost := Any.DecimalInRange(10, 100, 1);
InitPrice := Any.DecimalInRange(2 * InitUnitCost, 4 * InitUnitCost, 1);
InitDiscountPerc := Any.DecimalInRange(5, 20, 1);
Item := ProductInitTest.CreateItem(Shop."Item Templ. Code", InitUnitCost, InitPrice);

// [WHEN] Calculating initial prices without any discounts applied.
ProductPriceCalculation.SetShopAndCatalog(Shop, Catalog);
ProductPriceCalculation.CalcPrice(Item, '', '', UnitCost, Price, ComparePrice);

// [THEN] Verifying initial price settings.
LibraryAssert.AreEqual(InitUnitCost, UnitCost, 'Initial unit cost should match setup.');
LibraryAssert.AreEqual(InitPrice, Price, 'Initial price should match setup without discounts.');
#if CLEAN23
LibrarySales.CreateCustomer(Customer);
CustomerDiscountGroup := ProductInitTest.CreatePriceList(Shop.Code, Item."No.", InitPrice, InitDiscountPerc);
// [GIVEN] Updating catalog with customer-specific discount group details.
Catalog."Customer No." := Customer."No.";
Customer."Customer Disc. Group" := CustomerDiscountGroup.Code;
Customer.Modify();
Catalog.Modify();

// [WHEN] Recalculating prices post-update.
ProductPriceCalculation.SetShopAndCatalog(Shop, Catalog);
ProductPriceCalculation.CalcPrice(Item, '', '', UnitCost, Price, ComparePrice);

// [THEN] Confirming accurate reflection of discount updates in final prices.
LibraryAssert.AreEqual(InitUnitCost, UnitCost, 'Unit cost should remain unchanged post-update.');
LibraryAssert.AreEqual(InitPrice, ComparePrice, 'Compare Price should match initial settings.');
LibraryAssert.AreNearlyEqual(InitPrice * (1 - InitDiscountPerc / 100), Price, 0.01, 'Accurate calculation of discounted price should be verified.');
#endif
end;
}
Loading
Loading