{"version":3,"file":"static/js/e102c663941c051e99ff.bundle.js","mappings":"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","sources":["webpack://united-malt/./src/modules/on-hold-container/on-hold-container.tsx?0eb9","webpack://united-malt/./src/utilities/data-attribute-parser.ts?7345","webpack://united-malt/./lib/on-hold-container/module-registration.js?07f1","webpack://united-malt/external var \"React\"?0d3b","webpack://united-malt/external var \"ReactDOM\"?853b"],"sourcesContent":["//==============================================================================\r\n// Conditional Customer Status Container\r\n//\r\n// Light-weight module that shows child modules only if the currently logged in\r\n// user has a matching status to a selected config customer status. Otherwise, nothing is added to the DOM.\r\n//==============================================================================\r\nimport * as React from 'react';\r\n\r\nimport { convertCustomerAttributes } from '../../utilities/data-attribute-parser';\r\nimport { CustomerStatus } from '../../settings/app.settings';\r\n\r\nimport { IOnHoldContainerData } from './on-hold-container.data';\r\nimport { IOnHoldContainerProps } from './on-hold-container.props.autogenerated';\r\n\r\n\r\n//==============================================================================\r\n// CLASS DEFINITION\r\n//==============================================================================\r\n/**\r\n * ConditionalContainer component\r\n * @extends {React.PureComponent>}\r\n */\r\n//==============================================================================\r\nclass ConditionalContainer extends React.PureComponent> {\r\n\r\n //==========================================================================\r\n // PUBLIC METHODS\r\n //==========================================================================\r\n\r\n //------------------------------------------------------\r\n // Render function\r\n //------------------------------------------------------\r\n public render(): JSX.Element | null {\r\n const { slots, data, config } = this.props;\r\n\r\n // Ensure there are child slots. If not, abort.\r\n const hasSlots = slots && slots.childModules && slots.childModules.length;\r\n if (!hasSlots) {\r\n return null;\r\n }\r\n\r\n // Get customer info. If it hasn't been loaded yet, abort.\r\n const customerData = data.customerInformation.result;\r\n if (!customerData) {\r\n return null;\r\n }\r\n\r\n if (config.conditionType === 'onHold') {\r\n\r\n // If the customer doesn't have a credit hold, abort.\r\n if (!customerData.Blocked) {\r\n return null;\r\n }\r\n\r\n } else if (config.conditionType === 'notOnHold') {\r\n\r\n // If the customer has a credit hold, abort.\r\n if (customerData.Blocked) {\r\n return null;\r\n }\r\n\r\n } else {\r\n\r\n const customerAttributes = convertCustomerAttributes(customerData.Attributes || []);\r\n const onBoardingStatus = customerAttributes.CusOnboardStatus;\r\n const customerStatusIds = this.props.context.app.config.customerStatus as CustomerStatus;\r\n\r\n // If the customer doesn't have new customer status abort\r\n if (config.conditionType === 'newCust' && onBoardingStatus !== customerStatusIds.customerFirstTimeBuyerId) {\r\n return null;\r\n }\r\n\r\n // If the customer is not pending credit check abort\r\n if (config.conditionType === 'pendingCreditCheck' && onBoardingStatus !== customerStatusIds.customerOnHoldId) {\r\n return null;\r\n }\r\n\r\n }\r\n\r\n // Customer status condition met, render the child modules.\r\n return this._renderSlotItems(slots.childModules);\r\n }\r\n\r\n //==========================================================================\r\n // PRIVATE METHODS\r\n //==========================================================================\r\n\r\n //------------------------------------------------------\r\n //------------------------------------------------------\r\n private _renderSlotItems(items: React.ReactNode[]): JSX.Element {\r\n return (\r\n \r\n {items.map((slot: React.ReactNode, index: number) => (\r\n \r\n {slot}\r\n \r\n ))}\r\n \r\n );\r\n }\r\n}\r\n\r\nexport default ConditionalContainer;\r\n","//==============================================================================\r\n// D365 OData Attribute Parser\r\n//\r\n// In creating this, it became clear that \"attributes\" is a general term.\r\n//\r\n// Product attributes are a first-class entity. They have their own dedicated\r\n// fields and schema.\r\n//\r\n// The more generic term \"attributes\" is used as a generic extension system.\r\n// Almost every entity (including Product Attributes) has an ExtensionProperties\r\n// field for jamming extra information into. In some cases, D365 handles these\r\n// natively, such as sales order line and header attributes, or customer\r\n// attributes. Attributes using ExtensionProperties use the\r\n// CommerceProperty and CommercePropertyValue types.\r\n//\r\n// A major note about ExtensionProperty-based attributes: they have fields\r\n// for many different data types, but there's no indicator as to which\r\n// of the fields is actually used. The consumer of the data is expected to\r\n// know the data type ahead of time. In the case of D365-native attribute users\r\n// such as customers and sales orders, only the string type appears to work.\r\n//\r\n// This module includes parsers for generic ExtensionProperties-based attributes\r\n// and Product Attributes. Though different Product Attribute retail server\r\n// calls use the same AttributeValue entity to transmit the data, they appear\r\n// to return different fields from that entity. Because of this, two different\r\n// parser calls are included here. They currently share the same implementation,\r\n// but by including different call signatures we have the ability to diverge\r\n// the implementations if the need arises.\r\n//\r\n// A note about Product Attributes: These contain both a friendly name,\r\n// displayed to users in back office, and an internal name. The internal name\r\n// can be the same as the friendly name, but by convention we've been pushing\r\n// for a PascalCase scheme. At present, the searchByCriteria call returns only\r\n// the unfriendly name, and the GetAttributeValues call returns only the\r\n// friendly name. We don't have a known method of correlating the two. That may\r\n// be an argument for keeping the friendly and unfriendly names identical.\r\n//==============================================================================\r\nimport {\r\n CommerceProperty, // Generic attributes stored in ExtensionProperties\r\n CommercePropertyValue, // Generic attributes stored in AttributeValue\r\n AttributeValue, AttributeDataType, // Product attributes or Product Search Result attributes\r\n CustomerAttribute, // Customer attributes\r\n IDictionary,\r\n} from '@msdyn365-commerce/retail-proxy';\r\n\r\n//==============================================================================\r\n// INTERFACES AND CONSTANTS\r\n//==============================================================================\r\nexport type CommerceValueTypes = string | number | boolean | Date;\r\n\r\n// This is me giving up on proper typing. If doing this in TypeScript is possible, I don't know how.\r\n// For the key \"meta\", the type should be a hash of strings.\r\n// For all other keys, the type is a CommerceValueType.\r\nexport type AttributesWithMetadata = {\r\n [key: string]: CommerceValueTypes | IDictionary\r\n};\r\n\r\n// Type to support both internal and friendly name for attributes\r\nexport type AttributesLocalized = {\r\n [key: string]: {\r\n friendlyName?: string,\r\n value?: CommerceValueTypes | IDictionary\r\n }\r\n};\r\n\r\n// Return type for getTypeInfo()\r\ntype TypeData = {\r\n source: keyof AttributeValue,\r\n type: string,\r\n\r\n customerSource?: keyof CommercePropertyValue,\r\n};\r\n\r\n//==============================================================================\r\n// FUNCTIONS\r\n//==============================================================================\r\n\r\n//----------------------------------------------------------\r\n// This version handles ExtensionProperties conversion.\r\n//\r\n// While these have a bunch of potential fields, the value\r\n// is always stored within StringValue.\r\n// There isn't a data type field, so if the content wasn't\r\n// in StringValue we wouldn't know where to find it.\r\n//----------------------------------------------------------\r\nexport function convertExtensionProperties(attributeList: CommerceProperty[]): IDictionary {\r\n const output = {};\r\n\r\n attributeList.forEach(entry => {\r\n if (entry.Key) {\r\n output[entry.Key] = entry.Value?.StringValue; // Ecommerce seems to always use strings.\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n// For these attributes, the Name is always the friendly\r\n// name.\r\n// KeyName and ExtensionProperties aren't defined.\r\n//\r\n// These results seem to be missing CurrencyValue,\r\n// FloatValue, DateTimeOffsetValue\r\n// I don't know if those data types aren't allowed here.\r\n//\r\n// Return value: Hash of key: property values with variable\r\n// types. There is also a \"meta\" key containing a hash of\r\n// all the attribute keys and their corresponding types.\r\n//\r\n// Example:\r\n// {\r\n// flavor: 'bland',\r\n// calories: 5300,\r\n// meta: {\r\n// flavor: 'string',\r\n// calories: 'number'\r\n// }\r\n// }\r\n//----------------------------------------------------------\r\nexport function convertProductAttributes(attributeList: AttributeValue[]): AttributesWithMetadata {\r\n const output = {\r\n meta: {}\r\n };\r\n\r\n attributeList.forEach(attribute => {\r\n // These should always be present, but TypeScript insists they can be undefined.\r\n if (attribute.Name && attribute.DataTypeValue) {\r\n const typeData = getTypeInfo(attribute.DataTypeValue);\r\n output[attribute.Name] = attribute[typeData.source]; // Ecommerce seems to require strings\r\n output.meta[attribute.Name] = typeData.type;\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n// For these attributes, the\r\n// Name/KeyName/ExtensionProperties is always the unfriendly\r\n// name.\r\n//\r\n// These results are only missing the Swatches field.\r\n//\r\n// Though the returned value is a bit different, at present\r\n// the implementation for convertProductAttributes works for\r\n// search results.\r\n// If they diverge in the future, extend this function.\r\n//----------------------------------------------------------\r\nexport function convertSearchAttributes(attributeList: AttributeValue[]): AttributesWithMetadata {\r\n return convertProductAttributes(attributeList);\r\n}\r\n\r\n//----------------------------------------------------------\r\n// For these attributes, the Name is the friendly\r\n// name while KeyName is the internal name.\r\n//\r\n// This makes use of combined attributes containing both\r\n// internal and friendly name to support localization.\r\n//\r\n// Return value: Hash of internal name keys containing an object with both the\r\n// friendly name and attribute value There is also a \"meta\" key containing a\r\n// hash of all the attribute keys and their corresponding types.\r\n//\r\n// Example:\r\n// {\r\n// flavor: {\r\n// friendlyName: Flavor,\r\n// value: 'bland'\r\n// },\r\n// calories: {\r\n// friendlyName: Calories,\r\n// value: 5300\r\n// },\r\n// meta: {\r\n// flavor: 'string',\r\n// calories: 'number'\r\n// }\r\n// }\r\n//----------------------------------------------------------\r\nexport function convertProductAttributesLocalized(attributeList: AttributeValue[]): AttributesLocalized {\r\n const output = {\r\n meta: {}\r\n };\r\n\r\n attributeList.forEach(attribute => {\r\n if (attribute.KeyName && attribute.DataTypeValue) {\r\n const typeData = getTypeInfo(attribute.DataTypeValue);\r\n output[attribute.KeyName] = {\r\n friendlyName: attribute.Name,\r\n value: attribute[typeData.source]\r\n };\r\n output.meta[attribute.KeyName] = typeData.type;\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n//----------------------------------------------------------\r\nexport function convertCustomerAttributes(attributeList: CustomerAttribute[] | undefined): AttributesWithMetadata {\r\n const output = {\r\n meta: {}\r\n };\r\n\r\n attributeList?.forEach(attribute => {\r\n // These should always be present, but TypeScript insists they can be undefined.\r\n if (attribute.Name && attribute.DataTypeValue) {\r\n const typeData = getTypeInfo(attribute.DataTypeValue);\r\n output[attribute.Name] = attribute.AttributeValue && typeData.customerSource && attribute.AttributeValue[typeData.customerSource];\r\n output.meta[attribute.Name] = typeData.type;\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n// Finds the source field and type for an attribute\r\n//\r\n// This should probably be extended to better support\r\n// currency, which seems to be two fields glued together.\r\n//----------------------------------------------------------\r\nfunction getTypeInfo(type: AttributeDataType): TypeData {\r\n\r\n // Awkward, but this helps TypeScript enforce strict type checking\r\n type TypeMapType = {\r\n [key in AttributeDataType]: TypeData\r\n };\r\n\r\n const typeMap: TypeMapType = {\r\n [AttributeDataType.None]: {source: 'TextValue', type: 'string'}, // We need to choose something\r\n [AttributeDataType.Currency]: {source: 'CurrencyValue', type: 'number'}, // Should also include CurrencyCode, which is a string?\r\n [AttributeDataType.DateTime]: {source: 'DateTimeOffsetValue', type: 'Date'},\r\n [AttributeDataType.Decimal]: {source: 'FloatValue', type: 'number'},\r\n [AttributeDataType.Integer]: {source: 'IntegerValue', type: 'number', customerSource: 'IntegerValue'},\r\n [AttributeDataType.Text]: {source: 'TextValue', type: 'string', customerSource: 'StringValue'},\r\n [AttributeDataType.TrueFalse]: {source: 'BooleanValue', type: 'boolean', customerSource: 'BooleanValue'},\r\n [AttributeDataType.Video]: {source: 'TextValue', type: 'string'},\r\n [AttributeDataType.Image]: {source: 'TextValue', type: 'string'}\r\n };\r\n\r\n return typeMap[type];\r\n}\r\n","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 (binding.modules['on-hold-container'] = {\n c: () => require('partner/modules/on-hold-container/on-hold-container.tsx'),\n $type: 'containerModule',\n da: [{name:'customerInformation', path:'@msdyn365-commerce-modules/retail-actions/dist/lib/get-customer', runOn: 0}],\n \n iNM: false,\n ns: '__local__',\n n: 'on-hold-container',\n p: '__local__',\n \n pdp: '',\n \n \n md: 'src/modules/on-hold-container'\n });\n \n\n {\n const sanitizedActionPath = '@msdyn365-commerce-modules/retail-actions/dist/lib/get-customer';\n let dataAction = require('@msdyn365-commerce-modules/retail-actions/dist/lib/get-customer');\n registerSanitizedActionPath(sanitizedActionPath, dataAction);\n }\n \n\n \n window.__bindings__ = window.__bindings__ || {};\n window.__bindings__.modules = {\n ...window.__bindings__.modules || {},\n ...binding.modules\n };\n \n window.__bindings__.dataActions = {\n ...window.__bindings__.dataActions || {},\n ...binding.dataActions\n };","module.exports = React;","module.exports = ReactDOM;"],"names":["ConditionalContainer","React","render","slots","data","config","this","props","childModules","length","customerData","customerInformation","result","conditionType","Blocked","onBoardingStatus","convertCustomerAttributes","Attributes","CusOnboardStatus","customerStatusIds","context","app","customerStatus","customerFirstTimeBuyerId","customerOnHoldId","_renderSlotItems","items","map","slot","index","key","convertProductAttributes","attributeList","output","meta","forEach","attribute","Name","DataTypeValue","typeData","getTypeInfo","source","type","convertProductAttributesLocalized","KeyName","friendlyName","value","AttributeValue","customerSource","AttributeDataType","None","Currency","DateTime","Decimal","Integer","Text","TrueFalse","Video","Image","binding","modules","dataActions","c","require","$type","da","name","path","runOn","iNM","ns","n","p","pdp","md","registerSanitizedActionPath","sanitizedActionPath","dataAction","default","Error","prototype","RegistrationId","id","window","__bindings__","_objectSpread","module","exports","ReactDOM"],"sourceRoot":""}