Thursday, March 9, 2017

Calculation Framework

Introduction
Calculation framework helps us determining the monetary amounts associated with each orderitems since every orderitem can have reference to the offer, shipping mode, fulfillment center and contract. Consolidated calculated orderitems amount is applied to the order eventually.

High Level Steps of Calculation Framework
--------------------------------------------------------
OrderCalculate interface invokes the class PromotionEngineOrderCalculateCmdImpl which in turn invokes the four major steps mentioned below-
1. InitializeCalculationUsage  ---- Clears up the existing adjustments on orderitems and order
2. ApplyCalculationUsage calls:  -- Calculates and applies the amounts
     a. CalculationCodeCombine calls:
               CalculationCodeQualify
      b. CalculationCodeCalculate calls:
                 CalculationRuleCombine calls:
                               CalculationRuleQualify
                 CalculationRuleCalculate calls:
                              CalculationScaleLookup
                              CalculationRange
       c. CalculationCodeApply
3. SummarizeCalculationUsage   --- Summarizes the total adjustments to the order
4. FinalizeCalculationUsage    --- Validates & finalizes the Promotion


Overall Flow
-----------------
STENCALUSG table entry for the calusage_id determines the business logic to be executed for the below four steps of calculation framework. Let us consider the example of -1 calcusage(i.e discount)-

1) InitializeCalculationUsage
First of all, initializeCalculationUsage() is invoked which invokes the InitializeAdjustmentCmd interface based upon the entry in STENCALUSG table for CALUSAGE_ID -1. Default class implementation for discount InitializeAdjustmentCmdImpl is invoked and resets the adjustments to zero.
InitializeAdjustmentCmdImpl performs below activities-

e.g. nOrderItemId=50001, original dOrderItemAdjustment=0.00000
initializing ORDERS.TOTALADJUSTMENT to zero, dOldOrderAdjustmentAmount=0.00000

2) ApplyCalculationUsage
This is the major step in terms of customizations. ApplyCalculationUsageCmd is invoked which further invokes the following methods inside ApplyCalculationUsageCmdImpl-

2A) CalculationCodeCombineCmd (Internally invokes CalculationCodeQualifyCmd, Tables- px_promotion,clcdpromo,calcode)

SELECT * FROM cmdreg c where c.INTERFACENAME like '%CalculationCodeCombineCmd%' gives me com.ibm.commerce.order.calculation.PromotionEngineDiscountCalculationCodeCombineCmdImpl
So CalculationCodeCombineCmd interface in turn invokes PromotionEngineDiscountCalculationCodeCombineCmdImpl command

This command collects the promotions- calcodes that are eligible for the given orderitems. The relationship between calculation code and promotion is defined in CLCDPROMO which is created during promotion creation.

More specifically, the applyCalculationUsage calls PromotionEngineCalculationCodeCombineCmdImpl version of the CalcodeCombineCmd which invokes promotion engine. Once the promotionEngine is invoked, this retrieves the associated promotion execution records which are converted into the format that the calculation framework can understand.

2B) CalculationCodeCalculateCmd
After the above step, the data read from the above is used to calculate the discounts(via calrule combine and calrule calculate methods).

2C) CalculationCodeApplyCmd
The calcodes determined in step a and adjustments calculated in step b are finally applied to the order items in this step via the DiscountCalculationCodeApplyCmdImpl implementation.
That is the ORDADJUST and ORDIADJUST tables are populated in this step.

We can customize any of these by overriding these with your version of method in CALMETHOD table or by overriding in CMDREG table.

3) SummarizeCalculationUsage
Default implementation SummarizeAdjustmentCmdImpl is invoked which summarizes the total adjustments to the order.

e.g. PFB the log snippet-
SummarizeAdjustmentCmdImpl.performExecute orderitem id=50001, status=P
SummarizeAdjustmentCmdImpl.performExecute nOrderItemId=50001, status=P, dOrderItemAdjustmentForUsage=-5.70000
SummarizeAdjustmentCmdImpl.performExecute summarizing ORDERS.TOTALADJUSTMENT to dOrderAdjustmentTotal=-5.70000
SummarizeAdjustmentCmdImpl.performExecute summarizing SUBORDERS.TOTALADJUSTMENT to dSubOrderAdjustmentTotal=-5.70000
SummarizeAdjustmentCmdImpl.performExecute Exit

4) finalizeCalculationUsages
Default implementation is FinalizeDiscountCalculationUsageCmdImpl command which validates the promotion code and finalizes the Promotion Argument.

e.g. PFB the log snippet-
com.ibm.commerce.order.calculation.CalculationHelper.finalizeCalculationUsages finalizeCalculationUsageMethodId(storeId=10152,usageId=-1)=-204
com.ibm.commerce.order.calculation.FinalizeDiscountCalculationUsageCmdImpl.performExecute Entry
com.ibm.commerce.order.calculation.FinalizeDiscountCalculationUsageCmdImpl.performExecute Exit

Note: The calculation framework is invoked when you call OrderCalculate or OrderPrepare which in turn invokes the promotion engine when we pass the usage -1 as we mentioned Or we can also invoke promotion engine by calling PromotionEngineOrderCalculateCmdImpl.
Therefore, we can also customize this command based upon the needs.

OrderItemAddCmd/OrderItemUpdate/OrderPrepare commands calls the first three steps of the calculation framework whereas OrderProcess command calls the final step i.e. finalizeCalculationUsages of the calculation framework.

Five Major Components
---------------------------
1. Calculation methods
2. Calculation usages (-1 discount,-2 shipping,-3 sales tax,-4 shipping tax,-5 coupon,-6 surcharge,-7 shipping adjustment)      
3. Calculation codes
4. Calculation rules
5. Calculation scales and calculation ranges

Sequence of activities
------------------------
Define the calculation codes.
Define the calculation rules.
Define the calculation scales.
Define the calculation ranges.
Define the look-up results for the calculation ranges.
Associate the calculation scales with the calculation rules.
Attach the calculation code with the all catalog entries.

Customizations
If we do not have the monetary amounts to be applied on orderitems in the WCS DB and are to be retrieved from elsewhere then we can write our custom java classes for the calmethods by associating them inside the stencalusg table.

The custom java classes can make the real time call to retrieve the monetary amounts from the ultimate source e.g. shipping charges can be retrieved from the third party by adding the real time call inside the custom java class MyApplyShippingCmdImpl and the same class entru need to make inside the stencalusg table for the calusage_id -2.

This is how the custom ApplyShippingCmdImpl command would look like-

@Override
    public void performExecute() throws ECException {
        super.performExecute();
       
        if (iItems != null && iItems.length > 0) {
           try {
               for (int index = 0; index < iItems.length; index++) {
                    Item iItem = iItems[index];
                       //Setting dummy price which can be retrieved from third party
                       iItem.setShippingTotal(new BigDecimal(111));
                       iItem.commit();
               }
           }catch (Exception e) {
               e.printStackTrace();
           }
        }
    }

@Override
    public void setItems(Item[] aItems) {
        iItems = aItems;
        super.setItems(aItems);
    }

Wednesday, March 8, 2017

Payment Flow

Overall OOB Payment Flow
------------------------------------ 
1. When the buyer lands on Shipping-Billing page, Payment section drop down lists the various payment options. All of these payment options are configured in WCS DB as payment business policies for the store.

Tables used-
Policy/Policydesc/Policycmd/Policytype/Policytyc

2. Once buyer fills the credit card details and click next, AjaxRestOrderPrepare & AjaxRestOrderPIAdd Ajax REST calls are made (after successfull server side validation of credit card details using CheckCCNumberCmdImpl) which results in OrderPrepare and PIAddCmdImpl invocation respectively. PIAddComImpl adds the payment instructions to the order i.e. in PPCPAYINST and PPCEXTDATA WCS tables.
    CheckoutPayments.js -> processCheckout -> processPIAndCheckout -> addPaymentInstructions

3. Once buyer submits the order, payment plugin will be invoked and entries are made in ORDPAYINFO, PPCPAYMENT and PPCPAYTRAN tables-
    CheckoutHelper.js -> checkoutOrder -> AjaxRESTOrderSubmit

Typical Punchout Payment Setup Steps

In a typical punchout payment configuration below steps are being followed-
- Configuring the new Payment method in the DB
- Configuring the new Payment method in the payment xml files 
- Create the payment method jsp and place it at intended location. 
- Creating a Payment Plug-in
- Customizing the Billing Page Storefront
- Customizing the CallBackCmd with action registration in struts-confog-ext.xml and ACP load
- Configuring merchant related information
- Configuring certificate for the handshake
- Testing the setup with PSP test account.

These steps are explained in detail below-

Configuring a new Payment/Refund method 
-------------------------------------------------------------
In order to add a new payment/refund method we would be required to-
a. Make entries in OOB WCS tables (POLICY/POLICYDESC/POLICYCMD with the Payment/ReturnPayment type)
b. Define the payment/refund actions/rules in XML files.

1. Configure Payment
toolkitDir/workspace/WC/xml/config/payments/ppc/plugins/PSP/PluginDeployment.xml
2. Configure Payment Method
PaymentMethodConfigurations.xml
3. Configure Action Rules
toolkitDir/workspace/WC/xml/config/payments/edp/groups/default/PSP/ with all the files copied from toolkitDir/workspace/WC/xml/config/payments/edp/groups/default/CreditCardOffline
4. Add Payment Mappings
toolkitDir/workspace/WC/xml/config/payments/edp/groups/default/PaymentMappings.xml
5. Map payment systems to payment plug-ins
PaymentSystemPluginMapping.xml

For new entry inside POLICY table, Business Policy Name must match the payment/refund method ID configured in payment rules (the paymentMethod value in the PaymentMethodConfigurations.xml file, or the refundMethod value in the RefundMethodConfigurations.xml file).

Merchant Feature
---------------------------
Merchant information is managed in below WCS tables-
MERCHANT, MERCHCONF, MERCHCONFINFO and STOREMERCH

Creating a Payment Plug-in
---------------------------------
Create an EJB stateless session bean.
Ensure your plug-in remote interface extends the Plugin or QueryablePlugin interface.
Create a plug-in deployment descriptor.
Create a JAR file (EJB module).

Payment Business flow: Extension Points
------------------------------------------------------
In a typical setup which is subject to customization-
On WCS order submission, payment is authorized with order total amount and order is transferred to the external system( subject to customization ). After order fulfilment by the external OMS, a shipment confirmation message is sent back to WCS to capture payment for the shipped order items in this package.

For Payment, PrimePaymentCmd is called at Order Submission ( ProcessOrderCmdImpl )
ReservePaymentCmd is called at ReleaseToFulfillment
FinalizePaymentCmd is called at shipment confirmation

Bypassing Payments : Void Implementations
----------------------------------------------------------
Though bypassing the OOB payment flow can be done through bypassing the ajax calls from shipping billing page to bypass the call to PIAddCmd however below OOB void commands can also be used-
e.g. com.ibm.commerce.edp.commands.PrimePaymentCmd                 com.ibm.commerce.edp.commands.PrimePaymentVoidCmdImpl

Payment life cycle
-----------------------
a. There are three stages to payment processing: validation, reservation, and finalization.

b. The payment life cycle is related to the order life cycle stages: order capture, release to fulfillment, and shipping.

c. Order capture- Payment validated
Release to fulfillment- Payment reserved
Order Shipping- Payment finalized

Friday, January 27, 2017

Customizing REST service over Solr to include custom table data in WCS 8 Mod Pack1

Introduction
--------------
PFB the steps to include the custom table XI_RATING data in Solr response and then in REST response in WCS 8-

1) Create the new DB table which will keep the ratings of the products loaded through third party system, populate it with some data for testing-
CREATE TABLE "WCSDB"."X_RATINGS"  (
"CATENTRY_ID" BIGINT NOT NULL ,
"RATING" BIGINT NOT NULL)  

2) Create the custom preprocess file to pick the data from the custom table X_ratings and populate the tem ptable XI_Ratings
File name - WCDE80\search\pre-processConfig\MC_10001\DB2\wc-dataimport-preprocess-custom.xml

<_config:DIHPreProcessConfig xmlns:_config="http://www.ibm.com/xmlns/prod/commerce/foundation/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ibm.com/xmlns/prod/commerce/foundation/config ../../xsd/wc-dataimport-preprocess.xsd ">
  <_config:data-processing-config processor="com.ibm.commerce.foundation.dataimport.preprocess.StaticAttributeDataPreProcessor" batchSize="500">
      <_config:table definition="CREATE TABLE XI_RATINGS ( CATENTRY_ID BIGINT NOT NULL, RATING BIGINT, PRIMARY KEY (CATENTRY_ID))" name="XI_RATINGS"/>
         
   <_config:query sql="SELECT DISTINCT CATENTRY.CATENTRY_ID,X_RATINGS.RATING FROM CATENTRY,X_RATINGS WHERE CATENTRY.CATENTRY_ID = X_RATINGS.CATENTRY_ID"/>
       <_config:mapping>
          <_config:key queryColumn="CATENTRY_ID" tableColumn="CATENTRY_ID"/>
             <_config:column-mapping>
                <_config:column-column-mapping>
                    <_config:column-column queryColumn="RATING" tableColumn="RATING" />
                </_config:column-column-mapping>
             </_config:column-mapping>
        </_config:mapping>   
  </_config:data-processing-config>
</_config:DIHPreProcessConfig>

3) Modify the Solr extension files as follow-
a)x-schema.xml-
<field name="rating" type="string" indexed="true" stored="true" required="false" multiValued="false"/>

b) x-data-config.xml-
<field column="RATING" name="rating"/>

c) solrcore.properties-
dataImporter.ext.querySelect=XI_RATINGS.RATING,
dataImporter.ext.queryFrom=LEFT OUTER JOIN XI_RATINGS ON (CATENTRY.CATENTRY_ID=XI_RATINGS.CATENTRY_ID)

4) Run preprocess with server stopped, and then start server and build Solr index
Newly included field can be validated using the Solr testing URL-
http://localhost/solr/MC_10001_CatalogEntry_en_US/select?q=catentry_id:<catentryId>

5) Make the new search profile in wc-search.xml by extending the existing search profile invoked in the REST service call under Search folder-
<_config:profile name="X_findCatalogEntry" extends="IBM_findProductByIds_Details">
   <_config:query inherits="true">
       <_config:postprocessor           classname="com.ibm.commerce.foundation.server.services.rest.search.postprocessor.solr.SolrRESTSearchCatalogEntryViewUserDataQueryPostprocessor" />
   </_config:query>
   <_config:result inherits="true">
           <_config:field name="rating" />
   </_config:result>  
</_config:profile>

6) Make the new wc-component.xml under Search folder ext folder- (It takes care of the mapping we used to have it under wc-business-object-mediator.xml prior to version 7 feature pack 7)

<?xml version="1.0" encoding="UTF-8"?>
<_config:DevelopmentComponentConfiguration
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.ibm.com/xmlns/prod/commerce/foundation/config ../xsd/wc-component.xsd "
    xmlns:_config="http://www.ibm.com/xmlns/prod/commerce/foundation/config">

    <_config:valuemappingservice>
        <_config:valuemapping externalName="CatalogEntryUserDataFieldNameMapping" internalName="CatalogEntryUserDataFieldNameMapping">
                <_config:valuemap externalValue="RATING" internalValue="rating" />
        </_config:valuemapping>
    </_config:valuemappingservice>
</_config:DevelopmentComponentConfiguration>

7) Make the new wc-rest-resourceconfig.xml file under /Search-Rest/WebContent/WEB-INF/config/com.ibm.commerce.rest-ext/wc-rest-resourceconfig.xml

<ResourceConfig>
    <Resource name="productview">
    <GetUri uri="store/{storeId}/productview/byId/{productId}"
            description="Get product by unique ID"                 searchProfile="X_findCatalogEntry,IBM_findProductByIds_Details,IBM_findProductByIdsWithAttributesAndAttachments,IBM_findProductByIds_Summary,IBM_findProductByIds_Summary_WithNoEntitlementCheck,IBM_Admin_findProductByIds"/>
</Resource>
</ResourceConfig>

8) Restart the server and access the new indexed fields in userdata section using rest call.

9) Testing
http://localhost/search/resources/store/10158/productview/byId/121892?responseFormat=xml&catalogId=10158&currency=USD

Thursday, January 26, 2017

Customizing REST service over Solr in WCS 8 Mod Pack1

Introduction
---------------
There is a slight difference in the way custom fields of the OOB WCS tables are added in Solr response and ultimately in REST response. Solr extensions now needed to be put in x-schema.xml, x-data-config.xml and solrcore.properties instead of schema.xml and wc-data-config.xml

Steps to include custom data catentdesc.AUXDESCRIPTION1 column on PDP page REST call
-----------------------------------------------------------------------------------------------------------------
1) Go to Path- toolkit\search\solr\home\MC_10001\en_US\CatalogEntry\conf
Modify x-schema. xml,solrcore.properties and x-data-config.xml as follow-

x-schema.xml-
<field name="auxdescription1" type="wc_text" indexed="true" stored="true" required="false" multiValued="false"/>

x-data-config.xml-
<field column="AUXDESCRIPTION1" name="auxdescription1"/>

solrcore.properties-
dataImporter.ext.querySelect=CATENTDESC.AUXDESCRIPTION1,

2) Run preprocess with server stopped, and then start server and build Solr index
Newly included field can be validated using the Solr testing URL-
http://localhost/solr/MC_10001_CatalogEntry_en_US/select?q=catentry_id:<catentryId>

3) Make the new search profile in wc-search.xml by extending the existing search profile invoked in the REST service call under Search folder-
<_config:profile name="X_findCatalogEntry" extends="IBM_findProductByIds_Details">
       <_config:query inherits="true">
           <_config:postprocessor           classname="com.ibm.commerce.foundation.server.services.rest.search.postprocessor.solr.SolrRESTSearchCatalogEntryViewUserDataQueryPostprocessor" />
       </_config:query>
       <_config:result inherits="true">
               <_config:field name="auxdescription1" />
       </_config:result>   
    </_config:profile>

4) Make the new wc-component.xml under Search folder ext folder- (It takes care of the mapping we used to have it under wc-business-object-mediator.xml prior to version 7 feature pack 7)

<?xml version="1.0" encoding="UTF-8"?>
<_config:DevelopmentComponentConfiguration
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.ibm.com/xmlns/prod/commerce/foundation/config ../xsd/wc-component.xsd "
    xmlns:_config="http://www.ibm.com/xmlns/prod/commerce/foundation/config">

    <_config:valuemappingservice>
        <_config:valuemapping externalName="CatalogEntryUserDataFieldNameMapping" internalName="CatalogEntryUserDataFieldNameMapping">
                <_config:valuemap externalValue="AUXDESCRIPTION1" internalValue="auxdescription1" />
        </_config:valuemapping>
    </_config:valuemappingservice>
</_config:DevelopmentComponentConfiguration>


5) Make the new wc-rest-resourceconfig.xml file under /Search-Rest/WebContent/WEB-INF/config/com.ibm.commerce.rest-ext/wc-rest-resourceconfig.xml
 
<ResourceConfig>
    <Resource name="productview">
        <GetUri uri="store/{storeId}/productview/byId/{productId}"
                description="Get product by unique ID"                 searchProfile="X_findCatalogEntry,IBM_findProductByIds_Details,IBM_findProductByIdsWithAttributesAndAttachments,IBM_findProductByIds_Summary,IBM_findProductByIds_Summary_WithNoEntitlementCheck,IBM_Admin_findProductByIds"/>
    </Resource>
</ResourceConfig>

6) Restart the server and access the new indexed fields in userdata section using rest call with new search profile.

7) Testing
http://localhost/search/resources/store/10158/productview/byId/121892?responseFormat=xml&catalogId=10158&currency=USD

Wednesday, November 30, 2016

B2B Contracts

Contracts
A Contract helps defining the terms & conditions for the online customer. It becomes very crucial in setting up the different shopping experiences on the same online store for different buyer accounts in B2B setup.

These T&Cs modify the online customer's shopping experience including-
Products entitlement,
Price entitlement,
Shipping and payment options,
Permissible order limit.

1. A contract can either be assigned to Member group or Organization.

2. Buyer can have multiple contracts setup and active during the shopping session and he can even avail distinct contracts for distinct orderitems of the same order(OrderItems.TRADING_ID & TERMCOND_ID) provided that the contracts are compatible against each other(OrderItemBaseCmdIml-> validateTradingPaymentMethods()).

3. ContractSetInSessionCmdImpl command helps to setup a particular contract during shopping (out of various active contracts created for the buyer organization) which is ultimately saved inside EntitlementContext context of Ctxdata table

Types
1) The default contract
A store has a default contract which allows guest and unregistered shoppers to shop in the store
            Storedef -> Store default contract & default shipmode (Buyer default contract through Contract.Usage column 0 value)
2) A base contract
Can be shared by many contracts
3) A customer contract.
A customer contract is one that has a Buyer participant

Data Model
STOREENT(STOREENT_ID) -> ORGENTITY(STORE OWNER) -> ACCOUNT(ACCOUNT_ID) -> TRADING(TRADING_ID)  -> PARTICIPNT

Store Contracts (STORECNTR)
    Store -> Contracts
Business Accounts (ACCOUNT)
    Store -> Accounts
Participants (PARTICIPNT)
    Buyer organization -> Contracts
Terms and Conditions (TERMCOND)
    Contract -> Terms & Conditions


Storcntr- Contains all contracts deployed in the store
Contract- Base table for contract
Account- Represents a business account between a Buyer organization and a Seller organization
Participnt- Contains the Buyer organization and Contract relationship
Trading- Contract is a specific type of trading
TermCond- Contains all the terms and conditions associated with the contract such as Price rule, Catalog filter, Price list, Payment and Shipping method, Approval required etc.
Catfilter- Base table for catalog filter
Pricerule- Base table for the price rule
Expression- Contains the solr runtime expression for the contract.
Tradeposcn- Contains the price list details

Creating Contracts
1. Simplest way is to create a contract using accelerator,
2. We can also create a contract by extracting/loading the XML,
3. Creating a new version of a contract,
4. Creating a contract through custom dataload utility.


TermCond Mapping
TermCond table contains a number of generic columns used to store information about terms and condition with different terms and conditions use the columns differently. Each mapping shows how the information in the XML elements of the terms and conditions map to columns in the TERMCOND table-

PriceRuleTC
CatalogFilterTC
PriceTCMasterCatalogWithFiltering
ShippingTCShipToAddress
ShippingTCShippingMode
ShippingTCShippingCharge
OrderApprovalTC
RightToBuyTCByAmount
ObligationToBuyTCByAmount

Price List, Price Rule & Contracts
A very prominent usage of contracts in B2B system is to utilize it to setup the multiple pricing tier for the buyer aligned under different buyer organizations.

Price list can be created and assigned to the contract through price rule allowing the different set of buyers to avail different prices for the same products.
For a price rule to display offer prices on store pages, you must assign the price rule to a contract.

BUYER -> BUYER ORG -> CONTRACT <- PRICE RULE <- PRICE LIST <- PRICE

After you assign the price rule to a contract, customers shopping under the contract see and are entitled to prices from the price rule. Remember a price rule is one of many terms and conditions that a contract can have.

Tables-
PRICERULE: Each row of this table represents a price rule in a store. Price rule is a business rule which defines how to get a dynamic price under different business conditions
PRELEMENT: Each row of this table represents a price rule element.
PRELETEMPLATE: Each row of this table represents a price rule element template
PRELEMENTATTR: Each row of this table represents a price rule attribute in name value pair. P.S: This table maps the price rule of termcond table with actual price list in tradposcn table.

Data Flow-
CONTRACT -> TERMCOND(STRINGFIELD1) -> PRICERULE -> PRELEMENT -> PRELEMENTATTR -> TRADEPOSCN -> OFFER -> OFFERPRICE -> ACTUAL PRICE

CMC provides support for-
Price Rule,
Price List

UseCase: Applying Multiple Tier Pricing for different buyer orgs
Export an existing price list and then upload it again after modification as a new price list through CMC.
Now create a price rule to make use of this new price list
This price rule can be applied to a contract through accelerator
User logging into the buyer organization can avail the special pricing through the contract.

Catalog Filter and Contracts
Another prominent usage of contracts in B2B system is to utilize it to setup the multiple catalog tier for the buyer aligned under different buyer organizations.

Catalog filter can be created and assigned to the contract which allows the buyer to shop for the filtered items in the e-site.  
BUYER -> BUYER ORG -> CONTRACT <- CATALOG FILTER <- CATALOG ENTITY

Data Flow-
CONTRACT -> TERMCOND(BIGINTFIELD1) -> CATFILTER -> CFCATGROUP -> CFCONDGRP -> CFCOND -> CFCONDVAL

We can use catalog filters for the product entitlement, that is, to entitle customers to a subset of the catalog

Note: We can create catalog filters to filter objects for only our master catalog. We cannot create catalog filters for a sales catalog. So if we apply the catalog filer to the master catalog it eventually retrieves the entitled products from the sales catalog.

Catalog Filter Tables-
CATFILTER - Each row of this table represents a catalog filter.
CATFLTDSC- Each row of this table represents a language specific description of a certain catalog filter.
CFCATGROUP- Each row represents a selected catalog group in the catalog tree.
CFCONDGRP- Each row of this table represents a condition group in a certain catalog filter
CFCOND- Each row of this table represents a condition in a certain condition group
CFCONDVAL- Each row of this table represents the association between a condition and an attribute value.
PRODUCTSET- This table holds the definition of a product set. The actual representation of the product set is held in the PRSETCEREL table.
CFPRODUCTSET- Each row represents the relationship between a catalog filter and a product set used for filtering.

Unit Testing Contracts Filtering
Expression table entry helps building the solr expression for debugging  for catalog filter or productset-

e.g.
http://server/solr/MC_10001_CatalogEntry_en_US/select?q=*:*&fq=catalog_id:"11111"&fq=storeent_id:("22222" "33333")&fq=published:1&fq=((( +*:* -*:*) productset_id:("55555555") ) productset_id:("44444444") )

Saturday, August 13, 2016

Steps to enable registered users to access all stores in the Extended Sites business model

WCS users can access storefronts by virtue of having the role of Registered Customer in the organization that owns the store, or in any organization above it. The roles a user has access to during registration are defined within the MemberRegistrationAttributes.xml file.

By default the MemberRegistrationAttributes.xml file is set up to give access to only the store where the user is registering.

By Adding the below snippet in the top of the file MemberRegistrationAttributes.xml under <UserRoles> section, we can allow the registered user of any of the esite of the extended site setup to access all stores as a registered user-

<User registrationType="UserRegistration" memberAncestor="o=Default Organization,o=Root Organization"
                        storeAncestor="o=Extended Sites Seller Organization,o=Root Organization">
                  <Role name="Registered Customer" roleContext="explicit" DN="o=Extended Sites Seller Organization,o=Root Organization"/>
                </User>


Sunday, July 3, 2016

Customizing REST service over BOD Part-1 WCS 7 FEP 8

Introduction
REST services are built on top of OAGIS services. Each REST resource is mapped to a Business Object Document (BOD) noun which further follow either the SOI or SOA(BOD) paradigm.


High-Level Changes Required
BOD service can first itself be extended to include the additional attribute in userdata by modifying the BOD related configuration files such as wc-business-object-mediator.xml, wc-object-relational-metadata.xml, wc-component.xml and TPL files and then the additional BOD custom data can be mapped to REST response using rest-resourceName-clientobjects.xml file.

BOD Level Changes-
1. Extend the WCS DB Schema (in case of custom table/column)
2. Run the DSL wizard to generate the supporting BOD configuration files
3. Add the query template files.
4. Add the Access profiles.
4. Validate the changes (can be done through JUNIT)

REST Layer Changes-
1. wc-rest-resourceconfig.xml
2. rest-resourceName-clientobjects.xml
3. Resource Handler

e.g. rest-wishlist-clientobjects.xml is the mapping file used for the wishlist noun stored under the directory- Rest.war/WEB-INF/config/bodMapping

Details
We are considering the BOD pattern in this example so we will pick the wishlist noun to explain the flow and required files to be modified to add additional data


1. wc-rest-resourceconfig.xml is the main file which contains all the REST URLs being utilized for the nouns, This file should be extended if we want to add custom access profile or search profile for the noun-

<Resource name="wishlist">
    <GetUri uri="store/{storeId}/wishlist/@self" description="Get wish list data for a logged in user"
                accessProfile="IBM_Store_GiftListSummaryAndItems"/>
       <GetUri uri="store/{storeId}/wishlist/@default" description="Get default wish list for a logged in user"
         accessProfile="IBM_Store_GiftListSummaryAndItems"/>
      
    <GetUri uri="store/{storeId}/wishlist/{externalId}" description="Get wish list by external id"
                accessProfile="IBM_Store_GiftListSummaryAndItems"/>

   <GetUri uri="store/{storeId}/wishlist/{externalId}/item" description="Get wish list items by external id with paging support"  accessProfile="IBM_Store_GiftListItems"/>
</Resource>

2. rest-resourceName-clientobjects.xml
This file contains the mapping between REST data and BOD noun. Any customization to be done in this file requires a copy to be created under the structure-
Rest.war/WEB-INF/config/bodMapping-ext

e.g. below snippet provides support to add custom grgftreg data in userdata section-

<_config:URLParameter name="x_" nounElement="/UserData/UserDataField" key="false" return="true" type="UserData"/>


3. Resource Handler
Resource handler contains the RESTful services to manage the operations on the noun.
e.g. WishlistHandler class provides RESTful services to get and manage a shopper's wish lists.


4. wc-component.xml
It contains properties to configure various REST features.


5. wc-business-object-mediator.xml

It contains the mapping between physical and logical SDOs

e.g. below snippet maps the custom grgftreg fields-


<_config:property-mapping logicalType="com.ibm.commerce.giftcenter.facade.datatypes.GiftListType" physicalType="com.ibm.commerce.giftcenter.facade.server.entity.datatypes.Grgftreg">
             <_config:userDataProperty logicalPropertyName="field1" physicalPropertyName="field1"/>
            <_config:userDataProperty logicalPropertyName="field2" physicalPropertyName="field2"/>
            <_config:userDataProperty logicalPropertyName="field3" physicalPropertyName="field3"/>
            <_config:userDataProperty logicalPropertyName="field4" physicalPropertyName="field4"/>
            <_config:userDataProperty logicalPropertyName="field5" physicalPropertyName="field5"/>
         </_config:property-mapping>


6. wc-object-relational-metadata.xml

It contains the mapping between physical SDOs and the actual database tables.

e.g. below snippet maps the field1 column-


<_config:table name="GRGFTREG" occColumnName="OPTCOUNTER" propertyName="Grgftreg">
<_config:column name="FIELD1" nullable="true" primaryKey="false" propertyName="field1" type="INTEGER"/>
</_config:table>


7. TPL files

In the BOD paradigm, tpl files contains the queries( single step or two step ) to interact with the database.

e.g. the below section contains the second step of the query to be executed based upon the access profile-


BEGIN_PROFILE
   name=IBM_Store_GiftListSummaryAndItems
   BEGIN_ENTITY
     base_table=GRGFTREG
     associated_sql_statement=IBM_GR_Summary
     associated_sql_statement=IBM_GR_Registrant_Without_Address
     associated_sql_statement=IBM_GR_Events
     associated_sql_statement=IBM_GR_Items
    END_ENTITY
END_PROFILE