swcl.product.pathProductClass
Class PathProduct
The PathProduct class is a convenience wrapper for accessing products with the JSMA products. By establishing the concept of path products it allows to model hierarchical product structures sharing attributes with complex business rules. One of the main goals of PathProduct is next to the path products to simplify working with product data for integrators and making the application code as long term stable as possible leveraging possible changes in the internal APIs. With adding extensibility it also allows to change the businesslogic for certain products or product groups without chaning the application code.
PathProduct provides:
- Complex merging of multiple products (path products) to allow hierarchical access to product data
- Functional properties wrapping the internal cmplexity allowing stable and simple integration code using product data
- Flexible Extensibility for products via flexible attributes in the hierarchy to add new field and methods or change existing fields and methods
Index
The concept of "Path Products"
The JSMA products and JSMA product provide access to the IKONA Online PIM (PathProduct Information Management) which is 100% integrated into the IFE Management. For simple portals this is completely sufficient. But in more complex situations where different portals shall share the product database or products shall be provided to customers with little adaptions (i.e. a christmas edition with speical layouts) it might quickly get tedious to always copy the whole product data.
So it seems valuable to be able to provide a way to access product data in a hierarchical manner, where child products can inherit values from parent products. Thinking through that concept it appears that the rules of how to inherit, when to inherit and probably how to join the inherited data can be complex and always provide new requirements. So allowing to functionally combine/inherit/replace certain attributes and functions within the hierarchy is deemed to be necessary.
To solve this requirement the PathProduct wrapper provides the concept of "path products" which means that a product name (hrid) is defined to contain dots to split each hierarchy layer. So a standard cup could be named testing.fotogifts.cups.StandardCup in the system where a product with the name testing is the root path product and so forth. This leads to 4 products which get blended into one final product for the StandardCup.
Possible path product setup:
This allows to store informations in the 4 layers which are then blended together in the StandardCup. PathProduct provides many default fields to access the merged product data. Most of them can be overloaded by PathProductDelegates.
Use the PathProduct
Using the PathProduct is very simple just use the defined properties like simple properties. i.e. pathProduct.fqn resolves the Full Qualified Name of the product.
Some usage examples
... var pathProduct = new PathProduct(productName); //count path products with defined delegates var delegateCount = 0; pathProduct.each(function () { if (this.get("pathProductDelegateClass")) { delegateCount++; } }); //create a visual pattern with + indicating path product has a delegate and - that it has none from top to bottom var delegatePattern = pathProduct.reduceInv(function (last) { if (this.get("pathProductDelegateClass")) { last += "+"; } else { last += "-"; } return last; }, ""); //resolve the first product name and capacity with a defined capacity from top to bottom var firstProductWithCapacity = pathProduct.resolveInv(function () { if (this.get("capacity")) { return this.name + ", " + this.get("capacity"); } }); //returns the flex attribute capacity defaulting to "" from bottom to top var capacity = pathProduct.get("capacity", ""); //checks if the flex attribute capacity exists in one of the path product var capacityHas = pathProduct.has("capacity"); //returns the flex attribute capacity2 defaulting to "" from bottom to top var capacity2 = pathProduct.get("capacity2", "-"); //checks if the flex attribute capacity2 exists in one of the path product var capacity2Has = pathProduct.has("capacity2"); //returns the set of flex attribute names of all path products var flexAttributes = pathProduct.getFlexAttributeNames(); //create an array of tags properties from bottom to top var tags = pathProduct.concat("tags"); //create an array of displayNames from top to bottom var displayNames = pathProduct.concatInv("name1"); //create an array of pathProductDelegateClass flex attributes from top to bottom var pathProductDelegateClasses = pathProduct.concatInvFlexAttribute("pathProductDelegateClass"); //create a string of joined tags from bottom to top var tagsJoined = pathProduct.join("tags"); //create a string using | as separator from top to bottom var displayNamesJoined = pathProduct.joinInv("name", " | "); //create a string of pathProductDelegateClass flex attributes separated by :: from bottom to top var pathProductDelegateClassesJoined = pathProduct.joinFlexAttribute("pathProductDelegateClass", "::"); //create a string of pathProductDelegateClass flex attributes separated by :: from top to bottom var pathProductDelegateClassesJoinedInv = pathProduct.joinInvFlexAttribute("pathProductDelegateClass", "::"); ...
Setup the PathProduct
In setting up the path product it wraps the complex business logic of retrieveing the properties into simple properties you know from every simple JS object. For that PathProduct provides the different define... methods to simplify the setup process.
The most common way to reflect a property in that structure is to do a bottom to top path product matching which means that the first defined attribute or flexible attribute from bottom to top in the product hierarchy is used which is great for names, formats, description and so forth, where the child can override the parents attributes. See method defineProperty and defineFlexAttributeProperty.
Another common approach is to join the values from all path products into one array or string which is great for preview images, tags, keyword and so forth. See method join.
If you need to evaluate from top to bottom use the ...Inv... flavors of the methods.
In general the PathProduct wrapper defines properties with the default JS Object defineProperty to hide the functional nature of the properties and allow to define if the property will be enumerated when i.e. generating a string with JSON stringify or is allowed to be changed (see configurable) or written. This makes the application use the properties very intuitive within its code and provides to change internal mappings without having to change the application code.
Some examples of setting up a PathProduct
... //defines metaTitle to return the first not nul, undefied and not "" value from bottom to top pathProduct.defineProperty("metaTitle", "metaTitle", true, ""); //defines metaKeywords to join the metaKeywords property of the path products bottom to top Object.defineProperty(this, "metaKeywords", { get: function () { return self.join("metaKeywords", ", "); }, configurable: true, enumerable: true }); //defines price to return the internal value multiplied by 100 (EUR to Cent) Object.defineProperty(this, "price", { get: function () { var price = self.getProperty("price", 0); return Math.round(price * 100); }, configurable: true, enumerable: true }); ...
One of the most important additional feature to the path product concept is the extensibility, which can be driven by the products in the hierarchy, which is explained in the next paragraph.
Extend PathProduct with PathProductDelegates
Each of the path products can extend the PathProduct wrapper by providing a flex attribute pathProductDelegateClass which is set to a name of a macro in the system which has to provide a method extendPathProduct(pathProduct). This method will be called with the PathProduct instance allowing the delegate to modify, extend and remove properties and methods from the PathProduct wrapper. The call order is top to bottom providing an OOP like behaviour where the child overloads the parent.
PathProduct details showing how to wire a PathProductDelegate
For simplifying the extension in the PathProduct wrapper pattern PathProduct provides many useful methods in the pattern define...
Putting it all together
In the follwing chapter you will see how easy it is to use the PathProduct wrapper.
Using the PathProduct wrapper
Whenever you need to access product data in a macro:
1. Include the content swcl.product.pathProductClass
2. Construct a new PathProduct with the name of the desired path products
3. Thats it! You can now access all fields and methods like it was a "simple" product
Example
include("swcl.product.pathProductClass"); //<-- 1. include PathProduct Wrapper function main(productName) { if ((productName === undefined) || (productName.length === 0)) { return JSON.stringify({ status: "ERROR_PRODUCTNAME_INVALID" }); } var result; try { var pathProduct = new PathProduct(productName); //<-- 2. Construct PathProduct result = { status: "OK", pathProduct: pathProduct, //<-- 3. Will print all fields into the return string generated below productDisplay: pathProduct.display //<-- 3. Just access the fields like simple JS values }; } catch (ex) { result = { status: "ERROR_RESOLVING_PRODUCT", message: ex.message, stack: ex.stack }; } return JSON.stringify(result); }
Define a PathProductDelegate
Whenever you want to extend the PathProduct with a PathProductDelegate:
1. Define the flex attribute pathProductClass in one of the path products pointing to a macro you create
2. Define a method extendProduct(product) in your macro and extend the product instance within
3. Thats it! You extended the path product with your ProductDelegate.
Example
function extendPathProduct(pathProduct) //<-- 2. { //extend with static value pathProduct.myValue = 42; //use helper methods from pathProduct to provide funtional properties pathProduct.defineFlexAttributeProperty("deliveryTime", "deliveryTime", true, ""); //extend with own method (prototype is not needed as you just want to extend this instance) pathProduct.myMethod = function (param) { return param * this.myValue; } }
Synopsis
By now you should see using the PathProduct wrapper is very simple and intuitive and the possibilities of managing complex product data setups is unlimited!
Intended usage
The PathProduct wrapper is intended to provide:
- Flexibility
- Extensibility
- Convenience
- Stable application code
Not intended usage
The wrapper might cause a performance impact if you need to access many products within one page as the wrapping is a pretty complex and time consuming process as the main focus was to provide flexibility and convenience. For that cases it is in any way considerable to use own SQLQuery or SQLCommand contents to acess the data directly in the database or just materialize the really needed data from the products table.
Fields
The following fields are defined in the class PathProduct:
category, currency, deliveryInformation, description, display, editUrl, flexAttributeNames, format1, format2, fqn, fqnClass, hasTemplate, id, isDeleted, isDirectDelivery, isInPortal, isShopDelivery, mergedProductCount, mergedProducts, mergedProductsInv, metaDescription, metaKeywords, metaTitle, name, name1, name2, originalPrice, previewImages, price, printApiId, productImage, shortDescription, sku, specLis, tags, template, type, url, vat
string PathProduct.category
(default: "") Returns the products category property resolving bottom to top of the path products
string PathProduct.currency
(default: €) Returns current portals flex attribute currency for convenience
string PathProduct.deliveryInformation
(default: "") Returns the deliveryInformation property resolving bottom to top of the path products
string PathProduct.description
(default: "") Returns the products description property resolving bottom to top of the path products
string PathProduct.display
(default: "") Returns the products name1 property resolving bottom to top of the path products (renaming is here for allowing to extend displayment rules without overloading the name1 by that)
int PathProduct.editUrl
(default: /products/<productFqn>/edit)
string[] PathProduct.flexAttributeNames
(default: []) Returns all different flexAttribute names as joined array bottom to top of the path products
string PathProduct.format1
(default: "") Returns the products format1 property resolving bottom to top of the path products
string PathProduct.format2
(default: "") Returns the products format2 property resolving bottom to top of the path products
string PathProduct.fqn
(required; not configurable) Returns the full qualified name resolving bottom to top of the path products - the product is required to have a valid name property
string PathProduct.fqnClass
Returns the products fqn with - instead of . for usage in CSS property in cents resolving bottom to top of the path products
boolean PathProduct.hasTemplate
(default: false; configurable) Returns true if the product has a template false otherwise
int PathProduct.id
(required; not configurable) Returns the the id resolving bottom to top of the path products - the product is required to have a valid name property - ATTENTION: This value might change when changing the product db
boolean PathProduct.isDeleted
(default: true; not configurable) Returns true if the product is deleted resolving bottom to top of the path products
boolean PathProduct.isDirectDelivery
(default: false; not configurable) Returns true if the product is activated for home delivery resolving bottom to top of the path products
boolean PathProduct.isInPortal
(default: false; not configurable) Returns true if the product is mapped in the portal resolving bottom to top of the path products
boolean PathProduct.isShopDelivery
(default: false) Returns true if the product is activated for shop delivery resolving bottom to top of the path products
int PathProduct.mergedProductCount
(enumerable: false, readonly; not configurable) Returns the path product count
product[] PathProduct.mergedProducts
(enumerable: false, readonly; not configurable) Returns the path products as reversed list from bottom to top - see JSMA product
product[] PathProduct.mergedProductsInv
(enumerable: false; readonly; not configurable) Returns the path products as list from top to bottom - see JSMA product
string PathProduct.metaDescription
(default: "") Returns the products metaDescription property resolving bottom to top of the path products
string PathProduct.metaKeywords
(default: "") Returns the products metaKeywords property as joined string of the path products from bottom to top of the path products
string PathProduct.metaTitle
(default: "") Returns the products metaTitle property resolving bottom to top of the path products
string PathProduct.name
(required; not configurable) Returns the full qualified name resolving bottom to top of the path products - the product is required to have a valid name property
string PathProduct.name1
(default: "") Returns the products name1 property resolving bottom to top of the path products
string PathProduct.name2
(default: "") Returns the products name2 property resolving bottom to top of the path products
int PathProduct.originalPrice
(default: 0) Returns the products originalPrice property in cents resolving bottom to top of the path products
UUID[] PathProduct.previewImages
(default: []) Returns the products previewImageIds properties as joined array from bottom to top of the path products
int PathProduct.price
(default: 0) Returns the products price property in cents resolving bottom to top of the path products
UUID PathProduct.printApiId
(default: "") Returns the products print API ID which is needed for giving the product in orders to the backend resolving bottom to top of the path products
UUID PathProduct.productImage
(default: "") Returns the products productImageId property resolving bottom to top of the path products
string PathProduct.shortDescription
(default: "") Returns the products shortDescription property resolving bottom to top of the path products
string PathProduct.sku
(default: "") Returns the products sku property resolving bottom to top of the path products
t PathProduct.specLis
string[] PathProduct.tags
(default: []) Returns the products tags properties as joined array from bottom to top of the path products
string PathProduct.template
(default: null) Returns the first template bottom to top of the product chain which has a template
string PathProduct.type
(default: "") Returns the products typ property resolving bottom to top of the path products (renaming is currently done for correcting the typo in the JSMA product)
int PathProduct.url
(default: /products/<productFqn>)
int PathProduct.vat
(default: 0) Returns the products vat property resolving bottom to top of the path products
Methods
The following functions are methods of the class PathProduct:
PathProduct, concat, concatFlexAttribute, concatInv, concatInvFlexAttribute, defineFlexAttributeProperty, defineInvFlexAttributeProperty, defineInvProperty, defineProperty, each, eachInv, get, getFlexAttributeNames, getFlexAttributeProperty, getInvFlexAttributeProperty, getInvProperty, getProperty, has, join, joinFlexAttribute, joinInv, joinInvFlexAttribute, reduce, reduceInv, resolve, resolveInv
Constructor PathProduct(string path) throws Error
Constructs a new path product wrapper with a given product path
- Loads path products with JSMA products getProductsForNamePath
- Defines basic properties for a product
- Loads productDelegates for each path product from top to bottom
Parameter string path
The path of the product to be resolved
Returns PathProduct
A new instance of PathProduct
Throws Error
on:
- null or empty string for path
- empty list of found path products
object PathProduct.concat(string name)
Allows to concat an array of all the properties from all path products from bottom to top.
Parameter string name
Name of the property to concat
Returns object
Returns the concatenation of the values
object PathProduct.concatFlexAttribute(string name)
Allows to concat an array of all the flex attributes from all path products from bottom to top.
Parameter string name
Name of the property to concat
Returns object
Returns the concatenation of the values or []
object PathProduct.concatInv(string name)
Allows to concat an array of all the properties from all path products from top to bottom.
Parameter string name
Name of the property to concat
Returns object
Returns the concatenation of the values or []
object PathProduct.concatInvFlexAttribute(string name)
Allows to concat an array of all the flex attributes from all path products from top to bottom.
Parameter string name
Name of the property to concat
Returns object
Returns the concatenation of the values or []
PathProduct PathProduct.defineFlexAttributeProperty(string externalName, string internalName, boolean configurable, object defaultValue)
Retrieves a product flex attribute property resolving from bottom to top path product, which means the first not null, not undefined or not default value will be returned.
Parameter string externalName
Under this name the property will be mapped in the product wrapper allowing product.<externalName> or product["<externalName>"] to access it
Parameter string internalName
(optional; default: externalName) The name of the property to be retrieved from the path products
Parameter boolean configurable
(optional; default: false) Defined the property to allow to be overridden or not (see JS Object.setProperty() for more details on that)
Parameter object defaultValue
(optional; default: undefined) The value which is returned if no value in the path products is defined
Returns PathProduct
this for chaining statements
PathProduct PathProduct.defineInvFlexAttributeProperty(string externalName, string internalName, boolean configurable, object defaultValue)
Retrieves a product flex attribute property resolving from top to bottom path product, which means the first not null, not undefined or not default value will be returned.
Parameter string externalName
Under this name the property will be mapped in the product wrapper allowing product.<externalName> or product["<externalName>"] to access it
Parameter string internalName
(optional; default: externalName) The name of the property to be retrieved from the path products
Parameter boolean configurable
(optional; default: false) Defined the property to allow to be overridden or not (see JS Object.setProperty() for more details on that)
Parameter object defaultValue
(optional; default: undefined) The value which is returned if no value in the path products is defined
Returns PathProduct
this for chaining statements
PathProduct PathProduct.defineInvProperty(string externalName, string internalName, boolean configurable, object defaultValue)
Retrieves a product property resolving top to bottom path product, which means the first not null, not undefined or not default value will be returned.
Parameter string externalName
Under this name the property will be mapped in the product wrapper allowing product.<externalName> or product["<externalName>"] to access it
Parameter string internalName
(optional; default: externalName) The name of the property to be retrieved from the path products
Parameter boolean configurable
(optional; default: false) Defined the property to allow to be overridden or not (see JS Object.setProperty() for more details on that)
Parameter object defaultValue
(optional; default: undefined) The value which is returned if no value in the path products is defined
Returns PathProduct
this for chaining statements
PathProduct PathProduct.defineProperty(string externalName, string internalName, boolean configurable, object defaultValue)
Retrieves a product property using resolving from bottom to top path product, which means the first not null, not undefined or not default value will be returned.
Parameter string externalName
Under this name the property will be mapped in the product wrapper allowing product.<externalName> or product["<externalName>"] to access it
Parameter string internalName
(optional; default: externalName) The name of the property to be retrieved from the path products
Parameter boolean configurable
(optional; default: false) Defined the property to allow to be overridden or not (see JS Object.setProperty() for more details on that)
Parameter object defaultValue
(optional; default: undefined) The value which is returned if no value in the path products is defined
Returns PathProduct
this for chaining statements
PathProduct PathProduct.each(function callback)
Iterates through the path products from bottom to top calling the callback with this set to the certain product for each. See JSMA product for the this parameter of the callback.
Parameter function callback
Called with this set to the certain product for each path product
Returns PathProduct
this for chaining statements
PathProduct PathProduct.eachInv(function callback)
Iterates through the path products from top to bottom calling the callback with this set to the certain product for each. See JSMA product for the this parameter of the callback.
Parameter function callback
Called with this set to the certain product for each path product
Returns PathProduct
this for chaining statements
object PathProduct.get(string name, object defaultValue)
Returns the first not null, undefined and not defaultValue flex attribute with name by calling the callback set with this to the certain path product from bottom to top. This function is a shorthand for getFlexAttributeProperty.
Parameter string name
The flex attribute name to be retrieved from the path products
Parameter object defaultValue
(optional; default: undefined) Any default value you want want to be returned if no other result is found
Returns object
The first not null,undefined and not defaultValue flexible attribute in the path products
string[] PathProduct.getFlexAttributeNames()
Joins the different existing flex attributes of the path products to one array. Each flex attribute name may only exist once.
Returns string[]
All different flex attribute names of the path products which can then be retrieved using get
object PathProduct.getFlexAttributeProperty(string name, object defaultValue)
Returns the first not null, undefined and not defaultValue flex attribute with name by calling the callback set with this to the certain path product from bottom to top.
Parameter string name
The flex attribute name to be retrieved from the path products
Parameter object defaultValue
(optional; default: undefined) Any default value you want want to be returned if no other result is found
Returns object
The first not null,undefined and not defaultValue flexible attribute in the path products
object PathProduct.getInvFlexAttributeProperty(string name, object defaultValue)
Returns the first not null, undefined and not defaultValue flex attribute with name by calling the callback set with this to the certain path product from top to bottom.
Parameter string name
The flex attribute name to be retrieved from the path products
Parameter object defaultValue
(optional; default: undefined) Any default value you want want to be returned if no other result is found
Returns object
The first not null,undefined and not defaultValue flexible attribute in the path products
object PathProduct.getInvProperty(string name, object defaultValue)
Returns the first not null, undefined and not defaultValue attribute with name by calling the callback set with this to the certain path product from top to bottom.
Parameter string name
The flex attribute name to be retrieved from the path products
Parameter object defaultValue
(optional; default: undefined) Any default value you want want to be returned if no other result is found
Returns object
The first not null,undefined and not defaultValue flexible attribute in the path products
object PathProduct.getProperty(string name, object defaultValue)
Returns the first not null, undefined and not defaultValue attribute with name by calling the callback set with this to the certain path product from bottom to top.
Parameter string name
The flex attribute name to be retrieved from the path products
Parameter object defaultValue
(optional; default: undefined) Any default value you want want to be returned if no other result is found
Returns object
The first not null,undefined and not defaultValue flexible attribute in the path products
boolean PathProduct.has(string name)
Checks if one of the path products has a flex attribute with name from bottom to top which is not null or undefined.
Parameter string name
The flex attribute name to be checked if present from the path products
Returns boolean
True if one of the path products contains the flex attribute with name which is not undefined or null
object PathProduct.join(string name, string separator)
Allows to join all the properties name from all path products from bottom to top.
Parameter string name
Name of the property to join
Parameter string separator
Separator between elements
Returns object
Returns the concatenation of the values
object PathProduct.joinFlexAttribute(string name, string separator)
Allows to join all flex attributes name from all path products from bottom to top.
Parameter string name
Name of the property to join
Parameter string separator
Separator between elements
Returns object
Returns the concatenation of the values
object PathProduct.joinInv(string name, string separator)
Allows to join all the properties name from all path products from top to bottom.
Parameter string name
Name of the property to join
Parameter string separator
Separator between elements
Returns object
Returns the concatenation of the values
object PathProduct.joinInvFlexAttribute(string name, string separator)
Allows to join all flex attributes name from all path products from top to bottom.
Parameter string name
Name of the property to join
Parameter string separator
Separator between elements
Returns object
Returns the concatenation of the values
object PathProduct.reduce(function callback, function intialValue)
Allows to reduce a value from all path products from bottom to top. The callback is called with this as the certain path product. the initial value will be passed to the callback and the callback is expected to return a value for the call to the next callback. It is evaluated from top to bottom path product. See JSMA product for the this parameter of the callback.
Parameter function callback
Called with the lastValue (initialValue for the first) and this set to the certain product
Parameter function intialValue
(optional; default: undefined) Startvalue for the callback
Returns object
Returns the last return of the callback calls
object PathProduct.reduceInv(function callback, function intialValue)
Allows to reduce a value from all path products from top to bottom. The callback is called with this as the certain path product. the initial value will be passed to the callback and the callback is expected to return a value for the call to the next callback. It is evaluated from top to bottom path product. See JSMA product for the this parameter of the callback.
Parameter function callback
Called with the lastValue (initialValue for the first) and this set to the certain product
Parameter function intialValue
(optional; default: undefined) Startvalue for the callback
Returns object
Returns the last return of the callback calls
object PathProduct.resolve(function callback, object defaultValue)
Resolves a value by calling the callback set with this to the certain path product from bottom to top. The first callback return that is not null,undefined and not defaultValue will be returned by this function. See JSMA product for the this parameter of the callback.
Parameter function callback
Called with this set to the certain product for each path product and the defaultValue as parameter
Parameter object defaultValue
(optional; default: undefined) Any default value you want want to be returned if no other result is found
Returns object
The first not null,undefined and not defaultValue which is retrned by the callback
object PathProduct.resolveInv(function callback, object defaultValue)
Resolves a value by calling the callback set with this to the certain path product from top to bottom. The first callback return that is not null,undefined and not defaultValue will be returned by this function. See JSMA product for the this parameter of the callback.
Parameter function callback
Called with this set to the certain product for each path product and the defaultValue as parameter
Parameter object defaultValue
(optional; default: undefined) Any default value you want want to be returned if no other result is found
Returns object
The first not null,undefined and not defaultValue which is retrned by the callback