Skip to content
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
14 changes: 14 additions & 0 deletions api/queries/storefront.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ const productViewOptionFieldsFragment = gql`
}
`;

/** The fields we retrieve from a ProductViewLink. */
const productViewLinkFieldsFragment = gql`
fragment ProductViewLinkFields on ProductViewLink {
linkTypes
product {
sku
}
}
`;

/** The base fields we retrieve from any Product. */
const productViewBaseFieldsFragment = gql`
fragment ProductViewBaseFields on ProductView {
Expand Down Expand Up @@ -130,6 +140,9 @@ const GET_PRODUCT_DETAILS = gql`
...ProductViewPriceRangeFields
}
}
links {
...ProductViewLinkFields
}
}
}

Expand All @@ -140,6 +153,7 @@ const GET_PRODUCT_DETAILS = gql`
${productViewPriceRangeFieldsFragment}
${productViewOptionFieldsFragment}
${productViewOptionValueFieldsFragment}
${productViewLinkFieldsFragment}
`;

module.exports = {
Expand Down
70 changes: 68 additions & 2 deletions transformers/product.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,56 @@ const transformCustomAttributes = attributes => {
return acoAttributes;
};

/**
* Builds a variant reference ID.
*
* @param {string} masterSku - The master SKU
* @param {string} variantCode - The variant code
* @param {string | number} variantValue - The variant value
* @returns {string} The variant reference ID
*/
function buildVariantReferenceId(masterSku, variantCode, variantValue) {
return `${masterSku}-${variantCode}-${variantValue.toString()}`;
}

/**
* Transforms variationAttributes and masterSku to configurations format
*
* @param {string} masterSku - The master SKU
* @param {Array} variationAttributes - The variation attributes array
* @returns {Array} Array of configuration objects
*/
function transformVariantAttributes(masterSku, variationAttributes) {
if (!Array.isArray(variationAttributes)) return [];
return variationAttributes.map(attr => ({
attributeCode: attr.id,
label: attr.name,
type: 'CONFIGURABLE',
values: Array.isArray(attr.values)
? attr.values.map(v => ({
variantReferenceId: buildVariantReferenceId(masterSku, attr.id, v.value),
label: v.name,
}))
: [],
}));
}

/**
* Transforms variationValues to ACO attribute format
*
* @param {string} masterSku - The master SKU
* @param {object} variationValues - The variation values object
* @returns {Array} Array of ACO attribute objects
*/
function transformVariantValues(masterSku, variationValues) {
if (!variationValues || typeof variationValues !== 'object') return [];
return Object.entries(variationValues).map(([key, value]) => ({
code: key,
values: [value.toString()],
variantReferenceId: buildVariantReferenceId(masterSku, key, value),
}));
}

/**
* Transforms a Salesforce product to an ACO product.
*
Expand Down Expand Up @@ -116,11 +166,27 @@ const transformProduct = product => {
...transformCustomAttributes(product.customAttributes),
],
images: transformImages(product.images),
// TODO: Add links
// TODO: Add configurable product support
// TODO: Add bundle product support
};

//add configurations
if (product.type === 'MASTER') {
acoProduct.configurations = transformVariantAttributes(product.id, product.variationAttributes);
}

if (product.type === 'VARIANT') {
const masterSku = product.master.id;
acoProduct.links = [
{
type: 'variant_of',
sku: masterSku,
},
];

//attributes
acoProduct.attributes.push(...transformVariantValues(masterSku, product.variationValues));
}

// @ts-ignore
return acoProduct;
};
Expand Down
39 changes: 39 additions & 0 deletions types/salesforce.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,19 @@ declare interface SalesforceProduct {
customAttributes: SalesforceProductCustomAttributes[];
creationDate: string;
lastModified: string;
type:
| 'SIMPLE'
| 'MASTER'
| 'VARIANT'
| 'VARIATION_GROUP'
| 'BUNDLE'
| 'BUNDLED'
| 'PRODUCT_SET'
| 'PRODUCT_SET_PRODUCT';
variationAttributes: SalesforceProductVariationAttribute[];
variants?: SalesforceProductVariant[];
variationValues?: SalesforceProductVariationValues;
master?: SalesforceProductMaster;
}

declare interface SalesforceProductPrice {
Expand Down Expand Up @@ -125,3 +138,29 @@ declare interface SalesforceTrackedChanges {
isDeleted: boolean;
lastModified: string;
}

declare interface SalesforceProductVariationAttribute {
id: string;
attributeId: string;
name: string;
values: SalesforceProductVariationAttributeValue[];
}

declare interface SalesforceProductVariationAttributeValue {
description: string;
name: string;
value: string;
}

declare interface SalesforceProductVariant {
productId: string;
variationValues: SalesforceProductVariationValues;
}

declare interface SalesforceProductVariationValues {
[key: string]: unknown;
}

declare interface SalesforceProductMaster {
id: string;
}