Thursday, June 28, 2012

Pricing the Order : ATG

Pricing the Order

Order pricing in Commerce Reference Store is based on the Commerce pricing services described in the ATG Commerce Programming Guide. The process is managed by the /atg/commerce/pricing/PricingTools component, which calls the following pricing engines in the order listed:


/atg/commerce/pricing/ItemPricingEngine -- Determines the price for each item in the order.

/atg/commerce/pricing/OrderPricingEngine -- Determines the order subtotal, which includes the total price of all the items, but does not include shipping or taxes.

/atg/commerce/pricing/ShippingPricingEngine -- Determines the shipping price for each shipping group in the order.

/atg/commerce/pricing/TaxPricingEngine -- Determines the tax charges for the order.



Each pricing engine iterates through a set of precalculators to determine an initial price. It then applies any promotions of the corresponding type (i.e., item discount, order discount, or shipping discount) that have been granted to the customer. (See the Promotions chapter for information about the available promotions.) When one engine finishes its work, the next engine is called, until the total price is determined.


So, for example, if a customer has been granted a promotion for 10% off the order total, the


OrderPricingEngine:



1.Invokes /atg/commerce/pricing/calculators/OrdersSubtotalCalculator, which computes an initial subtotal by summing the prices (previously determined by ItemPricingEngine) of the items in the order.

2.Applies the promotion, which reduces the order price by 10%.

PricingTools then invokes ShippingPricingEngine.

ItemPricingEngine


Commerce Reference Store configures ItemPricingEngine to use precalculators that look up prices in price lists:

precalculators=\
   calculators/ItemPriceListCalculator,\
   calculators/ItemPriceListSaleCalculator,\
   calculators/ConfigurableItemPriceListCalculator,\
   calculators/ConfigurableItemPriceListSaleCalculator
OrderPricingEngine


Commerce Reference Store uses OrderPricingEngine without any additional configuration.


ShippingPricingEngine


Commerce Reference Store configures ShippingPricingEngine to use three precalculators: /atg/commerce/pricing/shipping/Ground, /atg/commerce/pricing/shipping/TwoDay, and /atg/commerce/pricing/shipping/NextDay. The calculator applied to an individual shipping group is determined by the shipping method specified for that shipping group.

The TwoDay and NextDay calculators are fixed-price calculators (class atg.commerce.pricing.FixedPriceShippingCalculator), applying prices of $9.50 and $18.95 to the shipping group, respectively. The Ground calculator (class atg.commerce.pricing.PriceRangeShippingCalculator) determines the shipping price based on the total cost of the items in the shipping group. The shipping prices are set through the ranges property of the calculator:


ranges=00.00:14.99:4.75,\
       15.00:49.99:5.95,\
       50.00:MAX_VALUE:6.50

This setting means that if the total is $14.99 or less, shipping is $4.75; if the total is between $15.00 and 49.99, shipping is $5.95; and if the total is $50.00 or more, shipping is $6.50.


TaxPricingEngine


TaxPricingEngine is configured in Commerce to use /atg/commerce/pricing/calculators/TaxProcessorTaxCalculator as its precalculator. This component (of class atg.commerce.pricing.AddressVerificationTaxProcessorTaxCalculator), has a taxProcessor property that is set to the component that performs or manages the actual tax calculations.

By default, this property is set to /atg/commerce/payment/DummyTaxProcessor, which always returns $0.00. If you integrate your store with tax-calculating software, you can instead set taxProcessor to a component that makes calls to the tax-calculating software and processes the results.

Enabling Express Checkout : ATG

In order to use the express checkout feature, the customer must have registered as a member, logged in as a member, and entered at least one valid credit card and one shipping address. Once these conditions are met, a customer may enable the express checkout feature by clicking see my express checkout ordering preferences under “My commerce profile” on the “My Profile” page and then clicking the Set Your Express Checkout Preferences button.








The hidden field in the form sample in express_checkout.jsp below sets the form handler’s updateRepositoryId property. This property is used by theB2CProfileFormHandler to ensure that the profile being edited is in fact the profile that is associated with the current session (in case a session expires or otherwise becomes invalid while a person is filling in a form). We recommend using this hidden field in all forms that invoke the handleUpdate method of ProfileFormHandler or its subclasses.

<dsp:form action="express_checkout.jsp">
  <dsp:input bean="B2CProfileFormHandler.updateRepositoryId"
             beanvalue="B2CProfileFormHandler.repositoryId" type="hidden"/>


After the user checks the Set Your Express Checkout Preferences button, she is presented with a form that asks for default shipping and billing information. The express checkout feature requires that at least one credit card already be entered. If the customer’s profile contains no credit cards, she is presented with a message and a link to the credit card entry page. After a customer has entered at least one credit card, she is presented again with the page above.




Users with valid credit cards see a form that lets them select a default credit card. Additionally, the “Save These Express Checkout Preferences” button is rendered.





When the customer pushes the Save These Express Checkout Preferences button, the expressCheckout property of the user’s profile is set. This ensures that the address, credit card, and shipping methods have been set and prevents invalid data from causing errors at checkout time.

Setting the Express Checkout preferences is specialized Pioneer Cycling Store functionality. This code can be found in <ATG2007.3dir>/PioneerCyclingJSP/j2ee-apps/pioneer/web-app/en/user/express_checkout_preferences.jsp.

The first form element on the page is the pull-down list for selecting the default shipping address. The customer’s default shipping address is stored in the property Profile.shippingAddress. The pull-down list in the screen shot above shows the list of all nicknames of addresses stored in Profile.secondaryAddressess. The pull down list is linked to the property ProfileFormHandler.editValue.defaultAddressNickname. When the form is submitted, the selected value is set in the Profile.shippingAddress property. The following snippet demonstrates how the shipping address is set.

Your current default shipping address is: <!-- <b><dsp:valueof param="key"/></b>.
-->
<p>
<dsp:getvalueof id="pval0" bean="Profile.shippingAddress"><dsp:include
     page="DisplayAddress.jsp" flush="true"><dsp:param name="address"
     value="<%=pval0%>"/></dsp:include></dsp:getvalueof>
<p>

<dsp:droplet name="IsEmpty">
 <dsp:param bean="Profile.secondaryAddresses" name="value"/>
 <dsp:oparam name="false">

Change it to:
<dsp:select bean="B2CProfileFormHandler.editValue.defaultAddressNickname">
 <dsp:droplet name="ForEach">
  <dsp:param bean="Profile.secondaryAddresses" name="array"/>
  <dsp:oparam name="outputStart">
   <dsp:option value=""/>&nbsp;Don't Change
  </dsp:oparam>
  <dsp:oparam name="output">
   <dsp:droplet name="Switch">
    <dsp:param name="value" param="key"/>
    <dsp:oparam name="editAddress">
    </dsp:oparam>
    <dsp:oparam name="newBillingAddress">
    </dsp:oparam>
    <dsp:oparam name="default">
     <dsp:getvalueof id="option119" param="key" idtype="java.lang.String">
<dsp:option value="<%=option119%>"/>
</dsp:getvalueof><dsp:valueof param="key"/>
    </dsp:oparam>
   </dsp:droplet>
  </dsp:oparam>
 </dsp:droplet>
</dsp:select>


The concepts involved in setting the default credit card are similar to setting the shipping address. The default credit card is stored in Profile.defaultCreditCard, which is a reference to a RepositoryItem of type credit_card that has the properties creditCardType and creditCardNumber. These are displayed on the page next to the word “Default:” to remind the user of the current setting, if any. Just below that is a pull-down list for selecting a new default credit card that shows a list of all credit cards on the user’s profile.

To display the current default value as pre-selected, we used the <dsp:setvalue> to set the form handler’s value for the default credit card from the profile. To actually render the <dsp:select> drop-down list, we used an IsEmpty servlet bean to determine if there is anything to render at all. The ForEach servlet bean has an empty oparam that one might expect to be able to use for the case when the credit cards are empty and an oparam="outputStart" for the <dsp:select> tag and oparam="outputEnd" for the </dsp:select>. The ForEach servlet bean has been tuned for top performance and it would be too inefficient for the page compiler to figure out which <dsp:select> and </dsp:select> and <dsp:option> tags go together. If we used a loosely coupled group, like radio buttons, the IsEmpty would not be necessary, but since we used select, we must help the page compiler by using IsEmpty.

Default: <dsp:valueof bean="Profile.defaultCreditCard.creditCardType"/>
<dsp:valueof bean="Profile.defaultCreditCard.creditCardNumber"
             converter="creditcard"/>
<p>

<dsp:setvalue bean="B2CProfileFormHandler.defaultCreditCardID"
     beanvalue="Profile.defaultCreditCard.id"/>

<dsp:droplet name="IsEmpty">
 <dsp:param bean="Profile.creditCards" name="value"/>
 <dsp:oparam name="true">
  <dsp:a href="credit_cards.jsp">
   <font color=#cc0000>
    Please enter one or more credit cards in order to enable this feature
   </font>
  </dsp:a>
  <br>
 </dsp:oparam>
 <dsp:oparam name="false">
  Choose from one of your saved credit cards<p>
  <dsp:select bean="B2CProfileFormHandler.defaultCreditCardID">
   <dsp:droplet name="ForEach">
    <dsp:param bean="Profile.creditCards" name="array"/>
    <dsp:oparam name="output">
     <dsp:getvalueof id="option226" param="element.id" idtype="java.lang.String">
<dsp:option value="<%=option226%>"/>
</dsp:getvalueof>
     <dsp:valueof converter="creditcard" param="key"/> &nbsp;
     <dsp:valueof param="element.creditCardType"/>
     <dsp:valueof converter="creditcard" param="element.creditCardNumber"/>
    </dsp:oparam>
   </dsp:droplet>
  </dsp:select>
 </dsp:oparam>
</dsp:droplet>


While credit cards and shipping addresses that must be drawn from the user’s profile, setting the shipping method is simpler because the list of possible shipping methods is common to all users. We used the same methods as above to pre-set the selected item on the pull-down list of shipping methods. The actual pull down list is generated by the AvailableShippingMethods servlet bean that is described in the Shipping Prices section of the Pricing chapter.

Default: <dsp:valueof bean="Profile.defaultCarrier"/>
<p>

<dsp:setvalue bean="B2CProfileFormHandler.defaultCarrier"
              beanvalue="Profile.defaultCarrier"/>

Choose from one of our shipping methods<p>
<!-- The droplet AvailableShippingMethods is able to give us a list of the -->
<!-- shipping methods that should be available to a user. -->
<dsp:droplet name="AvailableShippingMethods">
 <dsp:param bean="ShoppingCartModifier.shippingGroup" name="shippingGroup"/>
 <dsp:param bean="UserPricingModels.shippingPricingModels" name="pricingModels"/>
 <dsp:param bean="Profile" name="profile"/>
 <dsp:oparam name="output">
  <dsp:select bean="B2CProfileFormHandler.defaultCarrier">
   <dsp:droplet name="ForEach">
    <dsp:param name="array" param="availableShippingMethods"/>
    <dsp:param name="elementName" value="method"/>
    <dsp:oparam name="output">
    <dsp:getvalueof id="option313" param="method" idtype="java.lang.String">
<dsp:option value="<%=option313%>"/>
</dsp:getvalueof>
     <dsp:valueof param="method"/>
    </dsp:oparam>
   </dsp:droplet>
  </dsp:select>
 </dsp:oparam>
</dsp:droplet>


The last form element on the page is the Save These Express Checkout Preferences submit button. This button is rendered only if the list of credit cards in the profile is not empty. The form is submitted to B2CProfileFormHandler.setExpressCheckoutPreferences, which takes the values from the form fields and saves them to the profile.

<dsp:droplet name="IsEmpty">
<dsp:param bean="Profile.creditCards" name="value"/>
<dsp:oparam name="false">
 <dsp:input bean="B2CProfileFormHandler.setExpressCheckoutPreferences"
      type="submit" value="Save These Express Checkout Preferences"/>
  </dsp:oparam>
</dsp:droplet>

Thursday, June 14, 2012

Exports Data From Solid Database And Imports Data into Oracle or MySQL Database : ATG

Follow this steps, 


For exporting data from Solid database and importing into Oracle | MySQL  DB's


Step 1. First time you are starting the solid database,

            copy the C:\ATG\ATG9.1\DAS\solid\atgdb\solid.db

            to

            C:\ATG\ATG9.1\DAS\solid\i486-unknown-win32\solid.db

Step 2. Double Click on the file to start solid DB:

            C:\ATG\ATG9.1\DAS\solid\i486-unknown-win32\solfe.exe.

Step 3. To export the test data from solid database to Oracle or MySQL ,

             create the file

             C:\ATG\ATG9.1\home\localconfig\atg\dynamo\service\jdbc\JTDataSource.properties

             $class=atg.service.jdbc.MonitoredDataSource
             dataSource=/atg/dynamo/service/jdbc/FakeXADataSource
             min=5
             maxFree=-1
             blocking=true
             max=10


             C:\ATG\ATG9.1\home\localconfig\atg\dynamo\service
             \jdbc\FakeXADataSource.properties

Step 4. Add these lines to use Solid database:

            driver=solid.jdbc.SolidDriver
            URL=jdbc:solid://localhost:1313


Step 5. Execute the following commands to export the test data from solid database:

             cd C:\ATG\ATG9.1\home\bin

            startSQLRepository -m PioneerCyclingJSP -export all users.xml -repository   
            /atg/userprofiling /ProfileAdapterRepository

           startSQLRepository -m PioneerCyclingJSP -export all products.xml -repository 
           /atg/commerce/catalog/ProductCatalog

Step 6. Modify the following file to use    

            C:\ATG\ATG9.1\home\localconfig\atg\dynamo\service
            \jdbc\FakeXADataSource.properties.

            Oracle database.
   

            driver=oracle.jdbc.OracleDriver
            needsSeparateUserInfo=true
            URL=jdbc:oracle:thin:@localhost:1521:atgdb
            readOnly=false
            user=scott
            password=tiger
            database=atgdb

   

            MySQL database:
   
            driver=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
            needsSeparateUserInfo=true
            URL=jdbc:mysql://localhost:3306/atgdb
            readOnly=false
            user=root
            password=root
            database=atgdb
   


Note: You may need to change the above properties depending upon the database you use.


Step 7. Execute the following command to import the test data to Oracle | MySQL database:

            cd C:\ATG\ATG9.1\home\bin

            startSQLRepository -m PioneerCyclingJSP -import users.xml -repository
            /atg/userprofiling /ProfileAdapterRepository

            startSQLRepository -m PioneerCyclingJSP -import products.xml -repository   
            /atg/commerce/catalog/ProductCatalog

Now Check your Oracle DB or MySQL DB  whether imported tables are there in your schema or not.

Friday, June 8, 2012

ATG Basics : Inserting ATG Servlet Beans

Inserting ATG Servlet Beans



You can use the Document Editor to insert ATG servlet beans. For example, you can insert a ForEach servlet bean as follows:


1.    Place the cursor in the body of the document where you wish to insert the servlet bean.

2.    From the Insert menu, select Insert Servlet Bean. The Insert Servlet Bean dialog box opens.

3.    Select Servlet Beans from the Categories list, then select ForEach from the Components list. 
       Click OK.

4.    In the Insert ForEach Servlet Bean wizard, click the “...” button.

5.    In the Choose a Dynamic Value dialog box, enter the array property whose elements you wish to 
       retrieve.       
    
      For example:

      bean="/samples/Student_01.subjects

6.   Click OK, and then click Next in the wizard.

7.   In the Specify output text box, specify the output to display for each property element
     
      For example:

      <li><dsp:valueof param="element"></dsp:valueof>

8.    Click Next.

9.    In the Specify outputStart text box, enter the text to display before loop execution begins. 
      
       For example:

       <p>The student is registered for these courses:

10.  Click Next.

11.  Leave the Specify outputEnd text box blank, and click Next.

12.  Leave the Specify empty text box blank, and click Finish.


The document should now contain these tags:



<dsp:droplet name="/atg/dynamo/droplet/ForEach">

  <dsp:param bean="/samples/Student_01.subjects" name="array"/>
      <dsp:oparam name="outputStart">
            <p>The student is registered for these courses:
      </dsp:oparam>

      <dsp:oparam name="output">
            <li><dsp:valueof param="element"></dsp:valueof>
      </dsp:oparam>

</dsp:droplet>



Importing servlet beans




To make a servlet bean visible in the Dynamic Element Editor, import the component into the page with dsp:importbean.

 For example:

<dsp:importbean bean="/atg/dynamo/droplet/ForEach"/>


Importing the servlet bean lets you refer to it without including the entire path, as in this line:

<dsp:droplet name="ForEach">

By importing a Nucleus component into the pageContext with the dsp:importbean tag, other (non-EL) references to that component can exclude the Nucleus address.

Parameterized Query Example : ATG

The following is an example of how you might use a parameterized query. Note that error handling is not dealt with in these examples.

Suppose you wanted to create a Query like this:

firstName  = 'Jerry'

Then, you want to change that to

firstName = 'Phil'

Query Example without Parameters


The first example shows how you would need to do this without the use of parameters:

// Get the repository through our made up getRepository( ) call
Repository rep = getRepository();
RepositoryItemDescriptor desc = rep.getItemDescriptor("user");
RepositoryView view = desc.getRepositoryView();
QueryBuilder qb = view.getQueryBuilder();

// Build our first Query
// firstName = 'Jerry'
QueryExpression firstNameProp = qb.createPropertyQueryExpression("firstName");
QueryExpression jerryValue = qb.createConstantQueryExpression
(new String("Jerry"));
Query firstNameQuery = qb.createComparisonQuery(firstNameProp, jerryValue,
 QueryBuilder.EQUALS);

// Execute our first Query
RepositoryItem[] jerryItems = view.executeQuery(firstNameQuery);

// Set up our second Query now
QueryExpression philValue = qb.createConstantQueryExpression(new String("Phil"));
firstNameQuery = qb.createComparisonQuery(firstNameProp, philValue,
QueryBuilder.EQUALS);

// Execute our second Query
RepositoryItem[] philItems = view.executeQuery(firstNameQuery);



Query Example with Parameters


With the use of parameters in your queries, you can create a reusable Query as in the example that follows. Note that the view used is a ParameterSupportView instead of a RepositoryView:

// Get the repository through our made up getRepository( ) call
Repository rep = getRepository();
RepositoryItemDescriptor desc = rep.getItemDescriptor("user");
// Our RepositoryView is a ParameterSupportView this time, so we know it supports
// parameters in Queries
// Note – this assumes we have advanced knowledge that this view is an instance of
// a ParameterSupportView
ParameterSupportView view = (ParameterSupportView)desc.getRepositoryView();
QueryBuilder qb = view.getQueryBuilder();

// Builder our first Query up
// firstName = 'Jerry'
QueryExpression firstNameProp = qb.createPropertyQueryExpression("firstName");
QueryExpression parameterValue = qb.createParameterQueryExpression();
Query firstNameQuery = qb.createComparisonQuery
                       (firstNameProp, parameterValue, QueryBuilder.EQUALS);

// Execute our first Query
Object[] args = new Object[1];
args[0] = new String("Jerry");
RepositoryItem[] jerryItems = view.executeQuery(firstNameQuery, args);

// Set up our second Query now
args[0] = new String("Phil");
RepositoryItem[] philItems = view.executeQuery(firstNameQuery, args);


In the first example, we have to create a new constant QueryExpression if we want to change the name from Jerry to Phil. This means we must also create a new instance of a comparison Query to use the new QueryExpression. In the second example, we can increase efficiency by creating just one Query object, and changing the value of the name we want in an Object array that is passed to the executeQuery method. This also allows you to cache a Query in your internal application (above the query cache layer), and pass in varying parameter values at execution time.

Repository Query Examples

The examples in this section demonstrate how to perform some simple repository queries. In the Repository API, all queries are performed using Query or QueryExpression objects. A QueryExpression is a building block you can use to create simple or complex queries. A Query is a repository query that can be executed. A Query can also be used as a building block to create queries that are more complicated.

The following example supposes we have an item descriptor named user with an integer property named userType. This is how we might perform a simple query to find users whose userType property is 2.


import atg.repository.*;

MutableRepository pRepository =
  (MutableRepository)ServletUtil.getCurrentRequest().resolveName
  ("/atg/userprofiling/ProfileAdapterRepository");

    // Queries are created using QueryBuilders and executed by
    // RepositoryViews. A Query is defined in the context of a
    // specific item descriptor and thus must be built and executed with
    // the right QueryBuilder and RepositoryView.

    RepositoryItemDescriptor userDesc = pRepository.getItemDescriptor("user");
    RepositoryView userView = userDesc.getRepositoryView();
    QueryBuilder userBuilder = userView.getQueryBuilder();

    // create a QueryExpression that represents the property userType
    QueryExpression userType =
      userBuilder.createPropertyQueryExpression("userType");

    // create a QueryExpression that represents the constant 2
    QueryExpression two =
      userBuilder.createConstantQueryExpression(new Integer(2));

    // now we build our query: userType = 2
    Query userTypeIsTwo =
      userBuilder.createComparisonQuery(userType, two, QueryBuilder.EQUALS);

    // finally, execute the query and get the results
    RepositoryItem[] answer = userView.executeQuery(userTypeIsTwo);

    System.out.println("running query: userType = 2");
    if (answer == null)
      {
        System.out.println("no items were found");
      }
    else
      {
        for (int i=0; i<answer.length; i++)
          System.out.println("id: " + answer[i].getRepositoryId());
      }



Let’s expand the preceding example with a slightly more complicated query. The next code fragment builds on the preceding fragment to create the query userType < 2 AND login STARTS WITH "j":



import atg.repository.*;

MutableRepository pRepository =
  (MutableRepository)ServletUtil.getCurrentRequest().resolveName
  ("/atg/userprofiling/ProfileAdapterRepository");

    // reuse the building blocks we have to create
    // the "userType < 2" query
    Query userTypeLTTwo =
      userBuilder.createComparisonQuery(userType, two, QueryBuilder.LESS_THAN);

    // create the "login STARTS WITH j" query
    QueryExpression login =
      userBuilder.createPropertyQueryExpression("login");

    QueryExpression j =
      userBuilder.createConstantQueryExpression("j");

    //Note that we could make this query case-insensitive by adding another
    //parameter to the createPatternMatchQuery, with a value of true
    Query startsWithJ =
      userBuilder.createPatternMatchQuery(login, j, QueryBuilder.STARTS_WITH);


    // now AND the two pieces together. You can AND together as many
    // Query pieces as you like: we only have two in our example
    Query[] pieces = { userTypeLTTwo, startsWithJ };
    Query andQuery = userBuilder.createAndQuery(pieces);

    // execute the query and get the results
    answer = userView.executeQuery(andQuery);

    System.out.println("running query: userType < 2 AND login STARTS WITH j");
    if (answer == null)
      {
        System.out.println("no items were found");
      }
    else
      {
       for (int i=0; i<answer.length; i++)
          {
           RepositoryItem item = answer[i];
           String id = item.getRepositoryId();
           String l = (String)item.getPropertyValue("login");
           Integer a = (Integer)item.getPropertyValue("userType");
           System.out.println("item: " + id + ", login=" + l + ", userType=" + a);
          }
      }

   }

Popular Posts