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

Saturday, May 14, 2016

Pulishising E-Sites with B2B Store Model

IntroductionCreating the the extended sites setup depends upon many factors like the Store model /StorefrontAssetStore/CatalogAssetStore/Store currency/Inventory to be used.

We can refer the high level steps required to be performed to get e-sites published in B2B store model-
First of all we need to have the instance created in the server environment or WCS installation to be done if working in the local setup. Then we need to perform the below steps-

1) Log into WCS Admin Console and publish the ExtendedSitesOrganizationStructure.sar
2) Publishing the extended site hub using ExtendedSitesHub.sar.
3) Publish the Catalog Asset Store using ExtendedSitesCatalogAssetStore-FEP.sar
4) Publish the Storefront Asset Store using AuroraStorefrontAssetStore.sar.
5) Create the Buyer Organizations using WC Organization Admin Console
6) Create the Seller Organizations using WC Organization Admin Console
7) Create the required esites using WC Accelerator by providing values like storeIdentifier, default currency, store type and payment modes
8) Open the newly created stores using WC Acclerator
9) Create Sales Catalogs for Each Site as per the requirement
10) Load Catalog Data as per the requirement
11) SOLR Setup – SetupSearchIndex, Di-preprocess, Build Search Index

Note: By default SARs may not be available to be published in Admin console, in this case SARs need to be copied into the path defined in wc-server.xml.

Sunday, April 10, 2016

Organization Structure

Introduction
All parts of the WCS business whether its actor or entities, including customers, administrators, stores, catalogs and distributors, must be owned by either an organization or organizational unit.

1) Basic WCS Organization Structure
This is how the basic organization structure looks like after the WCS instance creation, regardless of the business model being used-



Root Organization- It's right there at top with all WCS organizations acting as descendants of the root organization. The site administrators are owned by the root organization.

Default Organization- The default organization is owned by the root organization. And this is where all the B2C and guest users point to.

Note: B2C users under the default organization can be managed by an administrator in WCS Accelerator. Business users outside of the default organization e.g. B2B users can be managed in the Organization Administration Console. 
 
 
2) B2C Organization Structure
The B2C organization structure contains three organizations: root, default, and seller-
 

Seller Organization- A seller organization is created to own all the stores (Retailer) and the Seller administrators who maintain the store. 

B2C Seller Organization ( Intermediate and Optional )- An intermediate B2C organization is created to own a single store (Retailer) and Seller administrators. 
 
 3) B2B Direct Organization Structure

 

Buyer Organization- B2B Buyers are represented by a buyer organization in the B2B organization structure. 
4) Extended Sites Organization Structure
The extended sites organization structure consists of the root organization, default organization, extended sites organization, and extended sites seller organization-



Access Control in WCS- Part2


Implementing access control policies

---------------------------------------------
PFB the details to implement access control in different elements-
1) Controller Commands
A.Using SQL Queries-
insert into acrescgry (ACRESCGRY_ID,RESCLASSNAME) values ((select counter from keys where tablename='acrescgry'),'com.sample.commands.MyOrderCmd');
insert into acresact (ACRESCGRY_ID, ACACTION_ID) values ((select counter from keys where tablename='acrescgry'),(select ACACTION_ID from acaction where action='Execute'));
insert into acresgpres (ACRESGRP_ID, ACRESCGRY_ID) values ((select ACRESGRP_ID from acresgrp where MEMBER_ID in (select orgentity_id from orgentity where orgentityname='Root Organization') and GRPNAME='RegisteredUserCmdResourceGroup'), (select counter from keys where tablename='acrescgry'));
update keys set counter=counter+1 where tablename =’acrescgry’;

B. Using ACPLOAD utlility-
<Policies>
                <Action Name="ExecuteCommand"  CommandName="Execute"/>
                <ResourceCategory Name="com.ibm.commerce.sample.commands.MyControllerCmdResourceCategory"
                                ResourceBeanClass="com.ibm.commerce.sample.commands.MyControllerCmd">
                                <ResourceAction Name="ExecuteCommand"/>
                </ResourceCategory>    
                <ResourceGroup Name="AllSiteUserCmdResourceGroup"  OwnerID="RootOrganization">
                                <ResourceGroupResource Name="com.ibm.commerce.sample.commands.MyControllerCmdResourceCategory"/>
                </ResourceGroup>
</Policies>


2) Views

A.Using SQL Queries-
insert into acaction (acaction_id, action) values ((select counter from keys where tablename='acaction'), 'MyView');
insert into acactactgp (ACACTGRP_ID,ACACTION_ID) values ((SELECT ACACTGRP_ID FROM ACACTGRP WHERE GROUPNAME = 'AllSiteUsersViews' and member_id in (select orgentity_id from orgentity where orgentityname='Root Organization') ), (select acaction_id from acaction where action='MyView'));
update keys set counter=counter+1 where tablename ='acaction';

B. Using ACPLOAD utlility-
<Policies>
                <Action Name="SpecialOrderView" CommandName="SpecialOrderView"/>
                <ActionGroup Name="AllSiteUsersViews" OwnerID="RootOrganization">
                                <ActionGroupAction Name="SpecialOrderView"/>
                </ActionGroup>
</Policies>

3) BOD command framework
Resources that the BOD commands act upon are nouns are represented by generated Java objects. These generated Java objects do not implement the Protectable interface required by the PolicyManager. 
To address this requirement, a wrapper object must be implemented for each noun to extract the information required by the PolicyManager to perform authorization checks. This mapping is defined in the wc-component.xml file

For SOI name-value pair commands, before they run, a command level and a resource level authorization is performed. 

In the BOD command framework, only resource level access control checks are performed, except for Get requests, where Get performs an access control check on whether the request is allowed to use the specified access profile.

There are two assets that need to be implemented for access control for a BOD command:
A. The Protectable Proxy class that represents the noun
B. Access control policies that grant user access to the particular command.
 
4) Enterprise Beans
Access control starts from the step when remote interface of the bean extends the com.ibm.commerce.security.Protectable interface at the time of creation

The enterprise bean class inherits default implementations for the following methods from com.ibm.commerce.base.objects.ECEntityBean:
      
fulfills()- The fulfills method must be implemented if there is an access control policy that includes this resource in its resource group, and also specifies a relationship or relationship group.
default returns false

getGroupingAttributeValue()- The getGroupingAttributeValue method must be implemented if there is an access control policy with an implicit resource group that includes certain instances of this resource, based on specific attribute values (for example, if there were an access control policy that pertains only pertains to Orders with status = 'P' (pending))
default returns null

getOwner()- Note that if the only relationship needed is "owner", then you do not need to override the fulfills method. In this case, the policy manager will make use of the result of the getOwner() method. 
default returns null

5) Data Beans
If a data bean is to be protected, it can either be directly, or indirectly protected by access control policies. 
If a data bean is directly protected, then there exists an access control policy that applies to that particular data bean. 
If a data bean is indirectly protected, it delegates protection to another data bean, for which an access control policy exists.

If you create a new data bean that is to be directly protected by an access control policy, the data bean must do the following:

A. Implement the com.ibm.commerce.security.Protectable interface. As such, the bean must provide an implementation of the getOwner() and fulfills(Long member, String relationship) methods. When a data bean implements the Protectable interface, the data bean manager calls the isAllowed method to determine if the user has the appropriate access control privileges, based upon the existing access control policies. The isAllowed method is described by the following code snippet:
    isAllowed(Context, "Display", protectable_databean);
    where protectable_databean is the data bean to be protected.
               
B. If resources that the bean interacts with are grouped by an attribute other than the resource's Java class name, the bean must implement the com.ibm.commerce.grouping.Groupable interface.
   
C. Implement the com.ibm.commerce.security.Delegator interface. This interface is described by the following code snippet:
    Interface Delegator {
            Protectable getDelegate();
    }
    Note: In order to be directly protected, the getDelegate method should return the data bean itself (that is, the data bean delegates to itself for the purpose of access control).

6) REST Services
A. For Create, Update, and Delete operations:
REST services must wrap BOD commands or controller commands to have access control enforced. This is the only supported and secure option.

B. For Get operations:
REST services must wrap BOD commands or data beans to have access control enforced.
REST over data beans: Access control is enforced if the underlying data bean implements the Delegator interface. If the data bean does not implement the Delegator interface, it can be called using local binding through JSP files, assuming the data bean does not expose sensitive data to the end user. If you are using remote binding through REST service calls, and the data bean does not implement the Delegator interface, only a Site Administrator can run the service call by default. This can be customized by overriding the isSiteResource(DataBean) method of the REST Resource Handler class.

Access Control in WCS - Part1

Introduction
----------------
Access control policies are enforced by the access control policy manager. Generally, when a user attempts to access a protected resource, the access control policy manager first determines what access control policies are applicable for that protected resource, and then, based upon the applicable access control policies, it determines if the user is allowed to access the requested resources.

An access control policy is a 4-tuple policy that is stored in the ACPOLICY table
Each access control policy takes the following form:
AccessControlPolicy [UserGroup, ActionGroup, ResourceGroup, Relationship]

The elements in the 4-tuple access control policy specify that a user belonging to a specific user group is permitted to perform actions in the specified action group on resources belonging to the specified resource group, as long as the user satisfies the conditions specified in the relationship or relationship group, with respect to the resource in question.

User/User Group
----------------------

A user group must be associated with member group type of -2. The value of -2 represents an access group and is defined in the MBRGRPTYPE table.

The membership of a user into a particular user group might be stated explicitly or implicitly. An explicit specification occurs if the MBRGRPMBR table states that the user belongs to a particular member group. 
An implicit specification occurs if the user satisfies a condition (for example, all users that fulfill the role of Product Manager) that is stated in the MBRGRPCOND table

Most conditions to include a user in a user group are based upon the user fulfilling a particular role. For example, there could be an access control policy that allows all users that fulfill the Product Manager role to perform catalog management operations. In this case, any user that assigned the Product Manager role in the MBRROLE table is then implicitly included in the user group.

Action/Action Group
--------------------------

The ActionGroup element comes from the ACACTGRP table. An action group refers to an explicitly specified group of actions. The listing of actions is stored in the ACACTION table and the relationship of each action to its action group (or groups) is stored in the ACACTACTGP table. An example of an action group is the "OrderWriteCommands" action group. This action group includes the following actions that are used to update orders:
  • com.ibm.commerce.order.commands.OrderDeleteCmd
  • com.ibm.commerce.order.commands.OrderCancelCmd
  • com.ibm.commerce.order.commands.OrderProfileUpdateCmd
  • com.ibm.commerce.order.commands.OrderUnlockCmd
  • com.ibm.commerce.order.commands.OrderScheduleCmd
  • com.ibm.commerce.order.commands.ScheduledOrderCancelCmd
  • com.ibm.commerce.order.commands.ScheduledOrderProcessCmd
  • com.ibm.commerce.order.commands.OrderItemAddCmd
  • com.ibm.commerce.order.commands.OrderItemDeleteCmd
  • com.ibm.commerce.order.commands.OrderItemUpdateCmd
  • com.ibm.commerce.order.commands.PayResetPMCmd
Resource/Resource Group
--------------------------------

A resource group is a mechanism to group together particular types of resources. Membership of a resource in a resource group can be specified in one of two ways:
    Using the conditions column in the ACRESGRP table
    Using the ACRESGPRES table

Relationship(Optional)
-------------------------------

The access control policy can optionally include either a Relationship or RelationshipGroup element as its fourth element.
If your access control policy uses a Relationship element, this comes from the ACRELATION table. If it includes a RelationshipGroup element, that comes from the ACRELGRP table. Note that neither need be included, but if you include one, you cannot include the other. A RelationshipGroup specification from the ACRELGRP table takes precedence over the Relationship information from the ACRELATION table.

Types
--------
Command-level (Broad),Also known as role-based.
•Specifies that users assigned to a particular role can execute certain commands.
Applied on controller commands and views
•For example,guest users can execute the commands that are contained in action group X.
 
Resource-level (Very fine)
•Specifies the relationship that a user must have with a resource before a given action can be performed.
Applied on databeans
•For example a user can only display an order they created

Mixed
Command-level Access Control determines whether the user is allowed to execute the particular command within the store you have specified. If a policy allows the user to execute the command, a subsequent Resource-level Access Control Policy could be applied to determine whether the user can access the resource in question.




Thursday, April 7, 2016

Bazaarvoice Feed Customization in WCS FEP 5 & 6

Bazaarvoice ratings and reviews in Feture pack 5 & 6
--------------------------------------------------------------------
Bazaarvoice is a software-as-a-service provider that offers ratings and reviews functionality to their clients. Support for the Bazaarvoice Ratings and Reviews component is included in the Aurora starter store in FEP 5 & 6 for Bazaarvoice clients.

Integration components
----------------------------
1) Storefront support
The Bazaarvoice JavaScript library is used in the Aurora JSP files to include ratings and review content in your store pages

2) Smart SEO feed
Bazaarvoice makes available a SEO representation of the User Generated Content (UGC) because search engines like Google do not index JavaScript rendered content in the form of ZIP file that contains small HTML files with Smart SEO content for ratings and reviews that are associated with an account.

3) Product catalog feed
Bazaarvoice requires clients to upload a product catalog feed that contains information about the catalog of the store. This data is used to represnet ratings and reviews on storefrfront pages

Bazaarvoice integration includes a tool that extracts the catalog for a store into an XML file. The tool packages the XML file into a ZIP archive, and uploads the archive to your Bazaarvoice FTP or SFTP site, We will look into the componenets which can be modified to get tailor made catalog feed matching the client needs.

Steps to generate product feed for bazaarvoice
-----------------------------------------------------------
1) Copy the WC_installdir/components/foundation/samples/RRDataExtract directory to WC_installdir/samples.

2) Navigate to the WC_installdir/samples/RRDataExtract directory. The bazaarvoiceFeedProps.properties file is your property_file and fill the values-

storeId- The ID of the store to extract the product catalog feed from.
wcs.admin.user- WebSphere Commerce site administrator user name.
wcs.admin.password- WebSphere Commerce site administrator password.
bv.user.name(Optional)- Your FTP or SFTP account user name for the Bazaarvoice server (bv_username)
bv.user.password(Optional)- Your FTP or SFTP account password for the Bazaarvoice server (bv_password).Encrypt the password with the wcs_encrypt utility.
seo.base.dir (Optional)- The base path into which the Smart SEO content is extracted
data.feed.base.dir- Full path base directory for product catalog feed
langid- The default language for the store.
currency- The default currency for the store.
wc.url.prefix-  The WebSphere Commerce Server host_name and preview port, typically 8007 for HTTP and 8006 for HTTPS. This parameter is used to extract data from certain web service URLs for the product catalog feed.
staging-    Indicates the environment for which to upload/download content to/from Bazaarvoice.
production-  Indicates the environment for which to upload/download content to/from Bazaarvoice.
sftp-  Indicates the method of upload or download feed to and from Bazaarvoice. If false, the method is set to FTP.Default value is true.
antivirus (Optional): Command to invoke for antivirus scan of SEO directory.

3) Navigate to the WC_installdir/components/foundation/bin directory and Run the script or batch file according to the envinment bazaarvoiceDataFeed.sh to initiate the upload of product catalog feed content to Bazaarvoice.

4) Verify that Bazaarvoice collected and processed the product catalog feed upload.

5) Run the script bazaarvoiceSeoFeed.sh to initiate the download of Smart SEO content from Bazaarvoice and Verify that the Smart SEO content was downloaded.


Components to customize the catalog feed
-----------------------------------------------------
Below componenets from the Bazaarvoice feed structure can be customized/modified to generate the tailor made Product Feed-

1) AbstractDataWriter (Class)
2) OutputDataWriter (Class)
3) CatalogEntryCategoryLevelSkuReaderMediator (Mediator class)
4) wc-query-CatalogEntry-admin-get.tpl tpl file
5) performDataExtract.xml (configuration file)
6) wc-dataextract-catalog-entry.xml.template (configuration file)
7) wc-dataextract-catalog-group.xml.template (configuration file)

Checkout Flow in WCS- Step 3

OrderPrepareCmdImpl
This step helps preparing the order for submission by determining its final prices( if we have to make a real time price call then this is the place), discounts, shipping charges, and taxes with the help of PrepareOrderCmd task command doProcess() method. 

It picks up all the current pending orders of the user in the store if no order reference number is specified. The remerge, merge, check, allocate, backorder and reverse parameters are applicable only if ATP inventory is enabled (STORE Table INVENTORYSYSTEM column value -1).

OrderPrepareCmd calls the following task commands in the sequence-
1.ValidateShippingAdjustmentCmd
2.ValidateShippingMethodCmd
3.PrepareOrderCmd

a. Validates the order is in the correct status which must be any one of the P, I, E, W, or N.
b. If the value of the input request property "commit" is 1(default is 0), a new database transaction is started for every order to be prepared. Otherwise, all orders are prepared in one transaction (the default behavior).

code snippet-
if(ibCommit){
MiscCmd.startNewTransaction(getCommandContext());
lockItemSpecificationsInOrders(abOrder);
}

c. ValidateShippingAdjustmentCmd is invoked to validate that the order hasn't changed since a shipping adjustment was added.
d. Finally PrepareOrderCmd task command is called to do pricing, calculation and inventory actions.

doProcess()
a. Delete generated order items (refer to the PREPAREFLAGS column in the ORDERITEMS table).
b. Check that all order items in the order are buyable (refer to the BUYABLE column in the CATENTRY table).
c. Call DoInventoryActionCmd to check the availability of the products with action CHECK_INVENTORY.
d. Obtain latest unit price for each order item, except those with manually overridden prices or are quotations. (refer to PREPAREFLAGS column of the ORDERITEMS table).
e. Re-calculate the amounts for the order.
f. Lock the order to indicate that it is ready for the OrderProcess command. The lock can be reset either by expiry, by changing the Order (for example, by using the OrderItemUpdate command), or explicitly by using the OrderUnlock command. The expiry period for a lock is stored in the QUOTEGOODFOR column of the STORE table.

Code Snippet-
        if(iATPParameters != null && isLockItemSpecInATP())
            lockItemSpecs(iATPParameters.getAllocate(), iATPParameters.getBackorder(),   iATPParameters.getReverse());

        aOrderProcessingUtility.removeGeneratedOrderItems();
        ensureAllOrderItemsAreBuyable(aOrderProcessingUtility);
        aOrderProcessingUtility.updateOrderItemAddresses();
        aOrderProcessingUtility.updateOrderItemConfigurations(getCommandContext());
        updateOrderItemPrices(aOrderProcessingUtility);

        if(iATPParameters != null)
            iATPParameters.refreshAll();

        calculateOrderForFreeGifts(aOrderProcessingUtility);
        aOrderProcessingUtility.checkOrderInventory();
        InventoryManagementHelper.flush();
        calculateOrder(aOrderProcessingUtility);
        aOrderProcessingUtility.saveOrder(); 


OrderProcessCmdImpl
    processOrders() -> processOrderComments() -> OrderCommentRecordContrlCmd
                        -> processOrderChannelId() -> order.BuschnId
                        -> processPIAdd(ibPerformPIAdd=true) -> PIAddCmd, validatePaymentMethodCmd
                        -> callProcessOrder(isUBFEnabled()) -> BusinessFlowUrlEventCmd -> PreProcessOrderCmdImpl
                                                                                                            -> validateOrderState
                                                            -> validateContract() -> CheckCatalogEntryEntitlementCmd
                                                            -> validateShippingAddress()
                                                            -> allocateInventory() -> DoInventoryActionCmd
                                                            -> checkorder() -> CheckOrderCmd
                                                            -> CheckOrderAcceptanceCmd
                                                            -> updateBillingAddress() -> ValidateOrderAddressCmd
                                                            -> CheckPaymentTCsCmd
                                                            -> ProcessOrderCmdImpl
                                                            -> mergeShopperPayInfo
                                                            -> handleOrderFraud()
                                                            -> checkOrderAndItemTotals()
                                                            -> updateInventory()
                                                            -> getInitialAmount() throws exception if dInitialAmount.compareTo(dOrderTotal)
                                                            -> UpdateSpendingLimitCmd