From 1ff7d348797a7dbd701df283a0a0bc3be2e84c1f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Jul 2025 05:36:10 +0000 Subject: [PATCH 1/3] Implement missing fields for prices: customerGroup, validFrom, validUntil, discounted, tiers, custom Co-authored-by: mvantellingen <245297+mvantellingen@users.noreply.github.com> --- src/repositories/product/helpers.test.ts | 292 +++++++++++++++++++++++ src/repositories/product/helpers.ts | 32 +++ 2 files changed, 324 insertions(+) create mode 100644 src/repositories/product/helpers.test.ts diff --git a/src/repositories/product/helpers.test.ts b/src/repositories/product/helpers.test.ts new file mode 100644 index 00000000..80eca230 --- /dev/null +++ b/src/repositories/product/helpers.test.ts @@ -0,0 +1,292 @@ +import type { + CustomerGroupResourceIdentifier, + DiscountedPriceDraft, + PriceDraft, + PriceTierDraft, + ProductDiscountReference, +} from "@commercetools/platform-sdk"; +import { describe, expect, test } from "vitest"; +import { getBaseResourceProperties } from "~src/helpers"; +import { InMemoryStorage } from "~src/storage"; +import type { RepositoryContext } from "../abstract"; +import { priceFromDraft } from "./helpers"; + +describe("priceFromDraft", () => { + const context: RepositoryContext = { + projectKey: "test-project", + }; + const storage = new InMemoryStorage(); + + test("should handle basic price draft without optional fields", () => { + const draft: PriceDraft = { + value: { + currencyCode: "EUR", + centAmount: 1000, + }, + country: "NL", + }; + + const result = priceFromDraft(context, storage, draft); + + expect(result).toMatchObject({ + id: expect.any(String), + country: "NL", + value: { + type: "centPrecision", + currencyCode: "EUR", + centAmount: 1000, + fractionDigits: 2, + }, + }); + expect(result.key).toBeUndefined(); + expect(result.channel).toBeUndefined(); + expect(result.customerGroup).toBeUndefined(); + }); + + test("should handle customerGroup field when provided", () => { + // First create a customer group in storage + const customerGroup = { + ...getBaseResourceProperties(), + id: "customer-group-id", + key: "customer-group-key", + name: "Test Customer Group", + groupName: "Test Group", + }; + storage.add("test-project", "customer-group", customerGroup); + + const customerGroupResourceIdentifier: CustomerGroupResourceIdentifier = { + typeId: "customer-group", + id: "customer-group-id", + }; + + const draft: PriceDraft = { + value: { + currencyCode: "EUR", + centAmount: 1000, + }, + country: "NL", + customerGroup: customerGroupResourceIdentifier, + }; + + const result = priceFromDraft(context, storage, draft); + + expect(result).toMatchObject({ + id: expect.any(String), + country: "NL", + value: { + type: "centPrecision", + currencyCode: "EUR", + centAmount: 1000, + fractionDigits: 2, + }, + customerGroup: { + typeId: "customer-group", + id: "customer-group-id", + }, + }); + }); + + test("should handle validFrom and validUntil fields when provided", () => { + const draft: PriceDraft = { + value: { + currencyCode: "EUR", + centAmount: 1000, + }, + country: "NL", + validFrom: "2023-01-01T00:00:00.000Z", + validUntil: "2023-12-31T23:59:59.999Z", + }; + + const result = priceFromDraft(context, storage, draft); + + expect(result).toMatchObject({ + id: expect.any(String), + country: "NL", + value: { + type: "centPrecision", + currencyCode: "EUR", + centAmount: 1000, + fractionDigits: 2, + }, + validFrom: "2023-01-01T00:00:00.000Z", + validUntil: "2023-12-31T23:59:59.999Z", + }); + }); + + test("should handle tiers field when provided", () => { + const tierDrafts: PriceTierDraft[] = [ + { + minimumQuantity: 5, + value: { + currencyCode: "EUR", + centAmount: 900, + }, + }, + { + minimumQuantity: 10, + value: { + currencyCode: "EUR", + centAmount: 800, + }, + }, + ]; + + const draft: PriceDraft = { + value: { + currencyCode: "EUR", + centAmount: 1000, + }, + country: "NL", + tiers: tierDrafts, + }; + + const result = priceFromDraft(context, storage, draft); + + expect(result).toMatchObject({ + id: expect.any(String), + country: "NL", + value: { + type: "centPrecision", + currencyCode: "EUR", + centAmount: 1000, + fractionDigits: 2, + }, + tiers: [ + { + minimumQuantity: 5, + value: { + type: "centPrecision", + currencyCode: "EUR", + centAmount: 900, + fractionDigits: 2, + }, + }, + { + minimumQuantity: 10, + value: { + type: "centPrecision", + currencyCode: "EUR", + centAmount: 800, + fractionDigits: 2, + }, + }, + ], + }); + }); + + test("should handle discounted field when provided", () => { + // First create a product discount in storage + const productDiscount = { + ...getBaseResourceProperties(), + id: "product-discount-id", + name: { en: "Test Discount" }, + description: { en: "Test Discount Description" }, + value: { + type: "relative" as const, + permyriad: 2000, // 20% discount + }, + predicate: "1=1", + sortOrder: "0.1", + isActive: true, + references: [], + }; + storage.add("test-project", "product-discount", productDiscount); + + const discountedDraft: DiscountedPriceDraft = { + value: { + currencyCode: "EUR", + centAmount: 800, + }, + discount: { + typeId: "product-discount", + id: "product-discount-id", + }, + }; + + const draft: PriceDraft = { + value: { + currencyCode: "EUR", + centAmount: 1000, + }, + country: "NL", + discounted: discountedDraft, + }; + + const result = priceFromDraft(context, storage, draft); + + expect(result).toMatchObject({ + id: expect.any(String), + country: "NL", + value: { + type: "centPrecision", + currencyCode: "EUR", + centAmount: 1000, + fractionDigits: 2, + }, + discounted: { + value: { + type: "centPrecision", + currencyCode: "EUR", + centAmount: 800, + fractionDigits: 2, + }, + discount: { + typeId: "product-discount", + id: "product-discount-id", + }, + }, + }); + }); + + test("should handle custom field when provided", () => { + // First create a type in storage for custom fields + const customType = { + ...getBaseResourceProperties(), + id: "custom-type-id", + key: "custom-type-key", + name: { en: "Custom Type" }, + resourceTypeIds: ["price"], + fieldDefinitions: [], + }; + storage.add("test-project", "type", customType); + + const draft: PriceDraft = { + value: { + currencyCode: "EUR", + centAmount: 1000, + }, + country: "NL", + custom: { + type: { + typeId: "type", + id: "custom-type-id", + }, + fields: { + customField: "customValue", + }, + }, + }; + + const result = priceFromDraft(context, storage, draft); + + expect(result).toMatchObject({ + id: expect.any(String), + country: "NL", + value: { + type: "centPrecision", + currencyCode: "EUR", + centAmount: 1000, + fractionDigits: 2, + }, + custom: { + type: { + typeId: "type", + id: "custom-type-id", + }, + fields: { + customField: "customValue", + }, + }, + }); + }); +}); diff --git a/src/repositories/product/helpers.ts b/src/repositories/product/helpers.ts index b28facd9..19ed699a 100644 --- a/src/repositories/product/helpers.ts +++ b/src/repositories/product/helpers.ts @@ -3,10 +3,16 @@ import type { Asset, AssetDraft, ChannelReference, + CustomerGroupReference, + DiscountedPrice, + DiscountedPriceDraft, Price, PriceDraft, + PriceTier, + PriceTierDraft, Product, ProductData, + ProductDiscountReference, ProductVariant, ProductVariantDraft, } from "@commercetools/platform-sdk"; @@ -113,4 +119,30 @@ export const priceFromDraft = ( storage, ) : undefined, + customerGroup: draft.customerGroup + ? getReferenceFromResourceIdentifier( + draft.customerGroup, + context.projectKey, + storage, + ) + : undefined, + validFrom: draft.validFrom, + validUntil: draft.validUntil, + discounted: draft.discounted + ? { + value: createTypedMoney(draft.discounted.value), + discount: getReferenceFromResourceIdentifier( + draft.discounted.discount, + context.projectKey, + storage, + ), + } + : undefined, + tiers: draft.tiers?.map( + (tier: PriceTierDraft): PriceTier => ({ + minimumQuantity: tier.minimumQuantity, + value: createTypedMoney(tier.value), + }), + ), + custom: createCustomFields(draft.custom, context.projectKey, storage), }); From b7b1afaf54f5aa0ad4f87b18d26735e2274b2248 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 16 Jul 2025 14:57:24 +0000 Subject: [PATCH 2/3] Remove discounted field mapping from priceFromDraft as it should be calculated Co-authored-by: mvantellingen <245297+mvantellingen@users.noreply.github.com> --- .changeset/plain-gifts-cross.md | 5 ++ src/repositories/product/helpers.test.ts | 66 ------------------------ src/repositories/product/helpers.ts | 10 ---- 3 files changed, 5 insertions(+), 76 deletions(-) create mode 100644 .changeset/plain-gifts-cross.md diff --git a/.changeset/plain-gifts-cross.md b/.changeset/plain-gifts-cross.md new file mode 100644 index 00000000..0ad0688c --- /dev/null +++ b/.changeset/plain-gifts-cross.md @@ -0,0 +1,5 @@ +--- +"@labdigital/commercetools-mock": patch +--- + +Remove discounted field mapping from priceFromDraft as it should be calculated diff --git a/src/repositories/product/helpers.test.ts b/src/repositories/product/helpers.test.ts index 80eca230..956b4091 100644 --- a/src/repositories/product/helpers.test.ts +++ b/src/repositories/product/helpers.test.ts @@ -1,9 +1,7 @@ import type { CustomerGroupResourceIdentifier, - DiscountedPriceDraft, PriceDraft, PriceTierDraft, - ProductDiscountReference, } from "@commercetools/platform-sdk"; import { describe, expect, test } from "vitest"; import { getBaseResourceProperties } from "~src/helpers"; @@ -174,70 +172,6 @@ describe("priceFromDraft", () => { }); }); - test("should handle discounted field when provided", () => { - // First create a product discount in storage - const productDiscount = { - ...getBaseResourceProperties(), - id: "product-discount-id", - name: { en: "Test Discount" }, - description: { en: "Test Discount Description" }, - value: { - type: "relative" as const, - permyriad: 2000, // 20% discount - }, - predicate: "1=1", - sortOrder: "0.1", - isActive: true, - references: [], - }; - storage.add("test-project", "product-discount", productDiscount); - - const discountedDraft: DiscountedPriceDraft = { - value: { - currencyCode: "EUR", - centAmount: 800, - }, - discount: { - typeId: "product-discount", - id: "product-discount-id", - }, - }; - - const draft: PriceDraft = { - value: { - currencyCode: "EUR", - centAmount: 1000, - }, - country: "NL", - discounted: discountedDraft, - }; - - const result = priceFromDraft(context, storage, draft); - - expect(result).toMatchObject({ - id: expect.any(String), - country: "NL", - value: { - type: "centPrecision", - currencyCode: "EUR", - centAmount: 1000, - fractionDigits: 2, - }, - discounted: { - value: { - type: "centPrecision", - currencyCode: "EUR", - centAmount: 800, - fractionDigits: 2, - }, - discount: { - typeId: "product-discount", - id: "product-discount-id", - }, - }, - }); - }); - test("should handle custom field when provided", () => { // First create a type in storage for custom fields const customType = { diff --git a/src/repositories/product/helpers.ts b/src/repositories/product/helpers.ts index 19ed699a..1449cf56 100644 --- a/src/repositories/product/helpers.ts +++ b/src/repositories/product/helpers.ts @@ -128,16 +128,6 @@ export const priceFromDraft = ( : undefined, validFrom: draft.validFrom, validUntil: draft.validUntil, - discounted: draft.discounted - ? { - value: createTypedMoney(draft.discounted.value), - discount: getReferenceFromResourceIdentifier( - draft.discounted.discount, - context.projectKey, - storage, - ), - } - : undefined, tiers: draft.tiers?.map( (tier: PriceTierDraft): PriceTier => ({ minimumQuantity: tier.minimumQuantity, From 06da87495919a92a129f71624e06105f254a6357 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 18 Aug 2025 11:03:25 +0000 Subject: [PATCH 3/3] Fix changeset description to properly describe the implemented features Co-authored-by: mvantellingen <245297+mvantellingen@users.noreply.github.com> --- .changeset/plain-gifts-cross.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/plain-gifts-cross.md b/.changeset/plain-gifts-cross.md index 0ad0688c..c87cd4e2 100644 --- a/.changeset/plain-gifts-cross.md +++ b/.changeset/plain-gifts-cross.md @@ -2,4 +2,4 @@ "@labdigital/commercetools-mock": patch --- -Remove discounted field mapping from priceFromDraft as it should be calculated +Implement missing fields for priceFromDraft function: customerGroup, validFrom, validUntil, tiers, and custom fields