{"version":3,"sources":["webpack:///./src/themes/dobbies/actions/utilities/arrayExtensions.ts?7472","webpack:///./src/themes/dobbies/actions/get-availabilities-cartlines.override.action.ts?523c","webpack:///./src/themes/dobbies/actions/get-store-location-information.override.action.ts?73e7","webpack:///./src/themes/dobbies/actions/get-products-in-active-cart.override.action.ts?221c","webpack:///./src/themes/dobbies/actions/utilities/product-inventory-information.ts?34ec","webpack:///./src/themes/dobbies/actions/get-full-available-inventory-nearby.override.action.ts?6d92","webpack:///./src/themes/dobbies/actions/get-product-availabilities-for-selected-variant.override.action.ts?63bc","webpack:///./src/themes/dobbies/actions/update-primary-address.override.action.ts?9ba2","webpack:///external \"React\"?c481","webpack:///./src/themes/dobbies/actions/get-feature-state.override.action.ts?ddfe","webpack:///./src/themes/dobbies/utilities/post-code-restriction/get-restricted-products.tsx?aa6b","webpack:///external \"ReactDOM\"?4b2d","webpack:///./lib/__local__/module-registration.js?8a42","webpack:///./src/themes/dobbies/actions/get-customer-address.action.ts?e710","webpack:///./src/themes/dobbies/actions/get-loyalty-card.override.action.ts?0fcc","webpack:///./src/themes/dobbies/actions/utilities/get-image-url.ts?0b76","webpack:///./src/themes/dobbies/actions/get-selected-variant.override.action.ts?2e07"],"names":["unique","value","Array","from","Set","ProductAvailabilitiesForCartLineItems","constructor","apiSettings","getCacheKey","buildCacheKey","this","getCacheObjectType","dataCacheType","getDeliveryMode","cartLine","featureSate","channelDeliveryOptionConfig","pickupDeliveryMode","DeliveryMode","PickupDeliveryModeCodes","find","deliveryMode","async","getAvailabilitiesForCartLineItems","input","ctx","Error","shippingItems","bopisItems","productAvailabilities","cart","getCartState","channelConfiguration","getOrgUnitConfigurationAsync","callerContext","products","getActiveCartProductsAction","ActiveCartProductsInput","featureState","context","getFeatureStateAction","FeatureStateInput","getFeatureState","retailMultiplePickUpOptionEnabled","item","Name","IsEnabled","getChannelDeliveryOptionConfigurationAsync","PickupDeliveryModeCode","EmailDeliveryModeCode","length","trace","Id","CartLines","push","productIds","map","x","ProductId","requestContext","app","config","maxQuantityForCartLineItem","inStockCode","inStockLabel","vendorShippedProducts","dobbiesPlantsProducts","dobbiesOtherProducts","productsByVendor","_getProductsByTypes","plantsProducts","shippingProductAvailabilites","getShippingProductAvailabilities","ProductWarehouseInventoryAvailabilities","mapProductInventoryInformation","productId","IsProductAvailable","ProductAvailableQuantity","AvailableQuantity","StockLevelCode","StockLevelLabel","InventLocationId","InventLocation","allProductAvailabilities","_getBopisItemAvailability","bopisItem","productWarehouse","WarehouseId","channel","InventLocationDataAreaId","DataAreaId","getProductWarehouseAvail","getEstimatedProductWarehouseAvailabilityAsync","bypassCache","queryResultSettings","productWarehouseMapping","channelId","catalogId","fulfillmentAttributeName","fulfillmentAttributeTextValue","searchCriteriaInput","Context","ChannelId","CatalogId","Ids","IncludeAttributes","searchByCriteriaAsync","product","RecordId","AttributeValues","attributes","isvendorShippedAttribute","attribute","trim","toLowerCase","TextValue","attributeName","toString","attributeTextValue","fulfillmentTypeAttribute","ExtensionProperties","uniqueProductList","otherProductAvailablities","getEstimatedAvailabilityAsync","ProductIds","DefaultWarehouseOnly","plantsProductAvailablities","FilterByChannelFulfillmentGroup","plantProduct","accumulatedInventorySum","warehouseIdsForFulfillment","accumulatedProductPhysicalAvailable","fulfillmentStores","filter","availability","store","PhysicalAvailable","getAccumulatedTotalAvailable","productInventoryAvailability","_mapToWarehouseInventoryAvailability","error","telemetry","totalAvailable","outOfStockCode","outOfStockLabel","PhysicalInventory","TotalAvailable","TotalAvailableInventoryLevelLabel","TotalAvailableInventoryLevelCode","PhysicalAvailableInventoryLevelLabel","PhysicalAvailableInventoryLevelCode","createObservableDataAction","id","action","inputData","GetOrgUnitLocationsByAreaInput","_Latitude","_Longitude","_Radius","_DistanceUnitValue","_IgnoreLocation","Latitude","Longitude","Radius","DistanceUnitValue","IgnoreLocation","createGetOrgUnitLocationsByAreaInput","getOrgUnitLocationsByArea","undefined","searchArea","retailMulitplePickupMFeatureState","getOrgUnitLocationsByAreaAsync","then","alphabeticallySortedStores","stores","sort","a","b","OrgUnitName","localeCompare","locationDeliveryOptions","orgUnitChannel","channelCollection","channelIdList","getChannelDeliveryOptionsAsync","channelDeliveryOptions","catch","message","exception","debug","_getLocationPickUpDeliveryModes","locationPromiseList","locationDeliveryOption","_channeldeliveryoption","orgUnitLocation","channelDeleiveryOptions","OrgUnitNumber","OrgUnitAvailability","getStoreHoursAsync","hours","OrgUnitLocation","OrgUnitPickUpDeliveryModes","StoreHours","_getLocationWithHours","Promise","all","cartState","defaultOrderQuantityLimitsFeatureConfig","platform","enableDefaultOrderQuantityLimits","resolve","featureStates","createGetFeatureStateInput","isQuantityLimitsFeatureEnabledInHq","ArrayExtensions","hasElements","getCustomer","GetCustomerInput","customerInfo","IsB2b","warning","isOrderQuantityLimitsFeatureEnabled","productIdsByWarehouseId","Map","resultProducts","forEach","has","get","set","entryWarehouseId","entryProductIds","getSimpleProducts","ProductInput","Boolean","reduce","accum","getActiveCartProductsActionWhenQuantityLimitsFeatureIsOn","hasInvoiceLine","productWithVendorInfo","_getProductsVendorInfo","actionContext","productsData","restrictedProducts","getRestrictedProducts","restrictedInfo","Key","Value","BooleanValue","isVendorShiped","extensionProperties","selectedAttributes","isVendorNameAvailable","selectedAttribute","commercePropertyValue","StringValue","commerceProperty","vendorname","estimatedShippingTime","InventoryLevels","GetFullAvailableInventoryNearbyInput","_productId","_latitude","_longitude","_radius","_ExcludeLocations","latitude","longitude","radius","ExcludeLocations","createGetFullAvailableInventoryNearbyInput","getFullAvailableInventoryNearbyAction","searchCriteria","createInventoryAvailabilitySearchCriteria","pickup","productInventoryInformation","productWarehouseInformation","DeliveryModeTypeFilter","None","storeMap","InventoryLocationId","excludedStores","availabilityPromiseList","includes","itemAvailabilities","element","ItemAvailabilities","ProductInventoryInformation","_getAvailabilityWithHours","getFullAvailableInventoryNearbyActionDataAction","ProductAvailabilitiesForSelectedVariantInput","createProductAvailabilitiesForSelectedVariantInput","getSelectedProductIdFromActionInput","getProductAvailabilitiesForSelectedVariantAction","selectedVariantInput","SelectedVariantInput","getSelectedVariant","productResult","ItemTypeValue","productAttributes","getAttributeValuesAsync","isVendorShipAttribute","vendorShipProductInventory","isPlantCategory","response","accumulatedAvailability","getAccumulatedAvailability","mergeProductWarehouseToProductAvailabities","productsWarehouseInventory","productAvailable","accumulatedProductCount","mapWarehouseAvailabilityForAccumulatedCount","productAvailability","updatePrimaryAddressHandler","customer","address","Addresses","setPrimaryAddress","updatePrimaryAddressAction","readAsync","updatedCustomer","updateAsync","update","updatePrimaryAddressActionDataAction","createAddressManagementInput","isBatched","primaryAddresses","addresses","addr","IsPrimary","module","exports","React","featureNames","getFeatureStatesAsync","getFeatureStateActionDataAction","attr","KeyName","JSON","parse","RestrictedPostCode","ReactDOM","binding","modules","dataActions","registerActionId","actionPath","default","prototype","Object","keys","exportName","Action","require","window","__bindings__","packageDataActions","GetCustomerAddressInput","Msdyn365","args","GetLoyaltyCardInput","userAccountNumber","createGetLoyaltyCardInput","user","isAuthenticated","customerAccountNumber","getLoyaltyAction","getCustomerLoyaltyCardsAsync","cards","tempCard","card","CardTenderTypeValue","firstCard","getLoyaltyCardAsync","CardNumber","LoyaltyEnrollmentDate","LoyaltyEnrollmentDateLocal","getLoyaltyActionDataAction","generateProductImageUrl","imageUrl","startsWith","baseImageUrl","encodeURIComponent","generateImageUrl","PrimaryImageUrl","matchingDimensionValues","getByIdAsync","baseProduct","isArray","baseProductHadUnmatchedDimension","Dimensions","dimension","matchedTargetDimension","targetDimension","DimensionTypeValue","DimensionValue","variants","getVariantsByDimensionValuesAsync","defaultComponent","getDefaultComponentsAsync","variantsByComponent","getVariantsByComponentsInSlotsAsync","variantId","simpleProduct","updatedKitProduct","Description","newImageUrl"],"mappings":"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","file":"static/js/19.3aff5cbd837dddc0d99a.chunk.js","sourcesContent":["/*\r\n* @name - unique\r\n* @description - Remove duplicate elements in the array.\r\n* @export\r\n* @public\r\n* @param {array} value - The array to examine.\r\n* @returns {array} - An array with only unique elements.\r\n*/\r\nexport function unique(value: T[]): T[] {\r\n return Array.from(new Set(value));\r\n}","import {\r\n ActiveCartProductsInput,\r\n buildCacheKey,\r\n getActiveCartProductsAction,\r\n IProductInventoryInformation,\r\n mapProductInventoryInformation\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\n\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICommerceApiSettings,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\nimport { getCartState } from '@msdyn365-commerce/global-state';\r\nimport {\r\n CartLine,\r\n ChannelDeliveryOptionConfiguration,\r\n FeatureState,\r\n ProductSearchCriteria,\r\n ProductWarehouse,\r\n ProductWarehouseInventoryInformation\r\n} from '@msdyn365-commerce/retail-proxy';\r\nimport { getOrgUnitConfigurationAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/OrgUnitsDataActions.g';\r\nimport {\r\n getEstimatedAvailabilityAsync,\r\n getEstimatedProductWarehouseAvailabilityAsync,\r\n searchByCriteriaAsync\r\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { getChannelDeliveryOptionConfigurationAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\r\nimport { ProductWarehouseInventoryAvailability } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\nimport { FeatureStateInput, getFeatureStateAction } from './get-feature-state.override.action';\r\nimport { unique } from './utilities';\r\n/**\r\n * Input class for availabilites for items in cart\r\n */\r\nexport class ProductAvailabilitiesForCartLineItems implements IActionInput {\r\n private apiSettings: ICommerceApiSettings;\r\n\r\n constructor(apiSettings: ICommerceApiSettings) {\r\n this.apiSettings = apiSettings;\r\n }\r\n\r\n public getCacheKey = () => buildCacheKey(`ActiveCartLineItemsAvailability`, this.apiSettings);\r\n public getCacheObjectType = () => 'ActiveCartLineItemsAvailability';\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\nconst createInput = (inputData: ICreateActionContext>) => {\r\n return new ProductAvailabilitiesForCartLineItems(inputData.requestContext.apiSettings);\r\n};\r\n\r\n/**\r\n * Calls the Retail API to get the product availabilites for items in the cart\r\n */\r\n/* Upgraded to 10.0.20 - START */\r\n/**\r\n * Calls the Retail Feature State API and returns a list of feature with isEnabled flag.\r\n */\r\nconst getDeliveryMode = (\r\n cartLine: CartLine,\r\n featureSate: boolean = false,\r\n channelDeliveryOptionConfig: ChannelDeliveryOptionConfiguration,\r\n pickupDeliveryMode?: string\r\n) => {\r\n if (!featureSate) {\r\n return cartLine.DeliveryMode === pickupDeliveryMode;\r\n }\r\n return (\r\n cartLine.DeliveryMode ===\r\n channelDeliveryOptionConfig?.PickupDeliveryModeCodes?.find(deliveryMode => deliveryMode === cartLine.DeliveryMode)\r\n );\r\n};\r\n\r\n/* Upgraded to 10.0.20 - END */\r\nexport async function getAvailabilitiesForCartLineItems(\r\n input: ProductAvailabilitiesForCartLineItems,\r\n ctx: IActionContext\r\n): Promise {\r\n // If no input is provided fail out\r\n if (!input) {\r\n throw new Error('[getAvailabilitiesForCartLineItems]No valid Input was provided, failing');\r\n }\r\n const shippingItems: CartLine[] = [];\r\n const bopisItems: CartLine[] = [];\r\n\r\n let productAvailabilities: IProductInventoryInformation[] = [];\r\n const multiplePickupStoreSwitchName = 'Dynamics.AX.Application.RetailMultiplePickupDeliveryModeFeature';\r\n let channelDeliveryOptionConfig: any;\r\n\r\n const cartState = await getCartState(ctx);\r\n const cart = cartState.cart;\r\n const channelConfiguration = await getOrgUnitConfigurationAsync({ callerContext: ctx });\r\n const products = await getActiveCartProductsAction(new ActiveCartProductsInput(), ctx);\r\n /* Upgraded to 10.0.20 - START */\r\n /**\r\n * Calls the Retail Feature State API and returns a list of feature with isEnabled flag.\r\n */\r\n async function getFeatureState(context: IActionContext): Promise {\r\n return getFeatureStateAction(new FeatureStateInput(), context);\r\n }\r\n const featureState = await getFeatureState(ctx);\r\n const retailMultiplePickUpOptionEnabled = featureState?.find(item => item.Name === multiplePickupStoreSwitchName)?.IsEnabled;\r\n if (retailMultiplePickUpOptionEnabled) {\r\n channelDeliveryOptionConfig = await getChannelDeliveryOptionConfigurationAsync({ callerContext: ctx });\r\n }\r\n /* Upgraded to 10.0.20 - END */\r\n const PickupDeliveryModeCode = channelConfiguration.PickupDeliveryModeCode;\r\n const EmailDeliveryModeCode = channelConfiguration.EmailDeliveryModeCode; // Upgraded to 10.0.16\r\n if (!cart || !channelConfiguration || !products || products.length === 0) {\r\n ctx.trace('[getAvailabilitiesForCartLineItems] Not able to get cart OR channelConfiguration or no products in cart');\r\n return [];\r\n }\r\n\r\n if (cart && cart.Id && cart.CartLines && cart.CartLines.length > 0 && channelConfiguration) {\r\n for (const cartLine of cart.CartLines) {\r\n if (\r\n cartLine.DeliveryMode &&\r\n cartLine.DeliveryMode !== '' &&\r\n getDeliveryMode(cartLine, retailMultiplePickUpOptionEnabled, channelDeliveryOptionConfig, PickupDeliveryModeCode)\r\n ) {\r\n bopisItems.push(cartLine);\r\n } else if (cartLine.DeliveryMode !== EmailDeliveryModeCode) {\r\n shippingItems.push(cartLine);\r\n }\r\n }\r\n }\r\n\r\n if (shippingItems && shippingItems.length > 0) {\r\n let productIds = shippingItems.map(x => x.ProductId!);\r\n productIds = unique(productIds);\r\n\r\n /* VSI Customization - START - 21/12/20 */\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { maxQuantityForCartLineItem, inStockCode, inStockLabel }\r\n }\r\n }\r\n } = ctx;\r\n\r\n let vendorShippedProducts: number[] = []; // List of vendorShip products\r\n let dobbiesPlantsProducts: number[] = []; // List of Dobbies plants products\r\n let dobbiesOtherProducts: number[] = []; // List of Dobbies all products except plants\r\n\r\n if (productIds.length > 0) {\r\n // First divide products into 2 categories to not call getEstimatedAvailabilityAsync for vendorShip items but just for dobbies products\r\n const productsByVendor = await _getProductsByTypes(ctx, productIds);\r\n vendorShippedProducts = productsByVendor.vendorShippedProducts;\r\n dobbiesPlantsProducts = productsByVendor.plantsProducts;\r\n dobbiesOtherProducts = productsByVendor.dobbiesOtherProducts;\r\n }\r\n\r\n const shippingProductAvailabilites = await getShippingProductAvailabilities(ctx, dobbiesOtherProducts, dobbiesPlantsProducts);\r\n\r\n if (\r\n shippingProductAvailabilites &&\r\n shippingProductAvailabilites.ProductWarehouseInventoryAvailabilities &&\r\n shippingProductAvailabilites.ProductWarehouseInventoryAvailabilities.length > 0\r\n ) {\r\n productAvailabilities = mapProductInventoryInformation(\r\n ctx,\r\n shippingProductAvailabilites.ProductWarehouseInventoryAvailabilities\r\n );\r\n }\r\n\r\n // Set maxQuantityForCartLineItem as limit for vendorShip items\r\n vendorShippedProducts.map(productId => {\r\n // Now map it into IProductInventoryInformation type\r\n productAvailabilities.push({\r\n IsProductAvailable: true,\r\n ProductAvailableQuantity: { ProductId: productId, AvailableQuantity: maxQuantityForCartLineItem },\r\n StockLevelCode: inStockCode,\r\n StockLevelLabel: inStockLabel,\r\n InventLocationId: channelConfiguration.InventLocation\r\n });\r\n });\r\n /* VSI Customization - END */\r\n }\r\n // Add bopis item availability\r\n const allProductAvailabilities = await _getBopisItemAvailability(ctx, productAvailabilities, bopisItems);\r\n\r\n if (allProductAvailabilities && allProductAvailabilities.length > 0) {\r\n return allProductAvailabilities;\r\n }\r\n\r\n ctx.trace('[getAvailabilitiesForCartLineItems] unable to get availabilites for product');\r\n return [];\r\n}\r\n\r\n/**\r\n * The function that returns the sum of all warehousees' PhysicalAvailable for plants Category\r\n */\r\nconst getAccumulatedTotalAvailable = (\r\n ctx: IActionContext,\r\n ProductWarehouseInventoryAvailabilities: ProductWarehouseInventoryAvailability[],\r\n productId: number\r\n) => {\r\n // Just check inventory in warehouseIdsForFulfillment\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { warehouseIdsForFulfillment }\r\n }\r\n }\r\n } = ctx;\r\n\r\n let accumulatedProductPhysicalAvailable = 0;\r\n const fulfillmentStores: string[] | undefined = warehouseIdsForFulfillment; // ['S011', 'S040']\r\n\r\n // First find product's warehouse Info in ProductWarehouseInventoryAvailabilities and then calculates their inventory's sum\r\n ProductWarehouseInventoryAvailabilities.filter(availability => {\r\n // First check if it is one of the warehouseIdsForFulfillment, only then add inventory\r\n const isFulfillmentStore =\r\n fulfillmentStores &&\r\n fulfillmentStores.find(store => {\r\n return availability.InventLocationId && availability.InventLocationId.toLowerCase() === store.toLowerCase();\r\n });\r\n\r\n return isFulfillmentStore && availability && availability.ProductId === productId;\r\n }).map(availability => {\r\n if (availability.PhysicalAvailable) {\r\n accumulatedProductPhysicalAvailable += availability.PhysicalAvailable;\r\n }\r\n });\r\n\r\n // Now just create an object with this product availability info and returns it\r\n return accumulatedProductPhysicalAvailable;\r\n};\r\n\r\n/* Following function checks inventory for bopis items */\r\nconst _getBopisItemAvailability = async (\r\n ctx: IActionContext,\r\n productAvailabilities: IProductInventoryInformation[],\r\n bopisItems: CartLine[]\r\n): Promise => {\r\n if (bopisItems && bopisItems.length > 0) {\r\n for (const bopisItem of bopisItems) {\r\n const productWarehouse: ProductWarehouse = {\r\n ProductId: bopisItem.ProductId,\r\n InventLocationId: bopisItem.WarehouseId\r\n };\r\n\r\n if (ctx.requestContext.channel && ctx.requestContext.channel.InventLocationDataAreaId) {\r\n productWarehouse.DataAreaId = ctx.requestContext.channel.InventLocationDataAreaId;\r\n }\r\n const getProductWarehouseAvail = await getEstimatedProductWarehouseAvailabilityAsync(\r\n { callerContext: ctx, bypassCache: 'get', queryResultSettings: {} },\r\n [productWarehouse]\r\n );\r\n if (\r\n getProductWarehouseAvail &&\r\n getProductWarehouseAvail.ProductWarehouseInventoryAvailabilities &&\r\n getProductWarehouseAvail.ProductWarehouseInventoryAvailabilities.length > 0\r\n ) {\r\n const productWarehouseMapping = mapProductInventoryInformation(\r\n ctx,\r\n getProductWarehouseAvail && getProductWarehouseAvail.ProductWarehouseInventoryAvailabilities\r\n );\r\n if (productWarehouseMapping && productWarehouseMapping.length) {\r\n for (const item of productWarehouseMapping) {\r\n productAvailabilities.push(item);\r\n }\r\n }\r\n }\r\n }\r\n return productAvailabilities;\r\n }\r\n return productAvailabilities;\r\n};\r\n\r\n/* Following function divides products into 3 categories 1. VendorShipProducts 2. DobbiesPlantProducts 3. DobbiesAllOtherProducts */\r\nconst _getProductsByTypes = async (\r\n ctx: IActionContext,\r\n productIds: number[]\r\n): Promise<{\r\n vendorShippedProducts: number[];\r\n plantsProducts: number[];\r\n dobbiesOtherProducts: number[];\r\n}> => {\r\n const vendorShippedProducts: number[] = [];\r\n const plantsProducts: number[] = [];\r\n const dobbiesOtherProducts: number[] = [];\r\n\r\n const callerContext = ctx;\r\n const {\r\n requestContext: {\r\n apiSettings: { channelId, catalogId },\r\n app: {\r\n config: { fulfillmentAttributeName, fulfillmentAttributeTextValue }\r\n }\r\n }\r\n } = ctx;\r\n const searchCriteriaInput: ProductSearchCriteria = {};\r\n searchCriteriaInput.Context = { ChannelId: channelId, CatalogId: catalogId };\r\n searchCriteriaInput.Ids = productIds;\r\n searchCriteriaInput.IncludeAttributes = true;\r\n // store product IDs in vendorShippedProducts array if product is vendor shipped\r\n const productsData = await searchByCriteriaAsync({ callerContext, queryResultSettings: {} }, searchCriteriaInput);\r\n productsData.map(product => {\r\n const { RecordId, AttributeValues } = product;\r\n const attributes = AttributeValues;\r\n const isvendorShippedAttribute =\r\n attributes &&\r\n attributes.find(attribute => {\r\n const attributeName = attribute.Name && attribute.Name.trim().toLowerCase();\r\n return attributeName === 'isvendershipproduct';\r\n });\r\n const isVendorShipped =\r\n isvendorShippedAttribute &&\r\n isvendorShippedAttribute.TextValue &&\r\n isvendorShippedAttribute.TextValue.trim().toLowerCase() === 'yes';\r\n if (isVendorShipped) {\r\n vendorShippedProducts.push(RecordId);\r\n } else {\r\n const attributeName = fulfillmentAttributeName\r\n ? fulfillmentAttributeName\r\n .toString()\r\n .toLowerCase()\r\n .trim()\r\n : 'fulfillmenttype';\r\n const attributeTextValue = fulfillmentAttributeTextValue\r\n ? fulfillmentAttributeTextValue\r\n .toString()\r\n .toLowerCase()\r\n .trim()\r\n : 'plants';\r\n\r\n const fulfillmentTypeAttribute = attributes && attributes.find(attribute => attribute?.Name?.toLowerCase() === attributeName);\r\n const isPlantFulfillment = fulfillmentTypeAttribute && fulfillmentTypeAttribute.TextValue?.toLowerCase() === attributeTextValue;\r\n if (isPlantFulfillment) {\r\n plantsProducts.push(RecordId);\r\n } else {\r\n dobbiesOtherProducts.push(RecordId);\r\n }\r\n }\r\n });\r\n\r\n return {\r\n vendorShippedProducts: vendorShippedProducts,\r\n plantsProducts: plantsProducts,\r\n dobbiesOtherProducts: dobbiesOtherProducts\r\n };\r\n};\r\n\r\n/* Following function uses 2 separate call to check availability\r\n * For plants products (fulfillment category), get availability from all warehouses with filtered by FilterByChannelFulfillmentGroup\r\n * For all other products of dobbies, check inventory from default warehouse only */\r\nconst getShippingProductAvailabilities = async (\r\n ctx: IActionContext,\r\n dobbiesOtherProducts: number[],\r\n dobbiesPlantsProducts: number[]\r\n): Promise => {\r\n try {\r\n let shippingProductAvailabilites: ProductWarehouseInventoryInformation = {\r\n ProductWarehouseInventoryAvailabilities: [],\r\n ExtensionProperties: []\r\n };\r\n\r\n if (dobbiesOtherProducts && dobbiesOtherProducts.length && dobbiesOtherProducts.length > 0) {\r\n const uniqueProductList = unique(dobbiesOtherProducts);\r\n const otherProductAvailablities = await getEstimatedAvailabilityAsync(\r\n { callerContext: ctx, bypassCache: 'get' },\r\n { ProductIds: uniqueProductList, DefaultWarehouseOnly: true }\r\n );\r\n\r\n if (\r\n otherProductAvailablities.ProductWarehouseInventoryAvailabilities &&\r\n otherProductAvailablities.ProductWarehouseInventoryAvailabilities.length > 0\r\n ) {\r\n shippingProductAvailabilites = otherProductAvailablities;\r\n }\r\n }\r\n if (dobbiesPlantsProducts && dobbiesPlantsProducts.length && dobbiesPlantsProducts.length > 0) {\r\n // Now call for plants products\r\n const uniqueProductList = unique(dobbiesPlantsProducts);\r\n const plantsProductAvailablities = await getEstimatedAvailabilityAsync(\r\n { callerContext: ctx, bypassCache: 'get' },\r\n { ProductIds: uniqueProductList, DefaultWarehouseOnly: false, FilterByChannelFulfillmentGroup: true }\r\n );\r\n\r\n if (\r\n plantsProductAvailablities.ProductWarehouseInventoryAvailabilities &&\r\n plantsProductAvailablities.ProductWarehouseInventoryAvailabilities.length > 0\r\n ) {\r\n // Get ProductWarehouseInventoryAvailabilities as a sum of all warehouse inventory for this product and use it\r\n uniqueProductList.map(plantProduct => {\r\n // Get accumulated inventory for each of product and map into an object of ProductWarehouseInventoryAvailability type\r\n const accumulatedInventorySum = plantsProductAvailablities.ProductWarehouseInventoryAvailabilities\r\n ? getAccumulatedTotalAvailable(\r\n ctx,\r\n plantsProductAvailablities.ProductWarehouseInventoryAvailabilities,\r\n plantProduct\r\n )\r\n : 0;\r\n\r\n // Now map it into ProductWarehouseInventoryAvailability type\r\n const productInventoryAvailability = _mapToWarehouseInventoryAvailability(ctx, plantProduct, accumulatedInventorySum);\r\n\r\n // Now add it into shippingProductAvailabilites\r\n shippingProductAvailabilites.ProductWarehouseInventoryAvailabilities?.push(productInventoryAvailability);\r\n });\r\n }\r\n }\r\n\r\n return shippingProductAvailabilites;\r\n } catch (error) {\r\n ctx.telemetry.trace(error);\r\n }\r\n return {};\r\n};\r\n\r\n/**\r\n * The function returns an object of ProductWarehouseInventoryAvailability using\r\n */\r\nconst _mapToWarehouseInventoryAvailability = (\r\n ctx: IActionContext,\r\n productId: number,\r\n totalAvailable: number\r\n): ProductWarehouseInventoryAvailability => {\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { inStockCode, inStockLabel, outOfStockCode, outOfStockLabel }\r\n }\r\n }\r\n } = ctx;\r\n\r\n return {\r\n InventLocationId: 'ECOM',\r\n ProductId: productId,\r\n PhysicalInventory: 0,\r\n TotalAvailable: totalAvailable,\r\n TotalAvailableInventoryLevelLabel: totalAvailable > 0 ? inStockLabel : outOfStockLabel,\r\n TotalAvailableInventoryLevelCode: totalAvailable > 0 ? inStockCode : outOfStockCode,\r\n PhysicalAvailable: totalAvailable,\r\n PhysicalAvailableInventoryLevelLabel: totalAvailable > 0 ? inStockLabel : outOfStockLabel,\r\n PhysicalAvailableInventoryLevelCode: totalAvailable > 0 ? inStockCode : outOfStockCode\r\n };\r\n};\r\n/* VSI Customization - END */\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-availabilities-cartlines',\r\n action: >getAvailabilitiesForCartLineItems,\r\n input: createInput\r\n});\r\n","import { IFullOrgUnitAvailability } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { CacheType, createObservableDataAction, IAction, IActionContext, IActionInput, IAny, ICreateActionContext, IGeneric } from '@msdyn365-commerce/core';\r\nimport { ChannelDeliveryOption, FeatureState, OrgUnitAvailability, OrgUnitLocation, SearchArea, StoreHours } from '@msdyn365-commerce/retail-proxy';\r\nimport { getChannelDeliveryOptionsAsync, getOrgUnitLocationsByAreaAsync, getStoreHoursAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/OrgUnitsDataActions.g';\r\nimport { FeatureStateInput, getFeatureStateAction } from './get-feature-state.override.action';\r\n\r\n/**\r\n * Get selected variant action input class\r\n */\r\nexport class GetOrgUnitLocationsByAreaInput implements IActionInput {\r\n public Latitude?: number;\r\n public Longitude?: number;\r\n public Radius?: number;\r\n public DistanceUnitValue?: number;\r\n public IgnoreLocation?: boolean;\r\n\r\n constructor(_Latitude?: number, _Longitude?: number, _Radius?: number, _DistanceUnitValue?: number, _IgnoreLocation?: boolean) {\r\n this.Latitude = _Latitude;\r\n this.Longitude = _Longitude;\r\n this.Radius = _Radius;\r\n this.DistanceUnitValue = _DistanceUnitValue;\r\n this.IgnoreLocation = _IgnoreLocation;\r\n }\r\n\r\n public getCacheKey = () => `GetOrgUnitLocationsByAreaInput`;\r\n public getCacheObjectType = () => 'GetOrgUnitLocationsByAreaInput';\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\n/**\r\n * CreateInput method for the getSelectedVariant data action\r\n * @param inputData The input data passed to the createInput method\r\n */\r\nexport const createGetOrgUnitLocationsByAreaInput = (inputData: ICreateActionContext>): GetOrgUnitLocationsByAreaInput => {\r\n return new GetOrgUnitLocationsByAreaInput();\r\n};\r\n/* Upgraded to 10.0.16 - START */\r\n/**\r\n * Calls the Retail Feature State API and returns a list of feature with isEnabled flag.\r\n */\r\nexport async function getFeatureState(context: IActionContext): Promise {\r\n return getFeatureStateAction(new FeatureStateInput(), context);\r\n}\r\n/* Upgraded to 10.0.16 - END */\r\n/**\r\n * Action method for the getSelectedVariant data action\r\n * @param input The action input class\r\n * @param ctx The action context\r\n */\r\nexport async function getOrgUnitLocationsByArea(\r\n input: GetOrgUnitLocationsByAreaInput,\r\n ctx: IActionContext\r\n): Promise {\r\n\r\n if ((input.Radius === undefined || !input.Latitude || !input.Longitude) && !input.IgnoreLocation) {\r\n // No valid location we want to return empty array so module can show no locations message\r\n return [];\r\n }\r\n\r\n const searchArea: SearchArea = {\r\n Latitude: input.Latitude,\r\n Longitude: input.Longitude,\r\n Radius: input.Radius,\r\n DistanceUnitValue: input.DistanceUnitValue || 0 // 0 is miles\r\n };\r\n /* Upgraded to 10.0.16 - START */\r\n const featureState = await getFeatureState(ctx);\r\n const retailMulitplePickupMFeatureState = featureState?.find(item => item.Name === 'Dynamics.AX.Application.RetailMultiplePickupDeliveryModeFeature')?.IsEnabled;\r\n /* Upgraded to 10.0.16 - END */\r\n return getOrgUnitLocationsByAreaAsync({ callerContext: ctx }, searchArea)\r\n .then(async (stores: OrgUnitLocation[]) => {\r\n // VSI-Customization START - stores sorted in alphabetically order.\r\n const alphabeticallySortedStores = stores?.sort((a, b) => a.OrgUnitName!.localeCompare(b.OrgUnitName!));\r\n // VSI-Customization END\r\n /* Upgraded to 10.0.16 - START */\r\n /* const locationPromiseList = alphabeticallySortedStores.map(store => _getLocationWithHours(store, ctx)); */\r\n let locationDeliveryOptions: ChannelDeliveryOption[] | undefined = [];\r\n // if mulitple pickup mode is enable then call getchanneldeliveryoption\r\n if (retailMulitplePickupMFeatureState) {\r\n const orgUnitChannel = alphabeticallySortedStores.map(store => store.ChannelId);\r\n locationDeliveryOptions = await _getLocationPickUpDeliveryModes(orgUnitChannel, ctx);\r\n }\r\n const locationPromiseList = alphabeticallySortedStores.map(store => {\r\n const locationDeliveryOption = locationDeliveryOptions?.find(_channeldeliveryoption => _channeldeliveryoption.ChannelId === store.ChannelId);\r\n return _getLocationWithHours(store, locationDeliveryOption, ctx);\r\n });\r\n /* Upgraded to 10.0.16 - END */\r\n return Promise.all(locationPromiseList);\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace('[GetOrgUnitLocationsByArea] error getting Locations');\r\n ctx.trace(error.message);\r\n ctx.telemetry.error(error.message);\r\n ctx.telemetry.debug(`[GetOrgUnitLocationsByArea] error getting Locations`);\r\n return [];\r\n });\r\n}\r\n\r\n/**\r\n * Action method that obtains the store information\r\n * @param orgUnitLocation The org unit location\r\n * @param storeMap a map that contains store information group by the inventory location id\r\n * @param ctx The action context\r\n */\r\nasync function _getLocationWithHours(\r\n orgUnitLocation: OrgUnitLocation,\r\n channelDeleiveryOptions: ChannelDeliveryOption | undefined, // Upgraded to 10.0.16\r\n ctx: IActionContext): Promise {\r\n if (!orgUnitLocation || !orgUnitLocation.OrgUnitNumber) {\r\n return { OrgUnitAvailability: undefined };\r\n }\r\n\r\n return getStoreHoursAsync({ callerContext: ctx }, orgUnitLocation.OrgUnitNumber)\r\n .then((hours: StoreHours) => {\r\n\r\n const availability: OrgUnitAvailability = {\r\n OrgUnitLocation: orgUnitLocation\r\n };\r\n\r\n if (hours && !(hours instanceof Error)) {\r\n return {\r\n OrgUnitAvailability: availability, StoreHours: hours,\r\n OrgUnitPickUpDeliveryModes: channelDeleiveryOptions /* Upgraded to 10.0.16 */\r\n };\r\n }\r\n\r\n return {\r\n OrgUnitAvailability: availability,\r\n OrgUnitPickUpDeliveryModes: channelDeleiveryOptions /* Upgraded to 10.0.16 */\r\n };\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace('[GetFullAvailableInventoryNearby] error getting availability with hours');\r\n ctx.trace(error.message);\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug(`[GetFullAvailableInventoryNearby] error getting availability with hours`);\r\n return { OrgUnitAvailability: {} };\r\n });\r\n}\r\n/* Upgraded to 10.0.16 - START */\r\n/**\r\n * Action method that obtains the store information\r\n * @param channelCollection The org unit channel Id list\r\n * @param ctx The action context\r\n */\r\nasync function _getLocationPickUpDeliveryModes(\r\n channelCollection: (number | undefined)[],\r\n ctx: IActionContext): Promise {\r\n if (channelCollection?.length === 0 || channelCollection === undefined) {\r\n return undefined;\r\n }\r\n const channelIdList: number[] = [];\r\n channelCollection?.map(id => {\r\n if (id !== undefined) {\r\n channelIdList.push(id);\r\n }\r\n });\r\n // to get all channel pickup delivery mode filterOption should be 4\r\n return getChannelDeliveryOptionsAsync({ callerContext: ctx }, channelIdList, 4)\r\n .then((channelDeliveryOptions: ChannelDeliveryOption[]) => {\r\n if (channelDeliveryOptions && !(channelDeliveryOptions instanceof Error)) {\r\n return channelDeliveryOptions;\r\n }\r\n return undefined;\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace('[GetFullAvailableInventoryNearby][getChannelDeliveryOptionsAsync] error getting availability with channel delivery options');\r\n ctx.trace(error.message);\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug(`[GetFullAvailableInventoryNearby] [getChannelDeliveryOptionsAsync] error getting availability with channel delivery options`);\r\n return [];\r\n });\r\n}\r\n/* Upgraded to 10.0.16 - END */\r\n/**\r\n * The complete getOrgUnitLocationsByArea data action\r\n */\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-store-location-information',\r\n action: >getOrgUnitLocationsByArea,\r\n input: createGetOrgUnitLocationsByAreaInput\r\n});","import {\r\n getSimpleProducts,\r\n ProductInput,\r\n createGetFeatureStateInput,\r\n getCustomer,\r\n GetCustomerInput,\r\n getFeatureState,\r\n ArrayExtensions\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n ICreateActionContext\r\n} from '@msdyn365-commerce/core';\r\nimport { getCartState } from '@msdyn365-commerce/global-state';\r\nimport { CommerceProperty, CommercePropertyValue, ProductSearchCriteria, FeatureState } from '@msdyn365-commerce/retail-proxy';\r\nimport { searchByCriteriaAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { Cart, SimpleProduct } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\nimport { getRestrictedProducts } from '../utilities/post-code-restriction/get-restricted-products';\r\n/**\r\n * Input class for activeCartWithProducts data action\r\n */\r\nexport class ActiveCartProductsInput implements IActionInput {\r\n public getCacheKey = () => `ActiveCartProducts`;\r\n public getCacheObjectType = () => 'ActiveCartProducts';\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\nconst createInput = (inputData: ICreateActionContext) => {\r\n return new ActiveCartProductsInput();\r\n};\r\n\r\n/**\r\n * Calls the Retail API and returns a cart object based on the passed GetCartInput\r\n * @param input\r\n * @param ctx\r\n */\r\nexport async function getActiveCartProductsAction(input: ActiveCartProductsInput, ctx: IActionContext): Promise {\r\n // If no cart ID is provided in input, we need to create a cart object\r\n if (!input) {\r\n throw new Error('[getActiveCartWithProducts]No valid Input was provided, failing');\r\n }\r\n\r\n const cartState = await getCartState(ctx);\r\n const cart = cartState.cart;\r\n\r\n const isQuantityLimitsFeatureIsOn: boolean = await isOrderQuantityLimitsFeatureEnabled(ctx);\r\n\r\n if (isQuantityLimitsFeatureIsOn) {\r\n return getActiveCartProductsActionWhenQuantityLimitsFeatureIsOn(cart, ctx);\r\n }\r\n\r\n // If there are cart lines, make call to get products\r\n if (!cartState.hasInvoiceLine && cart && cart.CartLines && cart.CartLines.length > 0) {\r\n ctx.trace('Getting cart product information...');\r\n return getSimpleProducts(\r\n cart.CartLines.map(cartLine => {\r\n if (cartLine.ProductId) {\r\n return new ProductInput(cartLine.ProductId, ctx.requestContext.apiSettings);\r\n }\r\n return undefined;\r\n }).filter(Boolean),\r\n ctx\r\n )\r\n .then((products: SimpleProduct[]) => {\r\n if (products) {\r\n /* VSI Customization - START - 15/12/20 */\r\n const productWithVendorInfo = _getProductsVendorInfo(ctx, products);\r\n if (productWithVendorInfo) {\r\n return productWithVendorInfo;\r\n }\r\n return products;\r\n /* VSI Customization - END */\r\n } else {\r\n return [];\r\n }\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace(error.toString());\r\n ctx.telemetry.error(error.message);\r\n ctx.telemetry.debug(`[getActiveCartWithProducts]Unable to hydrate cart with product information`);\r\n throw new Error('[getActiveCartWithProducts]Unable to hydrate cart with product information');\r\n });\r\n }\r\n\r\n ctx.trace('[getActiveCartWithProducts]No Products Found in cart');\r\n return [];\r\n}\r\n/* VSI Customization - START - 15/12/20 */\r\nconst _getProductsVendorInfo = async (actionContext: IActionContext, products: SimpleProduct[]) => {\r\n const callerContext = actionContext;\r\n const {\r\n requestContext: {\r\n apiSettings: { channelId, catalogId }\r\n }\r\n } = actionContext;\r\n if (products) {\r\n const searchCriteriaInput: ProductSearchCriteria = {};\r\n searchCriteriaInput.Context = { ChannelId: channelId, CatalogId: catalogId };\r\n const productIds: number[] = [];\r\n products.map(product => {\r\n productIds.push(product.RecordId);\r\n });\r\n searchCriteriaInput.Ids = productIds;\r\n searchCriteriaInput.IncludeAttributes = true;\r\n const productsData = await searchByCriteriaAsync({ callerContext, queryResultSettings: {} }, searchCriteriaInput);\r\n // Get restricted products list\r\n const restrictedProducts = getRestrictedProducts(productsData);\r\n productsData.map(product => {\r\n // Check if it is restricted product, add it in its ExtensionProperties\r\n const isRestrictedProduct = restrictedProducts.find(productId => productId === product.RecordId);\r\n const restrictedInfo: CommerceProperty = { Key: 'isRestrictedProduct', Value: { BooleanValue: !!isRestrictedProduct } };\r\n\r\n const attributes = product.AttributeValues;\r\n const isvendorShippedAttribute =\r\n attributes &&\r\n attributes.find(attribute => {\r\n const attributeName = attribute.Name && attribute.Name.trim().toLowerCase();\r\n return attributeName === 'isvendershipproduct'; // \"IsVendershipProduct\"\r\n });\r\n const isVendorShiped =\r\n isvendorShippedAttribute &&\r\n isvendorShippedAttribute.TextValue &&\r\n isvendorShippedAttribute.TextValue.trim().toLowerCase() === 'yes';\r\n const extensionProperties: CommerceProperty[] = [];\r\n if (isVendorShiped) {\r\n const selectedAttributes =\r\n attributes &&\r\n attributes.filter(attribute => {\r\n const attributeName = attribute.Name && attribute.Name.trim().toLowerCase();\r\n const isVendorNameAvailable = attribute.TextValue; // if vendor name is not undefined\r\n return (\r\n attributeName &&\r\n isVendorNameAvailable &&\r\n (attributeName === 'vendorname' || attributeName === 'estimatedshippingtime')\r\n );\r\n });\r\n if (selectedAttributes && selectedAttributes.length > 0) {\r\n selectedAttributes &&\r\n selectedAttributes.map(selectedAttribute => {\r\n const commercePropertyValue: CommercePropertyValue = { StringValue: selectedAttribute.TextValue };\r\n const commerceProperty: CommerceProperty = { Key: selectedAttribute.Name, Value: commercePropertyValue };\r\n extensionProperties.push(commerceProperty);\r\n });\r\n } else {\r\n const vendorname: CommerceProperty = { Key: 'vendorname', Value: { StringValue: 'Not Available' } };\r\n const estimatedShippingTime: CommerceProperty = {\r\n Key: 'estimatedshippingtime',\r\n Value: { StringValue: 'Not Available' }\r\n };\r\n extensionProperties.push(vendorname);\r\n extensionProperties.push(estimatedShippingTime);\r\n }\r\n } else {\r\n const vendorname: CommerceProperty = { Key: 'vendorname', Value: { StringValue: undefined } };\r\n const estimatedShippingTime: CommerceProperty = { Key: 'estimatedshippingtime', Value: { StringValue: undefined } };\r\n extensionProperties.push(vendorname);\r\n extensionProperties.push(estimatedShippingTime);\r\n }\r\n // Add restricted info against each cartLine\r\n extensionProperties.push(restrictedInfo);\r\n product.ExtensionProperties = extensionProperties;\r\n });\r\n return productsData;\r\n }\r\n return [];\r\n};\r\n/* VSI Customizatoin - END */\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-products-in-active-cart',\r\n action: >getActiveCartProductsAction,\r\n input: createInput\r\n});\r\n\r\nasync function getActiveCartProductsActionWhenQuantityLimitsFeatureIsOn(cart: Cart, ctx: IActionContext): Promise {\r\n const productIdsByWarehouseId: Map = new Map();\r\n let resultProducts: SimpleProduct[] = [];\r\n cart.CartLines?.forEach(cartLine =>\r\n productIdsByWarehouseId.has(cartLine.WarehouseId!)\r\n ? productIdsByWarehouseId.get(cartLine.WarehouseId!)?.push(cartLine.ProductId!)\r\n : productIdsByWarehouseId.set(cartLine.WarehouseId!, [cartLine.ProductId!])\r\n );\r\n return Promise.all(\r\n [...productIdsByWarehouseId].map(([entryWarehouseId, entryProductIds]) => {\r\n return getSimpleProducts(\r\n entryProductIds\r\n .map(productId => {\r\n if (productId) {\r\n return new ProductInput(productId, ctx.requestContext.apiSettings, undefined, entryWarehouseId);\r\n }\r\n return undefined;\r\n })\r\n .filter(Boolean),\r\n ctx\r\n ).then((products: SimpleProduct[]) => {\r\n if (products) {\r\n resultProducts = products.reduce((accum, product) => {\r\n if (product) {\r\n accum.push(product);\r\n }\r\n return accum;\r\n }, resultProducts);\r\n }\r\n });\r\n })\r\n ).then(() => resultProducts);\r\n}\r\n\r\nasync function isOrderQuantityLimitsFeatureEnabled(ctx: IActionContext): Promise {\r\n const defaultOrderQuantityLimitsFeatureConfig = ctx.requestContext.app?.platform?.enableDefaultOrderQuantityLimits;\r\n if (defaultOrderQuantityLimitsFeatureConfig === 'none') {\r\n return Promise.resolve(false);\r\n }\r\n\r\n const featureStates = await getFeatureState(createGetFeatureStateInput(ctx), ctx);\r\n let isQuantityLimitsFeatureEnabledInHq = false;\r\n if (ArrayExtensions.hasElements(featureStates)) {\r\n isQuantityLimitsFeatureEnabledInHq =\r\n featureStates.find(\r\n (featureState: FeatureState) => featureState.Name === 'Dynamics.AX.Application.RetailDefaultOrderQuantityLimitsFeature'\r\n )?.IsEnabled || false;\r\n }\r\n\r\n if (!isQuantityLimitsFeatureEnabledInHq) {\r\n return false;\r\n }\r\n\r\n if (defaultOrderQuantityLimitsFeatureConfig === 'all') {\r\n return Promise.resolve(true);\r\n }\r\n\r\n return getCustomer(new GetCustomerInput(ctx.requestContext.apiSettings), ctx)\r\n .then(customerInfo => {\r\n return (\r\n !!customerInfo &&\r\n ((defaultOrderQuantityLimitsFeatureConfig === 'b2b' && customerInfo.IsB2b) ||\r\n (defaultOrderQuantityLimitsFeatureConfig === 'b2c' && !customerInfo.IsB2b))\r\n );\r\n })\r\n .catch((error: Error) => {\r\n ctx.telemetry.warning(error.message);\r\n ctx.telemetry.debug('Unable to get customer info');\r\n return false;\r\n });\r\n}\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt in the project root for license information.\r\n *--------------------------------------------------------------*/\r\n\r\nimport { ProductAvailableQuantity } from '@msdyn365-commerce/retail-proxy';\r\n\r\n/**\r\n * This setting defines the delivery modes supported.\r\n */\r\nexport enum DeliveryMode {\r\n allWareHouses = 0,\r\n shipping = 1,\r\n pickup = 2\r\n}\r\n\r\n/**\r\n * This setting defines the inventory levels supported.\r\n */\r\nexport enum InventoryLevels {\r\n physicalAvailable = 'physicalAvailable',\r\n totalAvailable = 'totalAvailable',\r\n threshold = 'threshold'\r\n}\r\n\r\n/**\r\n * Product inventory information class.\r\n */\r\nexport interface IProductInventoryInformation {\r\n ProductAvailableQuantity: ProductAvailableQuantity;\r\n StockLevelCode?: string;\r\n StockLevelLabel?: string;\r\n IsProductAvailable: boolean;\r\n InventLocationId?: string;\r\n deliveryType?: DeliveryMode;\r\n}\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt in the project root for license information.\r\n *--------------------------------------------------------------*/\r\n\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\nimport {\r\n ChannelDeliveryOption,\r\n FeatureState,\r\n DeliveryModeTypeFilter,\r\n ItemAvailability,\r\n OrgUnitAvailability,\r\n OrgUnitLocation,\r\n ProductWarehouseInventoryInformation,\r\n SearchArea,\r\n StoreHours\r\n} from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n getChannelDeliveryOptionsAsync,\r\n getOrgUnitLocationsByAreaAsync,\r\n getStoreHoursAsync\r\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/OrgUnitsDataActions.g';\r\nimport { getEstimatedAvailabilityAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { IFullOrgUnitAvailability } from './utilities/full-org-unit-availability';\r\nimport { DeliveryMode, IProductInventoryInformation } from './utilities/product-inventory-information';\r\nimport { FeatureStateInput, getFeatureStateAction } from './get-feature-state.override.action';\r\nimport { createInventoryAvailabilitySearchCriteria, mapProductInventoryInformation } from '@msdyn365-commerce-modules/retail-actions';\r\n\r\n/**\r\n * Get selected variant action input class.\r\n */\r\nexport class GetFullAvailableInventoryNearbyInput implements IActionInput {\r\n public latitude?: number;\r\n\r\n public longitude?: number;\r\n\r\n public radius?: number;\r\n\r\n public productId?: number;\r\n\r\n public DistanceUnitValue?: number;\r\n\r\n public IgnoreLocation?: boolean;\r\n\r\n public ExcludeLocations?: (number | undefined)[];\r\n\r\n constructor(\r\n _productId?: number,\r\n _latitude?: number,\r\n _longitude?: number,\r\n _radius?: number,\r\n _DistanceUnitValue?: number,\r\n _IgnoreLocation?: boolean,\r\n _ExcludeLocations?: (number | undefined)[]\r\n ) {\r\n this.productId = _productId;\r\n this.latitude = _latitude;\r\n this.longitude = _longitude;\r\n this.radius = _radius;\r\n this.DistanceUnitValue = _DistanceUnitValue;\r\n this.IgnoreLocation = _IgnoreLocation;\r\n this.ExcludeLocations = _ExcludeLocations;\r\n }\r\n\r\n public getCacheKey = () => 'GetFullAvailableInventoryNearbyInputCache';\r\n\r\n public getCacheObjectType = () => 'GetFullAvailableInventoryNearbyInput';\r\n\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\n/**\r\n * CreateInput method for the getSelectedVariant data action.\r\n * @param inputData - The input data passed to the createInput method.\r\n * @returns GetFullAvailableInventoryNearbyInput - The action input.\r\n */\r\nexport const createGetFullAvailableInventoryNearbyInput = (\r\n inputData: ICreateActionContext>\r\n): GetFullAvailableInventoryNearbyInput => {\r\n return new GetFullAvailableInventoryNearbyInput();\r\n};\r\n\r\n/**\r\n * Calls the Retail Feature State API and returns a list of feature with isEnabled flag.\r\n * @param context - The context.\r\n * @returns FeatureState - The feature state.\r\n */\r\nexport async function getFeatureState(context: IActionContext): Promise {\r\n return getFeatureStateAction(new FeatureStateInput(), context);\r\n}\r\n\r\n/**\r\n * Action method for the getSelectedVariant data aciton.\r\n * @param input - The action input class.\r\n * @param ctx - The action context.\r\n * @returns IFullOrgUnitAvailability - The full org unit availability.\r\n */\r\nexport async function getFullAvailableInventoryNearbyAction(\r\n input: GetFullAvailableInventoryNearbyInput,\r\n ctx: IActionContext\r\n): Promise {\r\n // No valid product we want to return undefined so module knows there are no results yet\r\n if (!input.productId) {\r\n return undefined;\r\n }\r\n\r\n if (((!input.radius && input.radius !== 0) || !input.latitude || !input.longitude) && !input.IgnoreLocation) {\r\n // No valid location we want to return empty array so module can show no locations message\r\n return [];\r\n }\r\n\r\n const searchArea: SearchArea = {\r\n Latitude: input.latitude,\r\n Longitude: input.longitude,\r\n Radius: input.radius,\r\n DistanceUnitValue: input.DistanceUnitValue || 0 // 0 is miles\r\n };\r\n\r\n const featureState = await getFeatureState(ctx);\r\n const retailMulitplePickupMFeatureState = featureState?.find(\r\n item => item.Name === 'Dynamics.AX.Application.RetailMultiplePickupDeliveryModeFeature'\r\n )?.IsEnabled;\r\n const searchCriteria = createInventoryAvailabilitySearchCriteria(ctx, [input.productId], false, true, searchArea, DeliveryMode.pickup);\r\n return getEstimatedAvailabilityAsync({ callerContext: ctx }, searchCriteria)\r\n .then(async (productWarehouseInformation: ProductWarehouseInventoryInformation) => {\r\n // For store selector, inventory should always come from an individual store\r\n const productInventoryInformation = mapProductInventoryInformation(\r\n ctx,\r\n productWarehouseInformation.ProductWarehouseInventoryAvailabilities\r\n );\r\n return getOrgUnitLocationsByAreaAsync({ callerContext: ctx }, searchArea, DeliveryModeTypeFilter.None)\r\n .then(async (stores: OrgUnitLocation[]) => {\r\n // Constructing a store mapping based on the InventoryId.\r\n const storeMap = new Map();\r\n stores.forEach(store => {\r\n if (store.InventoryLocationId) {\r\n storeMap.set(store.InventoryLocationId, store);\r\n }\r\n });\r\n\r\n let locationDeliveryOptions: ChannelDeliveryOption[] | undefined = [];\r\n\r\n // If multiple pickup mode is enable then call getchanneldeliveryoption\r\n if (retailMulitplePickupMFeatureState) {\r\n const orgUnitChannel = stores.map(store => store.ChannelId);\r\n locationDeliveryOptions = await _getLocationPickUpDeliveryModes(orgUnitChannel, ctx);\r\n }\r\n\r\n const excludedStores = input.ExcludeLocations ?? [];\r\n const filteredStores = stores\r\n .filter(store => !excludedStores.includes(store.ChannelId))\r\n .sort((a, b) => a.OrgUnitName!.localeCompare(b.OrgUnitName!));\r\n const availabilityPromiseList = filteredStores.map(store => {\r\n const locationDeliveryOption = locationDeliveryOptions?.find(\r\n _channeldeliveryoption => _channeldeliveryoption.ChannelId === store.ChannelId\r\n );\r\n return _getAvailabilityWithHours(store, productInventoryInformation, storeMap, ctx, locationDeliveryOption);\r\n });\r\n\r\n return Promise.all(availabilityPromiseList);\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace('[GetFullAvailableInventoryNearby] error getting Available Inventory Nearby');\r\n ctx.trace(error.message);\r\n ctx.telemetry.error(error.message);\r\n ctx.telemetry.debug('[GetFullAvailableInventoryNearby] error getting Available Inventory Nearby');\r\n return [];\r\n });\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace(\r\n '[GetFullAvailableInventoryNearby][getEstimatedAvailabilityAsync] error getting availability product warehouse information.'\r\n );\r\n ctx.trace(error.message);\r\n ctx.telemetry.error(error.message);\r\n ctx.telemetry.debug(\r\n '[GetFullAvailableInventoryNearby][getEstimatedAvailabilityAsync] error getting availability product warehouse information.'\r\n );\r\n return [];\r\n });\r\n}\r\n\r\n/**\r\n * Action method that obtains the store information along with store hours and product availability.\r\n * @param orgUnitLocation - The org unit location.\r\n * @param productInventoryInformation - The product inventory information.\r\n * @param storeMap - A map that contains store information group by the inventory location id.\r\n * @param ctx The action context.\r\n * @param channelDeleiveryOptions - The channel delivery options.\r\n * @returns IFullOrgUnitAvailability - The full org unit availability.\r\n */\r\nasync function _getAvailabilityWithHours(\r\n orgUnitLocation: OrgUnitLocation,\r\n productInventoryInformation: IProductInventoryInformation[],\r\n storeMap: Map,\r\n ctx: IActionContext,\r\n channelDeleiveryOptions: ChannelDeliveryOption | undefined\r\n): Promise {\r\n if (!orgUnitLocation || !orgUnitLocation.OrgUnitNumber) {\r\n return { OrgUnitAvailability: undefined };\r\n }\r\n\r\n return getStoreHoursAsync({ callerContext: ctx }, orgUnitLocation.OrgUnitNumber)\r\n .then((hours: StoreHours) => {\r\n const itemAvailabilities: ItemAvailability[] = [];\r\n if (productInventoryInformation && storeMap) {\r\n productInventoryInformation.forEach(element => {\r\n if (\r\n element.InventLocationId &&\r\n storeMap.has(element.InventLocationId) &&\r\n element.InventLocationId === orgUnitLocation.InventoryLocationId\r\n ) {\r\n itemAvailabilities.push({ AvailableQuantity: element.ProductAvailableQuantity?.AvailableQuantity });\r\n }\r\n });\r\n }\r\n\r\n const availability: OrgUnitAvailability = {\r\n OrgUnitLocation: orgUnitLocation,\r\n ItemAvailabilities: itemAvailabilities\r\n };\r\n\r\n if (hours && !(hours instanceof Error)) {\r\n return {\r\n OrgUnitAvailability: availability,\r\n StoreHours: hours,\r\n ProductInventoryInformation: productInventoryInformation,\r\n OrgUnitPickUpDeliveryModes: channelDeleiveryOptions\r\n };\r\n }\r\n\r\n return {\r\n OrgUnitAvailability: availability,\r\n ProductInventoryInformation: productInventoryInformation,\r\n OrgUnitPickUpDeliveryModes: channelDeleiveryOptions\r\n };\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace('[GetFullAvailableInventoryNearby] error getting availability with hours');\r\n ctx.trace(error.message);\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug('[GetFullAvailableInventoryNearby] error getting availability with hours');\r\n return { OrgUnitAvailability: {} };\r\n });\r\n}\r\n\r\n/**\r\n * Action method that obtains the channel delivery option information.\r\n * @param channelCollection - The org unit channel Id list.\r\n * @param ctx - The action context.\r\n * @returns ChannelDeliveryOption - The channel delivery option collection.\r\n */\r\nasync function _getLocationPickUpDeliveryModes(\r\n channelCollection: (number | undefined)[],\r\n ctx: IActionContext\r\n): Promise {\r\n if (channelCollection?.length === 0 || channelCollection === undefined) {\r\n return undefined;\r\n }\r\n\r\n const channelIdList: number[] = [];\r\n channelCollection?.map(id => {\r\n if (id !== undefined) {\r\n channelIdList.push(id);\r\n }\r\n });\r\n\r\n // To get all channel pickup delivery mode filterOption should be 4\r\n return getChannelDeliveryOptionsAsync({ callerContext: ctx }, channelIdList, 4)\r\n .then((channelDeliveryOptions: ChannelDeliveryOption[]) => {\r\n if (channelDeliveryOptions && !(channelDeliveryOptions instanceof Error)) {\r\n return channelDeliveryOptions;\r\n }\r\n\r\n return undefined;\r\n })\r\n .catch((error: Error) => {\r\n ctx.trace(\r\n '[GetFullAvailableInventoryNearby][getChannelDeliveryOptionsAsync] error getting availability with channel delivery options'\r\n );\r\n ctx.trace(error.message);\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug(\r\n '[GetFullAvailableInventoryNearby] [getChannelDeliveryOptionsAsync] error getting availability with channel delivery options'\r\n );\r\n return [];\r\n });\r\n}\r\n\r\n/**\r\n * The complete getFullAvailableInventoryNearby data action.\r\n */\r\nexport const getFullAvailableInventoryNearbyActionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-full-available-inventory-nearby',\r\n action: >getFullAvailableInventoryNearbyAction,\r\n input: createGetFullAvailableInventoryNearbyInput\r\n});\r\n\r\nexport default getFullAvailableInventoryNearbyActionDataAction;\r\n","import {\r\n getSelectedProductIdFromActionInput,\r\n getSelectedVariant,\r\n IProductInventoryInformation,\r\n mapProductInventoryInformation,\r\n SelectedVariantInput\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\nimport { ProductWarehouseInventoryAvailability, ReleasedProductType } from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n getAttributeValuesAsync,\r\n getEstimatedAvailabilityAsync\r\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { ProductAvailableQuantity } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\n/**\r\n * Input class for the getProductAvailabilitiesForSelectedVariant Data Action\r\n */\r\nexport class ProductAvailabilitiesForSelectedVariantInput implements IActionInput {\r\n public productId: number;\r\n public channelId: number;\r\n\r\n constructor(productId: number | string, channelId: number) {\r\n this.productId = typeof productId === 'string' ? +productId : productId;\r\n this.channelId = channelId;\r\n }\r\n\r\n public getCacheKey = () => `ProductAvailabilitiesForSelectedVariant`;\r\n public getCacheObjectType = () => 'ProductAvailabilities';\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\n/**\r\n * createInput method for the getProductAvailabilitiesForSelectedVariant data action.\r\n * @param inputData The input data passed to the createInput method\r\n */\r\nexport const createProductAvailabilitiesForSelectedVariantInput = (\r\n inputData: ICreateActionContext>\r\n): ProductAvailabilitiesForSelectedVariantInput => {\r\n const productId = getSelectedProductIdFromActionInput(inputData);\r\n\r\n if (productId) {\r\n return new ProductAvailabilitiesForSelectedVariantInput(+productId, +inputData.requestContext.apiSettings.channelId);\r\n } else {\r\n throw new Error('Unable to create ProductAvailabilitiesForSelectedVariantInput, no productId found on module config or query');\r\n }\r\n};\r\n\r\n/**\r\n * The action method for the getProductAvailabilitiesForSelectedVariant data action\r\n */\r\n// tslint:disable-next-line: max-func-body-length\r\nexport async function getProductAvailabilitiesForSelectedVariantAction(\r\n input: ProductAvailabilitiesForSelectedVariantInput,\r\n ctx: IActionContext\r\n): Promise {\r\n const selectedVariantInput = new SelectedVariantInput(input.productId, input.channelId);\r\n /* Upgraded to 10.0.16 - START */\r\n // tslint:disable-next-line:prefer-type-cast\r\n const PRODUCTASSERVICE = 2 as ReleasedProductType.Service;\r\n /* Upgraded to 10.0.16 - END */\r\n return getSelectedVariant(selectedVariantInput, ctx)\r\n .then(async productResult => {\r\n if (\r\n productResult &&\r\n /* Upgraded to 10.0.16 - START - Add following condition */\r\n // As we just have master products only so will comment this condition\r\n productResult.ItemTypeValue !== PRODUCTASSERVICE /* && productResult.ProductTypeValue !== ProductType.Master */\r\n /* Upgraded to 10.0.16 - END */\r\n ) {\r\n try {\r\n /* VSI Customization - START - 09/04/21 */\r\n // Check if product is vendorShipped we dont need getEstimatedAvailabilityAsync call as we'll just display instock with maxCartLineQty limit\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { maxQuantityForCartLineItem, fulfillmentAttributeName, fulfillmentAttributeTextValue }\r\n }\r\n }\r\n } = ctx;\r\n\r\n let productInventoryInformation: IProductInventoryInformation[];\r\n\r\n // Make vendorShip products in stock by default\r\n const productAttributes = await getAttributeValuesAsync(\r\n { callerContext: ctx },\r\n input.productId,\r\n input.channelId,\r\n ctx.requestContext.apiSettings.catalogId\r\n );\r\n const isVendorShipAttribute = productAttributes.find(attribute => {\r\n const attributeName = attribute.Name && attribute.Name.trim().toLowerCase();\r\n return attributeName === 'isvendershipproduct';\r\n });\r\n\r\n if (\r\n isVendorShipAttribute &&\r\n isVendorShipAttribute.TextValue &&\r\n isVendorShipAttribute.TextValue.toLowerCase() === 'yes'\r\n ) {\r\n const vendorShipProductInventory: IProductInventoryInformation[] = [];\r\n\r\n vendorShipProductInventory.push({\r\n IsProductAvailable: true,\r\n ProductAvailableQuantity: {\r\n AvailableQuantity: maxQuantityForCartLineItem,\r\n ProductId: productResult.RecordId\r\n }\r\n });\r\n\r\n return vendorShipProductInventory;\r\n } else {\r\n const attributeName = fulfillmentAttributeName\r\n ? fulfillmentAttributeName\r\n .toString()\r\n .toLowerCase()\r\n .trim()\r\n : 'fulfillmenttype';\r\n const attributeTextValue = fulfillmentAttributeTextValue\r\n ? fulfillmentAttributeTextValue\r\n .toString()\r\n .toLowerCase()\r\n .trim()\r\n : 'plants';\r\n\r\n const fulfillmentTypeAttribute =\r\n productAttributes &&\r\n productAttributes.find(attribute => {\r\n return attribute?.Name?.toLowerCase() === attributeName;\r\n });\r\n const isPlantFulfillment =\r\n fulfillmentTypeAttribute && fulfillmentTypeAttribute.TextValue?.toLowerCase() === attributeTextValue;\r\n const isPlantCategory = isPlantFulfillment ? true : false;\r\n /* VSI Customization - END - 09/04/21 */\r\n return getEstimatedAvailabilityAsync(\r\n { callerContext: ctx },\r\n {\r\n ProductIds: [productResult.RecordId],\r\n DefaultWarehouseOnly: !isPlantCategory,\r\n FilterByChannelFulfillmentGroup: isPlantCategory\r\n }\r\n ).then(async response => {\r\n if (\r\n response &&\r\n response.ProductWarehouseInventoryAvailabilities &&\r\n response.ProductWarehouseInventoryAvailabilities.length\r\n ) {\r\n if (isPlantCategory) {\r\n // Get ProductWarehouseInventoryAvailabilities as a sum of all warehouse inventory and use it\r\n const accumulatedAvailability = getAccumulatedAvailability(\r\n ctx,\r\n response.ProductWarehouseInventoryAvailabilities\r\n );\r\n\r\n productInventoryInformation = mapProductInventoryInformation(ctx, accumulatedAvailability);\r\n } else {\r\n productInventoryInformation = mapProductInventoryInformation(\r\n ctx,\r\n response.ProductWarehouseInventoryAvailabilities\r\n );\r\n }\r\n }\r\n /* VSI Customization - END */\r\n return productInventoryInformation;\r\n });\r\n }\r\n } catch (error) {\r\n ctx.trace(error.message);\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug(`[getEstimatedAvailabilityAsync]Error executing action`);\r\n throw new Error('[getEstimatedAvailabilityAsync]Error executing action');\r\n }\r\n }\r\n return [];\r\n })\r\n .catch((error: Error) => {\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- can't assign type to the error variable.\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug('[getPriceForSelectedVariantAction]Error executing action');\r\n return undefined;\r\n });\r\n}\r\n\r\n/**\r\n * The function that maps a ProductWareHouse object into a ProductAvailabilityQuantity\r\n */\r\nexport function mergeProductWarehouseToProductAvailabities(\r\n productsWarehouseInventory: ProductWarehouseInventoryAvailability[]\r\n): ProductAvailableQuantity[] {\r\n const productAvailable: ProductAvailableQuantity[] = [];\r\n if (productsWarehouseInventory && productsWarehouseInventory.length > 0) {\r\n for (const product of productsWarehouseInventory) {\r\n if (product.TotalAvailable !== undefined && product.ProductId !== undefined) {\r\n productAvailable.push({ ProductId: product.ProductId, AvailableQuantity: product.TotalAvailable });\r\n }\r\n }\r\n }\r\n return productAvailable;\r\n}\r\n\r\n/**\r\n * The function that adds all warehouse's PhysicalAvailable for plants Category and return that ProductWarehouseInventoryAvailabilities\r\n */\r\nconst getAccumulatedAvailability = (\r\n ctx: IActionContext,\r\n ProductWarehouseInventoryAvailabilities: ProductWarehouseInventoryAvailability[]\r\n) => {\r\n // Just check inventory in warehouseIdsForFulfillment\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { warehouseIdsForFulfillment }\r\n }\r\n }\r\n } = ctx;\r\n\r\n let accumulatedProductCount = 0;\r\n const fulfillmentStores: string[] | undefined = warehouseIdsForFulfillment; // ['S011', 'S040']\r\n // We'll just check the PhysicalAvailable for plants fulfillment\r\n ProductWarehouseInventoryAvailabilities.filter(availability => {\r\n // First check if it is one of the warehouseIdsForFulfillment, only then add inventory\r\n return (\r\n fulfillmentStores &&\r\n fulfillmentStores.find(store => {\r\n return availability.InventLocationId && availability.InventLocationId.toLowerCase() === store.toLowerCase();\r\n })\r\n );\r\n }).map(availability => {\r\n if (availability.PhysicalAvailable) {\r\n accumulatedProductCount += availability.PhysicalAvailable;\r\n }\r\n });\r\n // Now just create an object with this product availability info and returns it\r\n return mapWarehouseAvailabilityForAccumulatedCount(ctx, ProductWarehouseInventoryAvailabilities, accumulatedProductCount);\r\n};\r\n\r\n/**\r\n * The function that creates an object of type ProductWarehouseInventoryAvailability with new provided accumulatedProductCount\r\n * and return it as an array of type\r\n */\r\nconst mapWarehouseAvailabilityForAccumulatedCount = (\r\n ctx: IActionContext,\r\n ProductWarehouseInventoryAvailabilities: ProductWarehouseInventoryAvailability[],\r\n accumulatedProductCount: number\r\n): ProductWarehouseInventoryAvailability[] => {\r\n // Use labels from app.settings for both in stock & out of stock cases\r\n const {\r\n requestContext: {\r\n app: {\r\n config: { inStockCode, inStockLabel, outOfStockCode, outOfStockLabel }\r\n }\r\n }\r\n } = ctx;\r\n\r\n const productAvailability = ProductWarehouseInventoryAvailabilities[0];\r\n\r\n return [\r\n {\r\n ProductId: productAvailability.ProductId,\r\n DataAreaId: productAvailability.DataAreaId,\r\n PhysicalInventory: 0,\r\n TotalAvailable: accumulatedProductCount,\r\n TotalAvailableInventoryLevelLabel: accumulatedProductCount > 0 ? inStockLabel : outOfStockCode,\r\n TotalAvailableInventoryLevelCode: accumulatedProductCount > 0 ? inStockCode : outOfStockLabel,\r\n PhysicalAvailable: accumulatedProductCount,\r\n PhysicalAvailableInventoryLevelLabel: accumulatedProductCount > 0 ? inStockLabel : outOfStockLabel,\r\n PhysicalAvailableInventoryLevelCode: accumulatedProductCount > 0 ? inStockCode : outOfStockCode\r\n }\r\n ];\r\n};\r\n/*** The complete getProductAvailabilitiesForSelectedVariant data action\r\n * Get the currently selected variant via the getSelectedVariant data action, and\r\n * then gets the availabilities for the variant via the getProductAvailabilities RetailServer API\r\n ****/\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-product-availabilities-for-selected-variant',\r\n action: >getProductAvailabilitiesForSelectedVariantAction,\r\n input: createProductAvailabilitiesForSelectedVariantInput\r\n});\r\n","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt in the project root for license information.\r\n *--------------------------------------------------------------*/\r\n\r\nimport { createObservableDataAction, IAction, IActionContext, IActionInput, IAny, ICreateActionContext } from '@msdyn365-commerce/core';\r\nimport {\r\n readAsync, updateAsync\r\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/CustomersDataActions.g';\r\nimport { Address, Customer } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\n\r\nimport { IAddressManagementInput } from '@msdyn365-commerce-modules/retail-actions/dist/types/add-address';\r\n\r\n// @ts-ignore\r\nimport { GetCustomerInput } from '@msdyn365-commerce-modules/retail-actions/dist/lib/get-customer';\r\n\r\n// @ts-ignore\r\nimport { createAddressManagementInput } from '@msdyn365-commerce-modules/retail-actions/dist/lib/add-address';\r\n\r\nexport function updatePrimaryAddressHandler(customer: Customer, address: Address): Customer {\r\n customer.Addresses = setPrimaryAddress({ ...address }, [...(customer.Addresses || [])]);\r\n return customer;\r\n}\r\n\r\nexport async function updatePrimaryAddressAction(input: IAddressManagementInput, ctx: IActionContext): Promise {\r\n const { address } = input;\r\n\r\n const customer = await readAsync({ callerContext: ctx, bypassCache: 'get' }, '');\r\n\r\n if (!customer) {\r\n throw new Error('Unable to find customer');\r\n }\r\n\r\n customer.Addresses = setPrimaryAddress({ ...address }, [...(customer.Addresses ?? [])]);\r\n const updatedCustomer = await updateAsync({ callerContext: ctx }, customer);\r\n\r\n if (!updatedCustomer) {\r\n throw new Error('Unable to update customer');\r\n }\r\n\r\n ctx.update(new GetCustomerInput(ctx.requestContext.apiSettings), updatedCustomer);\r\n\r\n return updatedCustomer.Addresses || [];\r\n}\r\n\r\n/**\r\n * The updatePrimaryAddress data action\r\n * Calls the read RetailServer API to get information about a customer\r\n * Merge the passed address information with the address information from\r\n * the retireved customer, and then updates that customer via the update RetailServer API.\r\n */\r\nexport const updatePrimaryAddressActionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/update-primary-address',\r\n action: >updatePrimaryAddressAction,\r\n input: <(args: ICreateActionContext) => IActionInput>(createAddressManagementInput),\r\n isBatched: false\r\n});\r\nexport default updatePrimaryAddressActionDataAction;\r\n\r\nconst setPrimaryAddress = (primaryAddresses: Address, addresses: Address[]): Address[] => {\r\n return addresses.map(addr => {\r\n if (addr.RecordId === primaryAddresses.RecordId) {\r\n addr.IsPrimary = true;\r\n } else {\r\n addr.IsPrimary = false;\r\n }\r\n return addr;\r\n });\r\n};","module.exports = React;","import {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\nimport { FeatureState } from '@msdyn365-commerce/retail-proxy';\r\n\r\nimport { getFeatureStatesAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\r\n\r\n/**\r\n * Input class for the getFeatureState data action\r\n */\r\nexport class FeatureStateInput implements IActionInput {\r\n public readonly featureNames: string[] = [\r\n 'Dynamics.AX.Application.RetailB2BEcommerceFeature',\r\n 'Dynamics.AX.Application.RetailDefaultOrderQuantityLimitsFeature',\r\n 'Dynamics.AX.Application.RetailMultiplePickupDeliveryModeFeature',\r\n 'Dynamics.AX.Application.RetailSearchPriceRangeFeature'\r\n ];\r\n\r\n public getCacheKey = () => `FeatureState`;\r\n public getCacheObjectType = () => 'FeatureState';\r\n public dataCacheType = (): CacheType => 'application';\r\n}\r\n\r\n/**\r\n * createInput method for the getFeatureState method\r\n * @param inputData The input data passed to the createInput method\r\n */\r\nexport const createGetFeatureStateInput = (inputData: ICreateActionContext>): IActionInput => {\r\n return new FeatureStateInput();\r\n};\r\n\r\n/**\r\n * The action method for the getFeatureState data action\r\n * @param input The action input\r\n * @param ctx The action context\r\n */\r\nexport async function getFeatureStateAction(input: FeatureStateInput, ctx: IActionContext): Promise {\r\n const featureState = await getFeatureStatesAsync({ callerContext: ctx }, input.featureNames);\r\n return featureState;\r\n}\r\n\r\n/**\r\n * The getFeatureState data action\r\n * Gets the feature state via the read RetailServer API\r\n * Returns address information associated with the retrieved customer\r\n */\r\nexport const getFeatureStateActionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-feature-state',\r\n action: >getFeatureStateAction,\r\n input: createGetFeatureStateInput\r\n});\r\nexport default getFeatureStateActionDataAction;\r\n","import { ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\r\n\r\nexport const getRestrictedProducts = (productsData: ProductSearchResult[]): number[] => {\r\n const restrictedProducts: number[] = [];\r\n\r\n productsData.map(product => {\r\n const attributes = product.AttributeValues;\r\n\r\n attributes &&\r\n attributes.map(attr => {\r\n if (attr?.KeyName && attr.KeyName === 'RestrictedPostCode' && attr.TextValue) {\r\n // @ts-ignore\r\n const postcodesTemp = JSON.parse(attr?.TextValue).RestrictedPostCode;\r\n if (postcodesTemp.length > 0) {\r\n restrictedProducts.push(product.RecordId);\r\n }\r\n }\r\n });\r\n });\r\n return restrictedProducts;\r\n};\r\n","module.exports = ReactDOM;","const binding = { modules: {}, dataActions: {} };\n\n const registerActionId = (actionPath) => {\n if (binding.dataActions[actionPath] &&\n binding.dataActions[actionPath].default &&\n binding.dataActions[actionPath].default.prototype &&\n binding.dataActions[actionPath].default.prototype.id) {\n binding.dataActions[binding.dataActions[actionPath].default.prototype.id] = binding.dataActions[actionPath];\n } else {\n Object.keys(binding.dataActions[actionPath] || {}).forEach(exportName => {\n if (binding.dataActions[actionPath][exportName] &&\n binding.dataActions[actionPath][exportName].prototype &&\n binding.dataActions[actionPath][exportName].prototype.Action) {\n binding.dataActions[binding.dataActions[actionPath][exportName].prototype.id] = binding.dataActions[actionPath][exportName];\n }\n })\n }\n };\n\n const registerSanitizedActionPath = (sanitizedActionPath, dataAction) => {\n if (process.env.NODE_ENV === 'development') {\n if (!dataAction.default) {\n throw new Error('Data action path does not have a default export');\n }\n if (!(dataAction.default.prototype.id && binding.dataActions[dataAction.default.prototype.id]) || !binding.dataActions[sanitizedActionPath]) {\n binding.dataActions[sanitizedActionPath] = dataAction;\n }\n } else {\n binding.dataActions[sanitizedActionPath] = dataAction;\n if (!binding.dataActions[sanitizedActionPath].default) {\n throw new Error('Data action path ' + sanitizedActionPath + ' does not have a default export');\n }\n binding.dataActions[sanitizedActionPath].default.prototype.RegistrationId = sanitizedActionPath;\n if (binding.dataActions[sanitizedActionPath].default.prototype.id) {\n binding.dataActions[binding.dataActions[sanitizedActionPath].default.prototype.id] = sanitizedActionPath;\n }\n }\n };\n \n\n { \n const actionPath = 'themes/dobbies/actions/get-availabilities-cartlines.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-availabilities-cartlines.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-customer-address.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-customer-address.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-feature-state.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-feature-state.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-full-available-inventory-nearby.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-full-available-inventory-nearby.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-loyalty-card.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-loyalty-card.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-product-availabilities-for-selected-variant.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-product-availabilities-for-selected-variant.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-products-in-active-cart.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-products-in-active-cart.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-selected-variant.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-selected-variant.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/get-store-location-information.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/get-store-location-information.override.action');\n registerActionId(actionPath);\n }\n\n { \n const actionPath = 'themes/dobbies/actions/update-primary-address.override.action';\n binding.dataActions[actionPath] = require('partner/themes/dobbies/actions/update-primary-address.override.action');\n registerActionId(actionPath);\n }\n\n \n window.__bindings__ = window.__bindings__ || {};\n window.__bindings__.modules = {\n ...window.__bindings__.modules || {},\n ...binding.modules\n };\n \n window.__bindings__.packageDataActions = {};\n window.__bindings__.packageDataActions['__local__'] = {\n ...binding.dataActions\n };","/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n *--------------------------------------------------------------------------------------------*/\r\n\r\nimport * as Msdyn365 from '@msdyn365-commerce/core';\r\nimport { Address } from '@msdyn365-commerce/retail-proxy';\r\n\r\n/**\r\n * GetCustomerAddress Input Action\r\n */\r\n\r\nexport class GetCustomerAddressInput implements Msdyn365.IActionInput {\r\n // TODO: Determine if the results of this get action should cache the results and if so provide\r\n // a cache object type and an appropriate cache key\r\n public getCacheKey = () => `customerAddress`;\r\n public getCacheObjectType = () => 'customerAddress';\r\n public dataCacheType = (): Msdyn365.CacheType => 'request';\r\n}\r\n\r\n// TODO: Create a data model here or import one to capture the response of the action\r\nexport interface IGetCustomerAddressData {\r\n addresses: Address[] | undefined;\r\n}\r\n\r\n/**\r\n * TODO: Use this function to create the input required to make the action call\r\n */\r\nconst createInput = (args: Msdyn365.ICreateActionContext): Msdyn365.IActionInput => {\r\n return new GetCustomerAddressInput();\r\n};\r\n\r\n/**\r\n * TODO: Use this function to call your action and process the results as needed\r\n */\r\nasync function action(input:GetCustomerAddressInput, ctx: Msdyn365.IActionContext):Promise {\r\n return { addresses: undefined };\r\n}\r\n\r\nexport default Msdyn365.createObservableDataAction({\r\n action: >action,\r\n id: 'GetCustomerAddress',\r\n input: createInput\r\n});","/*--------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * See License.txt in the project root for license information.\r\n *--------------------------------------------------------------*/\r\n\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n ICommerceApiSettings,\r\n ICreateActionContext\r\n} from '@msdyn365-commerce/core';\r\nimport { LoyaltyCard } from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n getCustomerLoyaltyCardsAsync,\r\n getLoyaltyCardAsync\r\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\r\nimport { buildCacheKey } from '@msdyn365-commerce-modules/retail-actions';\r\n/**\r\n * Input class for the getLoyaltyCard data action.\r\n */\r\nexport class GetLoyaltyCardInput implements IActionInput {\r\n public userAccountNumber?: string;\r\n\r\n public apiSettings: ICommerceApiSettings;\r\n\r\n constructor(apiSettings: ICommerceApiSettings, userAccountNumber?: string) {\r\n this.userAccountNumber = userAccountNumber;\r\n this.apiSettings = apiSettings;\r\n }\r\n\r\n public getCacheKey = () => buildCacheKey(`GetLoyaltyCard-${this.userAccountNumber}`, this.apiSettings);\r\n\r\n public getCacheObjectType = () => 'GetLoyaltyCard';\r\n\r\n public dataCacheType = (): CacheType => 'request';\r\n}\r\n\r\n/**\r\n * CreateInput method for the getLoyaltyCard method.\r\n * @param inputData The input data passed to the createInput method.\r\n */\r\nexport const createGetLoyaltyCardInput = (inputData: ICreateActionContext): GetLoyaltyCardInput => {\r\n const { requestContext } = inputData;\r\n if (!requestContext.user.isAuthenticated) {\r\n throw new Error('Unable to create get loyalty card input. User is not authenticated.');\r\n }\r\n\r\n return new GetLoyaltyCardInput(inputData.requestContext.apiSettings, inputData.requestContext.user.customerAccountNumber);\r\n};\r\n\r\n/**\r\n * The action method for the getLoyaltyCard data action.\r\n * @param input The action input.\r\n * @param ctx The action context.\r\n */\r\nexport async function getLoyaltyAction(input: GetLoyaltyCardInput, ctx: IActionContext): Promise {\r\n return getCustomerLoyaltyCardsAsync({ callerContext: ctx, queryResultSettings: {} }, input.userAccountNumber || null)\r\n .then(cards => {\r\n if (!cards || cards.length === 0) {\r\n return {};\r\n }\r\n\r\n const tempCard = cards.find(card => card.CardTenderTypeValue !== 3);\r\n if (!tempCard) throw new Error('Unable to find a non-blocked card');\r\n const firstCard = tempCard;\r\n // const firstCard = cards[0];\r\n\r\n return getLoyaltyCardAsync({ callerContext: ctx }, firstCard.CardNumber)\r\n .then(card => {\r\n card.LoyaltyEnrollmentDate = firstCard.LoyaltyEnrollmentDate;\r\n card.LoyaltyEnrollmentDateLocal = firstCard.LoyaltyEnrollmentDateLocal;\r\n return card;\r\n })\r\n\r\n .catch(error => {\r\n ctx.telemetry.exception(error);\r\n ctx.telemetry.debug('Unable to get loyalty card');\r\n throw new Error('Unable to get loyalty card');\r\n });\r\n })\r\n .catch(error => {\r\n ctx.telemetry.exception(error.message);\r\n ctx.telemetry.debug('Unable to get customers loyalty card');\r\n throw new Error('Unable to get customers loyalty card');\r\n });\r\n}\r\n\r\n/**\r\n * The getLoyaltyCard data action\r\n * Returns the loyalty card belonging to the customer.\r\n */\r\nexport const getLoyaltyActionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-loyalty-card',\r\n action: >getLoyaltyAction,\r\n input: <(args: ICreateActionContext) => IActionInput>createGetLoyaltyCardInput\r\n});\r\n\r\nexport default getLoyaltyActionDataAction;\r\n","import { ICommerceApiSettings } from '@msdyn365-commerce/core';\r\nimport { ProductSearchResult, SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\n\r\n/**\r\n * Generates a Image URL based on data return from retail server\r\n * @param imageUrl The image url returned by Retail Server\r\n * @param ctx The request context\r\n */\r\n export const generateImageUrl = (imageUrl: string | undefined, apiSettings: ICommerceApiSettings): string | undefined => {\r\n if (imageUrl) {\r\n // Images hosted in CMS include schema\r\n if (imageUrl.startsWith('http')) {\r\n return imageUrl;\r\n }\r\n\r\n // Images hosted in Retail Server must be encoded and joined with the base image url\r\n return apiSettings.baseImageUrl + encodeURIComponent(imageUrl);\r\n } else {\r\n // d365Commerce.telemetry.warning(`Unable to generate a proper Image URL for Product: ${product.RecordId}`);\r\n return undefined;\r\n }\r\n};\r\n\r\n/**\r\n * Generates a Image URL for a product based on data return from retail server\r\n * @param product The Product returned by Retail Server\r\n * @param ctx The request context\r\n */\r\n export const generateProductImageUrl = (\r\n product: SimpleProduct | ProductSearchResult,\r\n apiSettings: ICommerceApiSettings\r\n): string | undefined => {\r\n return generateImageUrl(product.PrimaryImageUrl, apiSettings);\r\n};","import { getSelectedProductIdFromActionInput } from '@msdyn365-commerce-modules/retail-actions';\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\n\r\nimport {\r\n getByIdAsync,\r\n getDefaultComponentsAsync,\r\n getVariantsByComponentsInSlotsAsync,\r\n getVariantsByDimensionValuesAsync\r\n} from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { ProductDimension, SimpleProduct } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\nimport { generateProductImageUrl } from './utilities/get-image-url';\r\n/**\r\n * Get selected variant action input class\r\n */\r\nexport class SelectedVariantInput implements IActionInput {\r\n public productId: number;\r\n public channelId: number;\r\n public matchingDimensionValues: ProductDimension[];\r\n\r\n constructor(productId: number, channelId: number, matchingDimensionValues?: ProductDimension[]) {\r\n this.productId = productId;\r\n this.channelId = channelId;\r\n this.matchingDimensionValues = matchingDimensionValues || [];\r\n }\r\n\r\n public getCacheKey = () => `SelectedVariant`;\r\n public getCacheObjectType = () => 'SimpleProduct';\r\n public dataCacheType = (): CacheType => 'application';\r\n}\r\n\r\n/**\r\n * CreateInput method for the getSelectedVariant data action\r\n * @param inputData The input data passed to the createInput method\r\n */\r\nconst createInput = (inputData: ICreateActionContext>): SelectedVariantInput => {\r\n const productId = getSelectedProductIdFromActionInput(inputData);\r\n\r\n if (productId) {\r\n return new SelectedVariantInput(+productId, +inputData.requestContext.apiSettings.channelId, []);\r\n } else {\r\n throw new Error('Unable to create SelectedVariantInput, no productId found on module config or query');\r\n }\r\n};\r\n\r\n/**\r\n * Action method for the getSelectedVariant data aciton\r\n * @param input The action input class\r\n * @param ctx The action context\r\n */\r\nasync function getSelectedVariantAction(input: SelectedVariantInput, ctx: IActionContext): Promise {\r\n let product: SimpleProduct | null = null;\r\n\r\n const response = await getByIdAsync({ callerContext: ctx }, input.productId, input.channelId);\r\n const baseProduct: SimpleProduct = Array.isArray(response) ? response[0] : response;\r\n\r\n // Need to dereference this before editing it. Otherwise we might not\r\n // properly get the mobx events because if things aren't properly observable\r\n // they won't fire when you set them, and then if you don't deref the value in\r\n // the cache will match the value when you try to save it, so it won't detect any\r\n // changes there either\r\n product = baseProduct && { ...baseProduct };\r\n\r\n if (product) {\r\n let baseProductHadUnmatchedDimension: boolean = false;\r\n if (product.Dimensions) {\r\n product.Dimensions.map(dimension => {\r\n const matchedTargetDimension = input.matchingDimensionValues?.find(\r\n targetDimension => targetDimension.DimensionTypeValue === dimension.DimensionTypeValue\r\n );\r\n\r\n if (matchedTargetDimension) {\r\n dimension.DimensionValue = matchedTargetDimension.DimensionValue;\r\n } else {\r\n baseProductHadUnmatchedDimension = true;\r\n }\r\n });\r\n }\r\n\r\n if (!baseProductHadUnmatchedDimension && input.matchingDimensionValues?.length > 0) {\r\n const variants = await getVariantsByDimensionValuesAsync(\r\n { callerContext: ctx, queryResultSettings: {} },\r\n baseProduct?.RecordId,\r\n input.channelId,\r\n input.matchingDimensionValues || []\r\n );\r\n\r\n if (variants && variants.length > 0) {\r\n product = variants[0];\r\n }\r\n }\r\n\r\n /**\r\n * VSI Customization -- STARTS\r\n * Check if the product is Kit through getDefaultComponentsAsync\r\n * If it is kit product then fetch and load it's variant instead of master product.\r\n * Assuming there will be only one vaiant of kit product.\r\n */\r\n\r\n const defaultComponent = await getDefaultComponentsAsync(\r\n { callerContext: ctx, queryResultSettings: {} },\r\n baseProduct?.RecordId,\r\n input.channelId\r\n );\r\n\r\n if (defaultComponent && defaultComponent.length > 0) {\r\n const variantsByComponent = await getVariantsByComponentsInSlotsAsync(\r\n { callerContext: ctx, queryResultSettings: {} },\r\n baseProduct?.RecordId,\r\n input.channelId,\r\n []\r\n );\r\n\r\n if (variantsByComponent.length && variantsByComponent.length > 0) {\r\n const variantId = variantsByComponent[0]?.RecordId;\r\n const simpleProduct = await getByIdAsync({ callerContext: ctx }, variantId, input.channelId);\r\n const kitProduct: SimpleProduct = Array.isArray(simpleProduct) ? simpleProduct[0] : simpleProduct;\r\n // Will use master product's details as that would be up-to-date\r\n /* As description & title doesn't get updated for variants but for master products so using master product's details */\r\n const updatedKitProduct = kitProduct;\r\n updatedKitProduct.Name = baseProduct.Name;\r\n updatedKitProduct.Description = baseProduct.Description;\r\n\r\n product = { ...updatedKitProduct };\r\n }\r\n }\r\n\r\n /**\r\n * VSI Customization -- ENDS\r\n */\r\n\r\n const newImageUrl = generateProductImageUrl(product, ctx.requestContext.apiSettings);\r\n\r\n if (newImageUrl) {\r\n product.PrimaryImageUrl = newImageUrl;\r\n }\r\n }\r\n\r\n return product || null;\r\n}\r\n\r\n/**\r\n * The complete getSelectedVariant data action\r\n */\r\nexport default createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-selected-variant',\r\n action: >getSelectedVariantAction,\r\n input: createInput\r\n});\r\n"],"sourceRoot":""}