atg

Version 9.1 ATG Commerce Programming Guide
ATG One Main Street Cambridge, MA 02142 USA www.atg.com

ATG Commerce Programming Guide Document Version
Doc9.1 COMMPROGv1 7/31/09

Copyright
Copyright © 1998-2009 Art Technology Group, Inc. All rights reserved. This publication may not, in whole or in part, be copied, photocopied, translated, or reduced to any electronic medium or machine-readable form for commercial use without prior consent, in writing, from Art Technology Group, Inc. (ATG). ATG does authorize you to copy documents published by ATG on its website for non-commercial uses within your organization only. In consideration of this authorization, you agree that any copy of these documents which you make shall retain all copyright and other proprietary notices contained herein.

Trademark and Copyright Information
ATG and Art Technology Group are registered trademarks of Art Technology Group, Inc. ATG Dynamo Application Server, ATG Adaptive Scenario Engine, ATG Scenario Personalization, ATG Portal, ATG Commerce, ATG Content Administration, ATG Data Anywhere Architecture, ATG Search, ATG Response Management, ATG Merchandising, ATG Knowledge, ATG Self Service, ATG Commerce Assist, ATG Advisor, ATG Forum and ATG Business Control Center are trademarks of Art Technology Group, Inc. Microsoft, Windows, Word, and Excel are the trademarks or registered trademarks of Microsoft Corporation in the United States and other countries. IBM, AIX, and MQ-Series are the trademarks or registered trademarks of IBM Corporation in the United States and other countries. Oracle is a registered trademark, and other Oracle product names, service names, slogans or logos referenced in this document are trademarks or registered trademarks of Oracle Corporation. Adobe Acrobat Reader is a registered trademark of Adobe. CORBA is a trademark of the OMG (Object Management Group). Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. Primus, and its respective logo, and Primus Knowledge Solutions, are trademarks, registered trademarks, or service marks of Primus. All other product names, service marks, and trademarks mentioned herein are trademarks of their respective owners. This publication may not, in whole or in part, be copied, photocopied, translated, or reduced to any electronic medium or machine-readable form for commercial use without prior consent, in writing, from Art Technology Group (ATG), Inc. ATG does authorize you to copy documents published by ATG on the World Wide Web for non-commercial uses within your organization only. In consideration of this authorization, you agree that any copy of these documents which you make shall retain all copyright and other proprietary notices contained herein. Portions of this product may contain the following: EditLive Authoring Software Copyright © 2004 Ephox Corporation. All rights reserved. Some code licensed from RSA Security, Inc. Some portions licensed from IBM, which are available at http://oss.software.ibm.com/icu4j/. This product may include software developed by the Apache Software Foundation (http://www.apache.org/). Spell checking software from Wintertree Software Inc. The Sentry Spell Checker Engine © 2000 Wintertree Software Inc.

Patent Protection
ATG products and services are protected by one or more of the following U.S. patents and other patents pending: 6,574,790; 6,587,849; 6,560,717; 6,883,014; 6,539,494; 7,024,462; 7,353,189; 7,075,921; 6,914,899; 6,791,974; 6,707,811; 7,203,188; 7,315,518; 7,328,201; 7,367,051.

No Warranty
This documentation is provided “as is” without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability, fitness for a particular purpose, or non-infringement. The contents of this publication could include technical inaccuracies or typographical errors. Changes are periodically added to the information herein; these changes will be incorporated in the new editions of the publication. ATG may make improvements and/or changes in the publication and/or product(s) described in the publication at any time without notice.

Limitation of Liability
In no event will ATG be liable for direct, indirect, special, incidental, economic, cover, or consequential damages arising out of the use of or inability to use this documentation even if advised of the possibility of such damages. Some states do not allow the exclusion or limitation of implied warranties or limitation of liability for incidental or consequential damages, so the above limitation or exclusion may not apply to you. Contact: ATG • One Main Street, Cambridge, MA 02142, USA • phone 617.386.1000 • fax 617.386.1111 • www.atg.com

ATG Commerce Programming Guide

µ

Contents

1

Introduction
Commerce Overview Product Catalog Purchasing and Fulfillment Services Inventory Management Pricing Services Targeted Promotions Merchandising Services Finding What You Need In This Guide

1
1 1 2 3 3 3 4 5 6

2

Configuring and Populating a Production Database
Configuring ATG Commerce with CIM Creating Database Tables Creating Tables for Core ATG Commerce Creating Tables for ATG Consumer Commerce Creating Tables for ATG Business Commerce Using ATG Commerce with an Oracle Database Configuring Storage Parameters Configuring a Catalog for Oracle Full Text Searching Using ATG Commerce with an MSSQL Database Transferring Product Catalog and Price List Data Using Copy and Switch Configuring a Database Copy Performing a Database Copy Configuring a Database Switch Performing a Database Switch Transferring Demo Data Exporting the Demo Data from SOLID Importing the Demo Data to Your Database Destroying Database Tables for ATG Commerce Destroying Tables for Core ATG Commerce Destroying Tables for ATG Consumer Commerce Destroying Tables for ATG Business Commerce

9
9 10 11 12 13 14 14 15 17 19 19 25 26 28 29 29 29 30 30 31 32

3

Integrating Third-Party Software With ATG Commerce
Integrating Payflow Pro with ATG Commerce Setting up Payflow Pro

35
35 36

iii
Contents

µ

ATG Commerce Programming Guide

Pre-Configuring the Integration Using ATG Commerce with Payflow Pro Integrating CyberSource with ATG Commerce Installing the CyberSource Distribution Initializing the CyberSource Integration Configuring ATG Commerce to Use CyberSource Moving the System to Production Designating Tax Status of Products Specifying Sales Origin and Shipment Location Information Calculating Taxes on the Item Level Specifying States and Provinces without Tax Obligations Integrating TAXWARE with ATG Commerce Before You Begin Integrating with TAXWARE TAXWARE Classes Configuring ATG Commerce to Use TAXWARE Using the SALES/USE and WORLDTAX Integration Customizing ATG Commerce’s TAXWARE Integration Customizing TaxWareCalculateTax Methods TaxResult and TaxRequest Fields VERAZIP Integration Customizing ATG Commerce’s VERAZIP Integration Customizing TaxWareVerifyZipInfo Methods

36 36 37 37 37 38 38 38 39 39 40 40 40 40 41 42 42 43 43 44 44 45

4

Using and Extending the Standard Catalog
Catalog Repository Categories and Products Category Properties Product Properties Defining a Root Category Defining Relationships between Categories and Products Specifying Template Pages for Categories and Products Associating Products with SKUs Extending the Repository for Internationalization Extending the Category and Product Item Types SKU Items and SKU Links SKU Properties SKU Link Properties Using SKU Media Properties Using SKU Price Properties Using the SKU Fulfiller Property Creating SKU Bundles Extending the SKU Item Type Configurable SKUs Folders and Media Items Folder Properties Media Item Properties Using Media-External Properties

47
47 48 49 50 52 52 54 55 56 58 59 60 60 61 61 62 62 62 63 63 64 64 65

iv
Contents

ATG Commerce Programming Guide

µ
65 65 66 67 69

Using Media-Internal Properties Designing a Multi-Locale Product Catalog Designing the Catalog Repository Setting Up Multiple Product Catalogs Setting Up a Single Product Catalog

5

Using Custom Catalogs
Using ATG Commerce with Custom Catalogs Converting from Standard to Custom Catalogs The Custom Catalog Repository Defining Root Categories Catalog Properties Category Properties categoryInfo Properties Product Properties productInfo Properties SKU Properties SKUInfo Properties Custom Catalog Security Custom Catalog Navigation Looking Up Items in the Catalog Using the parentCategory Property Custom Catalog Searching Overview of Custom Catalog Searching Configuring the Custom Catalog’s Search Form Handler Configuring Custom Catalog Search Types and Specifying Search Criteria Combining Custom Catalog Search Types Preconfigured Custom Catalog Search Components Processing and Displaying Custom Catalog Search Results Searching Custom Catalogs in Development Mode Using Search Form Handler with Internationalized Catalogs Assigning a Custom Catalog to a User

73
73 74 76 77 77 79 83 84 87 88 89 90 90 90 91 91 92 93 94 98 98 99 100 100 101

6

Using the Catalog Maintenance System
Batch Services Dynamic Services

103
103 110

7

ATG Commerce Profile Extensions
Profile Repository Extensions Promotions Address Books Credit Card Collection Gift Lists and Wish List Other Features Profile Form Handler Extensions Profile Tools and Property Manager Extension

113
113 113 114 114 114 115 115 115

v
Contents

µ
8 Configuring Merchandising Services

ATG Commerce Programming Guide

117
117 118 127 129 130 133 136 137 138 139 147 148 149 149 150 150 151 154

Setting Up Gift Lists and Wish Lists Gift List Form Handlers Gift List Servlet Beans Gift List Business Layer Classes Gift List Repository Purchase Process Extensions to Support Gift Lists Extending Gift List Functionality Disabling the Gift List Repository Setting Up Product Comparison Lists Understanding the Product Comparison System Extending the Product Comparison System Using TableInfo to Display a Product Comparison List Setting Up Gift Certificates and Coupons The Claimable Repository The ClaimableTools Component The ClaimableManager Component Setting Up Gift Certificates Setting Up Coupons

9

Using and Extending Pricing Services
Overview of Pricing Services Common Terms in Pricing Services How Pricing Services Generate Prices Deciding Between Dynamic and Static Product Pricing Public Pricing Interfaces and Classes The Base Pricing Engine Pricing Interfaces Pricing Classes Price Holding Classes Pricing Engine Classes Pricing Calculator Classes Qualifier Class QualifiedItem Class PricingTools Class Other Classes The Pricing Servlet Beans Default Pricing Engines Default Item Pricing Engine Default Order Pricing Engine Default Tax Pricing Engine Default Shipping Pricing Engine Default Pricing Calculators Default Item Discount Calculator Default Item Discount Multiplier Calculator Default Order Discount Calculator

159
160 161 162 163 164 164 166 169 169 175 177 188 193 193 196 199 199 200 200 201 202 203 203 204 205

vi
Contents

ATG Commerce Programming Guide

µ
206 207 208 208 209 209 210 210 212 213 213 214 216 216 216 216 217 217 224 224 225 229 230 231 232 233 234 234 235 237 238 238 240

Default Shipping Discount Calculator Default Qualifier Service Extending and Creating Pricing Engines Extending a Pricing Engine Replacing a Pricing Engine Creating a New Pricing Engine Extending and Creating Pricing Calculators Adding a New Pricing Calculator Extending Calculators Extending the Qualifier Class Adding a Helper Method for a New Calculator Adding New Criteria to the Filter Methods Replacing the Way a PMDL Rule Is Evaluated Replacing the Way the Qualifier Determines the Result Set Accessing FilteredCommerceItems Creating Promotions Types of Promotions Using PMDL Rules PromotionStatus Repository Items Using the Discount Rule Editor to Create PMDL Rules Examples of PMDL Rules Performance Issues Related to Promotion Delivery Using Price Lists Overview of Setting Up Price Lists Description of Volume Pricing Setting up Price List Functionality in ATG Consumer Commerce PriceListManager Price List Calculators Implementing Sale Prices using Price Lists Calculating Prices with a Specific Price List Using the CurrencyConversionFormatter to Convert Currency Price List Security Policy Converting a Product Catalog to Use Price Lists

10 Working With Purchase Process Objects
The Purchase Process Subsystems Base Commerce Classes and Interfaces Address Classes Business Layer Classes OrderTools Pipelines Order Repository Creating Commerce Objects Creating an Order Creating Multiple Orders Creating Commerce Items, Shipping Groups, and Payment Groups Adding an Item to an Order via a URL

243
243 244 248 248 249 253 254 255 255 256 257 261

vii
Contents

µ

ATG Commerce Programming Guide

Preventing Commerce Items from Being Added to Types of Shipping Groups263 Removing Commerce Objects from an Order 263 Using the SimpleOrderManager 264 Using Relationship Objects 264 Relationship Types 265 Commerce Item Relationships 269 Relationship Priority 269 Assigning Items to Shipping Groups 270 Assigning Costs to Payment Groups 271 Assigning an Order’s Total Cost to Payment Groups 272 Assigning an Order’s Component Costs to Payment Groups 273 Setting Handling Instructions 275 HandlingInstruction Objects 276 Adding Handling Instructions to a Shipping Group 276 ATG Commerce States 278 Purchase Process Class Diagrams 285 Order Interfaces Diagrams 285 Order Classes Diagram 296 Order Containment Diagram 309

11 Configuring Purchase Process Services
Loading Orders Refreshing Orders Modifying Orders Understanding the CartModifierFormHandler Modifying the Current Order Repricing Orders Saving Orders Updating an Order with the OrderManager Canceling Orders Checking Out Orders Preparing a Simple Order for Checkout Preparing a Complex Order for Checkout Checking Out an Order Processing Payment of Orders Overview of the Payment Process Extending the Payment Operations of a Payment Method Extending the Payment Process to Support a New Payment Method Extending Order Validation to Support New Payment Methods Scheduling Recurring Orders Understanding the scheduledOrder Repository Item Submitting Scheduled Orders Creating, Modifying, and Deleting Scheduled Orders Setting Restrictions on Orders Understanding the Order Restriction Classes Implementing Order Restrictions Tracking the Shopping Process

315
316 317 321 321 327 329 331 331 333 334 334 336 348 354 355 356 357 371 375 376 377 380 384 384 386 387

viii
Contents

ATG Commerce Programming Guide

µ
387 388 389 389 389 390 390 391 392

Shopping Process Stages Working with Shopping Process Stages Shopping Process Recorder Turning Off Recording of Shopping Process Tracking Troubleshooting Order Problems Handling Returned Items Working with ATG Commerce Form Handlers Managing Transactions in the ATG Commerce Form Handlers Extending the ATG Commerce Form Handlers

12 Customizing the Purchase Process Externals
Purchase Process Event Messages Integrating with Purchase Process Services Purchase Process Integration Points Adding Credit Card Types to ATG Commerce Extending the Purchase Process Adding a Subclass with Primitive Data Type Properties Adding a Subclass with Object Data Type Properties Manipulating Extended Objects Merging Orders

393
393 394 394 395 397 397 404 423 423

13 Processor Chains and the Pipeline Manager
Pipeline Manager Overview Using the Pipeline Editor Accessing the Pipeline Editor Opening an Existing Pipeline Definition Creating a New Pipeline Definition Editing Existing Pipeline Definitions Printing a Pipeline Definition Activating Verbose Mode Pipeline Debugging Changing the Display Font of the Pipeline Editor Reinitializing the Pipeline Manager Running a Processor Chain Creating a Processor Pipeline Configuring a Pipeline Manager Creating Processors Pipeline Definition Files Creating and Editing Processor Chains Programmatically Extending the PipelineChain and PipelineResult Classes Pipelines and Transactions Processor Transaction Management Spanning Transactions over a Chain Subset Extending the Processor Pipeline Classes Adding a Commerce Processor Using XML Combination Executing Processor Chains from Processors within Other Chains

425
425 426 427 427 428 430 431 431 432 433 433 433 434 435 435 435 440 443 446 446 447 447 448 449

ix
Contents

µ

ATG Commerce Programming Guide

Commerce Processor Chains updateOrder Pipeline Chain loadOrder Pipeline Chain refreshOrder Pipeline Chain processOrder Pipeline Chain validateForCheckout Pipeline Chain validatePostApproval Pipeline Chain validatePaymentGroupsPostApproval Pipeline Chain validateNoApproval Pipeline Chain recalcPaymentGroupAmounts Pipeline Chain repriceOrder Pipeline Chain moveToConfirmation Pipeline Chain moveToPurchaseInfo Pipeline Chain validateShippingInfo Pipeline Chain sendScenarioEvent Pipeline Chain

449 450 453 454 456 460 463 464 464 464 465 465 466 466 466

14 Inventory Framework
Overview of the Inventory System Using the Inventory System Inventory System Methods Inventory Classes InventoryManager InventoryException MissingInventoryItemException InventoryManager Implementations AbstractInventoryManagerImpl NoInventoryManager RepositoryInventoryManager CachingInventoryManager LocalizingInventoryManager Examples of Using the Inventory Manager Allocating Items for an Order Canceling or Removing an Item from an Order Displaying an Item’s Availability to a Customer Filling Partial Orders Preventing Inventory Deadlocks Handling Bundled SKUs in the Inventory Inventory Repository Inventory JMS Messages Configuring the SQL Repository Caching the Inventory Inventory Repository Administration Using the InventoryLookup Servlet Bean Building a New InventoryManager Configuring a New Inventory Manager

469
470 470 471 473 473 475 476 476 476 476 476 480 482 482 483 484 485 485 485 486 489 490 491 491 492 493 495 496

x
Contents

ATG Commerce Programming Guide

µ
497
498 501 501 510 514 561 563 564 564 565 567 571 574 575 575 577 577 578 579 580

15 Configuring the Order Fulfillment Framework
Overview of Fulfillment Process Running the Fulfillment Server Order Fulfillment Classes Fulfillment Pipelines Descriptions and Diagrams of Fulfillment Pipelines Using Locking in Fulfillment Using the OrderFulfiller Interface Using the Fulfiller Notifying the HardgoodFulfiller of a Shipment HardGoodFulfiller Examples Creating a New Fulfiller Configuring a New Fulfiller Order Fulfillment Events Fulfillment Server Fault Tolerance Fulfillment Message Redelivery Replacing the Default Fulfillment System Integrating the Order Fulfillment Framework with an External Shipping System Changing Payment Behavior in Fulfillment Server Using Scenarios in the Fulfillment Process Questions & Answers

16 Managing the Order Approval Process
Understanding the Order Approval Process Modifying the Order Approval Process Servlet Beans and Form Handlers for Approving Orders ApprovalRequiredDroplet Servlet Bean ApprovedDroplet Servlet Bean ApprovalFormHandler Pipeline Chains in the Order Approval Process approveOrder checkRequiresApproval orderApproved orderRejected checkApprovalComplete checkApprovalCompleteError JMS Messages in the Order Approval Process

583
583 588 588 588 589 589 589 590 592 593 594 595 597 598

17 Using Abandoned Order Services
An Overview of Abandoned Orders Abandonment States Order Repository Extensions Profile Repository Extensions The AbandonedOrderLogRepository Defining and Detecting Abandoned Orders Defining Abandoned and Lost Orders

601
601 603 603 604 605 605 606

xi
Contents

µ

ATG Commerce Programming Guide

Detecting Abandoned and Lost Orders Configuring AbandonedOrderService Configuring AbandonedOrderTools Scenario Events and Actions Scenario Events Scenario Actions Tracking Abandoned Orders of Transient Users AbandonedOrderEventListener TransientOrderRecorder Turning Off Transient Order Tracking Customizations and Extensions Defining Additional Types of Abandoned and Lost Orders Modifying the Criteria Used to Identify Abandoned and Lost Orders

606 608 610 615 615 618 621 621 622 622 622 622 624

18 Generating Invoices
Overview Invoices in Checkout Invoice Payment Enabling the InvoiceRequestProcessor Using the Invoice Manager Invoice Pipelines The Invoice Repository Invoice Repository Item DeliveryInfo Repository Item PaymentTerms Repository Item Sending Invoice JMS Messages

627
627 628 629 629 629 630 631 631 632 633 633

19 Using Requisitions and Contracts
Requisitions Contract Repository Items Using Contracts

635
635 636 636

20 Preparing to Use Commerce Reporting
Setting Up Commerce Reporting Environments Setting up the Asset Management Environment Setting Up the Production Environment Setting Up the Data Loading Environment Configuring a Parent Catalog Logging Data for Commerce Reporting Site Visit Data Logging Order Submit Data Logging Commerce Search Data Logging Product Catalog Data Logging User Data Logging Segment Data Logging Data Logging Configuration

639
639 640 640 640 640 641 642 642 643 643 644 645 646

xii
Contents

ATG Commerce Programming Guide

µ
647 648 650 650 654 655 655

Initial Data Logging for Catalogs, Users, and Segments JMS Message Information for Data Logging Loading Data for Commerce Reporting Data Loader Components Data Warehouse Loader Repository Handling Errors Pipeline Drivers and Processors

21 Customizing Reporting Data
Adding an Attribute to a Dimension Adding a New Dimension

667
668 669

22 ATG Commerce Web Services
Order Management Web Services addCreditCardToOrder Web Service addItemToOrder Web Service addItemToShippingGroup Web Service addShippingAddressToOrder Web Service cancelOrder Web Service createOrder Web Service createOrderForUser Web Service createOrderFromXML Web Service getCurrentOrderId Web Service getDefaultPaymentGroupId Web Service getDefaultShippingGroupId Web Service getOrderAsXML Web Service getOrdersAsXML Web Service getOrderStatus Web Service moveItemBetweenShippingGroups Web Service removeCreditCardFromOrder Web Service removeItemFromOrder Web Service removeItemQuantityFromShippingGroup Web Service removePaymentGroupFromOrder Web Service removeShippingGroupFromOrder Web Service setItemQuantity Web Service setOrderAmountToPaymentGroup Web Service submitOrderWithReprice Web Service Order Management Web Services Example Pricing Web Services calculateOrderPrice Web Service calculateOrderPriceSummary Web Service calculateItemPriceSummary Web Service Pricing Web Services Example Promotion Web Services claimCoupon Web Service getPromotionsAsXML Web Service

673
673 674 675 676 676 677 678 678 679 680 680 681 682 682 683 684 685 686 686 687 688 689 689 690 691 691 692 692 693 694 694 695 696

xiii
Contents

µ

ATG Commerce Programming Guide

grantPromotion Web Service revokePromotion Web Service Promotion Web Services Example Inventory Web Services getInventory Web Service getInventoryStatus Web Service setStockLevels Web Service setStockLevel Web Service Inventory Web Services Example Catalog Web Services catalogItemViewed Web Service getProductSkusXML Web Service getProductXMLByDescription Web Service getProductXMLById Web Service getProductXMLByRQL Web Service Catalog Web Services Example Profile Web Services getDefaultShippingAddress Web Service getDefaultBillingAddress Web Service getDefaultCreditCard Web Service setDefaultBillingAddress Web Service setDefaultCreditCard Web Service setDefaultShippingAddress Web Service Profile Web Services Example Commerce Web Services Security Using the Order Owner Security Policy

696 697 698 698 699 699 700 701 701 702 702 703 704 705 705 706 707 707 708 708 709 710 710 711 712 713

Appendix A: ATG Commerce and Session Backup Appendix B: ATG Commerce Databases
Core ATG Commerce Functionality Tables Product Catalog Tables Commerce Users Tables Claimable Tables Shopping Cart Events Table Inventory Tables Order Tables Promotion Tables User Promotion Tables Gift List Tables Price List Tables Custom Catalog Tables Abandoned Order Services Tables Order Markers Table ATG Business Commerce Tables ATG Business Commerce Product Catalog Tables

715 717
717 718 740 742 745 746 747 782 790 792 796 801 815 818 819 820

xiv
Contents

ATG Commerce Programming Guide

µ
822 828 834 839 843

ATG Business Commerce Order Tables ATG Business Commerce Organizational Tables ATG Business Commerce User Profile Extensions ATG Business Commerce Invoice Tables ATG Business Commerce Contract Tables

Appendix C: ATG Commerce Messages
Base ATG Commerce Messages Fulfillment System Messages Abandoned Order Messages ATG Business Commerce Messages

847
847 847 856 857

Appendix D: ATG Commerce Scenario Recorders
dcs dcs-analytics shoppingprocess

861
861 862 864

Index

867

xv
Contents

µ

ATG Commerce Programming Guide

xvi
Contents

ATG Commerce Programming Guide

µ

1 Introduction

Welcome to the ATG Commerce Programming Guide. The ATG Commerce application serves as the foundation for your online store. It contains everything you need to manage your product database, pricing, inventory, fulfillment, merchandising, targeted promotions, and customer relationships. ATG Commerce is available in two versions. ATG Consumer Commerce is used for developing standard business-to-consumer (B2C) online stores. ATG Business Commerce is used for sites oriented more toward business-to-business (B2B) uses. You will occasionally see the text “ATG Business Commerce only” or “ATG Consumer Commerce only” in this manual. This comprehensive guide covers ATG Business Commerce and ATG Consumer Commerce concepts for programmers. This chapter includes the following sections: Commerce Overview Finding What You Need In This Guide

Commerce Overview
This chapter introduces you to the major features of ATG Commerce: • • • • • • Product Catalog Purchasing and Fulfillment Services Targeted Promotions Inventory Management Pricing Services Merchandising Services

Product Catalog
The product catalog is a collection of repository items (categories, products, media, etc.) that provides the organizational framework for your commerce site. ATG Commerce includes a standard catalog implementation, based on the ATG SQL Repository, that you can use or extend as necessary. You can create and edit all of your repository items through the ATG Control Center, which also allows you to create page templates to display these items.

1
1 - Introduction

the order proceeds through checkout. you can create sites that support multiple shopping carts for a single user. Cost Centers allow customers to track internal costs by designating parts of their organization as cost centers. B2B applications often require that customers’ orders be reviewed by authorized persons who can approve or reject them. you can confine them to viewing and ordering only those products. Export an Order Via XML. ATG Commerce also includes an HTML-based Fulfillment Administration page that you can use for: • • • • Viewing orders that are ready to be shipped. As soon as a customer submits an order. if approved. enabling them to track costs by department and run related reports. Printing order information. multiple payment methods and shipping addresses. and check for the conditions that trigger an approval for an order. then create a schedule for the same order to be placed regularly during the time frame they specify. New classes in ATG Commerce allow you to export customer orders in XML for easy integration with your other systems. Your customers can create template orders from a new or existing order. This new feature gives your customers the option of being invoiced for orders they place. 2 1 . This system includes a collection of standard services which coordinate and execute the order fulfillment process. such as a computer that can be purchased with different hard drive capacities. This feature allows you to sell items with variable components. such as when an order limit is exceeded. and validating credit card information. if a corporate customer only wants its employees to order certain items from your store. ensuring items are shipped by the customer’s preferred method.Introduction . For example. the fulfillment framework can be customized to meet the needs of your site. Invoicing (ATG Business Commerce Only). Cost Centers (ATG Business Commerce only). You can display different versions of your product catalog for different viewers.µ ATG Commerce Programming Guide Custom Catalogs. and TAXWARE. Order Approvals (ATG Business Commerce only). You can integrate with third-party authorization and settlement tools such as Payflow Pro. then stop so the company can review its needs and perhaps change the standard order. Notifying the fulfillment system that a shipping group has changed and needs to be reprocessed. After an approver has reviewed the order. CyberSource. The approval process in ATG Business Commerce can identify customers for whom approvals are required. Notifying the fulfillment system that an order has been shipped to the customer. The system is designed for flexibility and easy customization. For example. Configurable Commerce Items. Like the purchase process. Purchasing and Fulfillment Services ATG Commerce provides tools to handle pre-checkout order-processing tasks such as adding items to a shopping cart. a company could set up a scheduled order to buy certain supplies on a monthly basis for the next year. the fulfillment framework takes over processing. Scheduled Orders.

These services make it possible to generate prices dynamically under constantly changing business conditions. or tax. which is separate from the product catalog. Price Lists. Price lists are managed through a single interface in the ACC. Inventory information is stored in the Inventory repository. allowing you to associate a particular catalog. price list(s). or preorder. Administrators can use this interface to view the results of the inventory query operations. backorder. and notify the system of inventory updates.ATG Commerce Programming Guide µ Requisitions (ATG Business Commerce only). backorder.Introduction . You can use the ATG Control Center to view. improving your customers’ ability to track internal activities. or preorder. add and delete inventory items. The pricing calculator performs the actual price calculation based on information from the pricing engine. shipping charge. enabling your customers to attach requisition numbers to orders. price lists can be used to implement business-to-business pricing where each customer can have its own unique pricing for products based on contracts. Make a specific number of items available for customers to purchase. Contracts tie together several important new features of ATG Business Commerce. Requisitions work with the order approval process. Pricing Services ATG Commerce pricing services revolve around pricing engines and pricing calculators. This feature allows you to target a specific set of prices to a specific group of customers. Contracts (ATG Business Commerce Only). ATG Commerce also includes an HTML-based administration interface for the Inventory Manager. Targeted Promotions Business managers can use ATG Commerce promotions to highlight products and offer discounts as a way of encouraging customers to make purchases. then submit them for approval within their organization. and edit their property values. individual item. Inventory Management The inventory framework facilitates inventory querying and inventory management for your site. based on a customer’s profile. For example. It allows you to: • • • • • Remove items from inventory. Determine when a specific item will be in stock. Notify the store of a customer’s intent to purchase an item that is not currently in stock (backorder) or has never been in stock (preorder). and payment terms with a specific organization. Promotions typically fall into the following categories: 3 1 . manipulate the various properties of each item. RFQ and pre-negotiated prices. The pricing engine determines the correct pricing model for an order. Determine and modify the number of items available for purchase.

Introduction .µ • • • • • • • • Specific amount off a particular product Specific amount off a whole order Percentage amount off a whole order Free product or free order ATG Commerce Programming Guide Percentage amount off a particular product Specific amount or percentage off a product based on an attribute Substitution (buy product A for the price of product B) Free shipping for a specific product You can create promotions through a simple interface in the ATG Control Center. When a customer purchases a gift certificate. 4 1 . in turn. • Comparison lists Comparison lists enable customers to select multiple product SKUs and compare them side-by-side. A wish list is similar to a gift list. wrapping and shipping. such as a birthday or wedding.. who. except that they are a type of promotion (20% of an order over $100. Coupons are similar to gift certificates. • Gift Certificates and Coupons You can set up gift certificates as an item in your product catalog. for example) sent to specific customers. can use it to pay for purchases on the site. and create a list of products that other site visitors can view. Customers redeem gift certificates and coupons entering a claim code during the checkout process. Part of the purchase process allows special handling instructions for gift purchases. Wish lists allow customers to save lists of products without actually placing the items in their shopping cart. • Gift Lists and Wish Lists Gift lists allow customers to register for an event. You can use the ATG Control Center to manage gift-list. coupon. such as address security. Merchandising Services ATG Commerce provides services for implementing a variety of merchandising features on your commerce site. Customers can create an unlimited number of gift lists for themselves. except that it is only accessible to the person who created it. Customers can access their wish lists and purchase items from it at any time. and gift certificate repository items. it is delivered via e-mail to the recipient.

Assembling applications that include ATG Commerce and reference application modules. products and SKUs. abandon order. CyberSource. price list. Here’s a key to finding the information you need:: Tasks Extending ATG Commerce programmatically by creating subclasses and modifying repositories. Creating a catalog and populating it with categories. Page Developers ATG Commerce Guide to Setting Up a Store ATG Commerce Guide to Setting Up a Store Business Users Business Users ATG Commerce Guide to Setting Up a Store Business Users ATG Merchandising User Guide Site Administrators ATG Programming Guide Site Administrators See Configuring and Populating a Production Database in this guide. Instructions for working with ATG Commerce live in a variety of books. and TAXWARE. Setting up scenarios and creating charts. and cost center tools. Programmers See the Integrating Third-Party Software With ATG Commerce chapter in this guide. Installing ATG Commerce databases in a production environment. ATG Merchandising User Guide Installing database tables in support of ATG Merchandising Site Administrators 5 1 .ATG Commerce Programming Guide µ Finding What You Need ATG Commerce is a comprehensive product that provides the tools you need to create a commerce Web site that’s customized to meet the particular needs of your business. SKUs in a publishing environment that uses projects to manage the tasks you perform and maintains versions of the commerce assets you edit. products. Integrating ATG Commerce with Payflow Pro.Introduction . Communicating with ATG Commerce through Web Services. Configuring the fulfillment and inventory tools provided out-the-box ATG Commerce. Users who also have ATG Merchandising should see the ATG Merchandising User Guide instead. Building JSPs that use Commerce servlet beans. Working with the out-of the-box promotion. Audience Programmers Instructions in this Guide Covered in several chapters in this guide. Developing a catalog and its categories.

(Site Administrator) Integrating Third-Party Software With ATG Commerce Details how to integrate Payflow Pro. and coupons. All All ATG Commerce Programming Guide Site Administrators See the appendices in this guide.Introduction . CyberSource. and recorders. (Programmer) 6 1 . (Programmer) ATG Commerce Profile Extensions Describes the extensions made to the Profile repository and form handlers by ATG Commerce. and TAXWARE with ATG Commerce. Working with the Motorprise Business Commerce Reference Application. (Programmer) Customizing the Purchase Process Externals Explains how to customize the purchase process. Working with the Pioneer Cycling Consumer Commerce Reference Application. product comparisons. and work with custom catalogs.µ Review database tables. ATG Business Commerce Reference Application Guide ATG Consumer Commerce Reference Application Guide Page Developers. configure. session backup procedures. Programmers ATG Commerce Guide to Setting Up a Store In This Guide This guide is divided into the following chapters: Configuring and Populating a Production Database Provides instructions on creating and configuring Commerce tables in a non-SOLID database. JMS messages. gift certificates. (Programmer) Configuring Merchandising Services Describes how to set up gift lists. Working with the ATG Commerce Sample Catalog. (Programmer) Using Custom Catalogs Describes how to create. (Programmer) Using and Extending Pricing Services Describes pricing services and provides instructions for extending them. wish lists. (Programmer) Configuring Purchase Process Services Instructs you to configure how your site presents and processes orders. (Programmer) Working With Purchase Process Objects Provides instructions for configuring the purchase process subsystem. (Site Administrator) Using and Extending the Standard Catalog Explains how to set up a standard catalog and its content.

and pipelines used in the order approval process. (Programmer) Appendix C: ATG Commerce Messages Describes the JMS messages included with ATG Commerce. (Programmer) Inventory Framework Describes the parts of the Inventory framework that you can customize. (Programmer) 7 1 . (Programmer) Configuring the Order Fulfillment Framework Describes how to work with and extend the Order Fulfillment framework. servlet beans. (Programmers . Also.Introduction . (Programmer) Appendix D: ATG Commerce Scenario Recorders Explains the recorder elements provided in support of Commerce scenarios.Business Commerce only) Preparing to Use Commerce Reporting Describes configuration and data logging and loading for Commerce Reporting.Business Commerce only) Using Abandoned Order Services Provides instructions on detecting and tracking abandoned orders. components. and pipelines used in that process.ATG Commerce Programming Guide µ Processor Chains and the Pipeline Manager Explains how the Pipeline Manager works with pipelines. (Programmer) Appendix A: ATG Commerce and Session Backup Describes the Commerce session backup strategy. (Programmer) Managing the Order Approval Process Details the handler methods. (Programmer) ATG Commerce Web Services Describes the Web Services that support Commerce features. (Programmers . describes Commerce pipelines. (Programmer) Generating Invoices Describes how invoices are generated at checkout and the repository.Business Commerce only) Using Requisitions and Contracts Explains how to track orders by requisition ID and associate Commerce items to a contract. (Programmers .(Programmer) Appendix B: ATG Commerce Databases Lists the Commerce database tables and their contents.

µ ATG Commerce Programming Guide 8 1 .Introduction .

Note: If your product stack includes ATG Commerce. The following sections describe how to create and configure your production database: Configuring ATG Commerce with CIM Creating Database Tables Using ATG Commerce with an Oracle Database Using ATG Commerce with an MSSQL Database Transferring Product Catalog and Price List Data Using Copy and Switch Transferring Demo Data Destroying Database Tables For ATG Commerce The information in this chapter focuses specifically on ATG Commerce databases. working installation running quickly and easily. Once you buy ATG Commerce. refer to the ATG Installation and Configuration Guide. requirements. CIM handles the following configuration steps: • Creates database tables and imports initial data as described in this chapter.Configuring and Populating a Production Database . and performance enhancements. ATG Content Administration and ATG Merchandising. Configuring ATG Commerce with CIM ATG’s Configuration and Installation Manager (CIM) helps to simplify ATG product configuration by walking you through the required steps. This ensures that all necessary steps are completed and are done in the correct order. For general information on production database configurations. Do not configure your production database following the steps provided in this chapter. including those for the ACI data ware house. instructions for creating the database tables you need are in the Configuring a Production Database section in the ATG Merchandising User Guide.. You can use CIM to get a basic. you will need to install a production-ready database before you can begin building your Web application. 9 2 .ATG Commerce Programming Guide µ 2 Configuring and Populating a Production Database The SOLID database included with the ATG platform is provided so that potential customers can sample the ATG products and determine whether they want to purchase it.

3. such as whether you plan to index by product or by SKU. You must manually configure these components to start automatically. To start CIM. Assembles your application EAR files for each ATG server (as described in the ATG Programming Guide). Automatic startup for the ProductCatalogOutputConfig components on either production or staging servers. 6. Note that CIM does not configure the following: • • Your Content Administration topography. Select the products you want to configure. See the CIM help and the ATG Installation and Configuration Guide for additional information on CIM. you need to create and configure the database tables for the following products: 1. Install your applications and the appropriate license files. CIM does handle some configuration options. including those needed for the ACI data warehouse. Type H at any prompt for additional information. Create tables for ATG Adaptive Scenario Engine by following the instructions provided in the Configuring Databases and Database Access chapter of the ATG Installation and Configuration Guide. • Creating Database Tables When you want to run ATG Commerce on a database other than SOLID. Select add-ons (such as Search or Reporting). including a lock manager (as described in the ATG Installation and Configuration Guide and the ATG Programming Guide) and a data warehouse loader server.µ • • • • ATG Commerce Programming Guide Creates data sources according to the database connection information you supply (as described in the ATG Installation and Configuration Guide). To configure Commerce using CIM. 10 2 . Continue through CIM according to the prompts. See the ATG Commerce Search Guide. Creates and configures ATG servers. go to <ATG9dir>/home/bin and type: cim 4.Configuring and Populating a Production Database . Deploys EAR files to your application server. 5. See the Setting Up an ATG Content Administration Server chapter of the ATG Content Administration Programming Guide. do the following: 1. 2. but you will most likely have to do additional configuration. Install your application server. Your Commerce store and IndexingOutputConfig component.

Configuring and Populating a Production Database .sql 11 2 .ATG Commerce Programming Guide µ 2.sql order_markers_ddl. you can skip all steps defined here and follow the instructions provided in their respective sections. Creating Tables for Core ATG Commerce First. ATG Business Commerce. Create the ATG Commerce tables necessary for your product suite: All ATG Commerce users should see the Creating Tables for Core ATG Commerce section.sql Purpose Configures the schema for the ATG Commerce Claimable repository Creates tables for ATG Commerce credit card profile extensions Creates a table for handling shopping cart events Creates tables for the ATG Commerce inventory system Creates tables for the ATG Commerce purchase process Defines the tables that contain order markers commerce_user. Note that if you want to run Pioneer Cycling Reference Application or Motorprise Reference Application. See Using ATG Commerce with an Oracle Database and Using ATG Commerce with an MSSQL database respectively. create the core ATG Commerce tables and then refer to the sections that follow for information on configuring the database tables that are specific to the version of ATG Commerce you are using. you can run these subscripts individually from the following directory: <ATG9dir>/DCS/sql/db_components/database-vendor Script name claimable_ddl.sql script from the following directory: <ATG9dir>/DCS/sql/install/database-vendor The dcs_ddl. To create the database tables for core ATG Commerce.sql dcs_mappers. If necessary.sql script is derived from the subscripts listed in the table below.sql order_ddl. ATG Consumer Commerce users should also see the Creating Tables for ATG Consumer Commerce section. If you are using an Oracle or MSSQL database with ATG Commerce. See Creating Pioneer Cycling Reference Application Tables and Creating Motorprise Reference Application Tables respectively. see the sections provided in this chapter for configuring your database. and ATG Consumer Commerce database tables. run the dcs_ddl. Pioneer Cycling and Motorprise users can skip this step if they want to install tables for all products at once as described below. For descriptions of core ATG Commerce.sql inventory_ddl. see Appendix B: ATG Commerce Databases. ATG Business Commerce users should also see the Creating Tables for ATG Business Commerce section.

You do not need to configure any additional database tables.sql reporting_views3.sql Description Creates tables for Pioneer Cycling catalog extensions Create tables for Pioneer Cycling profile extensions Creates tables for the French Pioneer Cycling product catalog 12 2 .sql script from the same directory.sql.sq l ATG Commerce Programming Guide Creates tables for price lists Creates tables for the ATG Commerce product catalog Creates tables for ATG Commerce pricing promotions Defines views for reporting Defines additional views for reporting Defines additional views for reporting Defines additional views for reporting Creates tables for ATG Commerce Giftlist services Creates tables for ATG Commerce promotion profile extensions Creating Tables for ATG Consumer Commerce To configure your database to work with ATG Consumer Commerce. ATG Consumer Commerce. from the following directory: <ATG9dir>/PioneerCyclingJSP/sql/install/database-vendor Alternatively.Configuring and Populating a Production Database . as described in Creating Tables for Core ATG Commerce. you can run these subscripts individually from the following directory: <ATG9dir>/PioneerCyclingJSP/sql/db_components/database-vendor File Name b2c_product_catalog_ddl. you only need to configure the core ATG Commerce tables.µ priceLists_ddl.sql reporting_views. Creating Pioneer Cycling Reference Application Tables You can configure your database to work with the ATG Adaptive Scenario Engine. core ATG Commerce.sql reporting_views2. The pioneercycling_ddl. and the Pioneer Cycling reference application by running a single script.sql script is derived from the subscripts described in Creating Tables for Core ATG Commerce as well as subscripts listed in the table below.sql reporting_views1.sql b2c_user_profile_ddl.sql product_catalog_ddl.s ql promotion_ddl.sql user_giftlist_ddl. run the pioneercycling_ddl. pioneercyclingall_ddl. If necessary. to configure just the database tables for the Pioneer Cycling reference application.sql user_promotion_ddl.sql french_product_catalog.

sql Creating Motorprise Reference Application Tables You can configure your database to work with the ATG Adaptive Scenario Engine.sql. you can create the ATG Business Commerce tables by running the b2bcommerce_ddl.Configuring and Populating a Production Database .sql contracts_ddl. and the Motorprise reference application by running a single script. Then .sql b2b_user_ddl.sql Description Creates tables for ATG Business Commerce order repository extensions Creates tables for ATG Business Commerce product catalog extensions Defines views for reporting Creates tables for ATG Business Commerce profile extensions Creates tables for the ATG Business Commerce contracts repository Creates tables for the ATG Business Commerce invoice repository Creates tables for ATG Business Commerce organization extensions b2b_product_catalog_ddl.sql script executes subscripts in a particular order to create the schema used by the ATG Business Commerce product. core ATG Commerce. motorpriseall_ddl.sql b2b_reporting_views.sql script from the following directory: <ATG9dir>/B2BCommerce/sql/install/database-vendor The b2bcommerce_ddl. you can run an individual subscript from the following directory: <ATG9dir>/B2BCommerce/sql/db_components/database-vendor Script name b2b_order_ddl. from the following directory: <ATG9dir>/MotorpriseJSP/sql/install/database-vendor 13 2 .sql organization_ddl. If necessary. configure the core ATG Commerce tables first. The remaining subscripts are described in the table below. Some subscripts are part of the core ATG Commerce product and are described in the Creating Tables for Core ATG Commerce section.ATG Commerce Programming Guide µ Creates tables for the Japanese Pioneer Cycling product catalog japanese_product_catalog.sql invoice_ddl.sql Creating Tables for ATG Business Commerce When you want to configure your database to work with ATG Business Commerce. as described in Creating Tables for Core ATG Commerce. ATG Business Commerce.

and the expected transaction volume. The size of the extents for the tablespaces needed to store ATG Commerce tables depends on your specific requirements in terms of the catalog items you have. 14 2 . you need to configure the storage parameters for several tables and configure your ATG Commerce catalog for full text searching.sql Purpose Creates tables for Motorprise profile extensions for authorization Creates tables for Motorprise custom catalog extensions Creates tables for Motorprise profile extensions for order details Creates tables for the Motorprise product catalog extensions for German content Creates tables for the Motorprise product catalog extensions for Japanese content japanese_catalog_ddl. The incremental extent limits the additional space that is reserved when the segment’s initial data blocks become full.sql Using ATG Commerce with an Oracle Database To use ATG Commerce with an Oracle database. and more space is required. you can run these subscripts individually from the following directory: <ATG9dir>/MotorpriseJSP/sql/db_components/database-vendor Script name b2b_auth_cc_ddl. You should spread your tablespaces across several disk drives and disk controllers. to configure just the database tables for the Motorprise reference application. To allocate space. the expected number of user profiles and Web site visitors. The initial extent parameter limits the amount of space that is reserved initially for a table’s data segment. If necessary. The motorprise_ddl.sql b2b_custom_catalog_ddl.sql script from the same directory. run the motorprise_ddl.sql b2b_user_orddet_ddl.sql script is derived from the subscripts that are described in the Creating Tables for ATG Business Commerce section as well as other subscripts listed in the table below.Configuring and Populating a Production Database . you need to specify the initial extent and the incremental extent for the tables that are likely to expand significantly.sql german_catalog_ddl. This section covers these configuration tasks: • • Configuring Storage Parameters Configuring a Catalog for Oracle Full Text Searching Configuring Storage Parameters The SQL scripts that configure ATG Commerce databases on Oracle do not set storage parameters to control how free database space is allocated.µ ATG Commerce Programming Guide Alternatively.

using the following format: 15 2 . Note: By default. which processes queries and returns information based on the content or themes of text stored in a text column of an Oracle database. you should configure ConText indexing to occur at regular intervals. To enable full text searching on columns. This behavior can cause a full deployment to hang indefinitely. the optimal settings for your database may vary depending on the expected number of user profiles. To specify a storage parameter. as well as the expected transaction volume. include it in the STORAGE clause of the CREATE TABLE statement for these tables. an Oracle database rebuilds a full-text index after each commit.Configuring and Populating a Production Database . you can set the extent sizes for the tablespaces to be 512K with pctincrease equal to 50. If you are loading the Pioneer Cycling reference application or Motorprise reference application on an Oracle database. These steps are described in more detail in the sections that follow. Make sure the simulateTextSearchQueries property of each product catalog repository component is set to false. Configuring a Catalog for Oracle Full Text Searching If your product catalog is stored in an Oracle database. For additional information about configuring storage parameters. To prevent this. As previously mentioned. and catalog items. Set up the proper ConText full text indexes on the appropriate columns in the database. you must configure the catalog to properly handle full text searching.ATG Commerce Programming Guide µ Incremental Extent 1M 1M 1M 2M 2M To begin. 2. There are two main steps involved in this configuration: 1. Setting Up the ConText Indexes The SQL Repository has built-in support for Oracle’s ConText full text search engine. you should configure the storage parameters for the following ATG Commerce tables: Table Name DCS_CATEGORY DCS_PRODUCT DCS_SKU DCS_MEDIA_BIN DSS_SCENARIO_INFO Initial Extent 1M 1M 1M 4M 4M Note: These storage parameters are guidelines only. See your Oracle documentation for information about how to do this. Web site visitors. see your Oracle documentation. you must create ConText indexes for the columns.

index these tables: If you have imported the Pioneer Cycling product catalog into Oracle. there are three SQL Repository components for the catalog: • • • /atg/commerce/catalog/ProductCatalog /atg/commerce/catalog/FrenchProductCatalog /atg/commerce/catalog/JapaneseProductCatalog 16 2 . create a ConText index on the DESCRIPTION. If you are using the default product catalog. LONG_DESCRIPTION. and DISPLAY_NAME columns. Configuring the Repository Components for Full Text Searching To enable a SQL Repository to use full text searching in an Oracle database.µ DCS_PRODUCT DCS_CATEGORY ATG Commerce Programming Guide CREATE INDEX schema-index-name ON schema-table (column) INDEXTYPE IS CTXSYS. index these tables: DCS_PRODUCT DCS_CATEGORY DFR_PRODUCT DFR_CATEGORY DJP_PRODUCT DJP_CATEGORY If you have imported the Motorprise product catalog into Oracle. Make sure this property is set to false for any SQL Repository component that connects to an Oracle database. index these tables: DCS_PRODUCT DCS_CATEGORY DBC_CATEGORY_DE DBC_PRODUCT_DE In each of these tables.CONTEXT PARAMETERS('SYNC (EVERY "interval-string" '). the SQL Repository component for the catalog has the Nucleus address /atg/commerce/catalog/ProductCatalog. If you have exported the Pioneer Cycling catalog into Oracle. If you are using the default product catalog.Configuring and Populating a Production Database . the simulateTextSearchQueries property of the SQL Repository component must be set to false.

17 2 . you must configure the database and catalog to properly handle full text searching.ATG Commerce Programming Guide µ Using ATG Commerce with an MSSQL Database If your ATG Commerce product catalog is stored in a Microsoft SQL Server database. There are four steps involved in the configuration process: 1. you must create full text indexes for the columns. index these tables: DCS_PRODUCT DCS_CATEGORY If you have imported the Pioneer Cycling product catalog into MS SQL. index these tables: DCS_PRODUCT DCS_CATEGORY DFR_PRODUCT DFR_CATEGORY DJP_PRODUCT DJP_CATEGORY If you have imported the Motorprise product catalog into MS SQL. Configure each search form handler component. If you are using the default ATG Commerce product catalog.Configuring and Populating a Production Database . 3. Set the simulateTextSearchQueries property of each product catalog repository component to false. index these tables: DCS_PRODUCT DCS_CATEGORY DBC_CATEGORY_DE DBC_PRODUCT_DE For each of these tables. create an index for the LONG_DESCRIPTION. DESCRIPTION and DISPLAY_NAME columns. See the subsections that follow for information on completing each step. Setting Up the MS SQL Full Text Indexes To enable full text searching on columns. See your Microsoft SQL Server documentation for specific information on performing this step. 4. Set up the proper full text indexes on the appropriate columns in the database. 2. Modify the template definition file.

catalog.catalog. be sure to also set the properties of those components as described above. you must configure these components to generate full-text queries in the appropriate form.custom. see the ATG Repository Guide. verify that the queries use the appropriate format for MS SQL Full Text Query.SearchFormHandler (or atg. there are three SQL repository components for the catalog: • • • /atg/commerce/catalog/ProductCatalog /atg/commerce/catalog/FrenchProductCatalog /atg/commerce/catalog/JapaneseProductCatalog Configuring the Search Form Handlers If your site uses components of class atg. the simulateTextSearchQueries property of the SQL repository component must be set to false. If you have exported the Pioneer Cycling catalog into MS SQL.µ Modifying the Template Definition File <query-items item-descriptor="product"> ATG Commerce Programming Guide If you include any full text search queries in the XML template definition file (using the <query-items> tag). 2.commerce. each component must be configured as follows: 1. Set the searchStringFormat property to MSSQL_TSQL. Configuring the Repository Components for Full Text Searching To enable a SQL repository to work with a full text search engine. Set the allowEmptySearch property to false.Configuring and Populating a Production Database . 18 2 . For example: description MATCHES "Ethernet" USING "MSSQL_TSQL" </query-items> For more information on template definition files.CatalogSearchFormHandler for custom catalogs) to build search forms for full-text searching. ATG Commerce includes five instances of this class in /atg/commerce/catalog/: • • • • • AdvProductSearch CatalogSearch CategorySearch ProductSearch ProductTextSearch If you’ve created your own instances of this class. To do this.commerce. By default. the SQL repository component for the catalog has the Nucleus address /atg/commerce/catalog/ProductCatalog. If you are using the default product catalog.

the mechanisms are the same regardless of what kind of database is used. Transferring Product Catalog and Price List Data Using Copy and Switch The database Copy and Switch features assist you in moving your product catalog and price lists data from one environment to another. Refer to the database client’s documentation for more information.) This chapter describes how to perform a database copy and switch of the ATG Commerce product catalog and price list repositories.custom. which are included with ATG Commerce. Some database clients require additional configuration to perform the database copy. which is located in Nucleus at /atg/projects/b2bstore/catalog/SearchCompare.commerce. Both database Copy and database Switch are Dynamo Application Framework (DAF) features that can be used with any database. This user interface requires initial configuration before you perform each type of update for the first time.ATG Commerce Programming Guide µ Also note that the Motorprise Store Solution Set uses its own instance of atg. see Appendix B: ATG Commerce Databases in this manual.Configuring and Populating a Production Database . For information about ATG Commerce database tables. However. (See the configuration sections in this chapter for more information on the configuration processes. 19 2 . The database Copy feature enables you to copy product catalog and price lists data from one database to another. Note: While the process used in this section assumes the data is in a SOLID database. However. from a staging environment to a “live” production environment. The differences are in the configuration of the environment within which ATG Commerce is running. If you have imported the Motorprise product catalog into MS SQL. see the ATG Installation and Configuration Guide. Configuring a Database Copy This section describes the configuration steps you must take before performing a database copy of your product catalog and price lists data. configure this component as described above as well. ATG Commerce provides a user interface for performing a database copy or switch. The database Switch feature enables you to switch the product catalog and price lists on your Web site to use a different data source. you don’t need to complete this process before subsequent database copies as long as the source and destination databases remain the same.CatalogSearchFormHandler. You must complete this process before performing an initial database copy.catalog. It includes the following sections: • • • • Configuring a Database Copy Performing a Database Copy Configuring a Database Switch Performing a Database Switch Note: For additional information about copying and switching databases and setting up your database servers. for example.

It executes a new process and uses the vendor’s bulk copy tools to copy the tables from one database to another. but the DBCopier in this process instead uses native commands according to the database manufacturer. Make sure that all the necessary environmental variables are set as specified by the vendor. The class from which you instantiate the DBCopier depends on the database you are using. you can refer to the ATG API Reference. The following are subclasses of atg.gsa: BcpDBCopier (for Microsoft and Sybase) DB2DBCopier OracleDBCopier SolidDBCopier 3. Alternatively. Verify that all the necessary drivers or client tools are installed. you can refer to the ATG API Reference and the ATG Installation and Configuration Guide. refer to the BcpDBCopier class (from which ProductCatalogMsSqlDBCopier is instantiated) in the ATG API 20 2 . They are: ProductCatalogMsSqlDBCopier Note: By default.adapter. The following are some SOLID-specific configuration settings: $SOLIDDIR should be defined in the environment in which Dynamo is running. Most interactions between the ATG Commerce and a database are done through JDBC. 2.DBCopier and are in package atg. [Data Sources] SOLID=TCP/IP localhost 1313.SOLID Note that “SOLID” is a valid server name. For information on the API for the specific DBCopier you are using.ini file. For more information on the maxTextOrImageSize property.Configuring and Populating a Production Database . The names of the servers to use when performing the database copy should be defined in the solid. therefore. you can use one of the preconfigured DBCopier components that are included with ATG Commerce.maxTextOrImageSize property is set to a negative value (-1) in order to force the copier not to use the –T option with the bcp utility. Verify that the environment is set up correctly. For more information on these DBCopier classes. See your vendor documentation for these specifications. ATG Commerce Programming Guide Follow these configuration steps to prepare to copy the product catalog and price lists data from one database to another: Create the destination database and all destination tables. the ProductCatalogMsSqlDBCopier. This means that the DBCopier and. the JVM running Dynamo must have the proper environment set up as specified by the vendor. Create a DBCopier component with which to copy the product catalog and price lists data.µ 1.adapter.gsa. the –T option does not work with MS SQL.

sql # # # # # # # # # # # # # # # # # # # # # The list of tables that will actually be copied. There are 3 sets of tables listed here: product catalog. refer to your database vendor documentation. promotions. The tables are updated in the order they appear in this list. ProductCatalogOracleDBCopier ProductCatalogDB2DBCopier ProductCatalogSybaseDBCopier ProductCatalogSolidDBCopier These DBCopier components are located in Nucleus at /atg/commerce/jdbc/.ATG Commerce Programming Guide µ Reference. $class=atg.adapter.SolidDBCopier # # The directory where temporary files are stored. For more information on the bcp utility. and price lists. These are the product catalog tables: dcs_folder dcs_media dcs_media_ext dcs_media_bin dcs_media_txt dcs_category dcs_category_acl 21 2 . # directory=d:/copytmp # # The name of the file that gets created to delete # data from the destination.gsa. If there are references between tables. The following code example is taken from the properties file of ProductCatalogSolidDBCopier: # This is an instance of the DBCopier specific for copying # ProductCatalog data from one Solid instance to another.Configuring and Populating a Production Database . make sure they appear in the correct order. Copy will overwrite these tables. # deleteDataFileName=del_dest_data. Only list static tables that do not change.

you should also add these files: # 22 2 .Configuring and Populating a Production Database .µ ATG Commerce Programming Guide # dcs_product # dcs_product_acl # dcs_sku # dcs_cat_groups # dcs_cat_chldprd # dcs_cat_chldcat # dcs_cat_ancestors # dcs_cat_rltdcat # dcs_cat_keywrds # dcs_cat_media # dcs_cat_aux_media # dcs_prd_keywrds # dcs_prd_media # dcs_prd_aux_media # dcs_prd_chldsku # dcs_prd_skuattr # dcs_prd_groups # dcs_prd_rltdprd # dcs_prd_ancestors # dcs_sku_attr # dcs_sku_link # dcs_sku_bndllnk # dcs_sku_media # dcs_sku_aux_media # dcs_sku_replace # dcs_sku_conf # dcs_config_prop # dcs_conf_options # dcs_config_opt # dcs_foreign_cat # # These are the promotion tables: # # dcs_promotion # dcs_promo_media # dcs_discount_promo # # These are the price list tables: # # dcs_price_list # dcs_complex_price # dcs_price # dcs_price_levels # dcs_price_level # dcs_gen_fol_pl # dcs_child_fol_pl # dcs_plfol_chld # # If you are using custom catalogs.

\ dcs_prd_chldsku.\ dcs_category.\ 23 2 .\ dcs_prd_media.\ dcs_media.\ dcs_media_txt.\ dcs_prd_ancestors.\ dcs_category_acl.\ dcs_cat_ancestors.\ dcs_product_acl.\ dcs_prd_groups.\ dcs_cat_keywrds.Configuring and Populating a Production Database .\ dcs_sku_attr.\ dcs_cat_groups.\ dcs_media_bin.ATG Commerce Programming Guide µ # dcs_catalog # dcs_root_cats # dcs_allroot_cats # dcs_root_subcats # dcs_sub_catalogs # dcs_category_info # dcs_product_info # dcs_sku_info # dcs_cat_subcats # dcs_cat_subroots # dcs_cat_catinfo # dcs_catinfo_anc # dcs_prd_prdinfo # dcs_prdinfo_rdprd # dcs_prdinfo_anc # dcs_sku_skuinfo # dcs_skuinfo_rplc # dcs_gen_fol_cat # dcs_child_fol_cat # dcs_catfol_chld # # tables= \ dcs_folder.\ dcs_prd_rltdprd.\ dcs_cat_media.\ dcs_cat_aux_media.\ dcs_prd_aux_media.\ dcs_sku.\ dcs_prd_keywrds.\ dcs_prd_skuattr.\ dcs_cat_chldprd.\ dcs_cat_chldcat.\ dcs_media_ext.\ dcs_product.\ dcs_cat_rltdcat.

\ dcs_sku_aux_media.\ dcs_price_levels. Verify that the tables property of the DBCopier component includes all the necessary tables to copy in the correct order. 5.\ dcs_price_list. you can set the loggingDebug property of the DBCopier component to true.\ dcs_discount_promo. 7.\ dcs_child_fol_pl.\ dcs_sku_replace. you can use the preconfigured DBCopyFormHandler included with ATG Commerce.DBCopyFormHandler to handle the database copy.\ dcs_price_level. It is located in Nucleus at /atg/commerce/jdbc/ProductCatalogCopierForm.droplet. Alternatively. # $class=atg. Check that the directory specified in the directory property of the DBCopier exists in the file system used by Dynamo.\ dcs_price. Optionally. The following code example is taken from the properties file of ProductCatalogCopierForm: # # This is an instance of the DBCopyFormHandler that is specific # to copying product catalog and price lists data.\ dcs_complex_price.\ dcs_foreign_cat. 4.\ dcs_gen_fol_pl.gsa. The tables in the destination database will be updated according to the list of tables in this property.\ dcs_sku_bndllnk.Configuring and Populating a Production Database .\ dcs_sku_conf.\ dcs_config_prop.µ dcs_sku_link.\ dcs_sku_media. note that the ProductCatalogOracleDBCopier and ProductCatalogSolidDBCopier components specify additional tables because Pioneer Cycling uses additional tables for its product catalog.DBCopyFormHandler $scope=request 6. and therefore a different DBCopier.adapter.\ dcs_plfol_chld ATG Commerce Programming Guide Note: If you are running Pioneer Cycling.\ dcs_promo_media. If you want to use a different database for the database copy.\ dcs_conf_options.\ dcs_config_opt. 24 2 .\ dcs_promotion. to obtain information on the activity of the DBCopier. Create an instance of atg.sql. you’ll need to manually add these tables to the DBCopier.

For example. 6. Click the Copy link. See the ATG Installation and Configuration Guide to find the default port. It can be used. Click the Copy button. # DBCopier=/atg/commerce/jdbc/ProductCatalogSolidDBCopier 8. The class used depends on the # brand of database being used. to copy the updated contents of the product catalog/price lists database on an Administration server to the product catalog/price lists database on a Staging server.ATG Commerce Programming Guide µ # # This is the DBCopier to use. ask your database administrator to copy the database. and Password for the Source database. as described in Performing a Database Copy. 25 2 . for example. Enter the Server Name. on JBoss the default URL is: http://hostname:8080/dyn/admin/atg/commerce/admin 2. The contents of the Source database are copied into the Destination database. Note: You must have read. Perform the database copy from the Copy Product Catalog and Price Lists page. write and delete permissions. The system displays the Product Catalog and Price Lists Copy/Switch page. (See Configuring a Database Copy for a code example of a DBCopier configuration file. To perform a database copy of the product catalog and price lists data: 1. 7. as well as import and export permissions. Username. and Password for the Destination database. Username. If you do not have the appropriate permissions. to perform the database copy. Note that the time it takes to perform the database copy depends on the size of the database. Click the Copy/Switch Commerce Data link.) Access the main Commerce Administration page of the Dynamo Administration UI using the port appropriate for your application server. Enter the Server Name. 3. Make sure the configuration file of the DBCopier you are using has been updated to account for any database tables you have created or deleted. Performing a Database Copy This section describes the process to copy the contents of one database to another database. 4. Note: your application must include the Dynamo Administration UI in order for you to access it. 5.Configuring and Populating a Production Database . The system displays the Copy Product Catalog and Price Lists page.

dataSource is set to ProductCatalogFakeXADataSourceA. Create the underlying data sources.µ Configuring a Database Switch ATG Commerce Programming Guide This section describes the configuration steps you must take before performing a database switch of the data source used by the product catalog and price lists on your Web site. Note: While the process used in this section assumes the data is in a SOLID database. you use a SwitchingDataSource to switch between two product catalog/price lists data sources. You must complete this process before performing an initial database switch. Configure the dataSource property in each of the data sources. They are: /atg/commerce/jdbc/ProductCatalogDataSourceA and /atg/commerce/jdbc/ProductCatalogDataSourceB. Create a SwitchingDataSource.SolidDriver URL=jdbc:solid://hostname:port user=user password=password The port for SOLID is typically 1313.Configuring and Populating a Production Database . However. Follow these configuration steps to prepare to switch the data source used by the product catalog and price lists repositories: 1. Alternatively. For example. The dataSource property contains a reference to the data source that stores information for connection to a database. These data sources are used as the example data sources in this procedure.jdbc. you don’t need to complete this process before subsequent database switches as long as the data sources involved remain the same. By default. and ProductCatalogDataSourceB. Both of these FakeXADataSource data sources are configured as follows: $class=atg. ProductCatalogDataSourceA. Alternatively. The Nucleus components used in this example are located at /atg/commerce/jdbc. In an actual database switch. both FakeXADataSource data sources have the same configuration. you can use the data sources provided with the default configuration of ATG Commerce. The SwitchingDataSource can switch from one underlying data source to another. 3. Note: In this example. you control to what database each data source points. you can use ProductCatalogSwitchingDataSource. 2.FakeXADataSource driver=solid. the configuration of the two data sources would be different.jdbc.service. the method could switch from a test database to a production database. the mechanisms are the same regardless of what kind of database is used. By setting this property for ProductCatalogDataSourceA and ProductCatalogDataSourceB. When you perform a database switch.dataSource is set to ProductCatalogFakeXADataSourceB. which is located in Nucleus at 26 2 .

the switchingDataSource property specifies the specific SwitchingDataSource controlled by the form handler. all DataSource method calls are passed through to the DataSource specified in the currentDataSource property. the PriceLists repository does not use this data source. $class=atg.properties file at localconfig/atg/commerce/pricing/priceLists/: dataSource=/atg/commerce/jdbc/ProductCatalogSwitchingDataSource 6. For more information on SwitchingDataSource.SwitchDataSourceFormHandler) to use the SwitchingDataSource.Configuring and Populating a Production Database . as described in Performing a Database Switch. By default.properties file at localconfig/atg/commerce/catalog/: dataSource=/atg/commerce/jdbc/ProductCatalogSwitchingDataSource 5. Perform the database switch. Configure the PriceLists repository to use the SwitchingDataSource. 4. Configure the ProductCatalog repository to use the SwitchingDataSource. see the ATG API Reference and the ATG Installation and Configuration Guide. By default.sql.droplet. which is defined at run time. 27 2 . This SwitchingDataSource is provided with the default configuration of ATG Commerce. In a SwitchingDataSource.jdbc. so you must add the following to the PriceLists. 7.service.SwitchingDataSource # # A map from data source names to data sources # dataSources=\ DataSourceA=/atg/commerce/jdbc/ProductCatalogDataSourceA. The initialDataSource is the data source used.ATG Commerce Programming Guide µ /atg/commerce/jdbc/.\ DataSourceB=/atg/commerce/jdbc/ProductCatalogDataSourceB # # The name of the data source that should be used # initialDataSourceName=DataSourceA The dataSources property of a SwitchingDataSource is a mapping of data source names to the Nucleus path of each data source. Configure the switchingDataSource property of the ProductCatalogSwitcher form handler (class atg. the ProductCatalog repository does not use this data source. A SwitchingDataSource is a DataSource that can switch between two or more underlying data sources. so you must add the following to the ProductCatalog. The Switch UI uses the ProductCatalogSwitcher form handler to perform the database switch. The following example shows the configuration for the ProductCatalogSwitchingDataSource included with ATG Commerce.

” The data source to which you just switched is now listed as the current data source. the following message displays at the top of the Switch the Product Catalog’s and Price List’s Data Sources: Switch page: “Now that you have prepared the data source. you must do so on each DRP server instance in a Dynamo server cluster. The system prepares for the switch by sending events to each of the repositories that are using the switching data source.” 6. When the switch is complete. Select the name of the data source to which you want to switch from the drop-down list at the bottom of the page.jhtml Note: your application must include the Dynamo Administration UI module in order for you to view this URL. access the Commerce Administration UI. When preparation is complete. For example. on JBoss the default URL is: http://hostname:8080/dyn/admin/atg/commerce/admin/en/index. Follow these steps to switch the data source currently used by the product catalog and price lists on your Web site. The data source currently being used by your site is displayed below the table. 5. Click the Copy/Switch Commerce Data link. and perform the database switch. 2.µ Performing a Database Switch ATG Commerce Programming Guide This section describes the process of switching the data source used by the product catalog and price lists on your Web site. The system displays the Switch the Product Catalog’s and Price List’s Data Source: Prepare page. you can finish the switch. Consequently.Configuring and Populating a Production Database . The system displays the Product Catalog and Price Lists Copy/Switch page. Access the main Commerce Administration page of the Dynamo Administration UI using the port appropriate for your application server. Each repository performs any functions needed to prepare for a switch. 1. you need to connect to the server’s Admin port. The names and paths of the available data sources are listed. 3. Click the Prepare for Switch button. for each DRP server instance. Click the Switch link. 28 2 . When you perform a database switch. 4. See the ATG Installation and Configuration Guide to find the default port. This is necessary because the SwitchingDataSource components on separate instances do not synchronize themselves. the page displays the following message: “You have finished switching the data source used by the Product Catalog and the Price Lists. Click the Switch button to complete the switch.

you must update your connection pool service to use the new database. Once you have exported the data to your database. To transfer the demo data to your production database. Exporting the Demo Data from SOLID Make sure that either there are no connection pool properties files.xml bin/startSQLRepository -m MotorpriseJSP -exportRepositories all all. Start the SOLID database and use the commands below (on one line. with no line breaks) to export the demo data to an XML file called all. Oracle users: Before importing the demo data. See your MS SQL documentation for instructions. if necessary Import the demo data Microsoft SQL users: In order to run the ATG demos with a Microsoft SQL database. go to the <ATG9dir>/home directory. You can set this property in your localconfig/GLOBAL. Your connection pool properties file must be pointing to the new target database.Configuring and Populating a Production Database . or that they are pointing to the demo SOLID database. set the useSetCharacterStream property of all SQL repository components to true so that non-8859 characters are displayed correctly.xml.xml to your target database. Demo Application Pioneer Cycling Command bin/startSQLRepository -m PioneerCyclingJSP -exportRepositories all all. 29 2 . Use the commands below (on one line.ATG Commerce Programming Guide µ Transferring Demo Data You can move the Pioneer Cycling and Motorprise demo data from the SOLID database to another database using the ATG startSQLRepository utility.xml. you must do the following: • • • Export the demo data Reset your production database. For more information on configuring connection pools. You can export that data to your production database to test the demos against your production environment. refer to the Configuring Databases and Database Access section of the ATG Installation and Configuration Guide. you must configure the database to be case-sensitive. Importing the Demo Data to Your Database Your connection pool properties file must be pointing to the new target database. see the ATG Installation and Configuration Guide.properties file: useSetCharacterStream=true From the command line. with no line breaks) to import the data contained in all.xml Motorprise For more information. All Dynamo supported databases can import all.

then the core ATG Commerce.µ Demo Application Pioneer Cycling Motorprise Command ATG Commerce Programming Guide bin/startSQLRepository -m PioneerCyclingJSP -import all. If necessary. Destroying Tables for Core ATG Commerce To destroy all core ATG Commerce tables. you need to destroy them in the opposite order you used for creating them.sql script from the following directory: <ATG9dir>/DCS/sql/install/database-vendor The drop_dcs_ddl. and ATG Consumer Commerce database tables. run the drop_dcs_ddl. Destroying Database Tables for ATG Commerce This section describes how to destroy the ATG Commerce database tables. you can run these subscripts individually from the following directory: <ATG9dir>/DCS/sql/uninstall/database-vendor File Name drop_claimable_ddl.sql drop_dcs_mappers.sql script is derived from the subscripts listed in the table below.xml bin/startSQLRepository -m MotorpriseJSP -import all.xml For more information about the startSQLRepository utility. This section includes the following subsections: • • • Destroying Tables for Core ATG Commerce Destroying Tables for ATG Consumer Commerce Destroying Tables for ATG Business Commerce For descriptions of core ATG Commerce.sql Description Destroys the schema for the ATG Commerce Claimable repository Destroys the tables for the ATG Commerce credit card profile extensions Destroys the table for handling shopping cart events drop_commerce_user. If you want to remove all tables for ATG Business Commerce. see the ATG Repository Guide. When you destroy database tables. ATG Business Commerce. followed by the ATG Adaptive Scenario Engine tables.sql 30 2 .Configuring and Populating a Production Database . for example. see Appendix B: ATG Commerce Databases. you would destroy first the ATG Business Commerce tables.

drop_pioneercyclingall_ddl.sql Destroying Tables for ATG Consumer Commerce To destroy all ATG Consumer Commerce tables. and the Pioneer Cycling reference application by running a single script.Configuring and Populating a Production Database .sql drop_product_catalog_ddl. from the following directory: <ATG9dir>/PioneerCyclingJSP/sql/install/database-vendor Alternatively. Destroying Pioneer Cycling Reference Application Tables You can destroy the database tables for the ATG Adaptive Scenario Engine. core ATG Commerce.sql drop_reporting_views1.ATG Commerce Programming Guide µ Destroys the tables for the ATG Commerce inventory system Destroys the tables for the ATG Commerce purchase process Destroys the tables that contain order markers Destroys the tables for the ATG Commerce price lists Destroys the tables for the ATG Commerce product catalog Destroys the tables for the ATG Commerce promotions Destroys the views for reporting Destroys additional views for reporting Destroys additional views for reporting Destroys additional views for reporting Destroys the tables for the ATG Commerce Giftlist Services Destroys the tables for the ATG Commerce promotions profile extensions drop_inventory_ddl.sql drop_user_promotion_ddl. to destroy just the database tables for the Pioneer Cycling reference application. you can run these subscripts individually from the following directory: <ATG9dir>/PioneerCyclingJSP/sql/uninstall/database-vendor 31 2 .sql drop_user_giftlist_ddl. ATG Consumer Commerce.sql script is derived from the subscripts that are described in Destroying Tables for Core ATG Commerce section as well as those listed in the table below.sql drop_order_ddl. You do not need to destroy any additional database tables. If necessary. you only need to destroy the core ATG Commerce tables.sql drop_reporting_views3. The drop_pioneercycling_ddl.sql drop_reporting_views.sql drop_promotion_ddl.sql drop_order_markers_ddl. run the drop_pioneercycling_ddl.sql drop_reporting_views2.sql script from the same directory.sql drop_priceLists_ddl. as described in Destroying Tables for Core ATG Commerce.sql.

as described in Destroying Tables for Core ATG Commerce and then run the ATG Business Commerce script appropriate for your product suite.sql script is derived from subscripts described in Destroying Tables for Core ATG Commerce as well as subscripts listed in the table below.sql drop_french_product_catalog. During the installation of ATG Business Commerce.sql ATG Commerce Programming Guide Purpose Destroys tables for the Pioneer Cycling catalog extensions Destroys tables for the Pioneer Cycling profile extensions Destroys tables for the French Pioneer Cycling catalog Destroys tables for the Japanese Pioneer Cycling catalog Destroying Tables for ATG Business Commerce To destroy all ATG Business Commerce tables.sql Purpose Destroys the tables for the ATG Business Commerce order repository extensions 32 2 .Configuring and Populating a Production Database . destroy first the core ATG Commerce tables.µ Script name drop_b2c_product_catalog_ddl.sql drop_japanese_product_catalog. you can run each subscript individually from the following directory: <ATG9dir>/B2BCommerce/sql/uninstall/database-vendor Script name drop_b2b_order_ddl. as described in Destroying Tables for Core ATG Commerce. If necessary. six views that are created by ATG Consumer Commerce are removed because they are not applicable in ATG Business Commerce. This is not an error.sql script from the following directory: <ATG9dir>/B2BCommerce/sql/install/database-vendor The drop_b2bcommerce_ddl. Note: While dropping these tables you may see error messages indicating that six views could not be removed.sql drop_b2c_user_profile_ddl. and then run the drop_b2bcommerce_ddl. The views involved are listed below: • • • • • • View DRPT_PRODUCTS View DRPT_CATEGORY View DRPTW_CAT_SALES View DRPTM_CAT_SALES View DRPTQ_CAT_SALES View DRPTA_CAT_SALES To destroy all ATG Business Commerce tables. destroy the core ATG Commerce tables.

sql drop_organization_ddl.sql drop_b2b_reporting_views.sql Purpose Destroys tables for the Motorprise profile extensions for authorization Destroys tables for the Motorprise custom catalog extensions Destroys tables for the Motorprise profile extensions for order details Destroys tables for the Motorprise product catalog extensions for German content drop_b2b_custom_catalog_ddl. you can run each subscript individually from the following directory: <ATG9dir>/MotorpriseJSP/sql/uninstall/database-vendor Script name drop_b2b_auth_cc_ddl. drop_motorpriseall_ddl. The drop_motoprise_ddl.sql. If necessary.sql drop_contracts_ddl.sql drop_b2b_user_ddl.ATG Commerce Programming Guide µ Destroys the tables for the ATG Business Commerce product catalog extensions Destroys the views for reporting on ATG Business Commerce Destroys the tables for the ATG Business Commerce profile extensions Destroys the tables for the ATG Business Commerce contracts repository Destroys the tables for the ATG Business Commerce invoice repository Destroys the tables for the ATG Business Commerce organization extensions drop_b2b_product_catalog_ddl.sql script is derived from the Destroying Tables for ATG Business Commerce as well as subscripts listed in the table below. core ATG Commerce.sql Destroying Motorprise Reference Application Tables You can destroy the database tables for ATG Adaptive Scenario Engine.sql drop_german_catalog_ddl. ATG Business Commerce.sql script from the same directory.sql drop_b2b_user_orddet_ddl. and the Motorprise reference application by running a single script. from the following directory: <ATG9dir>/MotorpriseJSP/sql/install/database-vendor Alternatively. run the drop_motorprise_ddl.sql 33 2 .sql drop_invoice_ddl.Configuring and Populating a Production Database . to destroy just the database tables for the Motorprise reference application.

sql ATG Commerce Programming Guide Destroys tables for the Motorprise product catalog extensions for Japanese content 34 2 .Configuring and Populating a Production Database .µ drop_japanese_catalog_ddl.

Install and register Payflow Pro. such as address verification. To use Payflow Pro with ATG Commerce. be sure to specify the module for the third party software you want to use. As an example. Assemble an application that includes ATG Commerce and Payflow Pro. See Pre-Configuring the Integration. 3. include the following modules: • • For ATG Business Commerce: B2BCommerce Cybersource Taxware For ATG Consumer Commerce: B2CCommerce Cybersource Taxware Integrating Payflow Pro with ATG Commerce The Payflow Pro payment object handles credit card authorization. and the module with the highest precedence is at the end of the line. When you assemble your application. and crediting.ATG Commerce Programming Guide µ 3 Integrating Third-Party Software With ATG Commerce This chapter describes how to integrate ATG Commerce with the following third party software applications: Integrating Payflow Pro with ATG Commerce Integrating CyberSource with ATG Commerce Integrating TAXWARE with ATG Commerce Note: You can use more than one third-party application module. 35 3 . CyberSource and TAXWARE both have a tax calculation feature. then the address verification implementation of the module with the highest precedence is used. See Setting Up Payflow Pro. 4. Start Payflow Pro Provide property values to two Nucleus components. If two application modules each implement the same capability. follow these steps: 1. The order of the modules affects their precedence. settlement.Integrating Third-Party Software With ATG Commerce . See Using ATG Commerce with Payflow Pro. To use CyberSource for credit verification and TAXWARE instead of CyberSource for tax information. 2.

be sure to install and configure Payflow Pro SDK.PayFlowProConnection $scope=global partner= vendor= user= password= hostAddress= hostPort= timeout= proxyAddress= proxyPort= proxyLogon= proxyPassword= Provide the same value to each property that you provided when you registered for Payflow Pro. and registering with VeriSign. You need to set up this service manually. 36 3 . you need to provide property values to two existing components. with the following contents: $class=atg. Although it’s recommended to set a value for all properties.payflowpro.Integrating Third-Party Software With ATG Commerce . Pre-Configuring the Integration Before you assemble your application. Also. you are not required to provide values for proxyAddress.properties in a local configuration directory. For information on ATG modules and application assembly. such as <ATG9dir>/home/localconfig. Set the vendor property to the merchant name. which involves downloading the product.commerce.payment. setting several environment variables. such as <ATG9dir>/home/localconfig. PayFlowProConnection. The first. Refer to the documentation and information available at http://www.verisign.com/.µ Setting up Payflow Pro ATG Commerce Programming Guide Before using Payflow Pro. with the following contents: $class=atg. create a file called PaymentManager. is a service that enables all Payflow Pro activities. see the ATG Programming Guide.integrations. or proxyPassword. Create a file called PayFlowProConnection. Keep track of the registration information you specify because you’ll need to provide some of it to the ATG Commerce. The registration process has two parts: setting up a Payflow Pro account and obtaining a Merchant account.PaymentManager $scope=global creditCardProcessor=/atg/commerce/payment/PayFlowProConnection Using ATG Commerce with Payflow Pro When you use ATG Commerce with Payflow Pro. proxyPort. proxyLogon.properties in a local configuration directory. ATG Commerce automatically configures the Payflow Pro integration as long as the following PayFlowPro module is specified during application assembly.

Integrating Third-Party Software With ATG Commerce .jar and copy it to the <ATG9dir>/Cybersource/lib directory. and crediting Tax calculations Address verification This section describes the process of enabling the CyberSource integration with ATG Commerce.crt The test keys and certificates are installed in the keys directory. settlement. Download and uncompress the CyberSource ICS Java Client distribution file Refer to the documentation and information available in the CyberSource PDF file at http://www.com Installing the CyberSource Distribution The CyberSource ZIP file contains a set of test certificates and keys that can be used to test the system. myCert for CyberSource must be changed as follows: • • On Windows: myCert=<CyberSource Install Dir>\\keys\\ICS2Test. your machine will have the configuration file ICSClient. Before using CyberSource. The configuration ICSClient. Rename the jar file to cdkjava_cybersource. you must set up the CyberSource integration.crt Edit ICSClient. Create the CyberSourceConnection.props to change the relative path of the keys and certificates to absolute path to make sure they will be properly located and loaded by the integration.crt On UNIX: myCert=<CyberSource Install Dir>/keys/ICS2Test.properties file in the following directory: 37 3 . your e-commerce site must: • • • Establish an appropriate business arrangement with CyberSource Inc.props in the properties folder of the CyberSource installation directory. Initializing the CyberSource Integration Before using CyberSource. After uncompressing the distribution file. For example.ATG Commerce Programming Guide µ Integrating CyberSource with ATG Commerce CyberSource performs the following tasks: • • • Credit card authorization.props file contains name=value pair information for communication with the CyberSource test payment server.cybersource. For example: # file with the location of your cert required myCert=ICS2Test.

Fix this problem by using the ATG Control Center to edit the /atg/commerce/payment/CyberSourceConnection component. 1.props Configuring ATG Commerce to Use CyberSource When you use ATG Commerce with CyberSource. Set the csConfigFile property to the correct path of the ICSClient. Designating Tax Status of Products CyberSource allows you to flag items with different product codes that indicate whether the product should be taxed. running routines that set up CONFIGPATH and CLASSPATH and add libraries to the system’s path. 2. see the ATG Programming Guide.props file not being found.props csConfigFile=<CyberSource Install Dir>/properties/ICSClient. The ATG Commerce tax data structure allows this information to be propagated to the integration. You can configure ATG Commerce to use these tax codes at the SKU level and then you can configure the tax calculators to extract the tax codes from the SKU and place into the TaxableItem. ATG Commerce automatically configures the CyberSource integration.props file: csConfigFile=<CyberSource Install Dir>\\properties\\ICSClient. See the Installing the CyberSource Distribution section for more information. perform the following steps: 1. For example: <property name="taxStatus" data-type="enumerated" default="default" column-name="tax_status" queryable="false"> 38 3 .Integrating Third-Party Software With ATG Commerce . If you receive errors about the ICSClient. you must specify the Cybersource module as well as either ATG Business Commerce or ATG Consumer Commerce modules during application assembly. For more information.props to replace the test data set with the live set.µ • • On Windows: On UNIX: ATG Commerce Programming Guide <ATG9dir>/home/localconfig/atg/commerce/payment This file should contain one line that sets the csConfigFile property to the absolute path of the ICSClient. Generate a new set of keys and certificates. In order to use CyberSource. refer to the CyberSource documentation. then the ICS Java libraries JAR file was not properly named or was not placed in the right location.properties file is incorrect. Edit ICSClient. the path in CyberSourceConnection. If you receive a ClassDefNotFound exception about any ICS classes not being found. For information on ATG modules and application assembly. Moving the System to Production When your system is ready to go into production. Add a taxStatus property to the SKU repository definition. Re-assemble your ATG application after fixing the problem.props file.

Integrating Third-Party Software With ATG Commerce . When you create a SKU. originZip: The zip code of the area from which the sale originated. by following these instructions: • Specify which products are not to be taxed. originState: The city from which the sale originated. Set the taxStatusProperty property on the /atg/commerce/pricing/calculators/TaxProcessorTaxCalculator service to taxStatus. Note: The tax_status column is already defined in the dcs_sku table. 39 3 . CyberSource will not calculate tax correctly. flag it with the appropriate taxStatus flag. If it is not. The CyberSourceTax component is located in the /atg/commerce/payment/ directory. Calculating Taxes on the Item Level When taxes are determined for a shipping group as a whole. Set CyberSource to calculate taxes on the item level. originCountry: The country from which the sale originated. This is the default behavior. shipFromZip: The zip code of the area from which the product will be shipped. Specifying Sales Origin and Shipment Location Information The CyberSourceTax component includes properties that represent information about the selling agency. See Designating Tax Status of Products. If some or all items should be taxed. 2. ATG Commerce assumes that all item in the group are taxable. 3. shipFromCity: The city from which the product will be shipped. The properties are: • • • • • • • • originCity: The city from which the sale originated. shipFromCountry: The city from which the product will be shipped.ATG Commerce Programming Guide µ <attribute name="useCodeForValue" value="false"/> <option value="default" code="0"/> <option value="beverages" code="1"/> <option value="clothing" code="2"/> <option value="electronic_software" code="3"/> <option value="groceries" code="4"/> <option value="physical_software" code="5"/> </property> Important: useCodeForValue must be set to false. shipFromState: The state from which the product will be shipped. you need to configure ATG Commerce to calculate taxes individually. See Calculating Taxes on the Item Level for more information. 4.

dll.so files are in the TAXWARE installation directory: Copy the files into the appropriate directory: HP-UX users: <ATG9dir>/Taxware/os_specific_files/hppa1.class file into your <ATG9dir>/Taxware/lib directory.dll) from the TAXWARE CD into the following directory: <ATG9dir>\Taxware\os_specific_files\i486-unknown-win32 • On UNIX: Copy the shared object files (libtaxcommon. and libverazip. avptax.so. libstep.NY. The . noNexus=MA. and avpzip.dll. The taxcommon. This value is passed to the CyberSource tax system. The CyberSourceTax component is located in the /atg/commerce/payment/ directory. TAXWARE’s VERAZIP system provides a means of verifying city.so.00 Solaris users: <ATG9dir>/Taxware/os_specific_files/sparc-sun-solaris2 TAXWARE Classes ATG Commerce’s TAXWARE SALES/USE and WORLDTAX integration consists of several classes: 40 3 . Integrating TAXWARE with ATG Commerce TAXWARE’s SALES/USE. and determining when additional information is needed to accurately assess taxes (such as county or city-limits information).useProductCode property to true.dll.dll. • On Windows: Place the shared objects files (taxcommon. Specifying States and Provinces without Tax Obligations The noNexus property in the CyberSourceTax component lists states and provinces that do not have tax obligations. libsalesusetax. avpstep. Before You Begin Integrating with TAXWARE Before you begin integrating TAXWARE with ATG Commerce.0-hp-hpux11.NJ. state.class file is in the TAXWARE installation directory.so. libworldtax.Integrating Third-Party Software With ATG Commerce . taxcommono.µ • ATG Commerce Programming Guide Specify the item calculation mode by setting the /atg/commerce/payment/CyberSourceTax. STEP and WORLDTAX systems provide an accurate means of calculating applicable taxes. and ZIP code information.so. libtaxcommono. copy the taxcommon. For example.so.so) from the TAXWARE CD.

One SalesTaxService object represents one origin and shipping-source location and is used by TaxWareCalculateTax to create a domestic TaxRequest that contains default company.ATG Commerce Programming Guide µ Class TaxWareCalculateTax Description TaxWareCalculateTax is an order processing class that implements the TaxProcessor interface. and transaction information. see the ATG Programming Guide. It is used by TaxWareCalculateTax to create an international TaxRequest that contains default company.Integrating Third-Party Software With ATG Commerce . This class calls to the TAXWARE VERAZIP system. This class also has an option to call to the VERAZIP system to obtain means for an extensive address verification procedure. You can choose this execution by toggling the useVerazip property in TaxWareCalculateTax. state. running routines that setup CONFIGPATH and CLASSPATH and add libraries to the system’s path. specify the following module as well as the ATG Business Commerce or ATG Consumer Commerce module during application assembly: Taxware For information on ATG modules and assembling applications. ATG Commerce automatically configures the TAXWARE integration. TAXWARE may report errors concerning invalid ZIP code or state information. To use TAXWARE. TaxWareVerifyZipInfo TaxWareVerifyZipInfo is an order processing class called by TaxWareCalculateTax to verify the city. This class calls the appropriate TaxService (domestic or international) to perform the tax calculation process. and origin information. WorldTaxService This service represents one ship-from location. The TaxWareCalculateTax calculates taxes and returns a TaxWareStatus object (implements TaxStatus interface) that contains the results of the calculation. 41 3 . ship-from. Represents a request for tax information. which your users may need to correct before proceeding. ship-from. Represents the result of tax information. SalesTaxService The persistent service that TaxWareCalculateTax calls. TaxRequest TaxResult Configuring ATG Commerce to Use TAXWARE When you use ATG Commerce with TAXWARE. and ZIP code information before taxes are calculated.

which is designated for United States or Canadian requests. If you do this. the TaxWareCalculateTax component points to SalesTaxService. you may want to create multiple /atg/commerce/payment/TaxWareCalculateTax components (for example. recordResult() and getAppropriateSalesTaxService() in methods. See TAXWARE’s documentation of the TAXWARE taxcommon API for a description of these fields. ATG Commerce Programming Guide Using the SALES/USE and WORLDTAX Integration Follow these steps to integrate SALES/USE and WORLDTAX with ATG Commerce if you want to customize the TAXWARE integration. Customizing ATG Commerce’s TAXWARE Integration You may want to customize ATG Commerce’s TAXWARE classes if: • • • your products fall into special taxation categories you have multiple origin or ship-from locations you need to record or log additional tax information Most customizations can be completed by creating a subclass of the TaxWareCalculateTax class. 3. OriginState. If you ship products from more than one location or origin. see the ATG Control Center online help. Use the ATG Control Center to perform these steps.µ 1. ShipFromState. ShipFromCountry. ShipFromCity. 42 3 . named NYCTaxWareCalculateTax and DallasTaxWareCalculateTax) and point their salesTaxService properties to the corresponding SalesTaxServices. you may want to create multiple SalesTaxServices under separate names (for example. you will need to subclass the TaxWareCalculateTax class so that it sets taxes only when appropriate. If so. If you created more than one SalesTaxService. NYCSalesTaxService and DallasSalesTaxService). OriginCity. By default. The properties of the WorldTaxService should be set accordingly. It is located in /atg/commerce/payment. Refer to your TAXWARE’s WORLDTAX manual for the information about these fields. OriginCountry. 5. set the $class property of TaxWareCalculateTax to your subclass. Note: Refer to the WORLDTAX manual to install TAXWARE WORLDTAX System. Check to see if any of your products fall into special taxation categories. For more information on using the ATG Control Center. Once you create a subclass. OriginZip. Use the ATG Control Center to modify the SalesTaxService component.. If you have more than one international location.Integrating Third-Party Software With ATG Commerce . See the Customizing ATG Commerce’s TAXWARE Integration section for more information. follow the steps 2-4 above to set multiple WORLDTAX services. 2. 4. If you want to perform a WORLDTAX calculation. You will probably want to override the modifyRequest(). OriginGeoCode. ShipFromGeoCode. Modify the following properties in SalesTaxService: companyId. and ShipFromZip. set the taxService property to /atg/commerce/payment/WorldTaxService. see Customizing ATG Commerce’s TAXWARE Integration below. See Customizing ATG Commerce’s TAXWARE Integration for more information.

If you have • multiple ship-from or origin locations. the convenience method TaxResult.commerce. You can set field values for fields without convenience methods by calling setFieldValue(). To prevent this NULL return. 43 3 . subclass atg. setting tax exemption information. See TAXWARE’s taxcommon API for possible field values.ATG Commerce Programming Guide µ Customizing TaxWareCalculateTax Methods The following TaxWareCalculateTax methods are called in the order listed. TaxRequestInfo. If you have multiple shipfrom or origin locations and an order may involve more than a single location.priceTax() and override priceTax. getAppropriateSalesTaxService() returns the appropriate SalesTaxService/WorldTaxService based on the user and order. If so. it probably makes sense to override modifyRequest() instead. Since TAXWARE supports multiple shipping destinations per order. see TaxRequestInfo class for more references. and each order only involves one of those locations. • If you have multiple items in the same order and these items fall under different tax categories. In this case. • modifyRequest() Make additional changes to the TaxRequest object before it is submitted to TAXWARE. The SalesTaxService/ WorldTaxService returned by getAppropriateSalesTaxService() is used to create a request. For example. getAppropriateSalesTaxService() takes a TaxRequestInfo object. you may also want to override calculateTaxes() to make multiple item requests to TAXWARE based on their tax categories.Integrating Third-Party Software With ATG Commerce . the current TaxWareCalculateTax implementation creates a multiple record TAXWARE input request where each record designates a unique shipping destination group with all items in it. setShipFromCity() calls setFieldValue("SHIPFROMCITY". Other fields can be accessed using the getTTTTFieldValue(). where TTTT is the type returned by that call.getCityTaxRate() actually just called returns the result of calling getDoubleFieldValue("TAXRATECITY"). CITY). Examples of information you may want to add or modify include setting appropriate origin and ship-from information. You may want your version of calculateTaxes() to make multiple calls to TaxWareCalculateTax’s version. assign it the order that is passed in and call the superclass.pricing. you should override modifyRequest to set the tax category. which is then passed to modifyRequest. you may want to over-ride this method to return the appropriate SalesTaxService/WorldTaxService. setting special taxcategory information. you will also likely want to add additional SalesTaxService/WorldTaxService properties that getAppropriateSalesTaxService will choose between.TaxProcessorTaxCalculator. where CITY is the string argument passed to setShipFromCity. If the order is NULL.getOrder() returns a NULL object. calculateTax and calculateTaxByShipping to check for • a null order. TaxResult and TaxRequest Fields ATG Commerce includes convenience methods for accessing commonly used fields of TaxResult and TaxRequest. For example.

If the address verification fails for a specific address. The verifyZipInfo property of TaxWareCalculateTax should point to TaxWareVerifyZip component in /atg/commerce/payment/. VERAZIP must be installed and functioning on the server machine. Since the VERAZIP Java interface calls into the TAXWARE VERAZIP libraries. 44 3 . state. and US transaction price amounts are in dollars. Amount and rate values can be obtained either as doubles or as longs. set the $class variable of /atg/commerce/payment/TaxWareVerifyZip to your subclass. without correction for place (so rate values are 100. ZipResult: Represents the result of ZIP code information. To install ATG Commerce’s TAXWARE VERAZIP integration. for example) Most customizations can be completed by creating a subclass of the TaxWareVerifyZipInfo class.000 larger and US transaction price amounts are in cents when accessed as Integer). the value should be of the appropriate type for the field. The long values represent the raw amount read for TAXWARE.Integrating Third-Party Software With ATG Commerce . The fields for a TaxRequest are defined in the InputRecordDef class and the fields for TaxResult are defined in the OutputRecordDef class. you need a working copy of VERAZIP on the server machine. VERAZIP Integration ATG Commerce’s VERAZIP integration consists of several classes: • TaxWareVerifyZipInfo is an Order Processing class that calls the VeraZipCaller class to perform the city. You can examine the field definitions to determine which fields are available and what type they are. • • ZipRequest: Represents a request for ZIP code information.µ ATG Commerce Programming Guide If you call setFieldValue() directly. The double values reflect the implicit decimal points (rates are a percentage). Customizing ATG Commerce’s VERAZIP Integration You may want to customize ATG Commerce’s TAXWARE VERAZIP classes if: • • • • you have additional location information you want to add to ZipRequest object you need to record or log addition ZIP code information you need to record or log additional tax information you need to specify additional fields in your TAXWARE request (if you are using WORLDTAX. If necessary. Once you have created a subclass. the sophisticated error message is returned in the TaxWareStatus object. The TaxWareVerifyZipInfo class adds ZIP amount information to the current order. it is set to false by default. You will likely want to override the modifyRequest() method. and ZIP code verification. use the Component Editor in the ATG Control Center to set the useVerazip property of TaxWareCalculateTax to false to prevent the TaxWareVerifyZip from executing.

Integrating Third-Party Software With ATG Commerce .ATG Commerce Programming Guide µ Customizing TaxWareVerifyZipInfo Methods The following TaxWareVerifyZipInfo methods are called in the order listed. • verifyZip() Accepts an object that implements the VeraZipable interface and uses that object to invoke the address verification routines. • modifyRequest() Make additional changes to the ZipRequest object before it is submitted to TAXWARE. 45 3 .

µ ATG Commerce Programming Guide 46 3 .Integrating Third-Party Software With ATG Commerce .

where different users see different versions of the catalog. Catalog Repository ATG Commerce uses the ATG SQL Repository to define the product catalog. as described in the ATG Commerce Catalog Administration chapter of the ATG Commerce Guide to Setting Up a Store. you may want to extend or modify this catalog definition to include additional item types or properties. as described in the ATG Repository Guide.Using and Extending the Standard Catalog . Folders organize media items. or if you have ATG Consumer Commerce and want to create custom catalogs. However. SKUs can be linked into static groups called bundles. see also the Using Custom Catalogs chapter of this manual.ATG Commerce Programming Guide µ 4 Using and Extending the Standard Catalog This chapter describes the standard product catalog definition and explains how to extend it if necessary to address the requirements of your commerce site. You create and modify catalog items through the ATG Control Center. 47 4 . you should be familiar with the ATG SQL Repository. SKU Items and SKU Links SKU items represent the actual items that customers buy. which are displayed in the customer’s Web browser when they visit your site. Categories can contain other categories as well as products. Note: If you have ATG Business Commerce. SKU links are a mechanism that enables you to create a single SKU from multiple items. (ATG Business Commerce sets up custom catalogs automatically.) This chapter includes the following sections: Catalog Repository The ATG Commerce product catalog is a ATG SQL Repository that enables your site to store objects in an SQL database and access those objects within Dynamo as Dynamic Beans. Folders and Media Items Media items are files such as JSPs and GIF images. The standard catalog provides sufficient functionality for many sites. or into configurable associations. Categories and Products Categories and products are catalog items that organize your catalog into a hierarchy that provides a navigational framework for your commerce site. Before reading this chapter.

xml file to specify where your new repository should appear in the ACC. A product can have several different SKUs associated with it. If you use the standard product catalog without modification. If you have created additional repositories. if you 48 4 . ATG Commerce comes with SQL scripts for creating the schema for the standard product catalog and the repository definition file that corresponds to this schema. A product is a navigational end-point in the catalog. There are three main parts: The database schema on your SQL database server. or both. 2.GSARepository. You can also achieve a similar result using additional SQL repositories instead. change the standard repository definition file. For more information. it cannot contain other categories or products. representing different varieties.gsa. For example. • • If you replace the standard repository definition file or extend it through XML file combination. you do not need to configure anything. In this example. which is of class atg.µ 1. The repository definition file. For example. You can extend the standard catalog or create an entirely different catalog structure in several ways: • To modify the standard product catalog by adding or removing items or properties. see the ATG Repository Guide for more information. Limes. and colors. ATG Commerce Programming Guide A catalog repository is similar to any other SQL repository.Using and Extending the Standard Catalog . products. To use an existing database schema. To design your catalog from scratch. which contains two products. A category can contain other categories.adapter. Categories and Products Categories and products are the heart of the catalog structure. The Citrus Fruit category could then include products called Lemons. The easiest way to implement multiple catalogs is through the ATG Commerce custom catalogs feature. and also contains another category. you must configure the SQL repository component appropriately. see Using Custom Catalogs. products do not represent the items that customers actually purchase. Oranges is an end-point. For example: <task>CatalogManagement</task> indicates that your new repository will appear under the Catalog Management menu option. The purchased items are called stock keeping units (SKUs). edit the task property of the admins. sizes. The /atg/commerce/catalog/ProductCatalog repository component is configured to use this schema and repository definition. which is an XML file that defines the relationship between the SQL database and the Dynamo repository component. then use the startSQLRepository script to generate the database schema. Citrus Fruit. Apples and Pears. Categories organize your catalog into a hierarchy that provides a navigational framework for your commerce site.. The repository component. write a repository definition file that corresponds to that schema. then use the startSQLRepository script to generate the database schema. write the repository definition file. 3. However. and Oranges. you could have a category called Fruit.

Static list of categories that are children of the category. a merge of fixedChildProducts and dynamicChildProducts. auxiliaryMedia childCategories childCategoryGroup childProductGroup childProducts creationDate description displayName dynamicChildCategories dynamicChildProducts dynamicRelatedCategorie s endDate fixedChildCategories fixedChildProducts 49 4 . The hierarchy defined by products and categories is not rigid. List of the categories in the content group specified by the relatedCategoryGroup property. Short descriptive text for display with the category. Static list of products that are children of the category. Category Properties The following table describes the category item properties in the standard product catalog:: Property ancestorCategories Description Generated Set of categories that are higher in the catalog hierarchy than the category. Date the category was created. some of the SKUs associated with it might be Valencia. List of the categories in the content group specified by the childCategoryGroup property. Name the ACC displays for the category. see SKU Items and SKU Links later in this chapter. Additional media to be displayed with the category. and Blood Orange. List of all products that are children of the category. For more information about SKUs. a merge of fixedChildCategories and dynamicChildCategories. if a collection filter is implemented to use this property. Navel. Each category or product can be the child of one or more categories. Name of the content group that contains the list of products that dynamicChildProducts is set to.ATG Commerce Programming Guide µ have a product called Oranges. Name of the content group that contains the list of categories that dynamicChildCategories is set to. List of the products in the content group specified by the childProductGroup property.Using and Extending the Standard Catalog . Date the category will no longer be available. List of all categories that are children of the category.

Name of the content group that contains the list of categories that dynamicRelatedCategories is set to. if a collection filter is implemented to use this property. Detailed descriptive text for display with the category. JSP used to display the category. relatedCategoryGroup root smallImage startDate template thumbnailImage version Product Properties The following table describes the product item properties in the standard product catalog: Property ancestorCategories Description Generated Set of categories that are higher in the catalog hierarchy than the product.µ fixedRelatedCategories keywords largeImage longDescription parentCategory relatedCategories ATG Commerce Programming Guide Static list of categories related to the category. Integer that is incremented automatically each time the category is updated. Additional media to be displayed with the product. Date the category becomes available. Boolean property that indicates if the category is the start of a hierarchical structure.Using and Extending the Standard Catalog . List of all SKUs that are children of the product. Default parent category for the category. List of all categories that are children of the category. Small image associated with the category. auxiliaryMedia brand childSKUs creationDate 50 4 . Thumbnail image associated with the category. Set of words that can be used in searching for the category. Date the product was created. used to prevent version conflict. Large image associated with the category. String that provides the product brand. a merge of fixedRelatedCategories and dynamicRelatedCategories.

Marks products as not recommendable by ATG Recommendations or similar recommendation services. Short descriptive text for display with the product. displayName dynamicRelatedProducts dynamicUpsellProducts endDate fixedRelatedProducts fixedUpsellProducts keywords largeImage longDescription nonreturnable parentCategory relatedProductGroup smallImage startDate 51 4 .ATG Commerce Programming Guide µ Property used to calculate the daysAvailable property. described below. List of the products in the content group specified by the upsellProductGroup property. unless disallowAsRecommendation is set to true. if a collection filter is implemented to use this property. if a collection filter is implemented to use this property. Default parent category for the product. Note: Using either the startDate or the creationDate ensures that a value exists for dateAvailable. Detailed descriptive text for display with the product. Note: Products are implicitly recommendable. If a startDate exists. description disallowAsRecommendation displayableSkuAttributes List of properties of the product’s SKUs that can be displayed by the DisplaySkuProperties servlet bean. making it possible to calculate daysAvailable. Small image associated with the product. Static list of products related to the product. Date the product will no longer be available. dateAvailable is set to that date. Marks products as not returnable. Name of the content group that contains the list of products that dynamicRelatedProducts uses. dateAvailable daysAvailable The number of days since the dateAvailable date has passed. Product name displayed by the ACC. dateAvailable is set to the creationDate instead. If not. Static list of upsell products. Date the product becomes available. Large image associated with the product. Set of words that can be used in searching for the product. List of the products in the content group specified by the relatedProductGroup property.Using and Extending the Standard Catalog .

Name of the content group that contains the list of products that dynamicUpsellProducts uses.NotEmptyChooserPropertyDescriptor class. Designate a category as a root category by setting the value of its root property to true.repository. a starting point is called a root category. This mechanism is used for the default definitions of several properties of the category and product items. The SQL Repository can transform the ID into the repository item and return the actual object. you need to know where to start when navigating. In the repository definition file. but you can set it to true for categories you want to designate as the top level of the product catalog. The SQL Repository also provides the ability to compute values of certain properties through Java code. Integer that is incremented automatically each time the product is updated. In an ATG Commerce catalog. The value of one of these items is the object ID. Defining Relationships between Categories and Products The SQL Repository allows you to define properties that return repository items. Most properties of the SQL Repository return values retrieved from the database. Thumbnail image associated with the product. This is a userdefined property that is computed by the atg. The value of this property is false by default. see the SQL Repository Item Properties chapter of the ATG Repository Guide.µ template thumbnailImage ATG Commerce Programming Guide JSP used to display the product. Deriving the childCategories and childProducts Properties The hierarchical relationships between categories and products are determined by their properties. the definition of the childCategories property looks like this: 52 4 . For more information about user-defined properties. You can use this targeter in a JSP as a way to start the navigation chain. See the Catalog Navigation and Searching chapter of the ATG Commerce Guide to Setting Up a Store for an example of using this targeter to find root categories. The childCategories property is a list of all categories that are children of the category. upsellProductGroup version Defining a Root Category With any group of categories. used to prevent version conflict. which sets the value of the property by merging the lists of categories in the fixedChildCategories and dynamicChildCategories properties.Using and Extending the Standard Catalog . The childCategories and childProducts properties of a category define the list of categories and products that are children of the category. to allow for dynamic definition of item relationships. This mechanism enables you to define the relationship between categories and products in many ways. Properties computed dynamically are called user-defined properties. ATG Commerce includes a targeter that finds all categories whose root property is true.

and set the childProductGroup property of the Hats category to the name of this content group.NotEmptyChooserPropertyDescriptor" data-type="list" component-item-type="category" writable="false" queryable="false"> <attribute name="properties" value="fixedChildCategories. childCategories) whose value is assembled from different sources. and sets the value of dynamicChildCategories to that list. and set the value of childCategoryGroup to the name of this content group. This property defines a list of categories that are related to the category. For more information about creating content groups. suppose your site has a category called Hats.dynamicChildCategories"/> <attribute name="merge" value="true"/> </property> This structure enables a page developer to refer to one named property (in this case. and childProductGroup properties. Dynamo computes the current value of childProducts as follows: 1. 2. retrieves the list of categories in that content group. if the Fruit category has Vegetables as a related category.GroupMembersPropertyDescriptor class. but which do not form a hierarchy with it.ATG Commerce Programming Guide µ <property name="childCategories" property-type="atg. For example. This mechanism enables you to use business rules to determine the list of child categories. The childProducts property of the category is computed in the same way.Using and Extending the Standard Catalog . Finds the current set of products in the content group specified in childProductGroup. Related categories are useful for cross-selling. you can create a content group that consists of categories that share a particular attribute. see Part 3: Performing Business User Tasks of the ATG Commerce Guide to Setting Up a Store. The fixedChildCategories property is an explicit list of categories you specify. dynamicChildProducts. 53 4 . For example. which contains a list of hats that changes from season to season. You could also create a content group called Seasonal Hats. the category item has a property named relatedCategories. you can use this relationship to display a link to the Vegetables category on the Fruit page. The dynamicChildCategories property is a user-defined property that is computed by the atg. Sets childProducts to the merge of the set of products in dynamicChildProducts and the set of products in fixedChildProducts.repository. while others are seasonal. which specifies the name of a content group. and some of the hats are available all year.repository. When a user accesses a page that refers to childProducts. Deriving the relatedCategories and relatedProducts Properties In addition to the childCategories property. You could set the fixedChildProducts property of the Hats category to a list of the hats that are available all year. For example. This class looks at the childCategoryGroup property. using the fixedChildProducts. and sets dynamicChildProperties to that set of products.

and relatedProductGroup properties.smallImage. dynamicChildCategories.repository. Removing the SQL Repository Definitions of User-Defined Properties If you do not plan to use dynamically related products or categories on your commerce site.repository. For example. For example. The product item has a relatedProducts property that is computed in the same way. if all categories are explicitly related. You can display categories and products on your commerce site using JSPs. The dynamicRelatedCategories property is also a user-defined property.displayName"/></b> <p><dsp:getvalueof id="img13" param="element. and a ForEach servlet bean to 54 4 . the following JSP segment uses the ProductLookup servlet bean to display the current product. The relatedCategories property is computed by the atg. and childCategoryGroup properties.µ ATG Commerce Programming Guide The relatedCategories property is a user-defined property that is derived in a similar way to the childCategories property. along with an image and a description. dynamicRelatedProducts.url" idtype="java. Rather than requiring you to create a separate JSP for each page on your commerce site. the page is filled in dynamically with information stored in the product’s properties. For example. which the atg. For example. <dsp:droplet name="/atg/commerce/catalog/ProductLookup"> <dsp:param param="itemId" name="id"/> <dsp:oparam name="output"> <p><b><dsp:valueof param="element. and just use the fixedChildCategories property. ATG Commerce enables you to create template pages that are filled in dynamically. when the user selects a product. which you can then rename as childCategories. This page would have little or no static content.GroupMembersPropertyDescriptor class computes by retrieving the list of categories in the content group specified by the relatedCategoryGroup property. using the fixedRelatedProducts. the following portion of a JSP uses a CategoryLookup servlet bean to retrieve the current category. Specifying Template Pages for Categories and Products Category and product items create a navigational framework for customers. which sets the value of the property by merging the lists of categories in the fixedRelatedCategories and dynamicRelatedCategories properties.lang. System performance improves when you simplify the data model to use only fixed relationships.String"> <dsp:img src="<%=img13%>"/> </dsp:getvalueof> <dsp:valueof param="element.NotEmptyChooserPropertyDescriptor class. This enables you to display any item without knowing in advance what template the item uses.Using and Extending the Standard Catalog . you can remove these properties from the repository definition. you could have a single template page for displaying any product. you can remove the definitions of the childCategories.description"/> </dsp:oparam> </dsp:droplet> You specify the template to use as a property of the category or product.

For more information about this servlet bean.url property of the product being linked to. Both item types have a template property. such as McIntosh. see the Displaying SKUs section of the Catalog Navigation and Searching chapter of the ATG Commerce Guide to Setting Up a Store.ATG Commerce Programming Guide µ create links to all of the child products of the category. as well as three image properties: thumbnailImage. You can also extend the category or product item to include additional properties. which you can use to specify a list of the SKU properties that can be displayed using the DisplaySkuProperties servlet bean. Delicious.url" idtype="java.String"> <dsp:a href="<%=a21%>"> <dsp:valueof param="element.lang.repositoryId" name="itemId"/> </dsp:a></dsp:getvalueof> </dsp:oparam> </dsp:droplet> </dsp:oparam> </dsp:droplet> For more information about the CategoryLookup and ProductLookup servlet beans. Associating Products with SKUs The childSKUs property of a product is a list of all the SKUs that are children of the product. media elements such as images and JSPs can be associated with a category or product through properties of the item.childProducts" name="array"/> <dsp:oparam name="outputStart"> <p><b>Child Products:</b> </dsp:oparam> <dsp:oparam name="output"> <dsp:getvalueof id="a21" param="element. see the Catalog Navigation and Searching chapter of the ATG Commerce Guide to Setting Up a Store. The product item also has a property named displayableSkuAttributes. 55 4 .Using and Extending the Standard Catalog . A product called Apples might have several different SKUs that represent different varieties of apples. In addition to the explicit properties that store media. smallImage. and Granny Smith.displayName"/> <dsp:param param="element. The URL for each link is found by looking at the template. a Map property called auxiliaryMedia allows you to store any number of other media elements. as discussed in the Extending the Category and Product Item Types section. <dsp:droplet name="/atg/commerce/catalog/CategoryLookup"> <dsp:param param="itemId" name="id"/> <dsp:oparam name="output"> <dsp:droplet name="/atg/dynamo/droplet/ForEach"> <dsp:param param="element.template. Media Properties As mentioned above. and largeImage.

create two new properties. then close the table: <property name="displayName_en" column-name="dislpay_name" data-type="string"> <attribute name="locale" value="en"/> </property> </table> Notice there is an attribute called “locale” on this property. We start off with the name of the item descriptor containing the property: <item-descriptor name="sku"> Remove the old definition of displayName. For example. do this inside the correct table tag: <table name="dcs_sku" type="primary" id-column="sku_id"> <property name="displayName" xml-combine="remove"/> To reuse the column name for the English display name (this way the English values do not need to be copied anywhere).µ ATG Commerce Programming Guide Extending the Repository for Internationalization To aid in internationalization. The derivation method uses this to determine the correct value. It looks similar to the English version above (with a different “locale” attribute). you could specify different display text to appear in different languages for the same catalog item. one for the English display name (reusing the column above) and one for the German display name (this requires a new table). The following example shows how to expand the displayName property to include English and German versions.Using and Extending the Standard Catalog . Now define the German version. In order for the XML combination to work. As provided in ATG Commerce. You can add a derivation property to any property in the catalog. then specify alternatives to use in each catalog. displayName looks like this: <item-descriptor name="sku" <table name="dcs_sku" type="primary" id-column="sku_id"> <property name="displayName" column-name="display_name" data-type="string"/> </table> </item-descriptor> First. define the English display name in the same table tag. ATG Commerce includes a feature that allows you to specify alternate text for some catalog items using derived properties. Define a new table for this: <table name="dcs_sku_de" type="auxiliary" id-column="sku_id"> <property name="displayName_de" column-name="display_name" data-type="string"> 56 4 .

but displayName_de is null. which keyService uses if the if the value with the real key is null. If no default key is defined. if locale=fr_FR_EURO. and finally look for “fr.getRepositoryKey. which returns the user’s current locale as the key. if the real key is “de_DE” and we are looking for displayName. Using a defaultKey may slow performance. 3. it first looks for a property where the locale attribute is fr_FR_EURO. then look for “fr_FR”. 2. Gets the repository key service Calls RepositoryKeyService. Returns the first property whose attribute matches. define the derived property.commerce.util. If the default key is the same as the current key. The complete XML looks like this: <item-descriptor name="sku"> <table name="dcs_sku" type="primary" id-column="sku_id"> <property name="displayName" xml-combine="remove"/> <property name="displayName_en" column-name="dislpay_name" data-type="string"> <attribute name="locale" value="en"/> 57 4 . Giving it the same name as the previously English property (“displayName”) means that JSP code that references this does not have to be rewritten: <property name="displayName data-type="string"> <derivation user-method="atg. it is not used. Compares this key to each expression’s <locale> value.Using and Extending the Standard Catalog . In other words. For example. then return displayName_en instead (assuming its locale is “en” and the defaultKey is “en” or “en_US”). In all other cases. there are no performance implications. a subclass of FirstWithAttribute. there is an extra clause on all search terms. It performs the following actions: 1.” There is also a defaultKey. 4.FirstWithLocale"> <expression>displayName_en</expression> <expression>displayName_de</expression> </derivation> <attribute name="derivationAttribute" value="locale"/> <attribute name="keyService" value="/atg/userprofiling/LocaleService"/> <attribute name="keySubProperty" value="locale"/> <attribute name="defaultKey" value="en"/> </property> The <derivation> tag uses a custom derivation method called FirstWithLocale.ATG Commerce Programming Guide µ <attribute name="locale" value="de"/> </property> </table> Next. The locale is searched in a locale-specific way.

add an option value to the product type enumeration: <property name="type" data-type="enumerated" columnname="product_type" writable="false" hidden="true"> <option value="option1"/> 58 4 .commerce.FirstWithLocale"> <expression>displayName_en</expression> <expression>displayName_de</expression> </derivation> <attribute name="keyService" value="/atg/userprofiling/LocaleService"/> <attribute name="defaultKey" value="en_US"/> </property> </item-descriptor> Extending the Category and Product Item Types By default. and can include additional properties that are unique to the sub-type.Using and Extending the Standard Catalog .µ </property> </table> ATG Commerce Programming Guide <table name="dcs_sku_de" type="auxiliary" id-column="sku_id"> <property name="displayName_de" column-name="display_name" data-type="string"> <attribute name="locale" value="de"/> </property> </table> <property name="displayName data-type="string"> <derivation user-method="atg.util. there is only one type of category and one type of product in the catalog. A sub-type inherits the properties from its parent item type. whose definition is independent of existing types. you can create new item types. and make the corresponding additions to the repository definition file. To create additional properties for an item type. For greater flexibility. However. These item types are sufficient for many commerce sites. or by creating additional item types. The default category and product item definitions include an enumerated property named type. modify the database schema to add columns to the database tables for that item type. Create an item type that is a sub-type of an existing type. you may find you need to extend the catalog by creating additional properties for these item types. There are two ways to create a new item type: • • Create an entirely new type. which you can use to create item sub-types: <property name="type" data-type="enumerated" column-name="product_type" writable="false" hidden="true"> </property> To create a product sub-type.

The properties of a SKU are used for display purposes. and can add properties not defined for the parent item type. customers do not actually purchase the product. Inheritance is a very convenient mechanism for creating new item types.Using and Extending the Standard Catalog . In the standard catalog. to avoid the performance and complexity issues associated with sub-types. For more information. product. especially for creating types that are closely related to each other. they purchase a SKU (stock keeping unit). However. see the Item Descriptor Inheritance section of the SQL Repository Data Models chapter of the ATG Repository Guide. SKU Items and SKU Links A product is a navigational end-point in the catalog. similar to products and category properties.properties --> </item-descriptor> The new item type inherits all of the defined properties of the parent item type. the standard catalog includes a SKU link item type that you can use to create SKU bundles. such as with computers. although it is treated as multiple items in fulfillment. keep in mind that performance decreases as the number of tables joined increases. and colors. However. Queries against items whose properties span multiple sub-types may require joins of all of the tables in the hierarchy. 59 4 . or a car with optional features. you should avoid using too many levels of inheritance. A SKU usually represents an indivisible unit that can be purchased. which could include different memory or hard drives. A product can have several different SKUs associated with it. sub-types are defined for the media item type only. and SKU item types would inherit all of their common properties (such as description and displayName). which are virtual SKUs that are composed of several other SKUs. The properties are also used to integrate with other ATG Commerce systems. See the Configurable SKUs section of this chapter. However. You can also create SKUs as configurable if they have components that might vary depending on customer preferences. Instead. such as pricing and fulfillment. If you use these kinds of queries. In a purely object-oriented design.ATG Commerce Programming Guide µ <option value="option2"/> </property> Then add a new item-descriptor to the repository definition file. Bundles allow the product catalog to offer a SKU that can be purchased as a single item. the catalog replicates the properties in each item definition. there would be a generic catalog item type from which the category. and set its super-type attribute to the name of the parent item type: <item-descriptor name="item-name" super-type="type" sub-typevalue="option1"> <!-. representing varieties. sizes.

Date on which this SKU becomes available. Small image associated with the SKU. List of SKU links that make up this SKU bundle. used to prevent version conflict.Using and Extending the Standard Catalog . if a collection filter is implemented to use this property. Date this SKU was created. Short descriptive text for display with this SKU. Products to suggest as replacements if this item is out of stock. Wholesale price of the SKU. Additional attributes of the SKU. Fulfiller who will ship the item. Large image associated with the SKU.µ SKU Properties Property auxiliaryMedia bundleLinks ATG Commerce Programming Guide The following table describes the SKU item properties in the standard product catalog: Description Additional media to be displayed with this SKU. if a collection filter is implemented to use this property. Price of the SKU if onSale property is true. creationDate description displayName dynamicAttributes endDate fulfiller largeImage listPrice onSale replacementProducts salePrice smallImage startDate template thumbnailImage version wholesalePrice SKU Link Properties The following table describes the SKU link properties in the standard product catalog: 60 4 . Thumbnail image associated with this SKU. Integer that is incremented automatically each time the SKU is updated. Date this SKU will no longer be available. Name used for the SKU the site. JSP template used to display this SKU. if null. Boolean property that indicates if the item is on sale. Default price of the SKU before any discounts or promotions. SKU is not a bundle.

the list and sale price calculators will require a small change in configuration. if a collection filter is implemented to use this property. These list and sale price calculators use these properties in the Pricing Engine. products. and auxiliaryMedia. or vice versa. 61 4 . thumbnailImage. and onSale properties can be moved to the product item type to simplify maintenance. Name used for the SKU link on the site. you might want to have different images for each SKU. WholesalePrice is not used by the pricing calculators at this time. you could even change the repository definition to remove the product item type entirely. Quantity of the SKU specified by the item property. and SKUs all have the same set of media properties in order to give you as much flexibility as possible. a product’s template page displays all of the child SKUs of the product.. Categories. and salePrice. rather than having a single set of images associated with the parent product. onSale. For example. If the price properties are moved. if a collection filter is implemented to use this property. but adds complexity to pricing administration. Your site may not need all of these properties. salePrice. largeImage. if SKUs are differentiated by a visible characteristic such as color. listPrice. used to prevent version conflict. Using SKU Price Properties The SKU item has four price properties: wholesalePrice. If each product has only one SKU. Placing the prices at the SKU level allows each individual SKU to have its own price. the pricing calculators assume the SKU is on sale and adjust the price. When the sale price is defined and onSale is set to true. but the wholesalePrice and salePrice can be undefined. Date this SKU link will no longer be available. smallImage. you might want to associate certain media items with products rather than SKUs. Date on which this SKU link becomes available. each SKU would not be displayed in its own template page. For example. SKU that is being bundled.Using and Extending the Standard Catalog . at most commerce sites. Depending on how your site is organized. Short descriptive text for display with this SKU link. see the Using and Extending Pricing Services chapter of this manual. then the listPrice. ListPrice is required. Integer that is incremented automatically each time the SKU link is updated. More commonly. If your product catalog does not need to price each SKU separately. item quantity startDate version Using SKU Media Properties The SKU item has the same set of media properties that categories and products have: template. For more information.ATG Commerce Programming Guide µ Property creationDate description displayName endDate Description Date this SKU link was created.

The additional rows can have a negative effect on performance. each SKU is represented by one row per attribute. if the SKUs are differentiated only by color. then bundleLinks is null. For more information. so each SKU can be represented by a single row in the table.µ Using the SKU Fulfiller Property Creating SKU Bundles ATG Commerce Programming Guide The fulfillment engine uses the fulfiller property to determine how to manage the fulfillment of the purchase. This mechanism is very flexible. Each SKU link includes a SKU and a quantity. So if dynamicAttributes specifies three attributes (e.Using and Extending the Standard Catalog . and length). size. Therefore. it fulfills the purchase by performing the fulfillment of each quantity of items defined in the SKU link. color. you can create a SKU link whose quantity is 1. you may be able to differentiate the SKUs for a product through the description properties of the SKUs. If the SKU is not a bundle. one that represents three red shirts and another that represents one black hat. If you create a sub-type. if you need to define a large number of attributes. see the Configuring the Order Fulfillment Framework chapter. The bundleLinks property designates a SKU as a bundle. 62 4 . or create sub-types of the SKU item type that include additional properties. However. which does not require modifying the SKU item definition. The property is a Map that stores a key/value pair for each attribute you define. etc. If you add properties. For more information. and include that SKU link in the bundleLinks list. For example. not SKU items. the SKU will be represented by three rows in a table. By default. See Extending the Category and Product Item Types for information about extending catalog item types. A SKU bundle can include any number of SKU links. is to store configuration information in the dynamicAttributes property.. explicitly adding properties to the SKU item definition is a better approach. see the Configuring the Order Fulfillment Framework chapter. a SKU link might represent three red shirts. For example. The bundleLinks property is a list whose elements are of another item type called a SKU link. Extending the SKU Item Type The base SKU definition does not include any configuration properties such as size. However. you could specify the dynamicAttributes property of a SKU as {color=red. An alternate approach. This property is an enumerated value. color. For example. rather than an individual item. Note that the bundleLinks property of the SKU item holds only SKU links. You may want to add properties to the SKU item type.g. because it allows each SKU to have its own set of configuration attributes. When the fulfillment system recognizes that a SKU is a bundle..size=small}. you must add it to the SKUItemTypes property of the /atg/commerce/catalog/CatalogTools component in order for it to be available to the PMDL rules used in promotions. For example. it defines a HardgoodFulfiller. this approach can become awkward if there are several different configuration variables. One disadvantage of this approach is that data is stored less efficiently than if you explicitly add configuration properties to the definition of the SKU item. Depending on the requirements of your site. each property corresponds to a column in a table. a SKU bundle might consist of two SKU links. If you use dynamicAttributes. the description of each SKU could mention the color.

As part of this abstract definition. These properties are intended to be overridden in the sub-types. it cannot be instantiated itself. The content can be either be either a binary file or a text file. not intended for display on the site. such as a particular model of hard drive. The media item is similar to an abstract Java object. You can use folders to organize media elements. 63 4 . An external system with which ATG Commerce communicates. to which other products can be added as options. not in the commerce site itself. An example of a configurable item is a computer. etc. The standard product catalog defines folder and media item types that correspond to these two parts of the repository. hard drive types. such as a computer.Using and Extending the Standard Catalog . such as Memory or Modems. Folders are used only in the administrator user interface. The following repository items are used when working with configurable SKUs: Item configurableSku Description Base SKU for the product. customers can order them with varying amounts of memory. The standard catalog includes three sub-types: • • media-external: This item type references a piece of content that is stored outside the database. endDate. in a different way than linked SKUs do. Both the folder and media items define several administrative properties: version. The SKU representing the actual product option. two properties are defined: data and url. The media item includes a property named type that is used to specify the media sub-type of the item. The configurableProperty holds the list of configurationOptions. Configurable items consist of a “base SKU” and a number of optional subSKUs for the user to choose among. creationDate.ATG Commerce Programming Guide µ Configurable SKUs A configurable SKU holds other SKUs. configurableProperty configurationOption foreignCatalog Folders and Media Items As described in the SQL Content Repositories chapter of the ATG Repository Guide. A category of subSKUs. video cards. a SQL Repository can be configured as a content repository. These properties are used as an aid to catalog administrators. A content repository is composed of folder and content repository items. The item type is marked as abstract by tagging it as expert in the repository definition file. startDate. and description. media-internal-binary: This item type can be used to store binary objects (such as images) in the catalog database.

used to prevent version conflict name parentFolder path startDate version Media Item Properties The following table describes the media item properties in the standard product catalog: Property url data mimeType Description Relative URL that can be used in a JSP to access the media item. Folder that contains this folder.µ • ATG Commerce Programming Guide media-internal-text: This item type can be used to store text files (such as JSPs) in the catalog database. Integer that is incremented automatically each time the folder is updated. Folder Properties The following table describes the folder item properties in the standard product catalog: Property creationDate description endDate Description Date this folder was created. if null. File name of the folder. Defines whether a media item is binary or text. For information about uploading media elements to your product catalog. see ATG Commerce Catalog Administration of the ATG Commerce Guide to Setting Up a Store. Date this folder becomes available. Short descriptive text for display with this folder. name path parentFolder 64 4 . if a collection filter is implemented to use this property. Folder that contains this media item. if a collection filter is implemented to use this property. A user-defined property that returns the content type value by examining the url property. Complete path for this media item. Complete pathname of the folder.Using and Extending the Standard Catalog . Date this folder will no longer be available. this folder is a root folder. File name for this media item.

The data property is either binary (for media-internal-binary items) or text (for media-internal-text items).FilePropertyDescriptor class. Short descriptive text for display with this media item. the data property is a user-defined property computed by the atg. if a collection filter is implemented to use this property. As part of defining a ContentRepositoryItem. Date this media item will no longer be available.ATG Commerce Programming Guide µ startDate Date this media item becomes available.distributor. if a collection filter is implemented to use this property. The mimeType property is a user-defined property that is computed by the MimeTyperPropertyDescriptor class. these values are automatically extracted from the File object returned from data. product catalogs. endDate description Using Media-External Properties In the media-external item type. see the Content Distribution chapter of the ATG Programming Guide. This section discusses the following topics: • Designing the Catalog Repository 65 4 . It also discusses which locales you should choose for your Dynamo server and database in order to make both compatible with the encodings of the content you wish to display on your site. For more information about configuring content distributors.repository. The url property of the media-internal item types is a user-defined property computed by the atg. Designing a Multi-Locale Product Catalog Designing a multi-locale Web site is a large undertaking. which determines the value from the name property. In a media-external item. Using Media-Internal Properties The media-internal sub-types differ only in the way the data property is defined. the /atg/commerce/catalog/ContentDistributorPool service extracts the content from the database and generates a URL to make the item accessible to a web browser. When a customer accesses a mediainternal-binary or media-internal-text item.io. the item definition must supply a length and a last modified value. If the url property is a relative URL. and database tables to meet the needs of a multi-locale site. This section offers some suggestions for designing Dynamo repositories. then data is a java.DistributorPropertyDescriptor class. The media-internal item types define their own length and lastModified properties. which references the file.File object.Using and Extending the Standard Catalog .

This is the simpler of the two methods. 66 4 . A catalog repository is similar to other SQL repositories. which is of class atg. because you can have a catalog administrator for each language who has access only to the appropriate repository. The database schema on your SQL database server. Also. which is an XML file that defines the relationship between the SQL database and the Dynamo repository component. 2. There are three main parts: 1. You can create a separate repository for each language or with a single repository for all languages. 3. Cons: You must maintain multiple copies of each item in the repository. • One Repository Configure a single repository for all languages and include a language attribute in each repository item. since each item is duplicated in each locale-specific repository. Pros: Separate targeting rules let you target different pieces of content to different locales. you should also have database tables that contain different product information for each locale. in which each rule references the appropriate language repository. you can separate your database tables so that the locale-specific properties of each product are stored in multi-valued tables that hold many different language versions of the same information. you can set up your catalog repository in one of two ways. This section discusses the pros and cons of single and multiple repository configurations.Using and Extending the Standard Catalog .µ • • Setting Up Multiple Product Catalogs Setting Up a Single Product Catalog ATG Commerce Programming Guide Designing the Catalog Repository If you are designing a multi-locale site with catalog repository content. consider the following pros and cons of each design: • Multiple Repositories Create a separate content repository for each language.GSARepository. This requires separate targeting rules for each locale. The repository definition file. administration of multiple repositories is easier than a single repository. These items draw their locale-specific attributes from a multi-valued table in the database. storing separate values for each locale-sensitive takes up a lot of space in the database. When you are designing your catalog repository.adapter. The repository component. If you have a repository for each locale. Pros: You can maintain only one copy of each repository item. The option you choose dictates how you must set up your database tables. site visitors from Japan may not be interested in the same style of jeans as site visitors from the US.gsa. For example. This method requires you to develop logic that uses the RequestLocale’s localeString property to get the property values corresponding to the proper locale. In addition. If you have a single repository.

For example. You have to store most languages other than English in UNICODE format. and a file productCatalog. The first table is not reused. and JapaneseProductCatalog. see the Catalog Repository section of this chapter.xml. Make sure that the definitionFiles property of each component points to the appropriate repository definition file. you can use ASCII and UNICODE where appropriate.xml. Dynamo’s primary English SKU table is named dcs_sku. Create a catalog repository XML file that defines the product catalog. If you are using separate repositories. See Populating the International Catalogs with Product Data for more information. the FrenchProductCatalog component’s 67 4 . but if you have a single repository you must store all data in UNICODE.Using and Extending the Standard Catalog . FrenchProductCatalog.ATG Commerce Programming Guide µ Cons: This configuration is more difficult to administer because data for every language is in one repository. Note that multi-byte languages require multi-byte character columns to hold the translated Strings. There are more database joins in a single repository because of the large number of multi-value tables. but using multi-value tables does increase the load on the database. Create appropriately named database tables for each locale. for example. For example. 2. 5. 4. For more information. Pioneer Cycling uses equivalent tables for it’s French and Japanese SKUs named dfr_sku and djp_sku respectively. 3. you must to create database tables that mirror the English product tables. each product catalog is defined by an XML file. Setting Up Multiple Product Catalogs If you set up a separate product catalog for each language on the site. If you decide to set up multiple product catalogs. For example. This slows Dynamo operation. This takes up more space in the database. the only difference is that the dfr_sku and djp_sku tables contain translated descriptions and prices that are specific to the French and Japanese locales.xml that represents the standard English product catalog. the Pioneer Cycling application adds the letters of the locale to the name of each table. you could rename the file frenchProductCatalog.xml file and modify it as necessary for the other locales your site is supporting. instead of ASCII. do the following: 1. despite the fact that all three tables have the same schema. The reduced performance may be imperceptible.xml. the Pioneer Cycling site has a separate XML file for each of the three languages the site supports: frenchProductCatalog. For example. To configure Dynamo to use multiple product catalogs. which only requires one byte per character. Copy the productCatalog. japaneseProductCatalog. You should rename this file so it is unique and recognizable for a certain locale. 6. All three tables contain matching data.xml file. which takes up 2 bytes per character. Populate the database tables with translated or otherwise locale-modified content. Create database tables that map to the catalog repository as described in the productCatalog. the Pioneer Cycling demo uses three components. Create a separate Control Center component for each product catalog. ProductCatalog. For example. For example. You cannot separate products that are Japanesespecific.

Populating the International Catalogs with Product Data When you want your site to have several duplicate catalogs. one for each language your site supports. ATG Commerce Programming Guide definitionFiles property should point to the file at /atg/commerce/catalog/frenchProductCatalog. you can specify that the key fr_FR attached to a JSP should pull content from the French Product Catalog. you can display items in a default language catalog. 4. For more information on how multiple product catalogs are set up in the Pioneer Cycling demo. JSPs can include hard-coded repository IDs because ATG Commerce uses the locale of a user’s browser to determine the appropriate language catalog’s items to display. then. Depending on how your site is configured. If a JSP can’t display an item from the requested language catalog. which makes it easier to maintain consistency and quality across catalogs.Using and Extending the Standard Catalog . 2. you create the first language catalog. in the ACC. You won’t need to replace the ID in copied catalog with an invented ID that’s unique and consistent with others. 3. having the same ID for a given item across catalogs may provide the following advantages: 1.µ 7.xml. Configure the useDefaultRepository and repository properties of the Nucleus component. Set the useDefaultRepository property to true if you want Dynamo to search the default repository when an item is not found in an alternate repository. a given item isn’t difficult to find. the CatalogTools component reverts to the standard product catalog. To populate a second language catalog. Because an item has the same ID in all catalogs. The alternateCatalogs property of the CatalogTools component specifies a mapping between repository keys and alternative repositories. For example. Create catalog items manually in the ACC. 5. translate property values into the appropriate language. then translate property values into the appropriate catalog. Promotions can apply to products from all catalogs. 68 4 . Before you replicate your catalog data. If you don’t provide this mapping. then create the second language catalog in one of the following ways: • • Copy the original catalog in bulk. You can use the CatalogTools component to set up a relationship between multilanguage repositories and their matching product catalogs. Configure the alternateCatalogs property of the /atg/commerce/catalog/CatalogTools component. see Adding Support for Multiple Locales in the Displaying and Accessing the Product Catalog chapter of the ATG Consumer Commerce Reference Application Guide. you copy the original in bulk. 8. even if the user’s request locale is not the same as the standard product catalog. Set the repository property to point to the default repository component. it is important to decide whether an item in multiple catalogs should use the same ID in each.

The item product. For example. To set up a single product catalog repository. One solution is to remove all the locale-specific properties (such as display_name. For example. This section describes one way.ATG Commerce Programming Guide µ If the listed advantages are actually disadvantages for your site. Setting Up a Single Product Catalog There are several ways to set up a single product catalog that contains content for multiple locales. your JSPs include hard-coded repository IDs that must access items in a specific catalog. (translated into Japanese)) fr_FR jp_JP Displaying data for this item in a JSP requires one extra step: adding logic that evaluates the user’s locale to display the correct value from the property’s map.shortDescription needs to have a map that looks like this: Key en_US Value This is a very protective and fashionable helmet. you must modify your database tables.shortDescription"/> you now access items <dsp:valueof param="product. this description String needs to be translated into a different language for each locale your site serves. assign each item a unique ID. long_description) and place them in multi-value tables. description. for example. For example.Using and Extending the Standard Catalog . there are many different ways to do this. if each item in the catalog has a property shortDescription of type String.shortDescription. Ceci est un très protectif et chic helmet. the current dcs_product table looks like this: Table Name: dcs_product product_id VARCHAR(40) (primary key) version NOT NULL NULL INTEGER 69 4 . which is to make every locale-sensitive property of every item in the catalog a multi-valued property that has key/value pairs for each locale. because. instead of accessing a product from a JSP where the product parameter contains the product repository item from the locale-specific catalog repository: <dsp:valueof param="product. Again.en_US"/> where the product parameter contains the product repository item that is take from the single repository of all the language catalogs.

µ creation_date start_date end_date display_name description long_description parent_cat_id product_type ATG Commerce Programming Guide TIMESTAMP TIMESTAMP TIMESTAMP VARCHAR(254) VARCHAR(254) LONG VARCHAR VARCHAR(40) INTEGER NULL NULL NULL NULL NULL NULL NULL NULL Here’s an example of how you could separate the properties in the dcs_product table into four separate multi-value tables to hold locale sensitive content for many different locales: Table #1: dcs_product product_id VARCHAR(40) (primary key) version creation_date start_date end_date parent_cat_id product_type NOT NULL NULL NULL NULL NULL NULL NULL INTEGER TIMESTAMP TIMESTAMP TIMESTAMP TIMESTAMP VARCHAR(40) Table #2: dcs_product_display_name product_id VARCHAR(40) NOT NULL REFERENCES dcs_product(product_id) (primary key) locale VARCHAR(42) NOT NULL (primary key) display_name VARCHAR(254) NULL Table #3: dcs_product_description 70 4 .Using and Extending the Standard Catalog .

0.0" encoding="ISO-8859-1" ?> <!DOCTYPE gsa-template PUBLIC "-//Art Technology Group.//DTD General SQL Adapter//EN" "http://www.atg.xml file that maps this schema: <?xml version="1.xml file to refer to these new tables. Here’s an example of a very simple productCatalog.ATG Commerce Programming Guide µ NOT NULL REFERENCES dcs_product(product_id) product_id VARCHAR(40) (primary key) locale VARCHAR(42) NOT NULL (primary key) description VARCHAR(254) NULL Table #4: dcs_product_long_description product_id VARCHAR(40) NOT NULL REFERENCES dcs_product(product_id) (primary key) locale VARCHAR(42) NOT NULL (primary key) long_description LONG VARCHAR NULL You’ll also have to modify your productCatalog.com/dtds/gsa/gsa_1.Using and Extending the Standard Catalog .dtd"> <gsa-template> <item-descriptor name="product" display-name-resource="itemDescriptorProduct"> <table name="dcs_product" type="primary" id-column-name="product_id"> <property category-resource="categoryInfo" name="version" data-type="int" column-name="version"/> <property category-resource="categoryInfo" name="creationDate" datatype="timestamp" column-name="creation_date"></property> <property category-resource="categoryBasics" name="startDate" datatype="timestamp" column-name="start_date" display-nameresource="startDate" required="false"> </property> <property category-resource="categoryBasics" name="endDate" datatype="timestamp" column-name="end_date" display-name-resource="endDate" required="false"> </property> <property category-resource="categoryCategorizationAndRelatedProducts" name="parentCategory" item-type="category" column-name="parent_cat_id" 71 4 . Inc.

µ ATG Commerce Programming Guide display-name-resource="parentCategory" required="false"> </property> <property name="type" data-type="enumerated" column-name="product_type"/> </property> </table> <table name="dcs_product_display_name" type="multi" id-column-name="product_id"> multi-column-name="locale"> <property category-resource="categoryBasics" name="displayName" data-type="map" component-data-type="string" column-name="display_name" required="true" display-name-resource="name"> </property> </table> <table name="dcs_product_description" type="multi" id-column-name="product_id"> multi-column-name="locale" <property category-resource="categoryPresentation" name="description" data-type="map" component-data-type="string" column-name="description" required="false" display-name-resource="description"> </property> </table> <table name="dcs_product_long_description" type="multi" id-column-name="product_id"> <property category-resource="categoryPresentation" name="longDescription" data-type="map" component-data-type="big string" column-name="long_description" required="false" display-name-resource="longDescription"> </property> </table> </item-descriptor> </gsa-template> 72 4 .Using and Extending the Standard Catalog .

This chapter consists of supplementary information that applies only to custom catalogs.Using Custom Catalogs . you can run ATG Commerce in two separate modes. see the Catalog Navigation and Searching chapter of the ATG Commerce Guide to Setting Up a Store to catalog navigation instructions. 73 5 . or have ATG Consumer Commerce and want to use the custom catalogs feature. The mode that you run in determines how the values custom catalog-related properties are obtained. You should also refer to the Using and Extending the Standard Catalog chapter for instructions on setting up a catalog. the product catalog repository is somewhat different. production mode or development mode. Development mode makes the updates incrementally so you can preview your changes throughout the development process. Development mode is more resource intensive than production mode because these properties have to be computed at the time they are referenced. and these properties are derived on-the-fly. • development mode: Uses derived properties so that you can preview a product catalog on a web site while you’re making changes without having to run the batch service (CatalogMaintenanceService). Also. If you have ATG Business Commerce installed. and navigation and searching involve components that are different from those used in standard catalogs. Using ATG Commerce with Custom Catalogs Converting from Standard to Custom Catalogs The Custom Catalog Repository Custom Catalog Navigation Custom Catalog Searching Assigning a Custom Catalog to a User Using ATG Commerce with Custom Catalogs When using custom catalogs. or different products altogether. rather than being pre-computed by the batch service. Development mode overrides the definitions of certain properties in the catalog repository that are normally computed by the batch service.ATG Commerce Programming Guide µ 5 Using Custom Catalogs Custom Catalogs allow you to set up your product catalog so different customers see different information about the products they view.

Running this script adds the following tables to your database: • • dcs_catalog dcs_root_cats 74 5 . When you run the batch service. The following steps describe how to perform this conversion. There are two “helper” properties that go with the catalogs property: computedCatalogs and derivedCatalogs. Using in Production Mode The production mode is the most efficient mode to run in when you won’t need to preview changes to the custom catalog. which already has the value stored there. which holds a list of all valid catalogs in which you can view that product.µ • ATG Commerce Programming Guide production mode: Uses computed properties. In the development mode. Using Development Mode The development mode allows you to preview the custom catalogs as you edit them. For example. it references derivedCatalogs. so performance is upgraded over development mode because time is no longer spent deriving the property values. For more information on assembling an ATG Commerce application with custom catalog in development mode. These tables are defined in custom_catalog_ddl. it stores the value into the computedCatalogs property. which derives the value at the time of the request. This script is located in the <ATG9dir>/DCS/CustomCatalogs/sql/db_components/<db-vendor> directory. there is a catalogs property for products. When running in production mode. catalogs property refers to derivedCatalogs. you should run the Catalog Maintenance Service as described in Using the Catalog Maintenance System. Step 1: Add New Database Tables Custom catalogs require some new database tables. When you switch to running production mode the computedCatalogs value is used. see the ATG Programming Guide. If you are running in development mode and you access the catalogs property. When the batch service runs. This mode uses the properties precomputed by the batch service.Using Custom Catalogs . regardless of what mode you are in. Keep in mind that before you set up your custom catalogs for the first time. Converting from Standard to Custom Catalogs To use custom catalogs.sql. you must convert your existing standard product catalog to the custom catalog configuration. so the value stored in computedCatalogs is not used. see the ATG Programming Guide. it references computedCatalogs. it stores the value in computedCatalogs. For more information on assembling an ATG Commerce application with custom catalog in production mode.

1.Using Custom Catalogs . Specify the following module during application assembly: DCS.CustomCatalogMigration 75 5 .ATG Commerce Programming Guide µ • • • • • • • • • • • • • • • • • • • • • • • • • • • • dcs_root_subcats dcs_sub_catalogs dcs_category_info dcs_product_info dcs_sku_info dcs_cat_subcats dcs_cat_subroots dcs_cat_catinfo dcs_catinfo_anc dcs_prd_prdinfo dcs_prdinfo_rdprd dcs_prdinfo_anc dcs_sku_skuinfo dcs_skuinfo_rplc dcs_gen_fol_cat dcs_child_fol_cat dcs_catfol_chld dcs_dir_anc_ctlgs dcs_ind_anc_ctlgs dcs_ctlg_anc_cats dcs_cat_prnt_ctlg dcs_cat_anc_cats dcs_prd_prnt_cats dcs_prd_anc_cats dcs_cat_catalogs dcs_prd_catalogs dcs_sku_catalogs dcs_user_catalog Step 2: Run the Custom Catalog Migration The Commerce Admin page includes a tool that automatically migrates your existing catalog to the new custom catalogs.

For example. see the ATG Personalization Programming Guide. 76 5 . For general information on Commerce reporting charts. • • • • • • <ATG9dir>/DCS/sql/uninstall/<db-vendor>/ drop_reporting_views3. the default URL on JBoss is: Note: your application must include the Dynamo Administration UI module in order for you to view this URL.sql <ATG9dir>/DCS/sql/uninstall/<db-vendor>/ drop_reporting_views2. Step 3: Assign Users to Custom Catalogs You can set each user’s catalog manually or automatically.sql <ATG9dir>/DCS/CustomCatalogs/sql/db_components/<db-vendor>/ custom_catalog_reporting1. 4.sql The Custom Catalog Repository Keep in mind that before you set up your custom catalogs for the first time. you should run the Catalog Maintenance Service as described in Using the Catalog Maintenance System. See the ATG Installation and Configuration Guide for the default port. 6. 3. Status updates display in the browser as the migration takes place. Select Standard to Custom Catalog Migration. Enter the nucleus path to your catalog repository component in the Catalog Repository To Migrate: field. custom catalog users must run the following scripts to set up the proper reporting views. Before using reporting charts. http://hostname:8080/dyn/admin ATG Commerce Programming Guide For more information on assembling applications. Access the ATG Dynamo Administration page by pointing your browser to the URL appropriate for your application server. For information on scenarios. Step 4: Set up Reporting Charts (optional) ATG Consumer Commerce customers can use reporting charts with Custom Catalogs. see the Using Commerce Charts chapter of the ATG Commerce Guide to Setting Up a Store.Using Custom Catalogs . To automatically assign your customers to a custom catalog. 5.µ 2. Enter a display name for the new custom catalog. Click on Migrate. use a scenario to set the catalog as soon as the user’s session begins. Click on the Commerce Administration link to open the ATG Commerce Administration page.sql <ATG9dir>/DCS/sql/uninstall/<db-vendor>/ drop_reporting_views1.sql <ATG9dir>/DCS/CustomCatalogs/sql/db_components/<db-vendor>/ custom_catalog_reporting. 7. see the ATG Programming Guide.sql <ATG9dir>/DCS/sql/db_components/<db-vendor>/ reporting_views2.

the repository structure is somewhat different. custom catalogs can be used exactly as regular catalogs are.Using Custom Catalogs . Defining Root Categories With any group of categories. they see all of the root categories of Catalog B (category3 and category4) as well as the root categories of the subcatalogs (category1 and category2) meaning there appear to be four root categories. However. Note: Root categories of a “root sub catalog” are also considered root categories. category4 rootSubCatalogs = CatalogA When a user of Catalog B views the allRootCategories. if Catalog A has Catalog B as a “Sub catalog at root” then allRootCategories of Catalog B are included in the allRootCategories of Catalog A. A given user can only have permission to view one catalog. see below for details. A catalog’s rootCategories combine with the rootCategories of its rootSubCatalogs to make up the list of the catalog’s allRootCategories. For example. The custom repository component is located at /atg/commerce/catalog/ProductCatalog. or derived from the user’s parentOrganization.ATG Commerce Programming Guide µ Catalogs consist of rootCategories and rootSubCatalogs. Property allRootCategories How it is set CCS Description Lists of all the root categories in the catalog. The allRootCategories property of the user’s catalog specifies all the categories in a catalog’s rootCategories property. Designate a category as a root category by setting the value of the rootCategories property of the catalog to include the category you want to be considered the top level of the product catalog. including the allRootCategories in the rootSubCatalogs. For the most part. This catalog can be assigned in the catalog property of the user’s profile. Catalog Properties The following table describes the catalog properties of the custom repository. For example: Catalog A: rootCategories = category1. category2 Catalog B: rootCategories = category3. 77 5 . This is used for display purposes. you need to know where to start when navigating. That starting point is called a root category.

lastModifiedDate rootCategoryIds Repository IDs of top-level categories in the catalog. Refers to the same database table as rootCategories. Required. and the subCatalogs of any categories in the catalog.µ allRootCategoryIds ATG Commerce Programming Guide Implicitly set by the CCS List of the repository IDs of all root categories for the catalog.Using Custom Catalogs . including rootSubCatalogs and their subCatalogs. Read-only. If not set. This property refers to the same database table as allRootCategories Date the catalog was created. Repository ID for the catalog. It lists of all catalogs contained within the catalog. Read-only. Date the catalog was last modified. This property refers to the same database table as subCatalogs This is an optional property that is not needed in the current versions of ATG Commerce. Repository IDs of catalogs contained within the catalog. Updated nightly to speed searching. and the subCatalogs of any categories in the catalog. List of catalogs whose root categories are also root categories of the catalog (for use in combining catalogs). the GSA generates the value. creationDate Implicitly set by GSA when catalog is created ACC Can be set in the ACC Implicitly set by GSA when catalog is modified Implicitly set in the ACC displayName id Name used for the catalog on the site. including rootSubCatalogs and their subCatalogs. This property is false by default subCatalogIds Optionally implicitly computed by the CCS subCatalogs CCS (optional) 78 5 . Must set computeSubCatalogs= true in CCS to compute. rootCategories rootSubCatalogs ACC ACC List of the top-level categories in the catalog. Read-only.

compiles a complete list of all ancestor catalogs within each catalog. The list of all catalogs that these elements belong to can be determined from the ancestor list of that closest containing catalog.Using Custom Catalogs . This allows other catalog elements (categories. (See directAncestorCatalogsAndSelf for further explanation) All the categories that can are connected to this catalog through its children. and update those catalogs ancestor-catalogs properties accordingly. The purpose of this property is so that CatalogCompletionService can find all the sub-catalogs of a given category that is being added to a catalog or another category. (See directAncestorCatalogsAndSelf for further explanation). Otherwise it is a Union. By maintaining this property. This property. along with indirectAncestorCatalogs. and SKUs) to only keep track of their closest containing catalog. directAncestorCatalo gsAndSelf CCS indirectAncestorCata logs CCS All the ancestor catalogs that do not use allRootCategories as their root categories. the system can query for catalogs that contain the category being added in the ancestorCategories.ATG Commerce Programming Guide µ All the catalogs that use this catalog’s allRootCategories as their root categories. This may not actually ancestorCategories CCS ancestorCatalogsAndS elf derived be derived if the NotEmptyChooserPropertyDescriptor user defined type is queryable. A rootCategory of a catalog only belongs in the allRootCategories list of an ancestor catalog if it is a direct ancestor. The ancestors are divided into direct and indirect lists to make it easier to compute the allRootCategories property. products. Category Properties The following table describes the category item properties in the custom catalog: 79 5 . The combination of directAncestorCatalogsAndSelf and indirectAncestorCatalogs.

regardless of catalog. production this is set by the CatalogMaintenanceService. Read-only. While a category can only be directly contained by one catalog. This is used to determine the catalog whose Access Control List should be used for admin permissions.Using Custom Catalogs . In production.childCategories is a combination of fixedChildCategories and subCatalogsChildCategories) RepositoryIDs of the ancestor categories. Uses same database table as ancestorCategories ancestorCategoryIds Implicitly set by CMS auxiliaryMedia ACC Additional media to be displayed with this category. in which case an entry is placed in this map. In development mode this is derived (non-queryable) by walking up the parentCategory until a catalog is reached. In catalog Derived in development mode Set by CMS in production mode. that catalog can be contained within another catalog.µ Property ancestorCategories ATG Commerce Programming Guide How it is set CMS Description All the categories that can be used to navigate to (through category.ancestorCatalogsAndS elf) but is not queryable. 80 5 . This is used to determine whether an end user has permission to view this category.childCategories) to this category. This is the catalog that owns this category. In development this is derived (Alias of catalog. All the catalogs that include some path to this category. catalogs Derived in development mode Set by CMS in production mode. categoryInfos ACC (optional) Map from catalogId to a categoryInfo. this value is set by the CatalogMaintenanceService. (category.

Name used for the category on the site. List of the products in the content group specified by the childProductGroup property. List of the categories in the content group specified by the relatedCategoryGroup property.ATG Commerce Programming Guide µ List of all categories that are children of this category. Read-only. Name of the content group that contains the list of dynamicChildCategories. Read-only. a merge of fixedChildProducts and dynamicChildProducts. a merge of fixedChildCategories and dynamicChildCategories. Required. Readonly. if a collection filter is implemented to use this property. Short descriptive text for display with this category. Used by catalog admin to explicitly set the descendant categories of a category. Read-only. Date this category will no longer be available. Date this category was created. List of the categories in the content group specified by the childCategoryGroup property. childCategories derived childCategoryGroup ACC childProductGroup ACC childProducts ACC creationDate Implicitly set by GSA ACC description displayName ACC dynamicChildCategories derived dynamicChildProducts derived dynamicRelatedCategori es derived endDate ACC fixedChildCategories ACC 81 5 . Readonly.Using Custom Catalogs . List of child categories of this category. List of all products that are children of this category. Name of the content group that contains the list of dynamicChildProducts. Read-only.

RepositoryID for this category. The purpose is twofold: 1) used in breadcrumbs 2) used in “Catalog” derivation to walk up the category tree to find the containing catalog. This will only hold a value if the catalog is a rootCategory of the given catalog. largeImage ACC longDescription ACC parentCatalog CCS parentCategory CCS relatedCategories derived Read-only. dynamicRelatedCategories. This is used in the ParentCatalog derivation. this represents a merge of fixedRelatedCategories.µ fixedChildProducts ATG Commerce Programming Guide ACC List of child products of this category. Static list of categories related to this category. Users can explicitly change this if they wish. The parent category of this category. Detailed descriptive text for display with this category. If fixedRelatedCategories ACC id ACC this property is not set through the ACC during creation. The CatalogCompletionService will arbitrarily choose one (if the value is null). The parent catalog of this category. and the categoryInfo property catalogsRelatedCategories. List of all categories that are children of this category. it implicitly set by GSA keywords ACC Set of words that can be used in searching for this category. It is possible there is more than one choice here. Large image associated with the category.Using Custom Catalogs . Used by catalog admin to explicitly set the descendant products of a category. 82 5 .

Using Custom Catalogs . if a collection filter is implemented to use this property. List of catalogs whose root categories will be considered child categories of this category. The CollectiveUnion of the “allRootCategories” of each catalog in “subCatalogs”. used to prevent version conflict. relatedCategoryGroup ACC smallImage ACC startDate ACC subCatalogs ACC subCatalogsChildCatego ries derived template thumbnailImage ACC ACC type Not used out-ofthe-box version Implicitly set by GSA categoryInfo Properties categoryInfo objects are no longer required for custom catalogs. You can create categoryInfo objects through the ACC if you wish to keep catalogspecific information for a category. Thumbnail image associated with this category.1.the complete list of all descendant categories of a category. Date this category becomes available. Used by catalog admin to explicitly set direct descendant catalogs of a category. All relevant information for a category is kept in the category item. Readonly. Integer that is incremented automatically each time the category is updated. use to indicate if an item belongs to the superclass or a subclass. categoryInfo objects were required in custom catalogs before ATG Commerce 6.ATG Commerce Programming Guide µ Name of the content group that contains the list of categories that dynamicRelatedCategories is set to. JSP used to display this category. Small image associated with the category. Provided for subclassing purposes. 83 5 . Used to help compile the “childCategories” property .

Read-only. regardless of catalog.Using Custom Catalogs . used to prevent version conflict. This property uses the same database table as ancestorCategories. 84 5 .µ Property How it is set ancestorCategories ATG Commerce Programming Guide Description Categories that are higher in the catalog hierarchy than this category. ancestorCategoryIds Implicitly set by CMS auxiliaryMedia ACC Additional media to be displayed with this product. RepositoryIDs of the ancestor categories. By default. Product Properties The following table describes the product item properties in the custom catalog: Property How it is set CMS Description ancestorCategories All the categories that have you can navigate through (through category. ancestorCategoryIds RepositoryIDs of the ancestor categories. By default. version Implicitly set by GSA Integer that is incremented automatically each time the categoryInfo is updated. Updated nightly to speed searching. this information is no longer stored in categoryInfo item – now in the ancestorCategoryId property of category item.childCategories and category. Used for hierarchical search. this information is no longer stored in categoryInfo item – now in the ancestorCategories property of category item. Read-only.childProducts) to this category.

List of child SKUs of this product. Can be set in displayableSkuAttribu tes ACC displayName ACC dynamicRelatedProduct s derived endDate ACC fixedRelatedProducts id ACC ACC (optional) ACC upon creation of product. RepositoryID for this category. if a collection filter is implemented to use this property. Generated Set of related products that are only shown to users of a particular catalog. Static list of products related to this product. Large image associated with the product. Date this product was created. Read-only. Read-only. Date this product will no longer be available. List of the products in the content group specified by the relatedProductGroup property. List of properties of the product’s SKUs that can be displayed by the DisplaySkuProperties servlet bean. Used to determine if an end user has permission to view this product. Detailed descriptive text for display with this product. it is implicitly set by GSA Set of words that can be used in searching for this product. Used by catalog admin to explicitly set child SKUs of a product. this value is set by the CatalogMaintenanceService. In production. If it is not set through the ACC. catalogs Derived (developm ent only) catalogsRelatedProduc ts derived childSKUs ACC creationDate Implicitly set by GSA ACC description Short descriptive text for display with this product.Using Custom Catalogs . Read-only.ATG Commerce Programming Guide µ In development this is the CollectiveUnion of “catalogs” for each category in “parentCategories”. This is not queryable. Required. Name used for the product on the site. keywords ACC largeImage longDescription ACC ACC 85 5 .

There is possibly more than one choice. Thumbnail image associated with this product. This is derived one way in development and another way in product.Using Custom Catalogs . use to indicate if an item belongs to the superclass or a subclass. Name of the content group that contains the list of dynamicRelatedProducts. Map from productId to a productInfo. parentCategoriesForCa talog CMS parentCategory derived productInfos relatedProductGroup ACC ACC relatedProducts ACC smallImage startDate ACC ACC Small image associated with the product. dynamicRelatedProducts. a merge of fixedRelatedProducts. This is used for breadcrumb purposes. Therefore adding a product to another category’s child list will automatically update the parentCategories property. List of all products that are children of this category. In production. Provided for subclassing purposes. This is used to derive the proper value for the “parentCategory” property. In development. if a collection filter is implemented to use this property.µ parentCategories ATG Commerce Programming Guide Implicit GSA reuse Reuses the same table as category. The CatalogMaintenanceService will choose arbitrarily if one is not yet chosen for the given catalog. the ProductsParentCategory derivation is used by inspecting each category in “parentCategories”. Read-only. Read-only. and the productInfo property catalogsRelatedProducts. Date this product becomes available. template thumbnailImage ACC ACC type Not used out-of-thebox 86 5 .fixedChildCategories. The parentCategory for each catalog. the CatalogMapDerivation is used to get the correct parent from “parentCategoriesForCatalog”. JSP used to display this product. Users may change the value. This is not queryable.

Read-only. this information is stored in ancestorCategories property of product item. version Implicitly set by GSA productInfo Properties productInfo objects are no longer required for custom catalogs. 87 5 . used to prevent version conflict. RepositoryIDs of the ancestor categories. Now stored in ancestorCategoryIds property of product item ancestorCategoryIds That property is implicitly computed by the CMS – it uses the same DB table as ancestorC ategories catalogsRelatedProdu cts parentCategory ACC Related products that are only shown to users of the catalog that maps to this productInfo. You can create productInfo objects using the ACC if you wish to keep catalog-specific information for a product. Parent category for this catalog. Read-only. Out-of-the-box. productInfo objects were required in custom catalogs before ATG Commerce 6. Property How it is set That property is computed by the CMS.ATG Commerce Programming Guide µ Integer that is incremented automatically each time the product is updated. Read-only.Using Custom Catalogs . Description ancestorCategories Set of categories that are higher in the catalog hierarchy than this product.1. Now kept in parentCat egoriesFo rCatalog map in Product item That property is computed by the CMS.

fixedReplacementPro ducts fulfiller id ACC ACC ACC Fulfiller who will ship the item. Replacement products that are only shown to users of a particular catalog. used to prevent version conflict. Required. largeImage ACC 88 5 . This is not queryable. otherwise implicitly set by GSA Large image associated with the SKU. SKU Properties The following table describes the SKU item properties in the custom catalog: Property How it is set ACC ACC Description auxiliaryMedia bundleLinks Additional media to be displayed with the SKU. Read-only. if null. Read-only. Used to determine if an end user has permission to view this SKU. Can be set in ACC upon item creation. Date the SKU is no longer available. catalogs Derived (develop ment only) catalogsReplacement Products creationDate derived Implicitly set by GSA ACC ACC ACC ACC description displayName dynamicAttributes endDate Short descriptive text for display with the SKU. if a collection filter is implemented to use this property. Read-only. Date the SKU is created. Name used for the SKU on the site. In production. List of SKU links that make up the SKU bundle. In development this is the CollectiveUnion of “catalogs” for each product in “parentProducts”.Using Custom Catalogs .µ version ATG Commerce Programming Guide Implicitly set by GSA Integer that is incremented automatically each time the product is updated. SKU is not a bundle. Repository ID for this SKU. Static list of SKUs related to this SKU. this value is set by the CatalogMaintenanceService. Additional attributes of the SKU.

listPrice ACC onSale parentProducts ACC implicit GSA reuse replacementProducts derived salePrice skuInfos smallImage startDate ACC ACC ACC ACC template thumbnailImage type ACC ACC Not used out-ofthe-box Implicitly set by GSA ACC version wholesalePrice SKUInfo Properties skuInfo objects are no longer required for custom catalogs. use to indicate if an item belongs to the superclass or a subclass. Map from SKU to a SKUInfo. 89 5 . You can create SkuInfo objects using the ACC if you wish to keep catalog-specific information for a SKU. Boolean property that indicates if the item is on sale. if a collection filter is implemented to use this property. Read-only. Reuses the same table as product.childSkus. Integer that is incremented automatically each time the SKU is updated. Date on which the SKU is available. Products to suggest as replacements if the item is out of stock. Property How it is set ACC Description catalogsRepla cementProduct s These are replacement products that are only shown to users of the catalog that maps to this SKUInfo. skuInfo objects were required in custom catalogs before ATG Commerce 6. Wholesale price of the SKU. Thumbnail image associated with the SKU.ATG Commerce Programming Guide µ Default price of the SKU before any discounts or promotions. used to prevent version conflict.1. Provided for subclassing purposes. Small image associated with the SKU. Read-only. Read-only. JSP template used to display the SKU. Price of the SKU if onSale property is true. Therefore adding a SKU to a product’s child list will automatically update the parentProducts property.Using Custom Catalogs .

commerce. Custom Catalog Navigation This section contains information on ATG Commerce classes intended to help customers navigate your store. Readonly.ItemLookupDroplet. This ATG Servlet Bean takes input parameters specifying the repository. and renders the specified item on the page. For information on implementing navigational strategies in your store.catalog.pr operties file with the following contents: repositoryPathAliasMap=\ /atg/commerce/catalog/SecureProductCatalog=/atg/commerce/catalog/ ProductCatalog sourceRepositoryPathToItemDecriptorNames+=\ /atg/commerce/catalog/SecureProductCatalog=category.sku. 90 5 . Note: If you are using custom catalogs in ATG Business Commerce with reporting.µ version ATG Commerce Programming Guide Implicitly set by GSA Integer that is incremented automatically each time the SKUInfo is updated. and the permissions they have. This servlet bean does not return items that are not visible from the current user’s catalog (as defined in their profile). see Implementing Custom Catalogs section of the ATG Commerce Guide to Setting Up a Store. In the custom catalogs security policy. SKU.servlet. in order for the ProductCatalog logs to be created during deployment. see the Secured Repositories chapter in the ATG Repository Guide). the repository ID. create a server_name/localconfig/atg/reporting/datacollection/commerce/ProductCatalogDeploymentListener. which makes it different from atg.Using Custom Catalogs .repository. ATG Commerce implements a security policy for catalogs based on the secured repositories feature (for more information.custom. and the item type.CatalogItemLookupDroplet class to locate and display items in a repository. media) except for category. the catalog. an access control list (ACL) is stored for each individual item (catalog. the ACL of a category is the same as the ACL of the catalog that contains it. Custom Catalog Security Securing a catalog allows certain users to view and edit a catalog while preventing other users from doing so. used to prevent version conflict. The ACL contains lists of users or groups of users.product. product.promotion See the Preparing to Use Commerce Reporting chapter in this guide for information on data logging. Looking Up Items in the Catalog Use the atg.

Four of these components are found in /atg/commerce/catalog/: CategoryLookup. parentCategory is a derived property in custom catalogs The value it returns is the parentCategory of the productInfo object that is mapped to the user’s current catalog. your site can track which parent category the customer accessed the product from.properties file to the actual name of the property. For example: parentCategoryPropertyName=higherCategory CatalogTools uses parentCategory to determine the ancestor categories of a product or category. You can use the parentCategory property of the category and product items to specify a default parent category for this purpose. If your site includes more than one catalog. if the customer then wants to move up the hierarchy. This section includes the following information related to searching custom catalogs: Overview of Custom Catalog Searching Configuring the Custom Catalog’s Search Form Handler 91 5 . Using the parentCategory Property A category or product can be the child of more than one category. you can set these through the servlet bean’s properties file. But if the customer finds the product by searching rather than navigating through the catalog hierarchy. ATG Commerce includes several ItemLookupDroplet components that are configured to use the product catalog as the default repository and find a specific item type. but can complicate navigation. set the parentCategoryPropertyName property in the /atg/commerce/catalog/CatalogTools. you can have the link point to the category specified by the parentCategory property. If your catalog uses a different name for the parentCategory property. SKULookup. or if your catalog uses item types not found in the standard catalog. Specifying multiple parent categories makes the catalog more flexible. and MediaLookup. To facilitate this feature. see Appendix A: ATG Commerce Servlet Beans of the ATG Commerce Guide to Setting Up a Store. you may want to create additional ItemLookupDroplet 4components.. In custom catalogs. you need to determine which parent category to move to. suppose you have a link on each page that takes the customer up one level in the catalog hierarchy. For example.ATG Commerce Programming Guide µ Rather than specifying the repository and item type through input parameters. For more information about the ItemLookupDroplet servlet bean. If customer views a product that has multiple parent categories. ProductLookup. a product can have different parentCategories for each catalog in which the product appears. Custom Catalog Searching You can provide searching mechanisms to enable customers to find products in the catalog that satisfy a set of criteria. This is especially true if the customer accesses a category or product through a search facility rather than by traversing the catalog hierarchy. and make this link point back to that category.Using Custom Catalogs .

For more information. you can extend CatalogSearchFormHandler or write another form handler. Configuration settings in the form handler’s properties file specify the kinds of elements to search for.” Note that your database must be configured properly to support full-text searches. or for both products and categories that have a specified set of property values. ATG Commerce includes several CatalogSearchFormHandler components in /atg/commerce/catalog. You can use this form handler to construct searches for one or more catalog item types. and so on. the children of those children. CatalogSearchFormHandler can be configured to perform four types of searching: Keyword Searches Keyword searches use keyword property names and input search strings to search product and category keywords. An example of a keyword search is “Show me all products and categories with the keyword shoe. customers specify target values to search for through form fields in a JSP. starting from a given category. An example of a full-text search is “Show me all products whose longDescription property contains the word wool.CatalogSearchFormHandler to search the catalog repository for items such as products and categories. Typically.custom.µ ATG Commerce Programming Guide Configuring Custom Catalog Search Types and Specifying Search Criteria Combining Custom Catalog Search Types Preconfigured Custom Catalog Search Components Processing and Displaying Custom Catalog Search Results Searching Custom Catalogs in Development Mode Using Search Form Handler with Internationalized Catalogs Overview of Custom Catalog Searching ATG Commerce provides the form handler class atg. The customer enters values that are used for keyword matching. see the discussion on databases and database access in the ATG Installation and Configuration Guide. The CatalogSearchFormHandler class should provide sufficient search functionality and flexibility for most sites.” Text Searches Full-text searches use text property names and input search strings to perform text pattern matching on properties. and including that category’s child categories. You can create additional CatalogSearchFormHandler components and configure them through their properties files or through the Component Editor in the ACC. or for categories that are tagged with a specified keyword. and you can specify which properties to examine when searching. For example. 92 5 . the properties of those elements to consider when searching. each one configured for a different set of search options (see Preconfigured Custom Catalog Search Components). If your store requires custom search capabilities.Using Custom Catalogs . Hierarchical Searches Hierarchical searches look in a subset of categories. you can search for products that contain a specified substring in their names.commerce. and additional configuration details for each type of search.catalog.

For example. An example of an advanced search is “Show me all products with the keyword shoe where price range is expensive.ATG Commerce Programming Guide µ The given category is indicated by the repository ID in the hierarchicalCategoryId property.CatalogSearchFormHandler $scope=session doKeywordSearch=true keywordsPropertyNames=keywords doTextSearch=true textSearchPropertyNames=description.Using Custom Catalogs . Advanced searches retrieve these values from the definition to display in a selection box. each naming one item type. You specify the item types to find by setting the itemTypes property in the form handler’s properties file to a list of strings. Unless you have implemented your own catalog management system. while a more general search page would use the second. SKUs.displayName doHierarchicalSearch=true ancestorCategoriesPropertyName=ancestorCategories doAdvancedSearch=true 93 5 . Item types typically include category or product.catalog. as described in Using the Catalog Maintenance System.custom. products. manufacturer. Advanced Searches Advanced searches provide possible search options for each property specified in the form handler’s advancedSearchPropertyNames property.commerce. In addition to specifying the item types to search for. You can also create multiple instances of CatalogSearchFormHandler and configure them to search for different kinds of objects. you could have one form handler that searches only for clothing products and another that searches for all products and categories. you must generate the ancestorCategories property for each product and category item. The advanced query is built from options selected by the customer to further refine the catalog search. To perform hierarchical searches.” Configuring the Custom Catalog’s Search Form Handler CatalogSearchFormHandler can search for any type of repository item in the catalog repository. but you can configure search form handlers to search for SKUs or for custom category or product subtypes you have created. a clothing search page might use the first form handler. and other catalog information. advanced searches allow a customer to search on a description. or price. enumerated types are defined in the repository with a set number of values. For example. The following is an example of a properties file for a CatalogSearchFormHandler component that can perform all four types of searching: $class=atg. For example. you must also set the property catalogTools so that it refers to a CatalogTools object that provides access to categories. you should use the default CatalogTools component at /atg/commerce/catalog/CatalogTools.

µ ATG Commerce Programming Guide advancedSearchPropertyNames=weightRange.childSKUs catalog^=/atg/commerce/catalog/custom/CatalogTools.manufacturer. For example. You could use this component and just enable keyword searching on the page by including this tag: <dsp:input type="hidden" bean="KeywordSearch.productItemTypes Because there are so many possible combinations of search options. By default. You can override the default behavior by setting the keywordsPropertyNames property of the form handler in its properties file. and you can create additional instances. but you have one page where you want to enable text searching as well. keyword searches look at the keywords property of each catalog item. You can specify the target values to search for by setting the keywords property of the search form handler to an array of strings. and each of these properties can be either single-valued or multi-valued. each configured differently. (You can change the separator character used to parse searchInput by setting the form handler’s keywordInputSeparator property.) You can force the search form handler to convert all keyword inputs to uppercase before searching by setting the toUpperCaseKeywords property to true. These values are typically specified by the customer through a form input field.catalog itemTypes^=/atg/commerce/customCatalogTools. it is convenient to have several CatalogSearchFormHandler components. You can also change the behavior of a CatalogSearchFormHandler component for an individual page by setting hidden input fields.doTextSearch" value="true"> Configuring Custom Catalog Search Types and Specifying Search Criteria As mentioned above. Similarly. set the property doKeywordSearch to true. Keyword Searches To enable keyword searches in the form handler. or by setting the searchInput property to a string containing one or more words separated by spaces. You can specify one or more properties to consider in keyword searches. suppose your site has a CatalogSearchFormHandler component named KeywordSearch that is configured only for keyword searching. CatalogSearchFormHandler provides four different types of searching: • • • • keyword searches text searches hierarchical searches advanced searches This section describes how to configure a SearchFormHandler component for each of these types of searching. you can force the form handler to convert keyword inputs to lowercase by setting toLowerCaseKeywords to true instead. ATG Commerce includes five different CatalogSearchFormHandler components (see Preconfigured Custom Catalog Search Components). 94 5 .Using Custom Catalogs .

By default. the resulting query is: keywordString CONTAINS "red" OR keywordString CONTAINS "green" OR keywordString CONTAINS "blue" Since CONTAINS performs a substring match. the item is returned by the search operation. The target search string is specified by setting the form handler’s searchInput property. and you search for the values red. the property is of type String). the keyword search generates a query for each property. If your database supports a full-text search engine. If this property is not set. the keyword search algorithm uses the QueryBuilder. For example. The implementation of text searching is RDBMS-specific and uses the database’s text searching facility. and set the repository component’s simulateTextSearchQueries property to false. typically by the customer entering the value in a form input field. and blue using keyword search. To enable this feature. because red is not an exact match for reduced calorie. and blue using keyword search. set the property doTextSearch to true.ATG Commerce Programming Guide µ Keyword searches treat single-valued and multi-valued properties differently. If a property specified in keywordsPropertyNames is single-valued (e..Using Custom Catalogs . green. If you specify multiple properties in keywordsPropertyNames. if you have a keywords property whose type is String[]. This means that if any one of the queries returns true. green. Text Searches To enable text searches in the form handler.. and you search for the values red. You specify which properties to examine by setting the textSearchPropertyNames property of the form handler. If a fulltext search engine is not available (either because your RDBMS does not support one. set the repository component’s simulateTextSearchQueries property to true. the SQL repository can simulate full-text searching by using the LIKE operator to determine whether the target value is a substring of any of the text properties being examined. text searches use a default set of properties that is defined by the repository. Note that although simulated full-text searching is useful for development purposes.CONTAINS query to examine each target value and see if it appears anywhere within the property’s current value. or because you do not have a license for the one your RDBMS supports). if a property specified in keywordsPropertyNames is multi-valued (for example. you must configure the search engine properly. the keyword search algorithm uses the QueryBuilder. However. the product catalog’s simulateTextSearchQueries is set to true to support full-text searching on the SOLID database that is included with Dynamo.INCLUDESANY query to perform a single search for an exact match between any value in the property and any value in the set of search criteria.g. if there is one. performance is unlikely to be adequate for a production server. because reduced contains the string red within it. the property is of type String[]). then combines these queries using the OR operator. this query returns false for an item whose keywords are diet and reduced calorie. if you have a keywordString property whose type is String. the resulting query is: keywords INCLUDES ANY ["red"."green". For more information about configuring 95 5 . this query returns true for an item whose keywordString has the value reduced calorie."blue"] Since INCLUDES ANY searches for an exact match. For example.

propertyValues. For multi-valued properties an INCLUDES test is generated. The key is the name of the property and the value is a 96 5 . which is a Dictionary containing one key/value pair for each property named in advancedSearchPropertyValues whose type is either enumerated or RepositoryItem. To enable hierarchical searches in the form handler. so all properties must match for the catalog item to be selected. see the discussion on databases and database access in the ATG Installation and Configuration Guide. set the form handler’s doAdvancedSearch property to true. to look for items whose color property is set to red. Advanced searches are limited to the set of properties you name here. and therefore specifies that the property matches any value. Hierarchical searching restricts the search results to items whose ancestor categories include the category specified through hierarchicalCategoryId. where color is a single String and availableSizes is an array of Strings.µ Hierarchical Searches ATG Commerce Programming Guide your database for full-text searching. If you are using the standard catalog schema. typically through form input fields. For example. searching color for a value of red and availableSizes for a value of medium. you may be able to configure this component to generate ancestor categories for your catalog items. You then specify the set of properties to search by setting the advancedSearchPropertyNames property. Target values are specified for one or more of these properties by adding values to the propertyValues property of the form handler. and the value to search for.Using Custom Catalogs . set the property doHierarchicalSearch to true. results in the following query: (color = red) AND (availableSizes INCLUDES medium) CatalogSearchFormHandler has a property called propertyValuesByType.color to red. You specify the category to start the search from by setting the form handler’s hierarchicalCategoryId property to the repository id of the category whose descendants you want to find. For single-valued properties a simple equality test is used. so that the query succeeds if any of the property’s values match the target value. the queries are combined using the AND operator. or you can specify ancestor categories by setting properties manually. See Using the Catalog Maintenance System for more information. This property is a Dictionary to which you add one key/value pair for each property you want to search. Advanced Searches To enable advanced searches. Specify the name of the ancestor category property by setting the ancestorCategoriesPropertyName property of the form handler. The key is the property name. For each property specified in propertyValues. or specified by the customer through a form input field. Hierarchical searching requires that each category and product item have a multi-valued property whose value is a complete list of all of its ancestor categories. If you specify multiple properties. For example. This property is typically set through a hidden input tag. Setting a value to an empty string omits it from the search. set CatalogSearchFormHandler. If your catalog does not use the default schema. each category and product item has an ancestorCategories property whose value is a Set of that item’s ancestor categories The values of these properties can be generated automatically using the component /atg/commerce/catalog/custom/AncestorGeneratorService. a query is generated based on whether the property is single-valued or multi-valued.

However. the size of an item.String"> <dsp:option value="<%=option11%>"/> <dsp:setvalue bean="" value="/> </dsp:getvalueof><dsp:valueof param="element">Unknown size</dsp:valueof> </dsp:oparam> </dsp:droplet> </dsp:select> For more examples. The RepositoryValues servlet bean returns essentially the same information as the propertyValuesByType property of the CatalogSeachFormHandler class. • RepositoryValues can look up values for any property of a repository item. Note: When running development mode. and large. medium.Create a select field to choose size and a default option --> Size: <dsp:select bean="SearchHandler.Using Custom Catalogs . The propertyValuesByType property is useful for building forms that allow customers to select.ATG Commerce Programming Guide µ Collection of the possible values.size"> <!-.Create a default choice --> <dsp:option value="" selected="true"/>Any size <!-.repository. For information on the Sample Catalog and how to run it.commerce.Now create an option for each defined value for size --> <dsp:droplet name="ForEach"> <dsp:param value="SearchHandler.propertyValuesByType. there are some important differences: • RepositoryValues determines possible values for only a single item type at a time.servlet. the /atg/commerce/catalog/RepositoryValues component becomes an instance of atg.catalog. while propertyValuesByType works with only the properties specified in the form handler’s advancedSearchPropertyNames property. For more information.size" name="array"/> <dsp:oparam name="output"> <dsp:getvalueof id="option11" param="element" idtype="java.PossibleValues class. The following example illustrates this: <!-. where size is an enumerated property with a set of predefined values like small.FilteringCatalogPossibleValues. while the propertyValuesByType property works with multiple item types at the same time.propertyValues. See the entry for PossibleValues in Appendix B: ATG Servlet Beans in the ATG Page Developer’s Guide for a detailed description of this servlet bean. 97 5 . see the Reference Applications section of the Introduction in the ATG Commerce Guide to Setting Up a Store.lang. for example. Another approach to determining the possible values of properties whose type is enumerated or RepositoryItem is to use the servlet bean located at /atg/commerce/catalog/RepositoryValues. see the Sample Catalog that is provided with ATG Commerce. see Searching Custom Catalogs in Development Mode. This component is an instance of the atg.

or you can combine advanced searching with hierarchical searching to find only items in a particular category. so that a match on either set of criteria selects an item for inclusion in the search results. For example. you can use any combination of search types. The query is of the form: (KeywordConditions OR TextConditions) AND HierarchicalConditions AND AdvancedSearchConditions For example. you can search on both keywords and text.Using Custom Catalogs . In fact. and finds matching products and categories. and you configure a search form handler to allow all four types of searches.µ • ATG Commerce Programming Guide RepositoryValues works anywhere in a JSP. CategorySearch searches keywords and descriptions and finds matching categories only. 98 5 .format=DVD The search will locate all comedies plus all movies whose description mentions Steve Martin. limiting the scope of the search to items that satisfy the hierarchical or advanced search requirements in addition to any specified text or keyword search criteria. while the propertyValuesByType property is only available within search forms you construct using the SearchFormHandler class. Search types are combined according to the following rules: • • Text and keyword searches are combined using the OR operator. descriptions. Preconfigured Custom Catalog Search Components ATG Commerce includes five preconfigured instances of CatalogSearchFormHandler in /atg/commerce/catalog: • • • CatalogSearch searches keywords. suppose you have a catalog of videos and DVDs. and display names. but will return only the subset of those movies that are found in the BudgetMovies category and are available on DVD. Hierarchical and advanced searches are combined using the AND operator. The customer enters the following search criteria: keywords=comedy textSearchPropertyNames=description searchInput=Steve Martin hierarchicalCategoryId=BudgetMovies propertyValues. ProductSearch searches keywords and descriptions and finds matching products only. Combining Custom Catalog Search Types The CatalogSearchFormHandler class allows you to specify multiple search types in a single request.

and finds products that match all search criteria. and another key called product whose value is a Collection of matching products. Typically. SearchFormHandler makes the search results available in two different properties. The searchResults property will have a Collection in which some of the items are categories and some of the items are products. open them in the ACC Component Editor and view their property settings. and finds matching products only.searchResultsByItemType.search" value="Go" type="submit"/> After executing the query. The key is the item type name (the value specified in the form handler’s itemTypes property). sorted by display name: Your search returned the following products: <dsp:droplet name="ForEach"> <dsp:param value="CatalogSearch.product" name="array"/> <dsp:param value="+displayName" name="sortProperties"/> 99 5 .Using Custom Catalogs .ATG Commerce Programming Guide µ • • ProductTextSearch searches only description fields. the searchResultsByItemType property will have a key called category whose value is a Collection of matching categories. see Searching Custom Catalogs in Development Mode. The following example uses ForEach with searchResultsByItemType to display only the products returned by the search. For more information. if you search for categories and products in the standard catalog schema. Processing and Displaying Custom Catalog Search Results SearchFormHandler executes its search query when the handleSearch method is called. the five preconfigured search components are instances of FilteringSearchFormHandler in atg/commerce/catalog. Note: When running development mode. and the value is a Collection of items of that type that satisfied the search criteria. as in this example: <dsp:input bean="/myCatalog/SearchForm. You can use the sorting capabilities of a servlet bean (such as ForEach) to control the order in which the items are displayed. you associate the form handler’s search property with a submit button. the items are not sorted. If you search for multiple item types (such as categories and products) all items returned by the search appear in the list regardless of their type. • For example. Within each Collection. not keywords. To see how these components are configured. AdvProductSearch combines keyword and text searching with hierarchical and advanced searching. The searchResultsByItemType property is a HashMap containing one key/value pair for each item type you searched for. which contain the same information but organize it differently: • The searchResults property is a Collection of all catalog items that satisfied the search criteria. but reflect the order they were retrieved from the database.

</dsp:oparam> </dsp:droplet> ATG Commerce Programming Guide <dsp:oparam name="output"> <li><dsp:valueof param="element. The following example demonstrates the different ways the two modes retrieve the same results. and checks the catalogs property of each. the query is run without the extra clause and items not in the user’s current catalog may be returned. A site that sells laptop computers with integrated modems.FilteringCatalogPossibleValues. FilteringCatalogSearchFormHandler then iterates through the results. Those items that do not contain the user’s current catalog among their catalogs are then removed from the list.displayName">Unknown product</dsp:valueof> </dsp:oparam> Searching Custom Catalogs in Development Mode Custom catalog searches in development mode are performed slightly differently than searches in production mode.FilteringSearchFormHandler the /atg/commerce/catalog/RepositoryValues component becomes an instance of atg. 100 5 . Therefore.commerce. the query includes a “where keywordString CONTAINS ‘red’” clause and the SearchFormHandler adds another clause to make the query “where keywordString CONTAINS ‘red’ and catalogs CONTAINS (the user’s current catalog)”. taking into account the different keyboard layouts and telephony standards that prevail in those countries. which can display product information in different languages. So the SearchFormHandler cannot add the extra clause to narrow the search to only the user’s current catalog. Instead. and SKUs is derived and non-queryable.commerce. If a user does a keyword search for “red” in production mode. • Using Search Form Handler with Internationalized Catalogs Some businesses require internationalized catalogs. In development mode: The catalogs property of categories. • In production mode: The SearchFormHandler and CatalogPossibleValues classes add a clause to the query that they pass to the repository that restricts the search results to the user’s current catalog. might show different sets of products to customers in the US and the UK. or display different sets of products to customers in different countries.catalog. for example.Using Custom Catalogs . and the “filtered” result set containing only items in the user’s current catalog is returned. Before returning the result set.µ <dsp:oparam name="empty"> <p>No matching products were found.catalog. the repository would only return items that exist in the user’s current catalog. products. The two main differences are: • • the five preconfigured search components become instances of atg.

If myCatalog is set. You can set it in either the user’s myCatalog property or the catalog property of the contract for the user’s parentOrganization.repositoryKey"> Using repositoryKey in conjunction with the alternateRepositories property of the CatalogTools component lets you ensure that customers see only the appropriate products when searching the catalog. set catalog to the catalog you want the user to see. You can then use customer locale as the repository key to determine which version of the catalog to display. you want to make sure they search the catalog specific to their language or locale. When the customer searches the catalog on an internationalized site.Using Custom Catalogs . catalog is a derived property. 101 5 . The search form handler uses repositoryKey to retrieve the appropriate catalog from the CatalogTools component. The repositoryKey property is typically set through a hidden input field in the search form. This property is included in ATG Business Commerce. but if you have ATG Consumer Commerce installed you will have to add it as detailed in Converting from Standard to Custom Catalogs. For ATG Consumer Commerce. The custom catalogs feature assumes the existence of a catalog property for the user repository item. Assigning a Custom Catalog to a User In order for a user to view a custom catalog. they must have that catalog assigned to them. If you don’t set repositoryKey. the parent organization’s setting is ignored. You can do this by setting the search form handler’s repositoryKey property to the name that identifies the repository you want to search. the standard catalog repository is used.locale"/>' type="hidden" bean="MySearchFormHandler.ATG Commerce Programming Guide µ The CatalogTools component includes a property called alternateRepositories that lets you specify a mapping between symbolic names (called repository keys) and alternative repositories to use as the product catalog. as in this example: <dsp:input value='<dsp:valueof bean="Profile. For ATG Business Commerce.

µ ATG Commerce Programming Guide 102 5 .Using Custom Catalogs .

Each service keeps in memory a history of all information. Each service has the following configurable property values 103 6 . This prevents services that use the same lock name from executing simultaneously on the same server. Batch Services Dynamic Services Note that some of these services are available only for custom catalogs. others for both standard and custom catalogs. They are: • • • • AncestorGeneratorService CatalogVerificationService CatalogUpdateService CatalogMaintenanceService Each service performs functions that can be selectively executed using the function names. They are exposed through a set of API. It also verifies the relationships of catalog repository items and properties. using the global lock management. These services are collectively referred to as the Catalog Maintenance System (CMS). For more information see Running the Batch Services from the Commerce Admin Page. All batch services can be run on demand or in scheduled mode.Using the Catalog Maintenance System . getErrorMessages. Each service creates a global lock at the start of execution. warning and error level messages. Batch Services There are four services that facilitate the updating of the catalog in batch mode. getWarningMessages.ATG Commerce Programming Guide µ 6 Using the Catalog Maintenance System ATG catalogs use several batch and dynamic services to perform catalog updates and to verify catalog relationships. and releases it upon completion. The CMS updates property values that enable navigation and hierarchical search. They can be viewed using the View Status option on the Commerce Administration Page. or other servers in the cluster. getInfoMessages and getCurrentMessage.

These messages are used for the maintenance log display on the Commerce Administration pages. It can be any of the functions exposed by the availableFunctions property. Default is true.µ Property schedule ATG Commerce Programming Guide Description Schedule on which the service will execute. Function names are used to identify specific processes that can be performed by the service such as.Using the Catalog Maintenance System . the service will schedule itself accordingly when it is first instantiated. availableFunctions functionsToPerformBy Default saveMessages maxItemsPerTransacti on jobName jobDescription lockTimeOut lockName AncestorGeneratorService Component: /atg/commerce/catalog/custom/AncestorGeneratorService (for custom catalogs) or /atg/commerce/catalog/AncestorGeneratorService (for standard catalogs) The AncestorGeneratorService updates the following property values for each of the catalog item types. Can be set to true or false. 104 6 . AGS_GENCATALOGS to generate ancestor catalogs. The scheduler job name used when the service is scheduled. This property is used to configure a default set of function names that are executed when none are provided. the info. or through the Java API. AGS_GENANCESTORS to generate ancestor categories. error. The name used for the global lock. The scheduled job description. such as in schedule mode. A list of function names that the service can perform. This can be used in the case of very large catalogs to spread updates across several transactions. This service must be executed after making catalog updates in order for catalog navigation and search to work correctly. If true. If this property is valued. The number of repository items that are updated before restarting the transaction. and warning messages from the last execution of the service are retained in memory. Time in milliseconds before a timeout when acquiring the global lock.

ATG Commerce Programming Guide µ Item Type Categories: Property Names catalogs catalog ancestorCategories catalogs ancestorCategories parentCategoriesForCatalog catalogs ancestorCategories Products: SKUs: Available Functions AGS_GENCATALOGS: generates the catalog and catalogs properties AGS_GENPARENTCATS: generates the parentCategoriesForCatalog property AGS_GENANCESTORS: generates the ancestorCategories property CatalogVerificationService Component: /atg/commerce/catalog/custom/CatalogVerificationService The CatalogVerificationService verifies/validates various relationships between catalog items. Item Type Catalogs Property Names ancestorCategories allRootCategories directAncestorCatalogsAndSelf indirectAncestorCatalogs subCatalogs (only if configured to use. It validates the following property values for each catalog item type. See CatalogUpdateService computeSubCatalogs) fixedRelatedCategories categoryInfos parentCategory Categories Products fixedRelatedProducts catalogsRelatedProducts productInfos parentCategoriesForCatalog fixedReplacementProducts catalogsReplacementProducts skuInfos SKUs 105 6 .Using the Catalog Maintenance System .

This service updates the following property values for each of the catalog item types. Item Type Catalog Property Names directAncestorCatalogsAndSelf indirectAncestorCatalogs ancestorCategories allRootCategories subCatalogs(optional) parentCatalog parentCategory Categories Available Functions CUS_UPDATECATALOGS: Updates all item properties in the catalog CatalogMaintenanceService Component: /atg/commerce/catalog/CatalogMaintenanceService This component is an extension of a standard batch service. It is a container of other batch maintenance services.Using the Catalog Maintenance System . you can run this service immediately after the import to compute all properties. 106 6 .µ Available Functions ATG Commerce Programming Guide CVS_VERIFYCATALOGS: verifies catalog item properties CVS_VERIFYCATEGORIES: verifies category item properties CVS_VERIFYPRODUCTS: verifies product item properties CVS_VERIFYSKUS: verifies SKU item properties CatalogUpdateService Component: /atg/commerce/catalog/custom/CatalogUpdateService The CatalogUpdateService updates the same catalog properties that are updated by the dynamic service CatalogCompletionService. this service can be used to batch update them on an as-needed basis. but in batch mode. If you use startSQLRepository to import catalog data. which can afterwards be maintained by CatalogCompletionService. This service can be run in a versioned ATG instance. It provides a single point of access to other batch services and a consolidated view of their processing results. Because the CatalogCompletionService can be disabled and may not be actively updating the catalog property values in real time.

It can be any of the function names exposed by the availableFunctions property. A consolidated list of all the availableFunctions provided by the contained services. such as in schedule mode. Therefore. and skuInfo). productInfo. Note that the viewable history log is maintained only in memory and is discarded after a recycle of the ATG server. the component’s important property is extraTriggeringAffectedItemDescriptors. product. For example: extraTriggeringAffectedItemDescriptors+=myCustomDesc1. see the ATG Content Administration Programming Guide. If null. this service can be scheduled to sequentially execute other services it contains. the CatalogMaintenanceHelper listens for changes to standard catalog items (catalog. By default.ATG Commerce Programming Guide µ The CatalogMaintenanceService exposes the history log for each of its registered services. Functions from any of the contained services can be selectively executed using the CatalogMaintenanceService. you can add them to this property.myCustomDesc2 For general information on ATG Content Administration. The ATG logs can be used as a historical reference to the service logs. the standard catalog repository is updated. In the case of the CatalogMaintenanceService this property can contain any of the function names exposed by the contained services. If you have created custom subtypes based on these item types. This component is used by installations that use ATG Content Administration to manage their catalogs. category. A list of catalog keys that will be updated. such as categories and products. sku.Using the Catalog Maintenance System . Additional property information: Property availableServices Description An array of Nucleus paths to each contained service component. or through the Java API. The CatalogMaintenanceService has a related /atg/epub/CatalogMaintenanceHelper component. which can be viewed from the Commerce Administration pages. so that changes to these item types can also trigger catalog maintenance services. it listens for ATG Content Administration deployments and runs catalog maintenance services automatically. categoryInfo. For ATG Commerce purposes. as opposed to scheduling each service individually. Each component is resolved by path and added to the servicesMap property. catalogRepositories availableFunctions functionsToPerformBy Default Available Functions 107 6 . This property is used to configure a default set of function names that are executed when none are provided.

For example. Catalog Update. click on the Basic Catalog Maintenance link. However. products. you must configure one agent server on your target site cluster to run the Catalog Maintenance Service. For more information. Click on the Start Process button at the bottom of the Verify Catalog page. The catalog batch maintenance services are available from the Commerce Administration page. it should be run after adding new categories. The default configuration runs all the functions of the AncestorGeneratorService and CatalogVerificationService. Click on the Start Process button at the bottom of the Basic Catalog Maintenance page. The default is to run all the functions of the CatalogUpdateService. Basic Catalog Maintenance and View Status.µ All functions available to the contained services. For more information on accessing the Dynamo Administration UI. To run Basic Catalog Maintenance from the Commerce Administration Page. Click on the Start Process button at the bottom of the Catalog Update page. The default is to run all the functions of the CatalogVerficationService. if the DCS catalog is updated outside of these processes or if the CatalogCompletionService is disabled. There are four options available on the menu. Basic Catalog Maintenance This process will execute the standard batch maintenance services against the DCS catalog. 108 6 . see the ATG Installation and Configuration Guide. ATG Commerce Programming Guide Running the Batch Services from the Commerce Admin Page Catalog Maintenance batch services should be run the in the staging environment. Important note: If you are using custom catalogs and are running ATG Content Administration. click on the Catalog Update link. To run CatalogVerficationService from the Commerce Administration Page. or SKUs. this process should be used to batch update the appropriate property values. Catalog Verification This process verifies catalog component relationships for accuracy. They should be run after any structural changes are made to the catalog. Catalog Update This CatalogUpdateService will batch update the catalog property values that are normally updated incrementally by the CatalogCompletionService. When this service is enabled all updates to the catalog that are made using the ACC or the Repository API will trigger these properties to be computed and updated dynamically.Using the Catalog Maintenance System . To run CatalogUpdateService from the Commerce Administration Page. see the Getting Started chapter of the ATG Merchandising User Guide. click on the Verify Catalog link. Catalog Verification.

Select the Methods tab. Choose File > Open Component. The Component Editor opens. either /atg/commerce/catalog/custom/CatalogMaintenanceService (for custom catalogs) or /atg/commerce/catalog/CatalogMaintenanceService(for standard catalogs). To view the status log from the Commerce Administration Page. click on the View Status link. The status from the last execution displays. errors and warnings from the last execution of maintenance on the server. In the Components > by Path window.ATG Commerce Programming Guide µ View Status The View status page let you view the information. For example: Running a Batch Service from the ACC To use the ACC to execute a service 1. select the component by path.Using the Catalog Maintenance System . 3. choose Component > Start Component. 4. 109 6 . If the component is not currently running. 2.

µ 5. The execution of the CatalogMaintenanceService is started in a new thread. This form handler executes the CatalogMaintenanceService. then the View Status page is shown. BCC user. As each 110 6 . • • • CatalogChangesListener CatalogCompletionService StandardCatalogCompletionService CatalogChangesListener Component: /atg/commerce/catalog/custom/CatalogChangesListener (for custom catalogs) or /atg/commerce/catalog/CatalogChangesListener (for standard catalogs) This component registers itself at deployment as a property changed listener for the product catalog. It is notified for each repository change made to a category or catalog item in the product catalog. Property information: Property basicMaintenanceFunctions Description These are the function names passed to the CatalogMaintenanceService for the execution of the Basic Catalog Maintenance option These are the function names passed to the CatalogMaintenanceService for the execution of Verify Catalog option These are the function names passed to the CatalogMaintenanceService for the execution of Update Catalog option verifyFunctions updateFunctions Dynamic Services Dynamic Services consists of components that enable the catalog properties to be dynamically updated as the catalog structure is modified by an ACC user.Using the Catalog Maintenance System . The View Status can be refreshed to monitor the progress of the batch maintenance run. passing a configurable set of functions for each available option. Batch Maintenance Form Handler Component: /atg/commerce/catalog/RunServiceFormHandler There is one form handler that is used to execute the batch services from the Commerce Administration Pages. ATG Commerce Programming Guide Click the Invoke button next to the performService method. or a program using the Repository API.

Running the Dynamic Services The dynamic service components are started automatically. The CatalogUpdateService also refers to this property to control updating of the subCatalogs property in real time. The StandardCatalogCompletionService updates the parentCategory property for product and category items. CatalogCompletionService Component: /atg/commerce/catalog/custom/CatalogCompletionService (for custom catalogs) or /atg/commerce/catalog/CatalogCompletionService (for standard catalogs) This component updates catalog item property values in real time based on changes made to the product catalog repository. If the parentCategories list is empty. the parentCategory of the new child is automatically set to the new parent if the child’s parentCategory property is null. the service checks the former child’s parentCategory. Additional property information: Property computeSubCatalogs Description If true. It is called by the CatalogChangesListener when changes are made to the product catalog repository. When a product or category is made a child of another category. and assigns the first category in the list as the new parentCategory. the service checks the former child’s parentCategories property. it calls the CatalogCompletionService to make dynamic updates to the appropriate catalog item property values.Using the Catalog Maintenance System .ATG Commerce Programming Guide µ change is made. You can disable the CatalogCompletionService or the StandardCatalogCompletionService by setting the service’s 111 6 . the catalog item’s subCatalogs property will be updated. When a product or category is removed as a child from a category. Enabled True/False StandardCatalogCompletionService Component: /atg/commerce/catalog/StandardCatalogCompletionService This component updates catalog item property values in real time based on changes made to the product catalog repository. parentCategory is set to null. The subCatalogs property is no longer used by custom catalogs. but remains available for backward compatibility. It is called by the CatalogChangesListener when changes are made to the product catalog repository. If parentCategory is set to the category that is no longer the parent. Refer to the CatalogUpdateService for a list of properties that are maintained by this service.

the components still start up with ATG Commerce. 112 6 .Using the Catalog Maintenance System . If you set the enabled property to false. but they do not do anything if called.µ ATG Commerce Programming Guide enabled property to false.

Associated with the user definition is an item type created for contact information (contactInfo) which encapsulates fields such as address. city. Profile Tools and Property Manager Extensions: Describes the extensions related to the ATG Commerce profile tools. promotions. It is located in /atg/userprofiling/ProfileAdapterRepository. Components of ATG Commerce rely on these extensions to perform their logic. In this adapter. Removing or modifying the profile additions may require modifying logic in ATG Commerce. • • Profile Repository Extensions The Personalization module’s Profile Repository is an instance of the Generic SQL Adapter. date of birth and home address.ATG Commerce Profile Extensions . such as first and last name. See the Standard User Profile Repository Definition section of the Setting Up a Profile Repository chapter in the ATG Personalization Programming Guide for more information on the attributes included. credit card collection and other minor features. the Personalization module defines a base “user” Item Descriptor. wish lists. e-mail address. Promotions Three attributes manage promotions for each user: 113 7 . promotions. which provide additional methods to access commerce specific profile properties such as shipping and billing addresses and credit card information. which provides additional access to profile property names specific to Commerce customers that are used by CommerceProfileTools. state.ATG Commerce Programming Guide µ 7 ATG Commerce Profile Extensions ATG Commerce extends the profile configuration and classes of the Personalization module in several ways to add functionality. Also describes the extensions related to the ATG Commerce Property Manager. address books. credit card collection and other features. postal code. Profile Form Handler Extensions: Describes the ATG Commerce profile form handler extensions. phone number. wish lists. This chapter includes information on the following subjects: • Profile Repository Extensions: Describes the attributes that ATG Commerce adds to the user Item Descriptor to support gift lists. This user has many general attributes defined. ATG Commerce adds several attributes to the user Item Descriptor to support gift lists. address books.

shippingAddress and secondaryAddresses. Giftlists: Stores the list of gift lists created by a user when they register an event. 114 7 . inactivePromotions: Stores promotions that can no longer be used. The billing and shipping address is a contactInfo and the secondary addresses are a map of contactInfo objects. A promotion would be moved into the inactive list if it was created with a limited number of uses and the user had reached the threshold. A credit card includes the following attributes: • • • • • • creditCardNumber creditCardType expirationMonth expirationDayOfMonth expirationYear billingAddress The user definition includes defaultCreditCard and creditCards map attribute.ATG Commerce Profile Extensions . which defines the getPricingModels method. It is intended that the billingAddress and shippingAddress attributes are for “default” address values for the user. ATG Commerce Programming Guide activePromotions: Stores the list of promotions that can be used by the user in usedPromotions: Stores any promotions used in an order.pricing. The session-scoped PricingModelHolder component (/atg/commerce/pricing/UserPricingModels) asks the item.PricingEngine interface. tax and order pricing engines to retrieve what promotions should be available for pricing. The user can create nicknames for other addresses and store those as the key/value pairs in the secondaryAddresses map. The implementation of this method returns a combined collection of global and user promotions. Each pricing engine implements the atg. Address Books Three attributes are defined as part of the address book: billingAddress. which comes from the activePromotions attribute. Credit Card Collection The Commerce profile extensions also include defining a new credit-card item type. Gift Lists and Wish List Three attributes manage gift lists for each user: • • Wishlist: Stores the index to the default wish list created for a user. Each of these collection attributes has a component item type of ‘promotion’ which is defined in the Product Catalog repository /atg/commerce/catalog/ProductCatalog. shipping.µ • • • pricing their orders.commerce.

Profile Tools and Property Manager Extension The ATG Commerce profile tools class (atg. Other Features The following list contains some other attributes that are used through out the commerce system. some items are backorderId).CommerceProfileTools) is a subclass of atg.userprofiling.ATG Commerce Programming Guide µ • OtherGiftlists: Stores the list of gift lists from which a customer is currently shopping. It provides additional methods to access commerce specific profile properties such as shipping and billing addresses and credit card information.CommerceProfileFormHandler) is a subclass of atg. the anonymous user’s active promotions are copied into the list of active promotions of the persistent user.commerce. For example. postCreateUser and postLoginUser methods from the ProfileFormHandler. These operations are performed by overriding the addPropertiesOnLogin.profile. an anonymous user can accumulate promotions in their activePromotions attribute. you can give the customer the option of allowing a shipping group to be automatically split if some items cannot be shipped together (e. If your site supports multiple shipping groups. see the Configuring Merchandising Services chapter. During the registration and login process. During login. In the associated JSPs use a <setvalue> call to set the current location. The giftlist repository is located in /commerce/gifts/Giftlists.ProfileTools. After log in. These are registries of other customers that have been accessed by the customer using the gift list search feature. currentLocation: This is an enumerated attribute to be used with targeting.profile.ATG Commerce Profile Extensions . If the user’s persistent profile contains any old shopping carts (Orders in an incomplete state).g. any shopping carts (Orders) created before logging in are changed to be persistent. For example.currentLocation" value="home"/> Profile Form Handler Extensions The ATG Commerce profile form handler (atg. the PricingModelHolder component is reinitialized to cache all the promotions that the persistent user has accumulated during previous sessions. <dsp:setvalue bean="Profile.ProfileFormHandler. It performs operations specific to Commerce. Each attribute has a component item type of gift-list defined in the Giftlist Repository.userprofiling.commerce. • allowPartialShipment: This Boolean value can be used as the user’s default setting for allowing partial shipments. • • daytimeTelephoneNumber: The user’s daytime telephone number. For more information on gift lists and wish lists. The ATG Commerce 115 7 . See the Configuring the Order Fulfillment Framework chapter for information on allowing partial shipments. these shopping carts are loaded into the user’s session.

delete and update profile repository shipping addresses as well as to retrieve all shipping addresses. The shipping address property names are stored in CommercePropertyManager. It provides additional access to profile property names specific to Commerce customers that are used by CommerceProfileTools. This provides a convenient central location to store property names that may change depending on the site. 116 7 . These different shipping addresses are managed by the CommerceProfileTools component. This extension of the tools component provides methods to create. For example.commerce.PropertyManager.µ ATG Commerce Programming Guide Property Manager (atg.ATG Commerce Profile Extensions .userprofiling.CommercePropertyManager) is a subclass of atg.profile. a registered Commerce customer may have multiple shipping addresses.

Configuring Merchandising Services . The following scenarios demonstrate how gift lists can be used on a commerce site. Example of Using a Gift List The following scenario describes how a site customer can use a gift list while shopping on the Pioneer Cycling Store Web site. Customers can access their wish lists every time they log into their accounts. This section describes how to implement these lists. such as birthdays or weddings. Gift lists can be used in two ways: • As gift lists Gift lists are lists of products that other site visitors can view. As wish lists Customers can use wish lists to save lists of products without placing the items in their shopping carts.commerce. Refer to the ATG API Reference for more information on the associated classes and programming interfaces. and they can purchase items from their wish lists at any time. This section describes how to implement comparison lists. for example. Setting Up Gift Lists and Wish Lists Gift lists are lists of items selected by a site visitor. Customers can use gift lists to register for events. Customers c an create an unlimited number of gift lists for themselves. A wish list is actually a gift list that is accessible to only the person who created it. address security. All customers have one default wish list. • The gift list class package is atg.gifts. Setting Up Product Comparison Lists Comparison lists enable customers to make side-by-side comparisons of different products and SKUs. Joseph Smith logs onto the site and creates a list of gifts he would like to receive 117 8 .ATG Commerce Programming Guide µ 8 Configuring Merchandising Services This chapter includes the following information on ATG Commerce merchandising services: Setting Up Gift Lists and Wish Lists Customers can use gift lists and wish lists to create lists of items for future purchase. and shipping. wrapping. Part of the purchase process allows for special handling instructions for gift purchasing. Setting Up Gift Certificates and Coupons Enables customers to purchase and use gift certificates and redeem coupons.

Sally can add the items to her default private wish list and save the list. Example of Using a Wish List The following scenario describes how a site customer uses a wish list while shopping on the Pioneer Cycling Store Web site. or event type. • Gift List Form Handlers and Gift List Servlet Beans: The form handlers and servlet beans provide an interface to the Giftlists repository. then visits the site and searches for “Joseph Smith. event name. They provide an interface between the customer and the manager classes with access to the Giftlists repository.µ ATG Commerce Programming Guide for his birthday. This section describes the components that are used to support this functionality. Forms (or JSPs) use these handlers to take input from the user and call methods to perform actions on the Giftlists repository. However. The business layer classes access the gift lists through the repository layer. Mike selects the correct list and views the items that Joseph selected. Gift List Repository: The repository definition maps the Giftlists repository to database tables. browses the store and finds a bike and many accessories she would like to purchase. you can extend this functionality if needed.” Mike can use advanced search criteria to refine his search by including a state. The next time she visits the site. A customer. Mike sees that Joseph needs two new inner tubes for his bike. Joseph’s friend. It serves only as a holder of items the customer has found. she can view her wish list. These classes consist of a GiftlistManager and GiftlistTools. Gift List Business Layer Classes: Business layer classes contain the logic for gift list creation and manipulation. They provide the interface between the UI and the business layer classes to create and edit gift lists. Each of these sub-areas is described in detail later in this section. The remaining items are saved in the wish list for later visits. Disable the repository if you are not going to use the gift list functionality. She can buy the bike and helmet by moving them to her shopping cart. these components support adding an item from a gift list to a shopping cart and updating the Giftlists repository at checkout. Mike.Configuring Merchandising Services . • • • • • Gift List Form Handlers Form handlers process forms and pages. Mike can see that someone has already purchased one of the inner tubes. This section describes what steps to take if extending the system is necessary. The store returns a list of gift lists found. The gift list functionality is broken down into the following sub-areas. Sally. Disabling the Gift List Repository: Describes how to disable the Giftlists repository. but can not afford to buy at the time. The gift list now reflects that two inner tubes have been purchased for Joseph. Purchase Process Extensions to Support Gift Lists: The purchase process has been extended to support purchasing gifts from published gift lists. For example. A wish list is not searchable or visible by other customers of the store. For more 118 8 . Mike decides to purchase the other inner tube for Joseph and adds it to his cart. During the checkout process. Mike can send the item to his own address or send it directly to Joseph. Extending gift list functionality: Gift list functionality provided in ATG Commerce supports most requirements of commerce sites.

Both success and failure URL properties are provided. Giftlist properties to store information entered by the customer to use for management of attributes. CommerceProfileTools Giftlist properties (for example. eventDate. The tools component to provide low level operations on the commerce specific profile. update and delete gift lists. GiftlistFormHandler Submit Handle Methods The GiftlistFormHandler has the following handle and support methods: 119 8 . should be session-scoped because multiple pages usually gather the information needed for gift list management. (See GiftitemDroplet in Gift List Servlet Beans for information on how to remove items from gift lists. as well as to store success and failure URLs for redirect after processing. Property GiftlistManager CatalogTools Function The manager component to interface with the repository.) Properties in the handler are used to store user input for processing. as well as to add items to gift lists. The site customer should be able to enter information on different pages to configure the same gift list. like most form handlers. see the Working with Forms and Form Handlers chapter in the ATG Programming Guide and the Using Repository Form Handlers chapter in the ATG Page Developer’s Guide. eventName. This handler accepts input from the customer to create. Some handle methods have pre and post methods defined to simplify extending the methods to add functionality.ATG Commerce Programming Guide µ information on form handlers.Configuring Merchandising Services . description) Navigation properties Navigation properties are used to tell Dynamo to what pages to redirect after an action is performed. GiftlistFormHandler Properties The GiftlistFormHandler has the following properties that support the management of gift lists and items in the repository. This section describes the following gift list form handlers: • • GiftlistFormHandler GiftlistSearch GiftlistFormHandler The GiftlistFormHandler provides the primary interface between the customer and the Giftlists repository. The tools component to provide low level operations on the catalog. The GiftlistFormHandler.

handleSaveGiftlist handleUpdateGiftlist preAddItemToGiftlist preSaveGiftlist postAddItemToGiftlist postSaveGiftlist 120 8 . The default implementation is empty. Creates and saves gift lists in the Giftlists repository. save properties and add the gift list to the customer’s profile. Executed at the end of the handleSaveGiftlist method.µ Method handleAddItemToGiftlist ATG Commerce Programming Guide Function Adds items to a gift list during the shopping process. quantity and giftlistId from the form. This method provides a way to extend the functionality of this form handler. Updates the current gift list. If it does. Then it checks if the item already exists in the giftlist. Deletes a gift list from the user’s profile and from the repository. The default implementation is empty. It calls removeGiftlist in the manager class with the profileId and giftlistId to remove it from the repository. Executed at the start of the handleAddItemToGiftlist method. This method provides a way to extend the functionality of this form handler. This method provides a way to extend the functionality of this form handler. It calls updateGiftlist in the manager class with gift list properties to update a particular gift list in the repository. Executed at the end of the handleAddItemToGiftlist method. The default implementation is empty. It looks up the product in the repository by skuId.Configuring Merchandising Services . This method provides a way to extend the functionality of this form handler. it adds the item to the gift list by calling addItemToGiftlist in the manager class with the correct parameters. This method performs a few steps to add the item. It calls createGiftlist in the manager class with gift list properties to create a gift list in the repository. It takes the skuId. Executed at the start of the handleSaveGiftlist method. The default implementation is empty. it increments the desired quantity. If it does not. handleCreateGiftlist handleDeleteGiftlist Creates a new Giftlist object.

This file is located at /atg/commerce/gifts/ in <ATG9dir>/DCS/config/config./user/lists.Configuring Merchandising Services . The GiftlistFormHandler has a set of properties you can use to control navigation after a form operation. Each operation has its own SuccessURL and ErrorURL properties. you could redirect the customer to a page explaining what missing information caused the failure.ATG Commerce Programming Guide µ GiftlistFormHandler Navigation Properties After a form operation (createGiftlist. The properties available include the following: • • • • • • • • createGiftlistSuccessURL createGiftlistErrorURL saveGiftlistSuccessURL savlleGiftlistErrorURL deleteGiftlistSuccessURL deleteGiftlistErrorURL addItemToGiftlistSuccessURL addItemToGiftlistErrorURL The value of each of these properties is a URL relative to the action page of the form. Either you can specify the values of these URL properties in the properties of the form handler or you can set them in the JSP itself using a hidden tag attribute. This page’s content depends on the type of form operation and whether the operation succeeded or not.properties file is used to configure the GiftlistFormHandler. If the value for a particular condition is not set.jsp " type="hidden"/> GiftlistFormHandler Example The GiftlistFormHandler..gifts.defaultLocale # Giftlist repository 121 8 . if an attempt to create a gift list fails. saveGiftlist. you can set the addItemToGiftlistSucessURL property with this tag: <dsp:input bean="GiftlistFormHandler.GiftlistFormHandler $scope=session # Profile properties profile=/atg/userprofiling/Profile defaultLocale^=/atg/commerce/pricing/PricingTools. no redirect takes place and the form is left on the page defined as the action page.jar.addItemToGiftlistSucessURL" value=". For example.commerce. you can redirect the customer to pages other than those specified by the form’s action attribute. addItemToGiftlist) is completed. $class=atg. For example. These properties specify the URLs to which to redirect on certain error and success conditions.

µ
giftlistRepository=Giftlists # Business layer giftlist manager giftlistManager=GiftlistManager

ATG Commerce Programming Guide

# Business layer order manager orderManager=/atg/commerce/order/OrderManager shoppingCart=/atg/commerce/ShoppingCart pipelineManager=/atg/commerce/PipelineManager # commerce tools giftlistTools=GiftlistTools catalogTools=/atg/commerce/catalog/CatalogTools profileTools=/atg/userprofiling/ProfileTools # giftlist properties itemType=gift-list

The following code sample demonstrates how to use the GiftlistFormHandler in a template. This serves as an example of how to display error messages, set up input and URL properties and make calls to handle methods in the form handler.

<!-Import statements for components--> <dsp:importbean <dsp:importbean <dsp:importbean <dsp:importbean <dsp:importbean bean="/atg/commerce/gifts/GiftlistFormHandler"/> bean="/atg/dynamo/droplet/ForEach"/> bean="/atg/dynamo/droplet/Switch"/> bean="/atg/dynamo/droplet/IsEmpty"/> bean="/atg/userprofiling/Profile"/>

<!-- Display any errors processing form --> <dsp:droplet name="/atg/dynamo/droplet/Switch"> <dsp:param bean="GiftlistFormHandler.formError" name="value"/> <dsp:oparam name="true"> <font color=cc0000><STRONG><UL> <dsp:droplet name="/atg/dynamo/droplet/ErrorMessageForEach"> <dsp:param bean="GiftlistFormHandler.formExceptions" name="exceptions"/> <dsp:oparam name="output"> <LI> <dsp:valueof param="message"/> </dsp:oparam> </dsp:droplet> </UL></STRONG></font> </dsp:oparam> </dsp:droplet> <!-Save giftlist --> <dsp:form action="lists.jsp" method="POST"> <!-Success and error URLs -->

122
8 - Configuring Merchandising Services

ATG Commerce Programming Guide

µ

<dsp:input bean="GiftlistFormHandler.saveGiftlistSuccessURL" value="./lists.jsp" type="hidden"/> <dsp:input bean="GiftlistFormHandler.saveGiftlistErrorURL" value="./new_list.jsp" type="hidden"/> <b>Event Name</b><br> <input size="40" value='<dsp:valueof bean="GiftlistFormHandler.eventName"/>' type="text"> <p> <b>Event Type</b> <dsp:select bean="GiftlistFormHandler.eventType"> <dsp:droplet name="ForEach"> <dsp:param bean="GiftlistFormHandler.eventTypes" name="array"/> <dsp:oparam name="output"> <dsp:getvalueof id="option76" param="element" idtype="java.lang.String"> <dsp:option value="<%=option76%>"/> </dsp:getvalueof><dsp:valueof param="element">UNDEFINED</dsp:valueof> </dsp:oparam> </dsp:droplet> </dsp:select><br> <p> <b>Event Description</b><br> <dsp:setvalue bean="GiftlistFormHandler.description" value=""/> <dsp:textarea bean="GiftlistFormHandler.description" value="" cols="40" rows="4"></dsp:textarea> <p> <b>Where should people ship the gifts?</b><p> <dsp:select bean="GiftlistFormHandler.shippingAddressId"> <!-display address nicknames for profile to select from --> <dsp:droplet name="ForEach"> <dsp:param bean="GiftlistFormHandler.addresses" name="array"/> <dsp:oparam name="output"> <dsp:getvalueof id="option117" param="key" idtype="java.lang.String"> <dsp:option value="<%=option117%>"/> </dsp:getvalueof><dsp:valueof param="element">UNDEFINED</dsp:valueof> </dsp:oparam> </dsp:droplet> </dsp:select><br> <table width=100% cellpadding=0 cellspacing=0 border=0> <tr><td class=box-top-store>Gift list public?</td></tr></table> <p> <dsp:input bean="GiftlistFormHandler.isPublished" value="true" type="radio" name="published"/> Make my list public now<br> <dsp:input bean="GiftlistFormHandler.isPublished" value="false" checked="<%=true%>" type="radio" name="published"/> Don't make my list public yet <dsp:input bean="GiftlistFormHandler.saveGiftlist" value="Save gift list" type="submit"/>

123
8 - Configuring Merchandising Services

µ
GiftlistSearch

ATG Commerce Programming Guide

The GiftlistSearch form handler searches the repository for gift lists. The handler uses input from the customer, such as owner name, event name, event type and state, to find gift lists published by other customers. It returns a list of gift lists that match the given criteria. Like most form handlers, GiftlistSearch should be session-scoped because multiple pages are typically involved in gathering and displaying information for gift list searching. This form handler uses supporting servlet beans to add the retrieved gift lists to the customer’s profile and to display gift list contents.
GiftlistSearch is configurable to support all gift list searching requirements. Booleans specify what

searching is done. The configurable searches include: • • • Name Search: Searches by the name of the gift list owner. Properties Search: Searches for matches of specific gift list properties (such as event name, event type, and owner’s state). Published List Search: Searches for both published and unpublished gift lists by turning doPublishedSearch to false in the configuration file.

GiftlistSearch Properties
GiftlistSearch has the following properties to support gift list searching:

Property
doNameSearch doAdvancedSearch

Function Specifies if searching by name. Specifies if searching gift lists by advanced properties. Advanced search property names. Specifies if searching only published gift lists. Input text parsed for searching.
Giftlist repository items found based on

advancedSearchPropertyNames doPublishedSearch searchInput searchResults

searching criteria.

GiftlistSearch Submit Handle Methods
GiftlistSearch has the following handle submit method:

124
8 - Configuring Merchandising Services

ATG Commerce Programming Guide

µ

Method
handleSearch

Function
handleSearch provides the core functionality of this form. It uses the

configuration set in the properties file to build its query string. This method builds the query based on the configuration and applies it to the Giftlists repository to find a list of gift lists. The list is stored in the results property for the form to display.

GiftlistSearch Example The following properties file is used to configure the GiftlistSearch form handler. This properties file is located at /atg/commerce/gifts/GiftlistSearch.properties in /<ATG9dir>/DCS/config/config.jar.

$class=atg.commerce.gifts.SearchFormHandler $scope=session doNameSearch=true nameSearchPropertyNames=owner.firstName,owner.lastName doAdvancedSearch=true advancedSearchPropertyNames=eventType,eventName,state doPublishedSearch=true publishedSearchPropertyNames=public,published giftlistRepository=Giftlists itemTypes=gift-list

The following code sample demonstrates how to use GiftlistSearch in a template. It is only one example of how it might be used to search for gift lists.
giftlist_search.jsp:

<!-Import statements for form components> <dsp:importbean bean="/atg/commerce/gifts/GiftlistSearch"/> <dsp:importbean bean="/atg/dynamo/droplet/IsEmpty"/> <dsp:importbean bean="/atg/dynamo/droplet/ForEach"/> <dsp:importbean bean="/atg/dynamo/droplet/Switch"/> <TITLE>Giftlist Search</TITLE> <dsp:form action="giftlist_search.jsp"> <p> <b>Find someone's gift list</b> <hr size=0>

125
8 - Configuring Merchandising Services

µ

ATG Commerce Programming Guide

Name: <dsp:input bean="GiftlistSearch.searchInput" size="30" type="text"/> <p> Optional criteria that may make it easier to find the right list: <p> <dsp:droplet name="ForEach"> <!-- For each property specified in GiftlistSearch.advancedSearchPropertyNames, retrieve all possible property values. This allows the customer to pick one to search on for advanced searching. --> <dsp:param bean="GiftlistSearch.propertyValuesByType" name="array"/> <dsp:oparam name="output"> <dsp:droplet name="Switch"> <dsp:param param="key" name="value"/> <!-- One property that a product in the store can have is weight range. In this case, if the property is weight range, we want to put all possible choices in a pulldown menu. --> <dsp:oparam name="eventType"> Event Type <!-- property to store the customer's selection is propertyValues -> <dsp:select bean="GiftlistSearch.propertyValues.eventType"> <dsp:option value=""/>Any <dsp:setvalue paramvalue="element" param="outerelem"/> <dsp:droplet name="ForEach"> <dsp:param param="outerelem" name="array"/> <dsp:oparam name="output"> <dsp:option/><dsp:valueof param="element">UNDEFINED</dsp:valueof> </dsp:oparam> </dsp:droplet> </dsp:select><br> </dsp:oparam> <dsp:oparam name="eventName"> <b>Event Name <!-- property to store the customer's selection is propertyValues -> <dsp:input bean="GiftlistSearch.propertyValues.eventName" size="30" value="" type="text"/> <br> </dsp:oparam> <dsp:oparam name="state"> <b>State <!-- property to store the customer's selection is propertyValues -> <dsp:input bean="GiftlistSearch.propertyValues.state" size="30" value="" type="text"/> <br> </dsp:oparam> </dsp:oparam> </dsp:droplet> </dsp:droplet>

126
8 - Configuring Merchandising Services

ATG Commerce Programming Guide

µ

<p> <dsp:input bean="GiftlistSearch.search" value="Perform Search" type="hidden"/> <dsp:input bean="GiftlistSearch.search" value="Perform Search" type="submit"/> </dsp:form>

Gift List Servlet Beans
Several servlet beans are provided to support gift list and wish list functionality. These servlet beans can be used with forms to look up gift lists and gift items, as well as to perform actions, such as removing or purchasing items from a gift list, adding gift lists to a profile, and removing gift lists from a profile.

Lookup Servlet Beans
The GiftlistLookupDroplet and GiftitemLookupDroplet servlet beans, located in Nucleus at /atg/commerce/gifts/, are instances of class atg.repository.servlet.ItemLookupDroplet. These servlet beans provide a way to search for and display gift lists and gift items in the Giftlists repository based on ID. For information about the input, output, and open parameters of servlet beans instantiated from ItemLookupDroplet, refer to Appendix B: ATG Servlet Beans in the ATG Page Developer’s Guide. The following code example demonstrates how to use the GiftlistLookupDroplet to look up a gift list in the repository and check that the owner ID equals the ID of the current profile before displaying the gift list.

<dsp:droplet name="/atg/commerce/gifts/GiftlistLookupDroplet"> <dsp:param param="giftlistId" name="id"/> <dsp:oparam name="output"> <dsp:droplet name="IsEmpty"> <dsp:param param="element" name="value"/> <dsp:oparam name="false"> <dsp:setvalue paramvalue="element" param="giftlist"/> <dsp:droplet name="/atg/dynamo/droplet/Switch"> <dsp:param bean="Profile.id" name="value"/> <dsp:getvalueof id="nameval2" param="giftlist.owner.id" idtype="java.lang.String"> <dsp:oparam name="<%=nameval2%>"> </dsp:oparam> </dsp:getvalueof> </dsp:droplet> </dsp:oparam> </dsp:droplet> </dsp:oparam> </dsp:droplet>

127
8 - Configuring Merchandising Services

µ
GiftlistDroplet

ATG Commerce Programming Guide

The GiftlistDroplet servlet bean (class atg.commerce.gifts.GiftlistDroplet), which is located in Nucleus at /atg/commerce/gifts/, adds or removes customer A’s gift list from customer B’s otherGiftlists Profile property, depending on the action supplied via the action input parameter. GiftlistDroplet is used in the Pioneer Cycling Reference Application to associate and disassociate gift lists created by others to a given customer. This enables the given customer to easily find those for whom the customer has shopped or is shopping.
GiftlistDroplet takes the following input parameters:

• • •

action: The action to perform on the gift list (“add” or “remove”). (Required) giftlistId: The ID of the gift list. (Required) profile: The profile of the current customer. If not passed, the profile will be resolved

by Nucleus.
GiftlistDroplet doesn’t set any output parameters. It renders the following open parameters

(oparams): • •
output: The oparam rendered if the gift list is added or removed successfully from a

profile.
error: The oparam rendered if an error occurs while adding or removing the gift list.

The following code example demonstrates how to use the GiftlistDroplet to add a gift list that was retrieved in a search to a customer’s profile.

<dsp:droplet name="/atg/dynamo/droplet/IsEmpty"> <dsp:param param="giftlistId" name="value"/> <dsp:oparam name="false"> <dsp:droplet name="/atg/commerce/gifts/GiftlistDroplet"> <dsp:param param="giftlistId" name="giftlistId"/> <dsp:param value="add" name="action"/> <dsp:param bean="/atg/userprofiling/Profile" name="profile"/> <dsp:oparam name="output">Output</dsp:oparam> <dsp:oparam name="error">Error</dsp:oparam> </dsp:droplet> </dsp:oparam> </dsp:droplet>

GiftitemDroplet
Servlet beans instantiated from class atg.commerce.gifts.GiftitemDroplet enable customers either to buy or to remove items from their own personal gift lists, depending on the configuration of the servlet bean. (For information on how to add items to a personal gift list, see GiftlistFormHandler. For information on how to buy items from another’s gift list, see CartModifierFormHandler.) Two Commerce servlet beans have been instantiated from GiftitemDroplet; they are BuyItemFromGiftlist and RemoveItemFromGiftlist. They take the following input parameters, both of which are required:

128
8 - Configuring Merchandising Services

ATG Commerce Programming Guide

µ

• •

giftId: The ID of the gift. giftlistId: The ID of the gift list.

They don’t set any output parameters. They render the following open parameters: • •
output: The oparam rendered if the item is bought or removed successfully from list. error: The oparam rendered if an error occurs during processing.

The following code example demonstrates how to use the RemoveItemFromGiftlist component to remove an item from a customer’s personal gift list.

<dsp:droplet name="/atg/dynamo/droplet/IsEmpty"> <dsp:param param="giftId" name="value"/> <dsp:oparam name="false"> <dsp:droplet name="/atg/commerce/gifts/RemoveItemFromGiftlist"> <dsp:param param="giftlistId" name="giftlistId"/> <dsp:param param="giftId" name="giftId"/> </dsp:droplet> </dsp:oparam> </dsp:droplet>

Gift List Business Layer Classes
The business layer classes contain the logic for managing gift lists and items. The methods within these classes are used to create, update, and delete selected gift lists for a given customer. The business layer components are the interface to the Giftlists repository. All calls to modify a gift list are made through these classes. Business layer objects include the following three classes: GiftlistManager and GiftlistTools. •
GiftlistManager: The majority of the functionality for gift list management exists in the GiftlistManager component. The class contains such methods as createGiftlist, updateGiftlist, addItemToGiftlist and removeItemFromGiftlist. These methods are higher level than those in GiftlistTools. It calls methods in the tools object to perform the lower level functionality (for example, repository access, property update). GiftlistTools: The GiftlistTools component is the low level interface and contains the logic for creating and editing gift lists in the repository. GiftlistTools is usually not called directly. It is usually called by the manager class to perform functionality on gift lists. This class defines repository item descriptors and property names and uses them to make updates to the repository.

Because these classes do not contain any state, it makes sense for them to exist as globally-scoped services in ATG Commerce. Rather than constructing a new object when required, ATG Commerce places one instance of each into the Nucleus hierarchy to be shared. They can be found in the hierarchy under: • •
GiftlistTools - /atg/commerce/gifts/GiftlistTools GiftlistManager - /atg/commerce/gifts/GiftlistManager

129
8 - Configuring Merchandising Services

µ
Gift List Repository

ATG Commerce Programming Guide

Note: Gift lists use the ClientLockManager component to control locks on repository items. The ClientLockManager prevents a deadlock situation or data corruption that could occur when multiple customers update the same gift list. The ClientLockManager is located at /atg/dynamo/service/ClientLockManager. See the Using Locking in Fulfillment section of the Fulfillment Framework chapter for more information on the ClientLockManager.

The Giftlists repository is the layer between ATG Commerce and the database server. It provides an interface to the database layer to persist gift list information. The Giftlists repository is a part of the Profile Adapter Repository that uses the SQL Repository implementation. For more information on SQL repositories, see the ATG Repository Guide. The Giftlists repository is defined in two configuration files: •
giftlists.xml defines the repository. It is located in ATG Commerce configpath at /atg/commerce/gifts/. This XML file defines gift lists and gift list item descriptors.

The Repository API uses this definition to save information in the database. •
userProfile.xml defines the relationship between users and gift lists. It is located in ATG Commerce configpath at /atg/userprofiling/. It adds properties to the user that provide maps to wish lists and gift lists.

The manipulation of gift lists and gift list items is performed using the GiftlistManager described in the Gift List Business Layer Classes section. The GiftlistManager provides methods to create, save, and update gift lists, as well as ones to create gift list items, remove them and move them to the shopping cart. The following XML files show how the repository is configured and mapped to the database schema. This file is located at /atg/commerce/gifts/giftlists.xml in <ATG9dir>/DCS/src/config/config.jar.

<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE taglib PUBLIC "-//Art Technology Group, Inc.//DTD General SQL Adapter//EN" "http://www.atg.com/dtds/gsa/gsa_1.0.dtd"> <gsa-template> <header> <name>Commerce Giftlists</name> <author>DCS Team</author> <version>$Id: giftlists.xml,v 1.5 2000/05/12 06:22:00 kmoy Exp $</version> </header> <!--

130
8 - Configuring Merchandising Services

ATG Commerce Programming Guide

µ

************************************************************* GiftList (also gift registries) ************************************************************* --> <item-descriptor name="gift-list"> <table name="dcs_giftlist" type="primary" id-column-name="id"> <property name="id"/> <property name="owner" item-type="user" repository="/atg/userprofiling/ProfileAdapterRepository" column-name="owner_id"/> <property name="public" data-type="boolean" column-name="is_public" default="false"/> <property name="published" data-type="boolean" column-name="is_published" default="false"/> <property name="eventName" data-type="string" column-name="event_name"/> <property name="eventDate" data-type="timestamp" column-name="event_date"/> <property name="eventType" data-type="enumerated" default="other" column-name="event_type"> <attribute name="useCodeForValue" value="false"/> <option value="valentine's day" code="0"/> <option value="wedding" code="1"/> <option value="bridal shower" code="2"/> <option value="baby shower" code="3"/> <option value="birthday" code="4"/> <option value="anniversary" code="5"/> <option value="christmas" code="6"/> <option value="chanukah" code="7"/> <option value="other holiday" code="8"/> <option value="i just want this stuff" code="9"/> <option value="other" code="10"/> </property> <property name="comments" data-type="string" column-name="comments"/> <property name="description" data-type="string" column-name="description"/> <property name="instructions" data-type="string" column-name="instructions"/> <property name="lastModifiedDate" data-type="timestamp" column-name="last_modified_date"/> <property name="creationDate" data-type="timestamp" column-name="creation_date"> <attribute name="useNowForDefault" value="true"/> </property> <property name="shippingAddress" item-type="contactInfo" repository="/atg/userprofiling/ProfileAdapterRepository" column-name="shipping_addr_id"/> </table> <table name="dcs_giftlist_item" type="multi"

131
8 - Configuring Merchandising Services

µ

ATG Commerce Programming Guide

id-column-name="giftlist_id" multi-column-name="sequence_num"> <property name="giftlistItems" data-type="list" component-item-type="gift-item" column-name="giftitem_id" cascade="delete"/> </table> </item-descriptor> <item-descriptor name="gift-item" display-property="displayName"> <table name="dcs_giftitem" type="primary" id-column-name="id"> <property name="id" column-name="id"/> <property name="catalogRefId" data-type="string" column-name="catalog_ref_id"/> <property name="productId" data-type="string" column-name="product_id"/> <property name="displayName" data-type="string" column-name="display_name"/> <property name="description" data-type="string" column-name="description"/> <property name="quantityDesired" data-type="long" column-name="quantity_desired"/> <property name="quantityPurchased" data-type="long" column-name="quantity_purchased"/> </table> </item-descriptor> </gsa-template>

The following section of code describes how gift lists are added to the user profile. The entire file is located at /atg/userprofiling/userProfile.xml in <ATG9dir>/DCS/config/config.jar.

<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE taglib PUBLIC "-//Art Technology Group, Inc.//DTD General SQL Adapter//EN" "http://www.atg.com/dtds/gsa/gsa_1.0.dtd"> <gsa-template> <header> <name>Commerce Related Profile Changes</name> <author>DCS Team</author> <version>$Id: userProfile.xml,v 1.24 2000/05/03 03:51:19 petere Exp $</version> </header> <item-descriptor name="user" default="true" sub-type-property="userType">

132
8 - Configuring Merchandising Services

ATG Commerce Programming Guide

µ

<!-- this is the key into private giftlist --> <table name="dcs_user_wishlist" type="auxiliary" id-column-name="user_id"> <property name="wishlist" item-type="gift-list" repository="/atg/commerce/gifts/Giftlists" column-name="giftlist_id" cascade="insert,update,delete"/> </table> <!-- this is the key into user created giftlists --> <table name="dcs_user_giftlist" type="multi" id-column-name="user_id" multi-column-name="sequence_num"> <property name="giftlists" data-type="list" component-item-type="gift-list" repository="/atg/commerce/gifts/Giftlists" column-name="giftlist_id" cascade="delete"/> </table> <!-- this is the key into giftlists found for other customers --> <table name="dcs_user_otherlist" type="multi" id-column-name="user_id" multi-column-name="sequence_num"> <property name="otherGiftlists" data-type="list" component-item-type="gift-list" repository="/atg/commerce/gifts/Giftlists" column-name="giftlist_id"/> </table> </gsa-template>

Purchase Process Extensions to Support Gift Lists
The ATG Commerce purchase process supports features such as browsing the catalog, adding items to a shopping cart, selecting payment methods, entering billing and shipping information, and the entire checkout process. To also support purchasing gifts off a gift list, components in the order package (atg.commerce.order) have been extended. To understand how gift lists work in ATG Commerce, it is important to know which components in the order package support this functionality. This section describes how order management and the purchasing process have been extended to support gift lists. (See the Configuring Purchase Process Services chapter for more information on the purchase process.) The following components provide gift list functionality to the purchase process: • • • •
CartModifierFormHandler GiftlistHandlingInstruction ShippingGroupDroplet and ShippingGroupFormHandler ProcUpdateGiftRepository

133
8 - Configuring Merchandising Services

µ

ProcSendGiftPurchasedMessage

ATG Commerce Programming Guide

CartModifierFormHandler
atg.commerce.order.purchase.CartModifierFormHandler is one class that provides the functionality to support shopping carts and the purchase process in ATG Commerce. More importantly, the addItemToOrder method of CartModifierFormHandler provides support for purchasing items that appear on gift lists. CartModifierFormHandler and the addItemToOrder method are described in Understanding the CartModifierFormHandler in the Configuring Purchase Process Services chapter.

Adding a gift item to an order is virtually the same as adding any item to an order. A gift item is distinguished by two additional form input fields, CartModifierFormHandler.giftlistId and CartModifierFormHandler.giftlistItemId. When these two fields contain non-null values, addItemToOrder calls addGiftToOrder in the GiftListManager component, which does additional processing for the gift as required by the purchase process. The following code sample demonstrates how to use the CartModifierFormHandler in a template for gifts. It is an example of how to set up input and URL properties and make calls to handle methods in the form handler. In this example, a customer is purchasing an item from another customer’s gift list and adding it to the shopping cart.

<dsp:droplet name="/atg/commerce/gifts/GiftlistLookupDroplet"> <dsp:param param="giftlistId" name="id"/> <dsp:param value="giftlist" name="elementName"/> <dsp:oparam name="output"> <table cellpadding=0 cellspacing=0 border=0> <tr> <td class=box-top-store> Get this gift for <dsp:valueof param="giftlist.owner.firstName">someone</dsp:valueof> </td> </tr> <tr> <td class=box> <dsp:form action="<%=request.getRequestURI()%>" method="post"> <input value='<dsp:valueof param="Product.repositoryId"/>' type="hidden" name="id"> <input type="hidden" name="itemType" value="Product"> <input value='<dsp:valueof param="Product.repositoryId"/>' type="hidden" name="itemId"> <dsp:input bean="CartModifierFormHandler.addItemToOrderSuccessURL" value="../checkout/cart.jsp" type="hidden"/> <dsp:input bean="CartModifierFormHandler.productId" paramvalue="Product.repositoryId" type="hidden"/> <dsp:input bean="CartModifierFormHandler.giftlistId" paramvalue="giftlist.id" type="hidden"/> <dsp:input bean="CartModifierFormHandler.giftlistItemId"

134
8 - Configuring Merchandising Services

ATG Commerce Programming Guide

µ

paramvalue="giftid" type="hidden"/> <dsp:droplet name="/atg/commerce/gifts/GiftitemLookupDroplet"> <dsp:param param="giftId" name="id"/> <dsp:param value="giftitem" name="elementName"/> <dsp:oparam name="output"> <dsp:input bean="CartModifierFormhandler.catalogRefIds" paramvalue="giftitem.catalogRefId" type="hidden"/> <dsp:valueof param="giftlist.owner.firstName">firstname</dsp:valueof> wants <dsp:valueof param="giftitem.quantityDesired">?</dsp:valueof> <dsp:valueof param="giftitem.catalogRefId">sku</dsp:valueof><br> and so far people have bought <dsp:valueof param="giftitem.quantityPurchased">?</dsp:valueof>. <p> </dsp:oparam> </dsp:droplet> Buy <dsp:input bean="CartModifierFormHandler.quantity" size="4" value="1" type="text"/> <dsp:input bean="CartModifierFormHandler.addItemToOrder" value="Add to Cart" type="submit"/> </dsp:form> </dsp:oparam> </dsp:droplet>

GiftlistHandlingInstruction
The GiftlistHandlingInstruction specifies what special handling needs to be done for a gift. For example, it could update gift list information to reflect that the item was purchased. A separate GiftlistHandlingInstruction could indicate that the gift should be wrapped. A GiftlistHandlingInstruction is created in the following sequence of events: When a person purchases an item off a gift list, CartModifierFormHandler calls addGiftToOrder in GiftlistManager. addGiftToOrder performs additional tasks to adding the item to an order. These tasks include: • • • Creating a new shipping group with the recipient’s address Adding that item(s) to the new shipping group Creating a GiftlistHandlingInstruction object for the item

For more information on Handling Instructions, see Setting Handling Instructions in the Configuring Purchase Process Services chapter.

ShippingGroupDroplet and ShippingGroupFormHandler
Your site may use ShippingGroupDroplet and ShippingGroupFormHandler to pull shipping information from the user’s profile and to allow the user to assign shipping addresses to items in an order.

135
8 - Configuring Merchandising Services

µ
ProcUpdateGiftRepository

ATG Commerce Programming Guide

Both of these components have been extended for gift lists so that shipping information for gift items is automatically preserved. See Adding Shipping Information to Shopping Carts in the Implementing Shopping Carts chapter of the ATG Commerce Guide to Setting Up a Store and Preparing a Complex Order for Checkout in the Configuring Purchase Process Services chapter for descriptions of these components.

A pipeline is an execution mechanism that allows for modular code execution. Pipelines are used in ATG Commerce to execute a series of tasks such as saving an order, loading an order and everything required during checkout. The PipelineManager used by ATG Commerce is located in /atg/commerce/PipelineManager. The commerce pipeline configuration file contains the definition for the processOrder chain. The ProcUpdateGiftRepository processor is added to the processOrder chain to support gift lists. It goes through the order and looks for a gift that has been added to the shopping cart. If one has been added, it updates the Giftlists repository to update the purchased count of items off the gift list.

ProcSendGiftPurchasedMessage
The ProcSendGiftPurchasedMessage processor is added to the processOrder chain. It goes through the order and looks for a gift that has been purchased. If one has been purchased, it sends a message that contains the order, gift and recipient profile to the Scenarios module. This message can be used to trigger an event such as sending an e-mail message to the recipient.

Extending Gift List Functionality
The ATG Commerce implementation of gift lists supports most of the requirements for this feature for a typical commerce site. However, gift list functionality can be extended, if necessary. This section describes how to extend gift list functionality by adding additional item properties to the gift-list item descriptor. The process includes the following basic steps: • • Updating the Database and Repository Definition Extending GiftlistFormHandler

Updating the Database and Repository Definition
You can extend your site’s gift list functionality by adding new gift-list item properties. To add new properties, do the following: 1. Modify your database schema and update the database script included with ATG Commerce. The script for gift lists is found in
<ATG9dir>/DCS/sql/db_components/database_vendor/user_giftlist_ddl.s ql.

2.

Extend the repository definition for gift lists by layering on a giftlists.xml file at /atg/commerce/gifts/ in your local configuration directory. This new file should add your new property to the gift-list item descriptor. As an example, the following XML example demonstrates how you might add the property giftlistStatus to the gift-list item descriptor.

136
8 - Configuring Merchandising Services

ATG Commerce Programming Guide

µ

<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE taglib PUBLIC "-//Art Technology Group, Inc.//DTD General SQL Adapter//EN" "http://www.atg.com/dtds/gsa/gsa_1.0.dtd"> <gsa-template> <header> <name>Commerce Giftlists</name> <author>Company XYZ</author> <version>$Id$</version> </header> <item-descriptor name="gift-list"> <property name="giftlistStatus" data-type="timestamp" column-name="giftlist_status"/> </item-descriptor> </gsa-template>

Note: You should only need to add to the schema and repository definition. Removing anything that is already there requires substantially more work.

Extending GiftlistFormHandler
After Updating the Database and Repository Definitions to support additional gift-list item properties, you also need to extend the GiftlistFormHandler component to support them. To do so, do the following: 1. Extend the class atg.commerce.gifts.GiftlistFormHandler to support your new properties and override related methods. The source code for this form handler can be found in <ATG9dir>\DCS\src\Java\atg\commerce\gifts. Note that most handlers in the GiftlistFormHandler have preXXX and postXXX methods that can be overridden to support your requirements. To support your new property, you should override the postSaveGiftlist method to save your new property value in the repository. 2. Layer on a GiftlistFormHandler.properties file to configure an instance of the new class you created in step 1. The contents of the configuration file would look similar to the following:
# MyNewGiftlistFormHandler # $class=xyz.commerce.gifts.MyNewGiftlistFormHandler

Disabling the Gift List Repository
If you are not going to use the Giftlists repository, you can disable it. This repository is represented by the /atg/commerce/gifts/Giftlist component. Disabling this repository prevents you from having to create the associated tables in your database. Perform the following steps to disable the Giftlists repository:

137
8 - Configuring Merchandising Services

µ
1. 2. 3.

ATG Commerce Programming Guide

Edit the /atg/registry/ContentRepositories component and remove the value in the initialRepositories property that references the /atg/commerce/gifts/Giftlist component. For more information, see the Configuring the SQL Repository Component section of the SQL Repository Reference chapter in the ATG Repository Guide. Edit the /atg/commerce/gifts/GiftlistTools component and set the giftlistRepository property to null. Edit the userProfile.xml file and remove properties that reference items in the Giftlists repository. The userProfile.xml file is located in the Commerce configuration layer. Remove the following lines:
<!-- this is the key into private giftlist --> <table name="dcs_user_wishlist" type="auxiliary" id-column-name="user_id"> <property category="Commerce - Lists" name="wishlist" item-type="gift-list" repository="/atg/commerce/gifts/Giftlists" column-name="giftlist_id"cascade="insert,update,delete" display-name="Wish list"/> </table> <!-- this is the key into user created giftlists --> <table name="dcs_user_giftlist" type="multi" id-column-name="user_id" multi-column-name="sequence_num"> <property category="Commerce - Lists" name="giftlists" data-type="list" component-item-type="gift-list" repository="/atg/commerce/gifts/Giftlists" column-name="giftlist_id" display-name="Gift list"/> </table> <!-- this is the key into giftlists found for other customers --> <table name="dcs_user_otherlist" type="multi" id-column-name="user_id" multi-column-name="sequence_num"> <property category="Commerce - Lists" name="otherGiftlists" data-type="list" component-item-type="gift-list" repository="/atg/commerce/gifts/Giftlists" column-name="giftlist_id" display-name="Other gift lists"/> </table>

4.

Remove the updateGiftRepository and sendGiftPurchased processors from the commerce pipeline. These processors are found in the processOrder pipeline chain. After these entries have been removed from the chain definition, create a link from the authorizePayment processor to the addOrderToRepository processor.

Setting Up Product Comparison Lists
Commerce sites often require the ability for a site user to compare items in the product catalog. A simple site may offer the user a single product comparison list and enable the user to add and remove products

138
8 - Configuring Merchandising Services

a different list to compare televisions. • ProductListContains A servlet bean that queries whether a product comparison list contains an entry for a specific product. Like Java 139 8 . SKU. ATG Commerce includes a globally-scoped instance of ProductListContains. The default implementation of the product comparison system enables the user to compare any number of products and to do so using the products’ category.) Additionally. ComparisonList atg.comparison package: • ComparisonList A class that provides a generic data structure to maintain an ordered list of objects and an associated set of sort directives to apply when displaying the items. located in Nucleus at /atg/commerce/catalog/comparison/ProductList.comparison.catalog. located in Nucleus at /atg/commerce/catalog/comparison/ProductListContains. and so on).commerce. it enables the page developer to display product comparison information as a sortable table. a list to compare cameras. product. • ProductComparisonList A subclass of ComparisonList that provides an extended API for comparing product information.catalog. ATG Commerce provides a product comparison system that enables you to meet both simple and complex requirements. This section describes the default implementation of the product comparison system and includes the following subsections: • • • Understanding the Product Comparison System Extending the Product Comparison System Using TableInfo to Display a Product Comparison List Understanding the Product Comparison System The product comparison system consists of the following four classes in the atg. (You can extend the system to include additional information. ATG Commerce includes a session-scoped instance of ProductListHandler. • ProductListHandler A form handler that manages product comparison lists.ATG Commerce Programming Guide µ from the list. as well as an associated set of sort directives to apply when displaying the items in the list.commerce. and inventory information. The objects in the list may be of any Java class. ATG Commerce includes a session-scoped instance of ProductComparisonList. which the user can manipulate to change the sort criteria for the displayed information. located in Nucleus at /atg/commerce/catalog/comparison/ProductListHandler. A more complex site may offer the user multiple comparison lists to compare different types of items (for example. as well as compare the properties of the products in the list.Configuring Merchandising Services .ComparisonList provides a generic data structure to maintain an ordered list of items that the user may want to compare.

In cases where the comparison information will be displayed as a table. The following table describes the ComparisonList methods used to maintain a list of items to compare. ATG Commerce includes a session-scoped instance of TableInfo. repository items. Returns the list of items being compared.Configuring Merchandising Services . Note that if your application calls the getItems method to obtain a reference to the list.util. or other self-contained objects. Removes an item from the comparison list if it was present in the list. If you want to compare more complex objects. user profiles. you’ll want to subclass ComparisonList to be able to manage application-specific objects. Method addItem Description Adds an item to the end of the comparison list if the item isn’t already present in the list. located in Nucleus at /atg/commerce/catalog/comparison/TableInfo.synchronizedList method to obtain a thread-safe version of the list upon which to operate. see the Implementing Sortable Tables chapter in the ATG Page Developer’s Guide. or sets of objects against each other. ComparisonList maintains the insertion order of items in the list. Use ComparisonList when you want to compare sets of simple Java beans. 140 8 . it prohibits duplicate entries in the list by ignoring requests to add items that compare equal to items already in the list. This makes it possible for multiple request-scoped servlet beans and form handlers to operate safely on a shared session-scoped ComparisonList. refer to the ATG API Reference. Removes all items from the comparison list. as long as all changes to the list are made through the ComparisonList API.service. returns -1 if the item does not appear in the list. For additional methods and details. this provides an easy way to associate default table display properties with a comparison list.util.Collections.TableInfo as a convenience to the developer. Returns the number of items in the comparison list. you should synchronize all operations on the list or call the java.µ ATG Commerce Programming Guide List classes. ComparisonList maintains a property of type atg. Returns the index of the specified item in the comparison list. Unlike List classes. For more information about the TableInfo component and how to use it to display sortable tables. clear containsItem getItem(n) getItems indexOf removeItem size ComparisonList internally synchronizes operations on the list. Returns true if the comparison list contains the specified item. Returns the item at the specified index in the comparison list.

ATG Commerce Programming Guide µ ProductComparisonList ProductComparisonList extends ComparisonList. a different list to compare televisions. The refreshInventoryData() method iterates over the items in the ProductComparisonList and loads updated inventory information into them. SKU. a new Entry object for each SKU associated with the given product is automatically constructed and added to the item list. When working with these objects in JSPs. This method enables you to update the inventory information for the items when you render the page that displays the 141 8 . and so on). which add entries to the list. When you call ProductComparisonList’s addAllSkus method. The setRefreshInventoryData(String unused) method calls the refreshInventoryData() method. it combines category.Configuring Merchandising Services . you get back an array of Entry objects. The API for ProductComparisonList The public API for ProductComparisonList can be divided broadly into the following four categories: • add methods. which remove entries from the list. a new Entry object is automatically constructed and added to the item list. Similarly.Entry or use the DynamicBeans system to retrieve the product. When the add method or addAllSkus method is called. then the sku property of the new Entry object is null. Entry is an inner class defined by ProductComparisonList. then the product’s default parent category is used. • • • remove methods. if no category ID for the given product is specified. then the category property of the new Entry object is null. which set and get various properties of the ProductComparisonList itself. you can refer to their properties in the same way you refer to the properties of any other Java bean. When you call ProductComparisonList’s add method. which refresh the inventory information for the items in the ProductComparisonList. ProductComparisonList uses the items property to store a list of Entry objects. SKU. you can either cast the objects to ProductComparisonList. a list to compare cameras. category. set and get methods. each of which represents a product or SKU that the user has added to her product comparison list. When you call getItems on a ProductComparisonList. and inventory information from the Entry. product. and inventory information about a product into a single object. category. When working with these objects in Java. If the product has no child SKUs. if no SKU is specified in the method call. which query whether the list contains an entry matching specified product. or SKU information. contains methods. then the given product’s first child SKU is used. You can configure additional instances of ProductComparisonList in Nucleus to provide multiple comparison lists (for example. providing an API designed to manage and compare products and SKUs. • set and refresh methods. If no default parent category for the given product is set.

Additionally. several methods of ProductComparisonList take an optional catalogKey parameter.refreshInventoryData"> For related form handler methods. which then uses the given key and its key-tocatalog mapping to select a product catalog repository. The product’s SKU. see ProductListHandler. To do so.Configuring Merchandising Services . Through the catalogKey parameter. you pass a key to CatalogTools. The various methods take different sets of arguments to support a wide range of application behaviors. If the SKU is not set explicitly when the product is added to the list.µ top of the page: ATG Commerce Programming Guide ProductComparisonList. For example. there are remove methods to remove all entries for a specific product. then the first SKU in the product’s childSkus list is used. and SKU. then the product’s default parent category is used. If the category is not set explicitly when the product is added to the list. Refer to the ATG API Reference for additional information on the public API for ProductComparisonList. and contains methods. See Extending the Product Comparison System for more information. the category property is null. The category of the product being compared. By subclassing ProductComparisonList and overriding createListEntry. RepositoryItem pSku) The createListEntry method is called to create a new list entry with a given category. you can extend or replace the properties of the Entry object. This String parameter is useful for applications using catalog localization because it enables you to specify the product catalog to use when operating on a product comparison list. remove. then the sku property is null. sku RepositoryItem 142 8 . The Entry Inner Class The public API for the Entry class exposes various properties that the page developer can display in a product comparison list or table. The default implementation includes the following properties: Property Name product category Property Type RepositoryItem RepositoryItem Description The product being compared. RepositoryItem pProduct. Also note that there is one important protected method: Protected Entry createListEntry(RepositoryItem pCategory. and to remove the entry for a particular category/product/SKU combination. to remove all entries for all products in a specified category. If the product has no child SKUs. you could use the following setvalue tag at the <setvalue bean="ProductList. There are several different variations on the add. product. If the product’s default parent category is unset.

\ Price=sku. similarly. to display the product link in a table column but sort the column on the product’s display name.productLinkForma t property. The default format for the link is <a href="product. inventoryInfo InventoryData productLink String However. you can use the productLink property in the configuration of the TableInfo object that maintains the table information. you could modify the example in the following manner: columns=\ Product Name=productLink.listPrice. If the sku property is null or the inventory information isn’t available. 143 8 .displayName</a>. repositoryId">product. (See the next section for more information on the InventoryData object.url?id=product.\ … Or.) An HTML fragment that specifies an anchor tag that links to the product’s page in the catalog. see the Implementing Sortable Tables chapter in the ATG Page Developer’s Guide. Note: If you display the product comparison information in a table.template. then the inventoryInfo property is null. you can change the format by setting the ProductComparisonList.listPrice. product.ATG Commerce Programming Guide µ The InventoryData object that describes the inventory status for the given product and SKU.\ Price=sku.Configuring Merchandising Services .displayName.\ … For more information on the TableInfo component. as in the following example: columns=\ Product Name=productLink.

template.category.categoryLinkForm at property. The default format for the link is <a href=category. with a form handler. as in the following example: <dsp:droplet name="ForEach"> <dsp:param bean="ProductComparisonList. Note: Like the productLink property.items" name="array"/> <dsp:oparam name="output"> <p>Product Name: <dsp:valueof param="element.product. See the description of the productLink property in this table for more information. you can change the format by setting the ProductComparisonList. the categoryLink property can be used in the configuration of a TableInfo component.repositoryId>category. refer to Examples of Product Comparison Pages in the Implementing Product Comparison chapter of the ATG Commerce Guide to Setting Up a Store.inventoryInfo. For a JSP example. You can also use this property to delete specific entries. A page developer can refer to the properties of the Entry objects using familiar JSP syntax.µ categoryLink String ATG Commerce Programming Guide An HTML fragment that specifies an anchor tag that links to the category’s page in the catalog.jsp page. However. You can use this property to retrieve individual entries by calling ProductComparisonList. id Int A unique ID that names the list entry.displayName</a>.getItems(id) in the Java code or by using <dsp:valueof bean="ProductList.displayName"/><br> Category: <dsp:valueof param="element.displayName"/><br> Inventory: <dsp:valueof param="element.entries[id]"/> in the . for example.url?id=category .Configuring Merchandising Services .inventoryAvailabilityMsg"/><br> </dsp:oparam> </dsp:droplet> The InventoryData Inner Class 144 8 .

refer to the Implementing Product Comparison chapter of the ATG Commerce Guide to Setting Up a Store. By default. located in Nucleus at /atg/commerce/catalog/comparison/ProductListHandler. then ProductListContains looks for a list entry whose sku property matches either the given product’s first child SKU or null if there are no SKUs for the given product.commerce.InventoryInfo).comparison. output. It returns a subset of the readable properties of an InventoryInfo object (class atg. refer to the ATG API Reference.repositoryKey property via a hidden input field in a form. you can specify the product catalog to use when operating on a product comparison list. • For a list of the input. In the latter situation.Entry) returns an instance of the InventoryData inner class (class atg.catalog. For a list of InventoryData properties.commerce. product.repositoryKey property to the key to pass to CatalogTools.comparison.ProductComparisonList.Entry.Configuring Merchandising Services . CatalogTools uses the given key and its key-to-catalog mapping to select a product catalog repository. ATG Commerce includes a session-scoped instance of ProductListHandler. If your application uses alternate product catalogs for different locales. 145 8 . and for JSP examples of how page developers can use ProductListContains. the ProductListContains servlet bean queries whether a product comparison list includes the given product.InventoryData).inventory. Namely.ProductComparisonList. However. To do so. The InventoryData object stores the inventory data for a given item in the product comparison list. then ProductListContains looks for a list entry whose category property matches either the given product’s default category or null if there is no default category for the given product. you would set the ProductListHandler. then the default product catalog repository is used. The behavior of ProductListContains parallels that of ProductComparisonList.catalog. and SKU. Typically.ATG Commerce Programming Guide µ The getInventoryInfo() method of the Entry inner class (class atg. unlike an InventoryInfo object. which enables it to participate in session failover. If you don’t specify a SKU for the given product. set the ProductListHandler. then you may want to configure multiple instances of ProductListHandler to manage the contents of each list. ProductListHandler The ProductListHandler form handler manages product comparison lists. ProductListContains behaves as follows: • If you don’t specify a category ID for the given product. If your application uses multiple instances of ProductComparisonList to manage multiple product comparison lists (for example. It is configured to operate on the product comparison list located at /atg/commerce/catalog/comparison/ProductList. If the repositoryKey property is unset. ProductListContains When given a category.commerce. you can specify a product ID with or without an accompanying category or SKU. an InventoryData object is serializable. a list to compare cameras and a different list to compare televisions). and open parameters for ProductListContains.

respectively. which you can set to redirect the user when the handle method succeeds or fails. your subclasses can override these methods to provide additional application-specific processing. handleRemoveCategory Removes all entries for the category specified by categoryID from the product comparison list. Adds all of the SKUs for all of the products specified by productIDList to the product comparison list.µ Handle Method handleAddProduct ATG Commerce Programming Guide The following table describes ProductListHandler’s handle methods for managing a product comparison list: Description Adds the product specified by productID to the product comparison list. If necessary. Calls the ProductComparisonList.Configuring Merchandising Services . applying optional category information if supplied in categoryID. applying optional category and SKU information if supplied in categoryID and skuID. if any. Also note that ProductListHandler has two optional properties.refreshInventoryDa ta() method. Adds all of the SKUs for the product specified by productID to the product comparison list. categoryID. Adds all of the products specified by productIDList to the product comparison list. applying optional category information if supplied in categoryID. refreshInventoryDataSuccessURL and refreshInventoryDataErrorURL. Removes the list entries whose ids are specified in entryIds from the product comparison list. Resets the form handler by setting productID. handleRemoveEntries 146 8 . Clears the product comparison list and redirects the user to the clearListSuccessURL on success. and skuID to null. handleAddProductAllSkus handleAddProductList handleAddProductListAllSkus handleCancel handleClearList handleRefreshInventoryData The handleRefreshInventoryData method also calls pre and post methods. applying optional category information if supplied in categoryID and the default SKU for each product.

applying the optional category and SKU information if supplied in categoryID and skuID. optional category and SKU information is managed in the same way. applying optional category information if supplied in categoryID.HashMap. then the form handler looks for the product’s first child SKU (that is. Similarly. category. applying optional category information if supplied in categoryID and the default SKU for each product.” which indicates how popular a given product is. then the property is set to null. Extending the Product Comparison System As previously described. If no default value exists. If a product’s category information isn’t specified in categoryID. you can call Entry. Removes all entries for the product specified by productID from the product comparison list.Configuring Merchandising Services . If no default value exists. value) to add a new property value to the Entry object. public class MyProductComparisonList extends ProductComparisonList { protected Entry createListEntry(RepositoryItem pCategory.put(name. sku.ATG Commerce Programming Guide µ Removes the product specified by productID from the product comparison list. SKU. For examples of how page developers can use ProductListHandler in JSPs to manage product comparison lists. it stores a hypothetical value called “popularity. your subclasses don’t need to provide similar methods for their own properties. then the property is set to null. For additional information on ProductListHandler’s methods. Namely.util. Sets the product comparison list to contain all the SKUs for all the products specified by productIDList. with each Entry object representing a product that the user has added to her product comparison list. if a product’s SKU information isn’t specified in skuID. if any. and inventory information in a single object. Sets the product comparison list to the products specified by productIDList. Although the Entry class contains convenience methods for setting and getting properties like product. handleRemoveProduct handleRemoveProductAllSkus handleSetProductList handleSetProductListAllSkus The behavior of ProductListHander’s handle methods parallels that of ProductComparisonList. You can subclass ProductComparisonList and override its createListEntry method to extend the information stored in an Entry object. product. RepositoryItem pSku) { 147 8 . ProductComparisonList maintains a list of Entry objects. Because Entry is a subclass of java. refer to Implementing Product Comparison chapter of the ATG Commerce Guide to Setting Up a Store. refer to the ATG API Reference. RepositoryItem pProduct. The following code example illustrates this point. the Entry object maintains category. respectively. the default SKU). then the form handler looks for the default category of the product. and inventoryInfo.

pSku). 148 8 .put("popularity". In general. Also by default. it is configured for use with ProductList (in ProductList. ATG Commerce provides one instance of TableInfo. if necessary and available. int score = computePopularity(pProduct). For an example of using multiple instances of TableInfo to manage a single product comparison table. A more complex site may offer the user multiple comparison lists to compare different types of items (for example. public int computePopularity(RepositoryItem pProduct) { . refer to the Implementing Sortable Tables chapter in the ATG Page Developer’s Guide. createListEntry is called with the same category and SKU values that the user ultimately sees on the page in the product comparison list. the column headings for the table.createListEntry(pCategory. such as the properties to display in the table. Page developers can refer to the popularity property of a ProductComparisonList entry to display the corresponding value in a JSP. Consequently. however. Depending on the complexity of your commerce site. pProduct. and so on). return e. refer to Implementing Product Comparison chapter of the ATG Commerce Guide to Setting Up a Store. For JSP examples of how to use the ProductList and TableInfo components to manage product comparisons. which maintains the list of Entry objects in its items property.tableInfo). refer to the Viewing Compare Results section of the Displaying and Accessing the Product Catalog chapter in the ATG Business Commerce Reference Application Guide. score). For detailed information on TableInfo. one list to compare cameras. it is configured for use with the Motorprise Reference Application. } } Note that by the time the createListEntry method is called. a different list to compare televisions.Configuring Merchandising Services . By default. a site will maintain one instance of ProductComparisonList and one instance of TableInfo for each comparison table that’s desired. you may require multiple instances of ProductComparisonList and TableInfo. located in Nucleus at /atg/commerce/catalog/comparison/TableInfo. and the sorting instructions for the table. e. The TableInfo component maintains the display information to compare the products in table form.µ } ATG Commerce Programming Guide Entry e = super. Using TableInfo to Display a Product Comparison List The ProductList component. also includes a reference to a TableInfo object in its tableInfo property. pCategory and pSku will have been populated with the product’s default parent category and first child SKU... A simple site may offer the user a single product comparison list.

The following example shows the pertinent code from the Claimable repository definition file: <item-descriptor name="claimable" sub-type-property="type" version-property="version"> . The repository itself is made up of two parts: the database schema and the XML repository definition file. The definition file represents an item that can be claimed (a sub-type of type Claimable) and then defines specific implementations of this item.xml # name for the repository repositoryName=Claimable # database access transactionManager=/atg/dynamo/transaction/TransactionManager dataSource=/atg/dynamo/service/jdbc/JTDataSource # XML parsing 149 8 .adapter. these are sometimes referred to as “claimable items” in ATG Commerce.) By providing gift certificates as an option for your customers.GSARepository # definition files for claimable objects definitionFiles=\ /atg/commerce/claimable/claimableRepository.ATG Commerce Programming Guide µ Setting Up Gift Certificates and Coupons ATG Commerce provides the ability to create and manage gift certificates and coupons. you can increase sales and attract new business.. (Collectively. The claimable item system in ATG Commerce is made up of three components: • • • The Claimable repository The ClaimableTools component The ClaimableManager component The Claimable Repository The Claimable repository holds all possible claimable items.. namely. Coupons can also help increase your customer base (for example.. by including them in a cold call e-mail campaign). gift certificates and coupons .Configuring Merchandising Services . </item-descriptor> The following example shows the properties file for the ClaimableRepository component (/atg/commerce/claimable/ClaimableRepository): $class=atg. but importantly they provide an alternative way to deliver promotions to your existing customers. <property name="type" data-type="enumerated"> <option value="GiftCertificateClaimable"/> <option value="PromotionClaimable"/> </property> ..gsa.

Additionally. Naming for various claimable item properties.Configuring Merchandising Services . The first use of the ClaimableTools component is simply to create and claim any type of claimable item. The ClaimableManager Component The ClaimableManager component (/atg/commerce/claimable/ClaimableManager) provides higher level access to the repository and is the mechanism that most applications use to interact with the claimable item functionality. as the claim code for a gift certificate). if someone changes the name of a field in the XML file. and then perform 150 8 . It provides the ability to claim items. Edit the /atg/commerce/claimable/ClaimableTools component and set the claimableRepository property to null. Disabling the Claimable Repository The Claimable repository is represented by the /atg/commerce/claimable/ClaimableRepository component. it takes the item-descriptor type as an argument and then creates and adds the claimable item to the repository. The second use of the ClaimableTools component is to provide configurable values for the various properties of claimable items. The value is created by the ObfuscatedIdGenerator service. 2.µ ATG Commerce Programming Guide XMLToolsFactory=/atg/dynamo/service/xml/XMLToolsFactory # id generator IdGenerator=/atg/dynamo/service/ObfuscatedIdGenerator lockManager=/atg/dynamo/service/ClientLockManager Each item in the Claimable repository has a repositoryId property. initialize them. The ClaimableTools Component The ClaimableTools component (/atg/commerce/claimable/ClaimableTools) provides two pieces of functionality: • • Low-level access to the Claimable repository. Edit the /atg/registry/ContentRepositories component and remove the value in the initialRepositories property that references the /atg/commerce/claimable/ClaimableRepository component. The system uses the value in this property as the key for claiming the item (for example. For example. you can reflect that change in the code by adjusting the property values of the ClaimableTools component. you can disable it. For claiming items. This is important to prevent users from guessing claim codes. Follow these steps to disable the ClaimableRepository: 1. If you are not going to use the Claimable repository. See the ID Generators section of the Core Dynamo Services chapter in the ATG Programming Guide. it can obtain any super-type of type claimable since they all share the same common base type of claimable. Disabling the repository prevents you from having to create the associated tables in your database. The standard IdGenerator generates sequential repositoryId values. The ObfuscatedIdGenerator service creates nonsequential repositoryId values.

adding separate SKUs for different amounts. thus combining several smaller functions from the ClaimableTools package. Processing a gift certificate involves the following steps: 1. Setting Up Gift Certificates Gift certificates allow a customer to pay for all or part of a purchase using a prepaid amount. Customer B uses (claims) the gift certificate to pay for all or part of an order. also through the ClaimableTools package. one for a $50 dollar certificate and another for a $100 certificate. The gift certificate is not functional unless the three required properties (identified below) are set. The ElectronicFulfiller then creates the gift certificate in the Claimable repository (by means of the ClaimableManager component) and sends an e-mail to the recipient notifying him or her that a gift certificate has been purchased on his or her behalf and including the code to use for claiming it.ATG Commerce Programming Guide µ functions that are specific to one type of claimable item. The Purchase and Fulfillment Process for Gift Certificates Set up gift certificates as items in your product catalog.Configuring Merchandising Services . For example. Then it attempts to adjust the status of the item to a claimed status. he or she enters a code for a gift certificate). An example of how the ClaimableManager component can layer together several pieces of functionality from the ClaimableTools package is as follows: when a user claims an item (for example. 151 8 . Customer A purchases the gift certificate on behalf of Customer B. The value of the gift certificate is stored in the listPrice property of each gift certificate SKU in the product catalog. creditClaimableGiftCertificate – credits a specific amount to a gift certificate. amount (Required) The original dollar value of the gift certificate. the ClaimableManager component attempts to claim the item through the ClaimableTools package. Each SKU has a fulfiller property that defines an ElectronicFulfiller. Other examples of functions that the ClaimableManager component provides are as follows: • • • createClaimableGiftCertificate – creates a gift certificate in the system. Refer to the Configuring the Order Fulfillment Framework chapter for more information on the ElectronicFulfiller. 3. 2. When Customer A adds a gift certificate to his or her shopping cart. ATG Commerce fulfills the purchase for Customer A (and sends a notification e-mail to Customer B as part of the fulfillment process). you could have two SKUs. the fulfiller property tells the OrderFulfiller to route the purchase to the specified ElectronicFulfiller. The following properties can be set when the gift certificate is created. debitClaimableGiftCertificate – debits a specific amount from the gift certificate.

add the SKU to the dropdown list:--> <dsp:droplet name="/atg/dynamo/droplet/ForEach"> <dsp:param param="Product.Configuring Merchandising Services . The following example shows the JSP code you would add to the page on which the gift certificate product is displayed.com/dsp. and define the relationship between the two. The date the gift certificate was purchased. when Customer A adds the gift certificate to his or her cart. ATG Commerce does this through an ElectronicShippingGroup.tld" prefix="dsp" %> <dsp:page> <dsp:form action="<%=request.repositoryId" type="hidden"/> <!--set id param so that the Navigator won't get messed up in case of an error that makes us return to this page.quantity" size="4" value="1" type="text"/> <!-----------DropDownList format (default) ----------. in this case an e-mail address.getServletPath()%>" method="post"> <!-.--> <!--Create a dropdown list will all Sku in the Product.µ amountAuthorized amountRemaining purchaserId purchasedDate lastUsed ATG Commerce Programming Guide (Required) The total amount of money on the gift certificate that has been authorized for debit.Store this Product's ID in the Form Handler: --> <dsp:input bean="ShoppingCartModifier. Setting the stock level of a gift certificate to 0 (out of stock) does not affect the gift certificate’s availability because the ElectronicFulfiller does not check a gift certificate’s stock level. Use the handleAddSoftGoodToOrder() method in the /atg/commerce/order/ShoppingCartModifier component to do this.repositoryId"/>' type="hidden" name="id"> Give <dsp:input bean="ShoppingCartModifier. The profileId of the person who bought the gift certificate. (Required) The current amount of money remaining on the gift certificate for debit. Note: By default. Sending an e-mail to the recipient of the gift certificate requires knowing his or her e-mail address. The latest date on which fulfillment updated the amount. you add an ElectronicShippingGroup to the order as well. which designates the necessary information for delivering electronic goods.catalogRefIds"> <!--For each of the SKUs in this Product. Store the selected SKU's id in the Form Handler: --> <dsp:select bean="ShoppingCartModifier. So.ProductId" paramvalue="Product.childSKUs" name="array"/> 152 8 .--> <input value='<dsp:valueof param="Product. It adds the gift certificate to the customer’s order and prompts him or her to specify the e-mail address of the recipient: <%@ taglib uri="http://www.atg. the stock level of a gift certificate is set to -1 indicating that an infinite number of the item is available.

Note that electronic goods require special processing.addSoftGoodToOrderErrorURL" value="product_gift_certificate.lang. The customer enters the recipient’s e-mail address into a form field set to the property ShoppingCartModifier.. so the submit method of the form is set to addSoftGoodOrder and not addItemToOrder. and then the ElectronicFulfiller examines it to determine where to send the message. 153 8 . Thus.repositoryID" idtype="java. For more information on the ShoppingCartModifier component./checkout/cart.addSoftGoodToOrderSuccessURL" value=".softGoodRecipientEmailAddress.jsp" type="hidden"/> </td> </tr> </table> </dsp:form> </dsp:page> In this example.ATG Commerce Programming Guide µ <dsp:param value="Sku" name="elementName"/> <dsp:param value="skuIndex" name="indexName"/> <dsp:oparam name="output"> <!--This is the ID to store.ADD TO CART BUTTON: Adds this SKU to the Order--> <dsp:input bean="ShoppingCartModifier. please refer to the Setting Up Gift Lists and Wish Lists section.displayName"/> </dsp:oparam> </dsp:droplet> <!--ForEach SKU droplet--> </dsp:select> to <br> Recipient's e-mail address <dsp:input bean="ShoppingCartModifier. the e-mail address is set in the ElectronicShippingGroup through the handleAddSoftGoodToOrder method. note the code that handles the recipient’s e-mail address.jsp" type="hidden"/> <dsp:input bean="ShoppingCartModifier. if this SKU is selected in dropdown:--> <dsp:getvalueof id="option48" param="Sku.Goto this URL if NO errors are found during the ADD TO CART button processing:--> <dsp:input bean="ShoppingCartModifier.String"> <dsp:option value="<%=option48%>"/> </dsp:getvalueof> <!--Display the SKU's display name in the dropdown list:--> <dsp:valueof param="Sku.Configuring Merchandising Services .softGoodRecipientEmailAddress" size="30"/> <p> <!-.addSoftGoodToOrder" value=" Add Gift Certificate to Cart " type="submit"/> <!-.

You must initialize the properties of the payment group to the correct values. This prevents the same gift certificate from being used for more than it is worth. During the handleMoveToConfirmation process. it creates a new GiftCertificate payment group and adds it to the order. debit. the amount that was authorized is checked against the amount that is being debited. The process for handling a coupon is as follows: 1. The properties to initialize include the claim code ID. the amountRemaining is reduced by the amount being authorized. each PaymentGroup in the order is authorized using the PaymentManager. using white space as the delimiter. the user profile ID. Most of the code for handling coupons is included in the ClaimableManager component and the standard promotion architecture. Please refer to the Configuring Purchase Process Services chapter for more information on payment groups. Finally. 154 8 . Setting Up Coupons ATG Commerce treats coupons as a type of promotion that customers can claim. create a relationship between the order and the new payment group indicating that the gift certificate payment group can account for any amount up to the value of the gift certificate.) When an order is submitted.µ Using a Gift Certificate ATG Commerce Programming Guide On your Checkout page (or an equivalent page on your site). During fulfillment. and the system adds the corresponding promotion to the customer’s profile.Configuring Merchandising Services . see the Processing Payment of Orders section. Obtain a coupon code. it adds an error to the FormHandler. This behavior allows customers to enter multiple gift certificate codes into a single text field. any amount that was authorized will be credited back to the gift certificate before the PaymentGroup is removed. the ShoppingCartModifier parses any values it finds in this field into tokens. and credit of gift certificates. The PaymentManager has different processors for gift certificates and credit cards. If the amount authorized was the same as the amount being debited. If it cannot find a corresponding item. it hands each token string to the ClaimableManager component. To make sure that the gift certificate is valid if an order is removed before the debit occurs (and after authorization). and the amount of the gift certificate. they are corrected now. (For more information. After the system tokenizes the giftCertificateNumbers property. If there are any differences. The processor used for gift certificates handles the authorization. The customer types in a specific code. Hook the text field up to the giftCertificateNumbers property of the ShoppingCartModifier component.debit returns successfully. If the system does find an item that corresponds to the token string. the PaymentGroup containing the gift certificate is debited through the PaymentManager (and ultimately the GiftCertificateProcessor). When a gift certificate is authorized. include a text field where customers can enter the claim codes for any gift certificates they may have (you send the codes in the gift certificate notification e-mail). When this happens. The ClaimableManager attempts to match each string to a corresponding gift certificate in the Claimable repository. Settling a Gift Certificate Gift certificate settlement is handled similar to the way that settlement for credit cards is handled. with a FormHandler to connect these two systems. the PaymentManager.

For example.claimCouponSuccessURL" value="CouponClaim.claimCoupon" type="submit"/> </dsp:form> </dsp:page> When a user enters a coupon code on a Checkout page.couponClaimCode" type="text"/> <dsp:input bean="CouponFormHandler. Add the resulting promotion to the activePromotions list in the user profile.Configuring Merchandising Services . discontinues that order.tld" prefix="dsp" %> <dsp:page> <dsp:form method="post"> <!-.atg. Create an input field on an appropriate site page (for example. the promotion applies to the second order.jsp" type="hidden"/> <!-. ATG Commerce checks that the coupon is active and the promotion associated with it is not expired.claimCouponSuccessURL" value="CouponClaim. The following example shows the JSP code for using the CouponFormHandler component: <%@ taglib uri="http://www.Get the coupon claim code --> Coupon code: <dsp:input bean="CouponFormHandler.com/dsp. Try to claim the coupon from the ClaimableRepository. have the form submit to the handleClaimCoupon method of the form handler. Use the /atg/commerce/promotion/CouponFormHandler component to obtain a coupon code and add it to a customer’s list of promotions in the customer’s activePromotions profile property. Then. as long as the promotion is active and applicable. 3. a Checkout page) and hook it up to the couponClaimCode property of the CouponFormHandler component. the user “claims” the coupon. This method uses the ClaimableManager component to attempt to get a coupon from the Claimable repository. Note that coupon codes are case-sensitive. which means that the promotion is added to the user’s activePromotions profile property. ATG Commerce determines whether the order qualifies for the coupon’s promotion by checking that: • • The order meets the requirements of the promotion The promotion has not expired This double-checking capability ensures that if a user claims a coupon as part of one order. If both conditions are met.Where to go to on success or failure --> <dsp:input bean="CouponFormHandler.jsp" type="hidden"/> <dsp:input bean="CouponFormHandler. COUP100 and coup100 are two different coupon codes.ATG Commerce Programming Guide µ 2. Then it extracts the promotion from the coupon and uses the PromotionTools component to place the promotion into the customer’s user profile. then creates a second one. During order pricing. 155 8 .

which is located in a . You can obtain the claim code for the coupon using coupon. The item-descriptor defines a claim code ID and a link to a promotion object in the Promotions repository.CouponDroplet.jar. If your Web site requires multiple types of coupons.Promotion Claimable object --> <item-descriptor name="PromotionClaimable" super-type="claimable" sub-type-value="PromotionClaimable"> <table name="dcspp_coupon" type="auxiliary" id-column-name="coupon_id"> <property name="promotion" column-name="promotion_id" item-type="promotion" repository="/atg/commerce/pricing/Promotions"/> </table> </item-descriptor> The coupon item-descriptor is defined in /atg/commerce/claimable/claimableRepository.commerce. not as part of the order.promotion. You can populate the Claimable repository through either the ATG Control Center or the atg.xml. When a coupon is claimed. The following example shows the JSP code for the CouponDroplet: <dsp:importbean bean="/atg/commerce/promotion/CouponDroplet"/> <h2>here is a coupon that was created: </h2> <dsp:droplet name="CouponDroplet"> <dsp:param value="promo60001" name="promoId"/> <dsp:oparam name="output"> <dsp:valueof param="coupon.checkPromotionType method checks the item type of the coupon corresponding to the given claim code against the array of acceptable item types in the CouponFormHandler. The other step to consider when you set up coupons is to make sure that there are coupons in the Claimable repository for a customer to claim. you can define additional item-descriptor types by editing the claimableRepository. For information on how to extend the commerce object hierarchy to include a new property. The CouponDroplet servlet bean takes either a promotion or promotion ID and then generates a coupon for it in the repository.id">no value</dsp:valueof> </dsp:oparam> <dsp:oparam name="error"> </dsp:oparam> </dsp:droplet> 156 8 . The value of the output parameter in the CouponDroplet is the coupon object.Configuring Merchandising Services . the CouponFormHandler. A claimed coupon is automatically applied to any order to which it qualifies.xml file and then specifying the valid coupon types in the validCouponItemTypes property in the CouponFormHandler properties file.id.validCouponItemTypes property.µ ATG Commerce Programming Guide A promotion given by a coupon persists on the user profile.jar file at <ATG9dir>/DCS/config/config. there’s no need to claim a coupon twice. refer to Extending the Purchase Process in the Customizing Purchase Process Externals chapter. The following example shows the default item-descriptor for coupons: <!-. You can persist a coupon code with an order by adding a new property to the Order object and storing the coupon code in the new property.

thereby creating a coupon code that is ready to send to a customer. 157 8 .ATG Commerce Programming Guide µ You could include the CouponDroplet in a targeted e-mail JSP.Configuring Merchandising Services .

Configuring Merchandising Services .µ ATG Commerce Programming Guide 158 8 .

Just as you can personalize content for every shopper who visits your site. This chapter contains information on the following topics: • • • • • • • Overview of Pricing Services: Describes how pricing engines and calculators work within the pricing framework. Using Price Lists: Describes how to use price lists to implement different pricing schemes for different customers. and use them in dynamic pricing situations. sales tax. You can also set up coupons. For more pricing information.ATG Commerce Programming Guide µ 9 Using and Extending Pricing Services The pricing services in ATG Commerce provide a flexible system for personalizing the prices of items in your product catalog.Using and Extending Pricing Services . you can use ATG Commerce pricing services to provide dynamic pricing for orders. As well as personalizing prices for catalog items. refer to the sections on pricing in these manuals as well as the information in this guide. Extending the Qualifier Class: Describes how to extend the Qualifier class. you can tailor prices and generate them dynamically on demand. Public Pricing Interfaces and Classes: Describes the interfaces and classes used in the pricing framework. target them for appropriate visitors. Creating Promotions: Describes how to set promotions up and deliver them to customers. Default Pricing Calculators: Describes the preconfigured discount pricing calculators that are supplied with ATG Commerce. Extending and Creating Pricing Engines: Describes how to add new pricing engines or extend existing pricing engines to fit the specific needs of your site. 159 9 . sales. Default Pricing Engines: Describes the preconfigured pricing engines that are supplied with ATG Commerce. and shipping. which evaluates discount rules to determine whether a calculator should apply a discount in a given situation. and other promotions. Extending and Creating Pricing Calculators: Describes how to add new calculators or extend existing calculators to fit the specific needs of your site. The system is granular enough to allow you to create a site on which a single item is priced differently for every shopper who views it. • • The ATG Consumer Commerce Reference Application Guide and the ATG Business Commerce Reference Application Guide contain extensive descriptions of how ATG implemented dynamic pricing in the Pioneer Cycling Store and Motorprise reference applications.

Each item has a list price that can be specified in the listPrice property of the Product Catalog repository. Pricing calculators are responsible for the following: • • • Looking up the price in the catalog by priceList. For example. By default. (Refer to the Qualifier Class section for more information. Alternatively. (Note that an “item” is a CommerceItem. sales tax. you might set up a “2-for-1” sale for a limited period on a specific type of item. which work together to determine prices for catalog items. Tax. The structure includes the following: • • • • A pricing engine One or more calculators A helper method in the qualifier service An item-descriptor in the Promotions repository. Orders. ATG Commerce pricing services can calculate the price of shipping for an order and apply discounts if applicable. ATG Commerce pricing services adapt the list price by applying any discounts or other promotions that you have set up. For example. ATG Commerce can perform dynamic pricing for the following types of pricing object: • Items. see Integrating Third-Party Software With ATG Commerce. and shipping. sites can use a third-party system such as CyberSource or TAXWARE to handle tax calculations. Invoking a qualifier service that identifies the objects to discount. ATG Commerce pricing services calculate the total cost of an order and can apply any discounts that are applicable (for example. • • • ATG Commerce uses the same basic structure for pricing each type of object described above. total orders. a customer might have a coupon offering a 10% discount on a total order.µ Overview of Pricing Services Pricing engines are responsible for three tasks: • • • ATG Commerce Programming Guide ATG Commerce pricing services are based on the behavior of two complementary elements: pricing engines and pricing calculators. Retrieving any promotions that are available to the site visitor. For more information on using a third-party system for this purpose. which represents a quantity of a SKU or a product). the structure for pricing and discounting catalog items includes the following: 160 9 . ATG Commerce pricing services can calculate the sales tax for an order. Shipping price.) Using information they receive from the engines and from the qualifier service to perform the actual process of determining prices. Invoking the calculators in the correct order. Determining which calculators generate the price.Using and Extending Pricing Services .

An object that contains the price of some piece of an order. Pricing Model Definition Language – This is how a promotion is described. Note: The structure for determining sales tax is slightly different because ATG Commerce does not support offering discounts on tax. Common Terms in Pricing Services The following table describes common terms used in pricing. and the profile used when a price was calculated.ATG Commerce Programming Guide µ • • • • An Item Pricing Engine An Item List Price Calculator.commerce.Using and Extending Pricing Services . The ACC includes a discount rule interface for creating rules. item.Qualifier The Item Discount item-descriptor in the repository /atg/commerce/pricing/Promotions. ShippingPriceInfo. there is no item-descriptor for tax discounts in the default Promotions repository. the locale. an Item Sale Price Calculator. Each of these is contained within the order. There is also a DetailedItemPriceInfo. PriceInfo PricingAdjustment PricingContext PricingModel Promotion 161 9 . For this reason. Pricing Term Calculator PMDL Definition An object that looks at all or part of an Order and returns a price. There are four main kinds of priceInfo objects: OrderPriceInfo. These two pieces are called the “qualifier” (when) and the “target” (what) and are a part of every promotion. Describes why and how a particular price was changed. and an Item Discount Calculator The findQualifyingItems call in atg. It also contains information about when the pricing model may be used. You could add such an item item-descriptor if necessary. or tax). after order (or the relevant component) has been priced. Each of these terms is described in detail in this chapter. It includes a description of the change and the amount. It includes a PMDL rule and the discount type and amount.pricing. See PricingModel. This includes the discount rules for when a promotion may apply and the rules for what may be discounted. ItemPriceInfo. described with ItemPriceInfo objects. It also contains the promotion (if any) that triggered the change. This is an abstract notion referring to one of the four sets of promotions (shipping. order. and TaxPriceInfo. A repository item that describes a discount.

may be discounted. How Pricing Services Generate Prices This section provides an overview of the way ATG Commerce uses pricing services to calculate prices. Note: You can also specify a priority level for any promotion by setting its Order of Application (priority) property in the Promotion repository. This rule defines when something can receive a discount. For example. It applies promotions by priority. 162 9 . The pricing engine sorts the promotions by this property before it applies them. A pricing engine is invoked from business-layer logic. (See PricingTools Class for more information.Using and Extending Pricing Services . All the precalculators (defined in ItemPricingEngine) are executed in order.µ Qualifier Target ATG Commerce Programming Guide This is a service that interprets a PMDL rule and decides what. 1. For more information. The pricing engine processes one at a time the objects for which it is tasked with generating a price. see Creating Promotions. The pricing engine builds a list of global promotions (ones that you define as applying automatically to all customers). tiered price) salePrice (if item is on sale) 2.) The pricing engine applies its configured precalculators. The engine looks up the 5. The pricing engine accesses the current customer’s profile and retrieves any promotions listed in the activePromotions property of the profile. This method looks at the activePromotions property to find all promotions associated with a given profile. The resulting lists are concatenated. searching for any promotion whose Automatically Give to All Customers (global) property is set to true. bulk price. For each available promotion. if anything. ATG Commerce does the following: Each promotion has a pricingCalculatorService property that specifies the calculator that the system must use to apply it.) Note: The list of promotions that the business logic passes to the pricing engine often comes from the engine itself through its getPricingModels method. The second part of a PMDL rule is called the target. This usually occurs during checkout. (You create promotions in the ATG Control Center. 4. It builds the list by using its globalPromotionsQuery property to query the Promotions repository. 3. such as a PriceItem servlet bean in a page or from the ATG Commerce PricingTools class. a site could use a list price precalculator or an order subtotal precalculator to establish a base price to which subsequent calculators then apply a discount. This rule defines which part of an order receives a discount. A precalculator modifies a price without using any associated promotions. This includes: listPrice (fixed price. The term qualifier also refers to the first part of a PMDL rule.

blue items appear with their static list or sale price. Using dynamic pricing on a product page can cause a significant decrease in performance compared to using static pricing.Using and Extending Pricing Services . each item in the catalog has a list price stored in the listPrice property of the catalog repository. suppose you send a specific group of customers a coupon for 20% off all blue items. The calculator applies the discount to the list of objects. 7. refer to the sections on the PriceItem and the PriceEachItem servlet beans in the ATG Commerce Guide to Setting Up a Store. you can still ensure a high level of performance by using the pricing features selectively. Deciding Between Dynamic and Static Product Pricing When building a product catalog. This process is repeated every time a price is requested. and sales tax. (A product or SKU that is priced statically just displays a price amount.ATG Commerce Programming Guide µ specified calculator in Nucleus and invokes it. You display the price on the appropriate site pages. if so. passing in the referring promotion. If you do decide to use dynamic pricing on product pages. and the item price appears on the Shopping Cart or Checkout page (for example) with a discount of 20%. which make any necessary modifications to the price after any discounts have been applied. shipping costs. The promotion calculator consults the qualifier service to get a list of objects that qualify for the discount. Even if you decide not to display dynamic pricing on a product page. For more information. On the product pages of the site. it is acceptable to show dynamic prices only when a customer places items in the shopping cart. dynamic pricing still occurs on the shopping cart and purchase process pages. when a customer with the “20% off” coupon adds a blue item to his or her shopping cart. 6. How Static Pricing Works With static pricing. You can also choose to restrict dynamic pricing to certain types of customers (for example. see How Static Pricing Works. You can use dynamic pricing on certain product templates and static pricing on others. The calculator marks any items that it uses as qualifiers for the promotion. which is the same for all customers. 163 9 . For these sites. dynamic pricing takes effect. However. For more information on dynamic pricing. how granular you need it to be. The pricing engine modifies the PriceInfo object of the object being discounted. For example. you must decide whether your site requires dynamic product pricing and.) Many sites do not need to show dynamic pricing on product pages. registered visitors only). as a property of the object whose price is being shown. for example a list price or a sale price. and the ATG Commerce Pricing Services can then use that price as a base for calculating order totals. The pricing engine applies its configured PostCalculators. This behavior prevents the qualifier items from being used again during the same price calculation.

There are many points from which you can extend existing ATG Commerce functionality. 164 9 . Public Pricing Interfaces and Classes ATG Commerce Pricing Services come with a powerful set of standard features that are designed to handle the pricing demands of most Web sites. you can write a new implementation of the many public pricing APIs that the product supplies.commerce. see the ATG API Reference.pricing package.salePrice" converter="currency"/>! </dsp:oparam> </dsp:droplet> For more information about the Switch servlet bean. Extensions of this interface describe objects that calculate a price for a specific class of object.listPrice" converter="currency"/> on sale for <dsp:valueof param="sku.pricing. This section includes information on the following: • • • The Base Pricing Engine Pricing Interfaces Pricing Classes For more information on pricing interfaces and classes. For example. use the Switch servlet bean with the onSale property from the Catalog repository.PricingEngine is the main interface for interacting with the atg. OrderPricingEngine extends PricingEngine and calculates prices for orders passed to it. The Base Pricing Engine atg. However. so you can extend a single class while still leveraging much of the ATG Commerce code base. you can maintain more than one price per item – for example. see Appendix B: ATG Servlet Beans in the ATG Page Developer’s Guide.listPrice" converter="currency"/> </dsp:oparam> <dsp:oparam name="true"> List price of <dsp:valueof param="sku. if your site requires additional functionality.onSale" name="value"/> <dsp:oparam name="false"> List price of <dsp:valueof param="sku.µ ATG Commerce Programming Guide Optionally. The APIs work together. When you want the alternate price to take effect. you can give each item a fixed sale price in addition to its list price by specifying a value for the salePrice property in the catalog repository. The following example is taken from the default ATG Commerce product catalog: <dsp:droplet name="/atg/dynamo/droplet/Switch"> <dsp:param param="sku.Using and Extending Pricing Services .commerce.

OrderPricingEngine Provides a price for atg.pricing.Using and Extending Pricing Services . The customer’s profile. but typically it includes the following: • • • • • The input object(s) to be priced.commerce.pricing. atg. For example. priceOrder.commerce.commerce. The PricingEngine interface itself does not describe any functionality other than the promotion extraction API because of the wide range of information that different PricingEngine implementations might require to calculate a price for their specific class of object.ShippingGroup objects. The pricing context is defined by the method’s input parameters.ItemPricingEngine Provides a price for atg.commerce. Return the price(s) to be associated with the input object(s). which extracts a collection of promotions from an input profile.order. Define one or more methods that do the following: Take an input object(s) to be priced.ShippingPricingEngine Provides a price for atg.Order objects. For example. the ItemPricingEngine implementation needs one set of input parameters.pricing. 165 9 . There is a Java object type for each type of price that is generated. The locale for which the price is being generated.order. Extend the PricingEngine interface.commerce. getPricingModels. follow the same basic procedure: 1.CommerceItem objects.ATG Commerce Programming Guide µ All PricingEngine implementations process promotions. which exists so that new APIs do not have to be created to accommodate additional pricing context information. The individual extensions of the PricingEngine interface contain the API methods for generating a given type of price.order. ATG Commerce Extensions of the PricingEngine ATG Commerce provides the following four extensions of the main PricingEngine interface: • • • atg. atg. while the OrderPricingEngine needs a different set. The PricingEngine interface itself contains only one method. The input promotions to apply to the prices. to generate a price for an order in a given context.commerce. atg.pricing. 2.OrderPricingEngine inherits the promotion extraction API from PricingEngine and defines one new method. It varies among PricingEngine extensions. Take an input context defined by zero or more parameters (in addition to the object to be priced).commerce. Extending the Base Pricing Engine For all extensions of the PricingEngine. A hash table of extra parameters.

commerce. the promotion takes effect and shows that one pair of shorts is free.ItemPricingEngine is an extension of the PricingEngine interface.TaxPricingEngine Determines tax for atg. the price shown is still full price for all the shorts. The prices that are generated are ItemPriceInfo objects.order. when the customer subsequently displays the contents of his or her cart.” While the customer is just browsing the catalog. • • The priceEachItem method batch processes all the items that are passed in. The priceItems method prices all input items all in the same context. get one pair free.µ • ATG Commerce Programming Guide atg. It describes an object that determines prices for atg.Using and Extending Pricing Services . To continue with the same example. For example. An ItemPricingEngine can determine prices in three ways: • The priceItem method prices an item as a single item.” and there is a promotion for “Buy 7 or more blue shorts. Pricing Interfaces This section describes the following ATG Commerce pricing interfaces: • • • • • • • • • ItemPricingEngine Interface ItemPricingCalculator Interface OrderPricingEngine Interface OrderPricingCalculator Interface ShippingPricingEngine Interface ShippingPricingCalculator Interface TaxPricingEngine Interface TaxPricingCalculator Interface PricingConstants Interface ItemPricingEngine Interface atg. However. Therefore. if the item passed in is “5 blue women’s shorts. These interfaces are described in the next section.” the promotion would not take effect. This call is mainly used for displaying item prices when a customer is browsing the catalog. the customer now puts “6 blue men’s shorts” in the shopping cart in addition to the “5 blue women’s shorts.commerce. Pricing Interfaces.order. get one pair free” promotion is not factored in when displaying prices.pricing. when the customer makes the decision to add the shorts to the shopping cart.commerce.Order objects.commerce. but they are priced as if they were passed into PriceItem one at a time. It reviews any promotions that are passed in through a pPricingModels parameter.pricing. The single item that is passed in is the only one available to satisfy the requirements of any promotion.CommerceItem objects. 166 9 . the “Buy 7 or more blue shorts.

Implementations of this interface create an OrderPriceInfo object that accurately represents the price of an input order. The order pricing engine invokes the priceOrder method of the OrderPricingCalculator (or calculators) that it is configured to use.pricing.commerce.commerce. Tax. For more information. the profile of the user.commerce. the promotions to factor. the context is as follows: the items to be priced. The specific way in which the engine creates the order object varies according to individual implementations. Order. The priceOrder method modifies the input pPriceQuote according to the current pricing context. The items would only receive the discount if priced in the same context. ATG Commerce includes several classes that are implementations of the ItemPricingCalculator interface. which you can use to determine an initial price for an item without any discounting. The pricing context is defined by the priceOrder method’s input parameters. ATG Commerce provides the OrderPricingEngineImpl class as a default implementation of the OrderPricingEngine interface. 167 9 .pricing. ItemPricingCalculator Interface atg. ATG Commerce provides the ItemPricingEngineImpl class as a default implementation of the ItemPricingEngine interface.ATG Commerce Programming Guide µ The pricing context is defined by the methods’ input parameters. the locale. and any additional parameters. For example. or priceItems method.OrderPricingCalculator.ItemListPriceCalculator class. atg. it includes the atg. It describes an object that determines prices for Order objects (the total price of all items in a customer’s shopping cart). The way in which they do this is depends on the implementation. An OrderPricingEngine uses the priceOrder method to determine the price of an order. modifies the price of an order.pricing. see Item.commerce. For more information on this class and other classes that implement this interface. and Shipping Pricing Engine Classes. and Shipping Pricing Engine Classes. The calculator’s priceItem method modifies the input priceObjects according to the current pricing context. see Pricing Calculator Classes. Tax. see Item. OrderPricingEngine Interface atg.Using and Extending Pricing Services . The item pricing engine invokes each calculator’s priceItem.ItemPricingCalculator modifies the price of a CommerceItem. The specific way in which the calculator modifies an order price varies according to individual implementations. a certain promotion might give 10 percent off an order if the pricing context includes one shirt and one pair of pants. In the case of priceItem.OrderPricingEngine is an extension of the PricingEngine interface. The context can be important because some promotions take effect only if the item appears in a pricing context with other items. For more information. For example. The specific way in which the calculator modifies an item price varies according to individual implementations. priceEachItem. Order.pricing. OrderPricingCalculator Interface The OrderPricingCalculator interface.

µ ShippingPricingEngine Interface ATG Commerce Programming Guide ATG Commerce includes several classes that are implementations of the OrderPricingCalculator interface. The getAvailableMethods call returns the methods available for shipping the specified group. 168 9 .commerce. TaxPricingCalculator Interface The atg.TaxPricingEngine is an extension of the PricingEngine interface. For more information.commerce. the current profile. Tax.pricing. it includes the atg. For more information. TaxPricingEngine Interface atg. The priceShippingGroup method asks this object to determine a price for the specified shipping group.commerce. see Pricing Calculator Classes. The priceShippingGroup method modifies the input pPriceQuote according to the current pricing context.pricing. a locale in which the pricing should occur. atg. It describes an object that determines taxes for Order objects. ATG Commerce provides the TaxPricingEngineImpl class as a default implementation of the TaxPricingEngine interface.commerce.pricing. Tax. Calling code provides the pricing context by inputting the order.pricing. see Item.commerce. and any additional parameters. it includes the atg.pricing. The specific way in which the calculator modifies a shipping price varies according to individual implementations. which you can use to apply a promotional discount to the shipping price of an order. see Item.ShippingPricingCalculator. For example. and Shipping Pricing Engine Classes. ShippingPricingCalculator Interface The ShippingPricingCalculator interface. ATG Commerce provides the ShippingPricingEngineImpl class as a default implementation of the ShippingPricingEngine interface. ATG Commerce includes several classes that are implementations of the ShippingPricingCalculator interface. Order.ShippingDiscountCalculator class.Using and Extending Pricing Services .commerce. atg.pricing. and Shipping Pricing Engine Classes.ShippingPricingEngine is an extension of the PricingEngine interface. Implementations of this interface determine the cost of shipping the contents of a shipping group. For more information on this class and other classes that implement this interface.OrderSubtotalCalculator class. The interface provides one way to ask for a tax price. Implementations of this interface determine the price for the tax associated with a specified order object. which you can use to calculate the raw subtotal for an order before any discounts are applied. For more information on this class and other classes that implement this interface. The shipping pricing engine invokes the priceShippingGroup method of the ShippingPricingCalculator (or calculators) that it is configured to use. any pricing models (promotions). see Pricing Calculator Classes. It describes an object that determines prices for ShippingGroup objects.TaxPricingCalculator interface modifies the price of tax for an order. Order. For example. modifies a price object that represents the cost of shipping for an order.

The calculator’s priceTax method modifies the input pPriceQuote according to the current pricing context.commerce. see Pricing Calculator Classes.commerce. 169 9 .commerce.AmountInfo parent class represents price information about an object. For example. Pricing Classes The following section describes the ATG Commerce pricing classes. it includes the atg.pricing.pricing. • • • • • • • • Price Holding Classes Pricing Engine Classes Pricing Calculator Classes Qualifier Class QualifiedItem Class PricingTools Class Other Classes The Pricing Servlet Beans Price Holding Classes This section describes the following ATG Commerce price holding classes: • • • • • • AmountInfo ItemPriceInfo DetailedItemPriceInfo OrderPriceInfo ShippingPriceInfo TaxPriceInfo AmountInfo The atg.commerce.PricingConstants interface contains constant values for static reference by other classes in the atg. ATG Commerce includes several classes that are implementations of the TaxPricingCalculator interface. TaxPriceInfo.commerce. OrderPriceInfo. it also contains information about how to interpret that amount. which you can use for situations in which a sales tax of zero is applicable for an order. This class is the base for the ItemPriceInfo.pricing package.ATG Commerce Programming Guide µ The tax pricing engine invokes the priceTax method of the TaxPricingCalculator (or calculators).pricing. For more information on this class and other classes that implement this interface.NoTaxCalculator class.Using and Extending Pricing Services . which are located in the atg. The specific way in which the calculator modifies a tax price varies according to individual implementations. and ShippingPriceInfo classes.pricing package. In addition to the actual amount. PricingConstants Interface The atg.

AmountInfo includes a method called markAsFinal(). The calculators perform all the computations and store the results. before any modifications. This method sets the amountIsFinal property and adds a PricingAdjustment to the amountInfo. Order. USD indicates that the price is in US dollars. and the precise individual item price can be found in the DetailedItemPriceInfo object.ItemPriceInfo class contains the following properties. which are modified by the item pricing calculators and returned by the item pricing engines: • listPrice: The base price of an item before any modifications are made.µ • • ATG Commerce Programming Guide The AmountInfo class is designed only to hold data. and the ItemPricingEngine. This information is useful if you need to determine how the object arrived at its current price (for example.pricing.priceItem check if the priceInfo for the object being priced has amountIsFinal=true. Calculated by multiplying the quantity by the listPrice. that priceInfo is immediately returned. If true. for customer service requests). It also contains detailed price information about how individual quantities of the CommerceItem were priced. amountIsFinal: Indicates if the amount is final. discounted: Indicates whether this quantity of items has been discounted. or the list price. ItemPriceInfo The atg. currentPriceDetails: A list of DetailedItemPriceInfo objects that constitute a breakdown of the price represented by this object. the items either have no price. quantityAsQualifier: The quantity of the item that acted as a qualifier for any discount. priceList: The priceList used to calculate the price. For example. onSale: Indicates whether the price for an item is on sale. If it is set to true. quantityDiscounted: The quantity of the item to which any type of discount has been applied. If using tiered pricing. 170 9 . • • • amount: The raw number that represents the price. and Shipping PricingEngines. The sum of the amounts of these DetailedItemPriceInfos should always equal this object’s amount. The Tax. • The ItemPriceInfo class contains information about the price of an item (a CommerceItem). pricingAdjustments: Provides an audit trail of everything that happened to the AmountInfo up to this point. If the flag is false.Using and Extending Pricing Services . salePrice: The sale price of an item before any modifications are made. The following list describes important properties in the AmountInfo class: currencyCode: Indicates the currency of the price. • • • • • • • rawTotalPrice: The base price for the item. orderDiscountShare: The amount of all order discounts that applied to this item. this number is the average of the unit prices (total divided by quantity purchased). then this price is final and will never be recalculated.commerce.

One DetailedItemPriceInfo entry for the quantity of 2. get 1 free” then the amount property of the ItemPriceInfo would be $90. This is used for two reasons: • To split the details of items in different shipping groups. Another feature of DetailedItemPriceInfo is the range property. The amount property of the ItemPriceInfo is the final price for the given CommerceItem. and 3 items received Discount A and the other two received Discount B. There is a range property in ShippingGroupCommerceItemRelationship. If part of the quantity of the CommerceItem was discounted due to a promotion. see the ItemPriceInfo section. For more information on the ItemPriceInfo object. Instead of a detail referring to “5 items” it is more specific and refers to “the first 5 items” or “items 2-6”. if the order contains 10 shirts at $10. this information is reflected in the ItemPriceInfo. DetailedItemPriceInfo object #2: quantity: 1 amount: $0. and one with the promotion that caused the item to be free. DetailedItemPriceInfo This section describes DetailedItemPriceInfo objects. describing the changes discount A made to the price. The PricingAdjustments in the ItemPriceInfo would contain one PricingAdjustment for the list price. The ItemPriceInfo object describes the price for an entire CommerceItem in an order. One with the list price.00 PricingAdjustment: set to the list price. In the example above. describing the changes discount B made to the price.00 PricingAdjustment: There would be two PricingAdjustments. and there was a promotion “Buy 9 shirts. if an item’s quantity is 5. and one for the promotion. there would be two DetailedItemPriceInfo entries in currentPriceDetails: • • One DetailedItemPriceInfo entry for the quantity of 3. The DetailedItemPriceInfo objects provide a much more detailed view of the price of the item.Using and Extending Pricing Services . • During qualification of a promotion (the process of determining if a particular promotion applies to the order) we need to know which items have been looked at 171 9 .ATG Commerce Programming Guide µ For example. For example. Information in this section includes how DetailedItemPriceInfo objects relate to each other and to their ItemPriceInfo. DetailedItemPriceInfo objects cannot refer to items in more than one shipping group.00. The amount property of ItemPriceInfo (inherited from AmountInfo) should always equal the sum of the amounts of the DetailedItemPriceInfo entries in currentPriceDetails.00 each. there would be two DetailedItemPriceInfo objects: DetailedItemPriceInfo object #1: quantity: 9 amount: $90.

The logic for making sure that each detail only refers to items in one shipping group is contained in this method: pricingTools. • To make sure all of the above statements are true. They can usually look up a list price and multiply it by the quantity.Using and Extending Pricing Services . Profile . The following statements are true for all CommerceItem objects: Each CommerceItem has exactly one ItemPriceInfo.µ • • • ATG Commerce Programming Guide and which items have already qualified a promotion. The following sections describe how the three different types of item calculators interact with DetailedItemPriceInfos: • • • Using List Price Calculators with DetailedItemPriceInfo Objects Using Sale Price Calculators with DetailedItemPriceInfo Objects Using Item Discount Calculators with DetailedItemPriceInfo Objects Using List Price Calculators with DetailedItemPriceInfo Objects The list price calculators are responsible for calculating the price based on the list price. For more information. or the second shirt. etc. The price of a particular item (if there are 10 shirts.detailedItemPriceTools. Locale .The total price for which the new DetailedItemPriceInfo objects must account.The person for whom the items are to be discounted (currently ignored). the same sale price.) is described by exactly one detail. and the same promotions.The CommerceItem being priced.createInitialDetailedItemPriceInfos This method takes the following parameters: • TotalPrice . If the entire quantity of the item is being shipped to the same place. each ItemPricingCalculator has the responsibility of manipulating the DetailedItemPriceInfos correctly. TotalPrice is the price of the entire CommerceItem (listPrice * quantity). PriceQuote . see the Qualifier Class section. (The same list price. PriceQuote is the ItemPriceInfo • • • • • to which the newly created details will be added.The discount that will be set in the PricingAdjustment (usually null). This is needed to get to the ShippingGroupCommerceItemRelationships. Item . there will only need to be one DetailedItemPriceInfo. Each DetailedItemPriceInfo in the ItemPriceInfo describes the price of a quantity of items that are all priced in exactly the same way.The current working price of Item. the first shirt.) All the items described by a DetailedItemPriceInfo are in the same shipping group.The locale in which the items are to be discounted (currently ignored). 172 9 . PricingModel .

This calculator splits the details since each quantity of the item will not necessarily get the same unit sale price. This is taken from the ItemPriceInfo to which the newly created details will be added. This will usually be the entire list of details. It is the responsibility of the caller to update the ItemPriceInfo objects. This is ignored in the default implementation.The person for whom the items are to be discounted (currently ignored). UnitSalePrice . The entire quantity gets the same price. This functionality is contained in a centralized method: pricingTools. This method will only modify the DetailedItemPriceInfo objects.detailedItemPriceTools.assignSalePriceToDetails. Item .Any extra information that this method might need to set the number of the qualifying item (currently ignored). Using Sale Price Calculators with DetailedItemPriceInfo Objects The calculators responsible for calculating the sale price usually change the price of the entire quantity. The total adjustment for each detail is this amount times the quantity of the detail.Using and Extending Pricing Services .CommerceItem being priced.Any extra information that this method might need to set the prices of a number of the qualifying item(currently ignored). and then modifies the amount accordingly. there is another version of this method that also takes a Range argument. This is also ignored. These parameters are the only parameters required to perform list pricing and bulk pricing. The assignSalePriceToDetails method takes the following parameters: • • • • • • • • • DetailedItemPriceInfos .The adjustment description used when creating all new PricingAdjustments that is added to each new detail.The locale in which the items are to be discounted (currently ignored). AdjustmentDescription .The current working price of Item. ExtraParameters . PricingModel . It is the responsibility of the caller to update the ItemPriceInfo.This is the adjustment description used when creating all new PricingAdjustments. To facilitate tiered pricing. PriceQuote . Profile .The discount that will be set in the PricingAdjustment (usually null). The ItemTieredPriceCalculator will call this method once per tier. The calculator retrieves the sale price. the TotalPrice is the price for the range as opposed to the entire CommerceItem.The list of DetailedItemPriceInfo objects that should be adjusted. AdjustmentDescription . 173 9 . This method will only modify the DetailedItemPriceInfo objects. The assignSalePriceToDetails method walks through each detail and adjusts the amount accordingly. This means that new details will only be created for the given range. In this case.The sale price for a single given CommerceItem. There is no reason to create any new details.ATG Commerce Programming Guide µ • • ExtraParameters . Locale . One sale calculator that does not use this method is the ItemSalesTieredPriceCalculator. subtracts the list price.

• nonTaxableShippingItemsSubtotalPriceInfos: A map of shipping group IDs to all OrderPriceInfo properties that describe the prices of the totals of the nontaxable items in the order’s shipping groups. it calls pricingTools. total: The current working total. tax. It modifies the current detail to be discounted and changes its price.commerce.detailedItemPriceTools. this property does not apply. shippingItemsSubtotalPriceInfos: A map of shipping group IDs to all OrderPriceInfo properties that describe the prices of the shipping groups. the ItemDiscountCalculator frequently splits details. Ranges—The list of Ranges that should have a DetailedItemPriceInfo. This method takes the current detail and creates enough new details so that there is one per Range that is passed in.splitDetailsAccordingtoRanges. with each detail. which are modified by order pricing calculators and returned by order pricing engines: • taxableShippingItemsSubtotalPriceInfos: A map of shipping group IDs to OrderPriceInfo properties that describe the prices of the totals of the taxable items in the order’s shipping groups. The OrderPriceInfo class contains the following properties. 174 9 . manualAdjustedTotal: The total value of manual adjustments on the order. and shipping costs. It creates a new DetailedItemPriceInfo for the undiscounted portion and set its quantity to the number of undiscounted items.Using and Extending Pricing Services . Therefore. Manual • • adjustments are applied using the Commerce Service Center. All the details are returned. • • • • rawSubTotal: The subtotal of the order before applying order-level promotions.OrderPriceInfo class contains information about the price of an order. This method takes the following parameters: • • Detail—The DetailedItemPriceInfo to split apart. Using Item Discount Calculators with DetailedItemPriceInfo Objects The calculators that are responsible for discounting the price based on a promotion usually only adjust the price for some subset of the quantity. including all promotions.pricing. if you are not using that application.µ ATG Commerce Programming Guide Therefore it usually splits each detail to maintain the property that each item in a detail was priced in exactly the same way (this includes having the same unit sale price). OrderPriceInfo The atg. Then. tax: The tax on the order. shipping: The shipping cost of the order. The size of these must equal the quantity of Detail. What our implementation of the ItemDiscountCalculator does is figure out the range that is undiscounted and figure out the range that is discounted.

• 175 9 .ATG Commerce Programming Guide µ ShippingPriceInfo The atg. Tax. countyTax: Indicates any county tax.scheduler. Order.commerce. locale. and other configuration functionality.pricing.TaxPriceInfo class represents tax price information.commerce. It contains the following properties.Scheduler that this service uses to run the globalPromotionsQuery. It contains the following property. TaxPriceInfo The atg. The TaxPriceInfo contains the tax price information for only the items that appear in that shipping group. cityTax: Indicates any city tax. which are then passed to into pricing engine methods. • • • • • Pricing Engine Classes This section describes the following pricing engine classes: • • PricingEngineService Item. which are modified by tax pricing calculators and returned by tax pricing engines.Using and Extending Pricing Services . and Shipping Pricing Engine Classes ItemPricingEngineImpl ShippingPricingEngineImpl TaxPricingEngineImpl OrderPricingEngineImpl PricingEngineService The PricingEngineService class is a GenericService implementation of a PricingEngine. stateTax: Indicates any state tax. countryTax: Indicates any country tax.ShippingPriceInfo class contains information about the price of a ShippingGroup.service. updateSchedule: The schedule for running the globalPromotionsQuery. The PricingEngineService class contains the following properties: • scheduler: The atg. which is modified by shipping pricing calculators and returned by shipping pricing engines: • rawShipping: Represents the shipping price before any promotions or adjustments are applied.pricing. PricingEngine implementations can extend this class to leverage scheduling. Re-running the query generates a new list of global promotions. global promotions. districtTax: Indicates any district or territory tax. • shippingItemsTaxPriceInfos: A map of shipping group IDs to TaxPriceInfo objects.

µ • • prices. ItemPricingEngine sets this to ItemPriceInfo. It computes the price of items both individually and in a larger context. As described earlier in How Pricing Services Generate Prices. For example. • • • • • ATG Commerce Programming Guide defaultLocale: The default locale in which this pricing engine should generate priceInfoClass: The class of the prices that this engine generates. It computes the shipping cost for an order by invoking a series of ShippingPricingCalculators. each engine calls a series of calculators as follows: 1. The ShippingPricingEngineImpl class is an implementation of the ShippingPricingEngine interface. promotionItemTypes: An array of item descriptor names in the repository shown in the promotionsRepository property. The TaxPricingEngineImpl is an implementation of the TaxPricingEngine interface. profileProperties: A list of profile properties to be checked for active promotions. It invokes a series of ItemPricingCalculators. promotionsRepository: The name of the repository that holds the promotions this engine can use. • Item. This property is configured based on the class extension. Order. which is described in the previous section. A typical way to mark global promotions is to have assign all promotions in the promotionsRepository a boolean property global. The OrderPricingEngineImpl class is an implementation of the OrderPricingEngine interface. Tax. It computes the tax for an order. PricingEngineService. It invokes them on the input pPriceQuote in the order in which they appear in its preCalculators property. • • • Each of these implementation classes also extends the abstract class. pricingModelComparator: The comparator used to sort promotions. It computes the price for an order. 176 9 . globalPromotionsQuery: An RQL query that is run on the promotionsRepository to return all promotions that should always be taken into account in every pricing. A promotion that this engine uses as a pricing model must be of one of the types in promotionItemTypes. pricingModelProperties: A configuration bean that holds the name of every property of a pricing model RepositoryItem. and Shipping Pricing Engine Classes The following four classes are implementations of their respective pricing engine interfaces: • The ItemPricingEngineImpl class is an implementation of the ItemPricingEngine interface. invoking a series of OrderPricingCalculators. invoking a series of TaxPricingCalculators.Using and Extending Pricing Services . and to have the query return all promotions whose global property value is true. The engine invokes one or more preCalculators to provide a base price to which subsequent calculators can then apply a discount.

and then it processes the promotions one at a time. tax. 3. They can be extended according to your pricing needs. It invokes them on the input pPriceQuote in the order in which they appear in its postCalculators property. the OrderPricingEngineImpl calls OrderPricingCalculators and the TaxPricingEngineImpl calls TaxPricingCalculators. Pricing Calculator Classes These classes are used by the ATG Commerce item. Again. each pricing engine calls postcalculators of its own type. (Discount calculators are specified in a promotion’s pricingCalculatorService property. and shipping pricing engines to calculate prices.ATG Commerce Programming Guide µ (Each type of engine calls its corresponding type of precalculator – for example.) Finally the engine invokes any postCalculators configured for it.Using and Extending Pricing Services . • • DiscountCalculatorService Item Calculator Classes ItemPriceCalculator ItemDiscountCalculator ItemDiscountMultiplierCalculator ItemListPriceCalculator ItemSalePriceCalculator ConfigurableItemPriceCalculator • Order Calculator Classes OrderDiscountCalculator OrderSubtotalCalculator • Shipping Calculator Classes ShippingCalculatorImpl ShippingDiscountCalculator PriceRangeShippingCalculator DoubleRangeShippingCalculator FixedPriceShippingCalculator PropertyRangeShippingCalculator WeightRangeShippingCalculator • Tax Calculator Classes NoTaxCalculator TaxProcessorTaxCalculator 177 9 . order. The engine uses its getPricingModels method to extract any promotions from the customer’s profile. invoking the discount calculators from each one.) 2.

pricing.ItemPriceCalculator is the parent class for many item pricing calculators (for example. ItemListPriceCalculator and ItemSalePriceCalculator). and the discount amount. ItemPriceCalculator extends ApplicationLoggingImpl. It holds information common to all the discount calculators. ItemPriceCalculator The abstract class atg. This property determines what happens when a discount would cause the amount to be negative. It contains a single abstract method: priceItems. • • pricingModelProperties: Points to a configuration bean that holds the names of all the properties of a pricing model repository item.0 when a discount causes an amount to be negative.DiscountCalculatorService class is an extension of GenericService. and the current price.pricing.Using and Extending Pricing Services . It calculates a price based on an existing price. which can extend this class to eliminate redundant configuration code. Extending classes implement this method to leverage the other item pricing functionality that this class provides. The following list describes important properties in the DiscountCalculatorService class: • qualifierService: Specifies the Qualifier service that performs the actual evaluation of the discount rule against the running environment. This class determines a price for an object based on a pricesource object and the properties of that pricesource. For more information. This functionality is used by all discount calculators. The adjust method can be used as a quick way to apply a discount. consolidating the functionality that these calculators have in common. so classes that extend it have access to Nucleus logging services. the discount type.commerce. negativeAmountException: ATG Commerce never discounts the price of an object to less than zero. 178 9 .µ • Price List Calculator Classes Price List ItemListPriceCalculator Price List ItemPriceCalculator Price List ItemSalesPriceCalculator ATG Commerce Programming Guide Price List ConfigurableItemPriceListCalculator Price List ItemSalesTieredPriceCalculator Price List ItemTieredPriceCalculator DiscountCalculatorService The atg. see Qualifier Class. False: (default) Log a warning message and set the amount to 0.commerce. DiscountCalculatorService computes a price based on the type of discount. True: Throw an exception when a discount causes an amount to be negative. The ItemPriceCalculator class also contains the following properties: • loggingIdentifier: The ID that this class uses to identify itself in logs. the discount amount.

getPriceSource: Returns the catalogRef property of the input CommerceItem if priceFromCatalogRef is true. The catalogRef property of items to be priced points to a SKU in the SKU catalog. In this example.00 When a CommerceItem is passed to the ItemListPriceCalculator. this particular Itemlistpricecalculator looks at the item’s catalogRef property (SKU) and retrieves the value of 179 9 . see the atg. The priceSource object can be one of two objects. The productRef property points to a product in the product catalog. the ItemListPriceCalculator is set with the following properties: • • priceFromCatalogRef=true (indicating it will get its property from a SKU) pricePropertyName=listPrice. That SKU has the following properties: • • • color = blue itemType = shorts listPrice = 10. which extend ItemPriceCalculator) identifies the property on the priceSource object (the SKU or product) which contains the price for the current item. getPriceSource returns the productRef property. In this example. the SKU catalog contains a SKU that identifies blue shorts. depending on the boolean value of the priceFromCatalogRef property. The ItemListPriceCalculator and ItemSalePriceCalculator read this value and return a price object that contains the price.ATG Commerce Programming Guide µ • pricePropertyName: The name of the property of the priceSource that represents an item’s price. getPriceSource returns the productRef property. getPriceSource returns the catalogRef property of the input CommerceItem. • ItemPriceCalculator determines an item’s price based on a property value. The property value comes from a priceSource object. The pricePropertyName in the ItemPriceCalculator (and therefore the ItemListPriceCalculator and ItemSalePriceCalculator. • requirePriceValue: If this property is true. For more information.Using and Extending Pricing Services . Examples of How Classes that Extend ItemPriceCalculator Determine Prices The ItemListPriceCalculator extends ItemPriceCalculator. If false. • • If true.CommerceItem entry in the ATG API Reference. the priceSource object is the catalogRef property of the item to be priced. If priceFromCatalogRef is false.commerce. • priceFromCatalogRef: If this property is true. the priceSource object is the productRef property of the item to be priced.order. If this property is false. The priceSource is the value returned from the getPriceSource property. an exception is thrown if the priceSource of the CommerceItem does not have its pricePropertyName property set.

if an item originally costs $20. The calculator then gets the sale price using the SKU’s salePrice property. a percentage. and it would show that the ItemSalePriceCalculator was responsible for the change. the onSale property would be set to true. The adjustment would be -3.00). When an item is passed to the ItemSalePriceCalculator. For example. • • • • • color=blue itemType=shorts listPrice=10. The ItemListPriceCalculator then modifies the input price to be 10. The ItemSalePriceCalculator has an additional property called onSalePropertyName. For more information on the default implementation of this class.ItemDiscountCalculator class calculates the new price for an item or items based on a given pricing model. In this example.00 onSale=true salePrice=7.Using and Extending Pricing Services . The onSalePropertyName property of ItemSalePriceCalculator is set to onSale. the new price is $15.00.00. refer to the Default Item Discount Calculator section.µ ATG Commerce Programming Guide that object’s listPrice property (10.00 and registers that a change has been made to the price. A SKU in the SKU catalog has a property called onSale. it uses the value of the SKU’s onSale property to determine if it’s on sale. and $5 is taken off the price.commerce. which is a boolean property on the priceSource object that indicates whether the item is on sale. In this example. The ItemSalePriceCalculator works almost the same way. The discount can be a fixed amount. The 180 9 . This registering is done by creating a new PricingAdjustment and adding it to the adjustments property of the price object. It calls Qualifier. ItemDiscountMultiplierCalculator The atg.pricing. ItemDiscountCalculator The atg.ItemDiscountMultiplierCalculator class adjusts the amount of a discount by factor N.pricing. The pricePropertyName property is set to salePrice. It applies the discount that the pricing model describes to the price in the ItemPriceInfo corresponding to each passed CommerceItem. The calculator then modifies the input price for the item to be 7.00 When the ItemSalePriceCalculator receives this item.00 and returns it. the value is true. The ItemDiscountCalculator inherits all the properties of DiscountCalculatorService. where N is the adjuster amount defined in a PricingModel. The price in this case is 7. or a fixed price. it has a catalogRef property that points to a SKU from the SKU catalog. indicating that the SKU is on sale. which in this case is an ItemPriceInfo. If a SKU were on sale.findQualifyingItems to get this list. the priceFromCatalogRef property of ItemSalePriceCalculator is set to true. The ItemDiscountCalculator class performs this discounting by consulting the Qualifier service for a list of items that should receive the input discount.commerce.

ItemSalePriceCalculator class extends the ItemPriceCalculator. For more information on the default implementation of this class. Then the overridden adjust method defined in this class determines the new adjustment. A price source is the catalogRef or productRef of a CommerceItem. The ItemPriceCalculator section includes an example of how the ItemSalePriceCalculator determines a price. The ItemListPriceCalculator sets the listPrice property of the input price object to the input Price. It computes the price of the configurable item by adding up the price of all the individual subSKUs and the price of the configurable SKU.Using and Extending Pricing Services . If one of the pricing methods of ItemSalePriceCalculator is invoked. ItemListPriceCalculator The atg.commerce. ItemSalePriceCalculator The atg. This is typically the first in a series of calculations.commerce. It calculates the list price of a configurable item and sets the itemPriceInfo to that amount. If the number N is 2. This calculator could be used to create promotions such as “Double Coupon Days.ItemListPriceCalculator class is a calculator that determines the list price of an item and sets the itemPriceInfo to that amount. ItemDiscountCalculator. If the configurable item is on sale then the sale price will also be modified. The ItemPriceCalculator section includes an example of how the ItemListPriceCalculator determines a price. This class extends the ItemPriceCalculator. It determines the sale price of an item and discounts the itemPriceInfo to that amount. all input items are discounted to the sale price. is used to determine which items qualify for getting a double discount. refer to the Default Item Discount Multiplier Calculator section. The list price is determined based on the value returned from the getPriceSource property. with this calculator providing a starting price for other calculators. This class also maintains the audit trail of the ItemPriceInfo.pricing. ConfigurableItemPriceCalculator The atg.pricing. the new discount amount would be $10 and the new price would also be $10.” The parent class. 181 9 . The ItemSalePriceCalculator class also contains the following property: • onSalePropertyName: The boolean property of the price source that determines if the price source is on sale. This sets the list price with the prices of the subSKUs that are configured in the configurable item.commerce.pricing.ConfigurableItemPriceCalculator class extends the ItemPriceCalculator. There is no rule associated with this calculator.ATG Commerce Programming Guide µ ItemDiscountMultiplierCalculator takes this discount amount and multiplies it by the number N.

For more information on the default implementation of this class. This calculator consults the Qualifer service.commerce.OrderSubtotalCalculator class computes the rawSubtotal and amount of an OrderPriceInfo that corresponds to the input order. The implementation of priceShippingGroup checks that there are items in the shipping group.ShippingDiscountCalculator class calculates ShippingPriceInfos for specified ShippingGroups.pricing. the price quote is reset to zero. implement the getAmount method as the base shipping cost in this calculator. UPS 2-day or UPS Next Day. refer to the Default Shipping Discount Calculator section. soft goods. If the addAmount property is true. the amount returned is added to the current ShippingPriceInfo amount. The order’s subtotal is always calculated by summing the prices of the items in the order. Set the shippingMethod property to the name of a particular delivery process that your site offers. If a pricing model is passed in. For example.commerce. If there are no items. it is ignored. For more information on the default implementation of this class. OrderSubtotalCalculator The atg. The amount returned is set into the ShippingPriceInfo.pricing. it computes a ShippingPriceInfo based on the input PricingModel (RepositoryItem). refer to the Default Order Discount Calculator section. Unlike in the case of discount calculators.commerce.findQualifyingOrder. This calculator consults the Qualifer service for the ShippingGroup to be priced. If there are items to price for shipping.ShippingCalculatorImpl class is an abstract class that acts as a starting point for general price calculation in shipping groups. It calculates OrderPriceInfo values for orders when the calculator is invoked.OrderDiscountCalculator class implements the OrderPricingCalculator. should not be priced for shipping. It calls Qualifier.pricing. If it gets back a ShippingGroup. the performPricing method confirms that the items in the group should be priced. ShippingCalculatorImpl The atg. for example UPS Ground.commerce. In addition. this calculator always attempts to perform pricing. This option is useful for situations in which you do not want to give customers a choice of different shipping methods. ShippingDiscountCalculator The atg. If it gets back an order. This behavior allows for the addition of surcharges. If the ignoreShippingMethod property is true.findQualifyingShipping.µ OrderDiscountCalculator ATG Commerce Programming Guide The atg.pricing. there is no rule that determines whether the subtotal should be calculated. an OrderPriceInfo is computed based on the input PricingModel (RepositoryItem). then the calculator does not expose a shipping method name (through getAvailableMethods). looking for the order to be priced by calling Qualifier.Using and Extending Pricing Services . When extending this class. 182 9 . such as gift certificates.

With the given array of price range configurations (format: low:high:price).\ 41. instead of setting the price quote amount to the value of the amount property.25.99:4. For example: ranges=00.99:6. the calculator adds the amount to the current amount in the price quote. and WeightRangeShippngCalculator classes.00:30.00:15. For example: ranges=00. • • shippingMethod: The shippingMethod property is set to the name of a particular delivery process.50.00:MAX_VALUE:10.commerce. For example: UPS Ground.00 Note: The keyword MAX_VALUE indicates the maximum possible value in the range. UPS 2-day or UPS Next Day.00:30. ignoreShippingMethod: Setting the ignoreShippingMethod property to true prevents this calculator from exposing the shipping method name (through getAvailableMethods).99:7.\ 16.\ 41. which increases the shipping price. This can be used to configure a “surcharge” calculator. The service is configured through the ranges property. the calculator adds the amount to the 183 9 .PriceRangeShippingCalculator class determines the shipping price based on the subtotal of all the items in the shipping group.00:40. the service parses the values into their double format for calculating shipping costs.commerce.\ 31.DoubleRangeShippingCalculator class is an abstract shipping calculator that determines the shipping price by comparing a value from the ShippingGroup to a series of ranges.00.99:7.\ 16.50. PropertyRangeShippingCalculator.99:6.\ 31.pricing.pricing. With the given array of price range configurations (format: low:high:price) the service parses the values into their double format for calculating shipping costs. It is extended by the PriceRangeShippingCalculator.Using and Extending Pricing Services .00 Note: The keyword MAX_VALUE indicates the maximum possible value in the range.00. instead of setting the price quote amount to the value of the amount property. In addition.00:MAX_VALUE:10.00:15.00:40. The service is configured through the ranges property.25.ATG Commerce Programming Guide µ PriceRangeShippingCalculator The atg. DoubleRangeShippingCalculator This atg. This option is useful for situations in which you do not want to give customers a choice of different shipping methods. The DoubleRangeShippingCalculator also contains the following properties: • addAmount: If the property addAmount is true. The PriceRangeShippingCalculator also contains the following properties: • addAmount: If the property addAmount is true.99:4. this calculator always attempts to perform pricing.

for example UPS Ground.00:15.Using and Extending Pricing Services . PropertyRangeShippingCalculator The atg. each of which has a weight of 1. To base shipping cost on the cumulative weight total.commerce.25.00. this calculator always attempts to perform pricing. • • shippingMethod: The shippingMethod property is set to the name of a particular delivery process.99:7. UPS 2-day or UPS Next Day.00:MAX_VALUE:10. This behavior can be used to configure a “surcharge” calculator.00:40. which increases the shipping price.99:4. This behavior can be used to configure a “surcharge” calculator. For example: UPS Ground. ignoreShippingMethod: Setting the ignoreShippingMethod property to true prevents this calculator from exposing the shipping method name (through getAvailableMethods).pricing.commerce. ATG Commerce calculates a total of 3 and uses the ranges property to determine how much to charge.pricing. the calculator adds the amount to the current amount in the price quote. which increases the shipping price. The FixedPriceShippingCalculator also contains the following properties: • addAmount: If the property addAmount is true.50.PropertyRangeShippingCalculator class is a highly-flexible shipping calculator that identifies some item property and adds the value provided to each item in the shipping group together to create a shipping group total.\ 31.FixedPriceShippingCalculator class is a shipping calculator that sets the shipping amount to a fixed price. For example. this calculator always attempts to perform pricing. ignoreShippingMethod: Setting the ignoreShippingMethod property to true prevents this calculator from exposing the shipping method name (through getAvailableMethods).00:30. In addition. which provides a shipping cost for each range. FixedPriceShippingCalculator The atg. all items may have a property called weight that correlates to the weight of the item in pounds.\ 16. This option is useful for situations in which you do not want to give customers a choice of different shipping methods.99:6. shippingMethod: The shippingMethod property is set to the name of a particular delivery process.00 184 9 .µ • • ATG Commerce Programming Guide current amount in the price quote. you set the PropertyRangeShippingCalculator propertyName property to weight. If your shipping group has 3 items. instead of setting the price quote amount to the value of the amount property. UPS 2-day or UPS Next Day. The range property takes the format of low:high:price and holds these options: ranges=00. The total falls into one of the ranges specified in the ranges property.\ 41. In addition. This option is useful for situations in which you do not want to give customers a choice of different shipping methods.

\ 16. • useCatalogRef: If the useCatalogRef property is set to true. • propertyName: Set the propertyName property to the name of the property that you want to add across all items.00:MAX_VALUE:10.00 Note: The keyword MAX_VALUE indicates the maximum possible value in the range. the calculator adds the amount to the current amount in the price quote. 185 9 . • • shippingMethod: The shippingMethod property is set to the name of a particular delivery process. the product is used as the source. instead of setting the price quote amount to the value of the amount property.00:30.WeightRangeShippingCalculator class is a shipping calculator that determines the shipping price based on the sum of the weights of each item in a shipping group.00:40. The service is configured through the ranges property. For example. For example: ranges=00. This can be used to configure a “surcharge” calculator.00:15.ATG Commerce Programming Guide µ In this example. WeightRangeShippingCalculator The atg.25. instead of setting the price quote amount to the value of the amount property. UPS 2-day or UPS Next Day. For example: UPS Ground. Note that keyword MAX_VALUE indicates the maximum possible value in the range. With the given array of price range configurations (format: low:high:price). UPS 2-day or UPS Next Day.pricing. the service parses the values into their double format for calculating shipping costs. For example: UPS Ground. the property value is extracted from the catalogRef of the CommerceItem (usually the SKU).99:7. the calculator adds the amount to the current amount in the price quote.commerce.Using and Extending Pricing Services . • shippingMethod: The shippingMethod property is set to the name of a particular delivery process. this calculator always attempts to perform pricing. “weight” would calculate the total weight of an order by adding together the weight property values of all the items. This can be used to configure a “surcharge” calculator. This option is useful for situations in which you do not want to give customers a choice of different shipping methods.50. ignoreShippingMethod: Setting the ignoreShippingMethod property to true prevents this calculator from exposing the shipping method name (through getAvailableMethods).99:6. which increases the shipping price.99:4.50.00. shipping charges total $4. In addition.\ 41. The PropertyRangeShippingCalculator also contains the following properties: • addAmount: If the property addAmount is true. which increases the shipping price. The WeightRangeShippingCalculator also contains the following properties: • addAmount: If the property addAmount is true. If useCatalogRef property is set to false.\ 31.

This class consults a TaxProcessor (an implementation of the atg. tax is calculated by total order. For more information.commerce. Note: The default TaxProcessor for ATG Commerce is /atg/commerce/payment/DummyTaxProcessor. See Integrating CyberSource with ATG Commerce for more information. 186 9 . TaxProcessorTaxCalculator class has the following properties: • taxStatusProperty: The property in the SKU repository that indicates whether each SKU is taxable or not. • • • • • taxProcessor: The ATG tax integration that this calculator consults for tax amounts. the calculator calculates tax by shipping group. The TaxProcessorTaxCalculator component is located in the ACC at atg/commerce/pricing/calculators. The default is /atg/commerce/pricing/PricingTools. The ConfigurableItemPriceListCalculator calculator then iterates through the subSKUs and modifies the list price and amount accordingly.TaxProcessor interface) to determine how much tax to charge for an order. orderManager: The location of the OrderManager class instance. NoTaxCalculator The atg. the TaxProcessor verifies the addresses passed in before attempting to calculate tax. ItemListPriceCalculator calculator sets the list price and the amount of the ItemPriceInfo based on the price of the ConfigurableSku. refer to Integrating Third-Party Software With ATG Commerce.TaxProcessorTaxCalculator class if you are setting up a site that uses third-party software such as CyberSource to handle tax calculation.µ • ATG Commerce Programming Guide ignoreShippingMethod: Setting the ignoreShippingMethod property to true prevents this calculator from exposing the shipping method name (through getAvailableMethods).tax. this calculator always attempts to perform pricing. calculateTaxByShipping: If true.” Price List ConfigurableItemPriceListCalculator The ConfigurableItemPriceListCalculator calculator assumes the ItemListPriceCalculator has already run. pricingTools: The location of the PricingTools class instance.pricing. This option is useful for situations in which you do not want to give customers a choice of different shipping methods.pricing. verifyAddresses: If true. currently either CyberSourceTax or TaxWareTax.NoTaxCalculator class creates a new TaxPriceInfo object that specifies a tax price of zero for an order.commerce. The default is /atg/commerce/order/OrderManager.Using and Extending Pricing Services .payment. If false. which always returns “no tax. In addition. TaxProcessorTaxCalculator You use the atg.

See the Price List Calculators section of the Using Price Lists section of this chapter. 187 9 . pricingSchemeNames: the Map whose key is the allowed scheme names and whose value is the corresponding calculators. Price List ItemListPriceCalculator A calculator that determines the list price of an item and sets the itemPriceInfo to that amount. then coming into this calculator the listPrice will be $5 and the amount will be $10. The pricing scheme for that item is list pricing. consider a situation when a parentSKU is $5.ATG Commerce Programming Guide µ For example. profilePriceListPropertyName: the property name in the repository for the user’s price list.Using and Extending Pricing Services . The ItemListPriceCalculator component is located in the ACC at atg/commerce/pricing/calculators/ ItemListPriceCalculator. It first selects the priceList to use based on the profilePriceListPropertyName property. See the Price List Calculators section of the Using Price Lists section of this chapter. pricingSchemePropertyName: the property name in the repository for the pricing scheme. If we buy two of this configurable SKU. • • priceListManager: points to the location of the PriceListManager. NullPriceListIsError: If true. For more information on this calculator. The ItemPriceListCalculator component is located in the ACC at atg/commerce/pricing/calculators/ItemPriceListCalculator. The ItemPriceCalculator then delegates the pricing to different ItemSchemePriceCalculators based on the item’s pricing scheme by the pricingSchemePropertyName property. then the default price list is never used. For more information on this calculator. and the price list is null. If false. then nothing happens. See the Price List Calculators section of the Using Price Lists section of this chapter. For more information on this calculator. If false. The ConfigurableItemPriceListCalculator component is located in the ACC at atg/commerce/pricing/calculators/ConfigurableItemPriceListCalculator. It has the following properties: • • • • loggingIdentifier: the ID that this class uses to identify itself in logs. then an error is thrown. Price List ItemPriceCalculator The ItemPriceCalculator class can either price a single commerce item or price a list of commerce items. and the price list is null or there is no price in the • price list. After the ConfigurableItemPriceListCalculator calculator runs the listPrice will be $8 and the amount will be $16. useDefaultPriceList: If true and ProfilePriceListPropertyName is null. then the value of the automaticallyUseDefaultPriceList property of the PriceListManager determines if the default price list is used. subSKU A is $2 and subSKU B is $1.

It does not decide how they should change. See the Price List Calculators section of the Using Price Lists section of this chapter. For more information on this calculator. see the Price List Calculators section of the Using Price Lists section of this chapter. For more information on this calculator. which is located in the ACC at atg/commerce/pricing/calculators/SalePriceListsTieredCalculator. however.pricing.nucleus. that the calculator alone determines the new price. In addition. The Qualifier does not modify the actual prices.commerce.GenericService. which is located in the ACC at atg/commerce/pricing/calculators/SalePriceListsListCalculator. For more information on tiered pricing. it only decides what should change. because Qualifier extends atg. • ItemDiscountCalculator uses the qualifier’s findQualifyingItems method. Price List ItemSalesTieredPriceCalculator A calculator which determines the sales tiered price of an item and sets the itemPriceInfo to be that amount. the calculator passes to the qualifier the parameters that make up its pricing context. The ItemSalesTieredPriceCalculator implements the SalePriceListsTieredCalculator component. which returns a list of QualifiedItems. which is located in the ACC at atg/commerce/pricing/calculators/PriceListsTieredCalculator. The Qualifier checks on whether anything qualifies for the discount and then figures out which pieces should receive the discount. For more information on this calculator. discounting each element with an appropriate value. Each calculator calls its corresponding helper method in the Qualifier class to determine the objects to which it should apply the discount. 188 9 . The pricing scheme for that item is tier pricing. Qualifier Class The atg. An instance of the Qualifier class is sometimes referred to as a qualifier service. The definition of tiered pricing can be referenced in ItemTieredPriceCalculator. see the Using Price Lists section of this chapter. See the Price List Calculators section of the Using Price Lists section of this chapter. findQualifyingItems returns a Collection.Using and Extending Pricing Services . The ItemSalesPriceCalculator implements the SalePriceListsListCalculator component. Price List ItemTieredPriceCalculator The ItemTieredPriceCalculator determines the tiered price of an item and sets the itemPriceInfo to that amount. Note. The calculator goes through the result set returned by the qualifier. The ItemTieredPriceCalculator implements the PriceListsTieredCalculator component.µ Price List ItemSalesPriceCalculator ATG Commerce Programming Guide The ItemSalesPriceCalculator sets the sales price for a commerce item.Qualifier class is a helper class for discount calculators.

For example. the calculator is ItemDiscountCalculator. Qualifier Properties The Qualifier class contains the following properties: • • pmdlCache: The cache that maps pricing model RepositoryItems to their parsed PMDL bean representations. The promotion contains a PMDL rule that describes the discount. A pricing engine uses its getPricingModels method to retrieve a promotion from a customer profile. For more information. The ItemDiscountCalculator calls the findQualifyingItems method in the Qualifier class and passes the current pricing context into the helper method’s input parameters. pricingModelProperties: A list of the names of the properties of a pricing model RepositoryItem. the findQualifyingItems method returns a list containing one or more CommerceItems to discount. refer to Extending the Qualifier Class. • • OrderDiscountCalculator uses the qualifier’s findQualifyingOrdermethod. 1. a rule might define a discount in which a customer receives three items for the price of one. 189 9 . In this example. The CommerceItem containing these DetailedItemPriceInfos is also stored. For more information. which returns a MatchingObject identifying the Order to discount. ItemDiscountCalculator and the findQualifyingItems method) work together to generate a price for an item. 3. QualifiedItem maps a DetailedItemPriceInfo to the list of Ranges that qualified for the discount. Each method determines it result set by comparing the PMDL rule of a given promotion (a RepositoryItem) to the input environment. 5. (For more information on promotions and PMDL rules.) The following steps describe how an existing calculator and its corresponding Qualifier class method (in this case. ShippingDiscountCalculator uses the qualifier’s findQualifyingShipping method. you may need to extend the Qualifier class by adding a new helper findQualifyingxxx method for the new calculator. The Qualifier class can be extended. If the pricing context matches the conditions specified in the PMDL rule. which returns a MatchingObject object identifying the ShippingGroup to discount. see Creating Promotions. The ItemDiscountCalculator inspects the input discount and generates a new price for each item in the returned list. see the QualifiedItem Class.ATG Commerce Programming Guide µ The component type of this collection is QualifiedItem. The promotion’s pricingCalculatorService property specifies the calculator to use to determine the amount of the discount. 4. 2.Using and Extending Pricing Services . If you create a new type of pricing calculator.

get 1 plum for $1 The order in this example is for one orange. negative prices cannot act as qualifiers.filterShippingForTarget protected method. get 1 banana for $1 Promotion #3: Buy 1 banana. discounting the plum to $1. The shipping group can use the promotion. then the orange is list price. (The Qualifier. the following three promotions are being applied to an order: Promotion #1: Buy 1 orange. If it is true. which is called by the Qualifier. one apple. If this property is set to true (the default value). (For more information. zero prices cannot act as qualifiers. checks the value of the promotion’s oneUsePerOrder property. 190 9 . the method returns false. • filterForQualifierOnSale: Indicates whether items that were priced with a sale price should be allowed to act as qualifiers. discounting the apple to $1. If this property is set to true (the default value).Using and Extending Pricing Services . and the banana is list price (since the apple was discounted). banana and plum to $1 each. In this example. If this property is set to true (the default value). The value of the filterQualifierDiscountedByAnyDiscountId changes the way the promotions are applied in the following ways: If filterQualifierDiscountedByAnyDiscountId is false. • filterForQualifierDiscountedByAnyDiscountId: Determines whether items discounted by any discount can act as qualifiers. items discounted by the current discount cannot act as qualifiers. one banana. it then checks to see if the promotion has been used elsewhere in the order. The default is true. The following example demonstrates how the filterForQualifierDiscountedByAnyDiscountId works. This property is set to False by default. then the orange is list price discounting the apple.) filterShippingForTarget: Determines whether the shipping group can receive the discount.findQualifyingShipping method. or if the promotion hasn’t been used elsewhere in the order.µ • ATG Commerce Programming Guide The following Qualifier class properties determine the objects that the evaluateQualifier method can use to evaluate the qualifier element of a PMDL rule. If this property is set to true (the default value). filterForQualifierZeroPrices: Determines whether items with zero prices can act as qualifiers. If it has. the method returns true. and one plum. get 1 apple for $1 Promotion #2: Buy 1 apple. see Replacing the Way a PMDL Rule Is Evaluated. it masks the filterForQualifierDiscountedByCurrentDiscountId property. filterForQualifierDiscountedByCurrentDiscountId: Determines whether • • • items discounted by the current discount can act as qualifiers. and the shipping group cannot use the promotion. If the oneUsePerOrder property is false.) filterForQualifierNegativePrices: Determines whether items with negative prices can act as qualifiers. If filterQualifierDiscountedByAnyDiscountId is true.

• • filterForTargetOnSale: Indicates whether items that were priced with a sale price should be allowed to receive the current discount.00. In this example. filterForTargetPriceLessThanOrEqualToPromotionPrice: Determines whether items with prices that are already less than the price that would be granted by a “fixed price” promotion should receive the promotion. filterForTargetDiscountedByCurrentDiscountId: Determines whether items that have been discounted by the current discount can receive the discount again.ATG Commerce Programming Guide µ The following Qualifier class properties determine the items that the evaluateTarget method can use to evaluate the target element of a PMDL rule. The default value is true. • filterForTargetActedAsQualifierForAnyDiscount: Determines whether items that have acted as a qualifier for any discount can receive the current discount. The ItemPricingEngine iterates through each of the promotions. Evaluating Qualifiers Example This section describes how qualifiers are evaluated using a “buy 1 get 1 free” example. The default value is false. Because neither item is on sale.00. (For more information. the promotion points to the ItemDiscountCalculator.00 and the list price of the hat of $5. The default value is true. filterForTargetZeroPrices: Determines whether items with zero prices can act as qualifiers. In this example. the following occurs during item pricing: 1. get 1 hat free” promotion is the only promotion.Using and Extending Pricing Services . The default value is true. The ItemPricingEngine iterates through each of the pre-calculators: The ItemListPriceCalculator looks up the list price of each item in the order. This will update the ItemPriceInfo for both the CommerceItem objects in the order. Based on the list prices. The pricing engine calls the calculator specified in the promotion. the “Buy 1 shirt. see Replacing the Way a PMDL Rule Is Evaluated.00 and the PMDL rule is: Condition: When order contains at least 1 (product named Shirt) Apply discount to: up to 1 (product named Hat) If the list price of the shirt is $10. The default value is true. filterForTargetDiscountedByAnyDiscountId: Determines whether items that • have been discounted by any discount can receive the discount again. 2. The priceItems method of this 191 9 .00 and the hat will be priced at $5. the shirt is priced at $10. this has no effect on the price.Fixed price” where the fixed price is $0. This example uses a promotion of type “Item Discount .) • • • filterForTargetNegativePrices: Determines whether items with negative prices can act as qualifiers. The ItemSalePriceCalculator looks up the sale price of each item in the order. The default value is true. The default value is true.

locale order orderPriceInfo The order’s price shippingGroup The shipping group that is being priced. The value is null because it’s not pricing a shipping group.findQualifyingItems.TRUE.The following arguments are passed to evaluateQualifier: Description priceQuotes Value in this example $10 and $5 A list of the two ItemPriceInfo objects. In this example. findQualifyingItems performs the following functions (as well as some standard parameter verification and error checking): wrapCommerceItems .µ ATG Commerce Programming Guide calculator calls findQualifyingItems. This calls QualifierService. none of the qualifiers apply. evaluateQualifier . The value is null because it has not been calculated yet. Current promotion Shirt and hat pricingModel Buy 1 shirt. There are three choices for the 192 9 .runs through the list of the qualifier filters. The current order being priced. this method returns Boolean. The reason this is a boolean value is because this is a when rule. In this example. items List of CommerceItem objects.creates FilteredCommerceItems for each item filterItemsForQualifier . The value is null because it’s not pricing a shipping group.Using and Extending Pricing Services . The user’s locale. shippingPriceInfo The costs associated with the shipping group that is being priced. get 1 hat free profile The current profile object. This is null if the item price is being retrieved for displaying within the catalog.

In this example.commerce. qualifyingDetailsMap: A map keyed by the DetailedItemPriceInfo objects contained in the ItemPriceInfo object (which.QualifiedItem class holds information about a CommerceItem that qualifies for a discount. QualifiedItem Class The atg. This method goes through each detail of each item that qualifies (there is only one in our case) and updates the price. Refer to Extending the ItemDiscountCalculator for more in formation on the uses of this class. we must determine which items will receive the discount. Note: Because this promotion involves a when rule. currency-related methods for use by all pricing engines. Because the promotion is valid. The item will be a MatchingObject whose matchingObject property is the hat CommerceItem and whose quantity property is 1. It also has a number of static. If this was a for rule. The calculator now knows which items should receive the discount. the list of arguments here will be the same as the list passed to evaluteQualifier. Note: If the rule were a for rule. is contained in the CommerceItem). then evaluateQualifier would return the list of items that triggered the promotion.pricing.commerce. when.findQualifyingItems method. The information includes the names of the items that qualify and their quantity. evaluateQualifier returns a boolean value. so it calls priceQualifyingItems. one item should be discounted so this method will return a List with one item in it. and for. The values are Range objects which specify which item prices in each DetailedItemPriceInfo will receive the discount.ATG Commerce Programming Guide µ condition: always. (filterItemsForTarget).pricing package.Using and Extending Pricing Services . Item pricing is now complete. PricingTools Class The atg. in turn. Assuming none of the target filters applied.PricingTools class performs a variety of pricing functions for different types of pricing engines. The first step is to filter the items for the target.commerce. QualifiedItems are returned from the Qualifier. If the promotion was “For next 1 (product named shirt)” then this method would return a List containing one MatchingObject that wrapped the “shirt” CommerceItem and had quantity 1. In the case of always and when.pricing. In ATG Commerce. we would first determine which DetailedItemPriceInfo(s) acted as the qualifier. The QualifiedItem class contains the following properties: • • item: The CommerceItem that qualified for a discount. the classes that extend the 193 9 . we can immediately evaluate the target. Call evaluateTarget. The PricingTools class is the main way that business-layer logic interacts with the pricing engines and the other classes in the atg.

Map pExtraParameters) 194 9 . Map pExtraParameters) Prices the item outside the context of an order. shippingPricingEngine: The pricing engine that calculates prices for shipping • groups. shipping. • double priceItemsForOrderTotal(Order pOrder. Locale pLocale. roundDown and needsRounding methods (see below). Map pExtraParameters) Returns the double value of the total price for all items in the order. An order has no shipping groups when it is delivered online. itemPricingEngine: The pricing engine that calculates prices for items. orders. When a store using ATG Commerce needs a price for items. Collection pPricingModels. • void priceEachItem(List pCommerceItems. RepositoryItem pProfile. or tax. • • taxPricingEngine: The pricing engine that calculates tax for orders.µ The properties of PricingTools are as follows: • • ATG Commerce Programming Guide ItemPricingDroplet class (PriceItemDroplet and PriceEachItemDroplet) use PricingTools to interface with all the ATG Commerce pricing engines. An item is identified as a set quantity of a SKU or product. and shipping is therefore not calculated for this type of order. PricingTools can be consulted to return the price. Collection pPricingModels. PricingTools includes methods that can be called to produce prices. roundingDecimalPlaces: Specifies the number of decimal places to which the an input price is rounded . both individually and in groups. These methods consult the configured pricing engines. and with no other items present. RepositoryItem pProfile. Locale pLocale. This method calls through to the priceEachItem call of ItemPricingEngine. • double priceOrderForOrderTotal(Order pOrder. PricingTools contains translation functions that identify which currencyCode goes with which locale. Collection pPricingModels. Map pExtraParameters) Prices each item as if it were in the order all by itself. Locale pLocale. An order contains one or more shipping groups when the contents of the order require shipping for delivery. In addition. the order might be discounted separately from the constituent items. RepositoryItem pProfile. Locale pLocale. the price is just the sum of the prices of the items in the order. It sets each item’s priceInfo property to be the proper price result. This price can then be used as the price for the order containing all these items. RepositoryItem pProfile. Tax is calculated on the order total. However. This property is used by the round.Using and Extending Pricing Services . Collection pPricingModels. and sets each item’s priceInfo property to be the proper price result. Typically. • void priceItem(CommerceItem pCommerceItem. orderPricingEngine: The pricing engine that calculates prices for orders. This method calls through to the priceEachItem call of the ItemPricingEngine.

The AmountInfo returned also maintains an audit trail of the adjustments made to the price by each order-level promotion. the tax for the order is computed. Map pExtraParameters) Computes tax. order tax. Uses the promotions already stored in the pricingModelHolder as factors in the prices. RepositoryItem pProfile. Locale pLocale. taking into account any shipping promotions. Takes into account the shipping promotions passed in by pPricingModels. Map pExtraParameters) Computes item prices. Unlike in the above method. the only discounts this method takes into account are those derived from the input profile. PricingModelHolder pPricingModels. Locale pLocale. Map pExtraParameters) Returns the AmountInfo object representing the order’s price. This method rounds numbers 1 through 4 down and 5 through 9 up. Collection pOrderPricingModels. RepositoryItem pProfile. Collection pItemPricingModels. and shipping costs for the input order. Collection. in addition to the promotions derived from the input profile. shipping. Collection pShippingPricingModels. It is important to always round if you are making a pricing 195 9 . • OrderPriceInfo priceOrderTotal(Order pOrder. Locale pLocale. • double round(double pNumber) Rounds the input number to the number of decimal places specified by the roundingDecimalPlaces property. • double priceShippingForOrderTotal(Order pOrder. RepositoryItem pProfile.ATG Commerce Programming Guide µ Returns the double value of the sum of the prices for all of the items in the order. If the input number has more decimal places than N. Collection pPricingModels. the input number needs to be rounded. and order prices for the input order.Using and Extending Pricing Services . In addition. the shipping costs for the order are computed. Map pExtraParameters) Computes a tax amount in the form of a double. All input promotions are factored into the price. Lastly. Takes into account the tax promotions passed in through pPricingModels. • double priceTaxForOrderTotal(Order pOrder. additionally taking any order level discounts into account. Map pExtraParameters) Computes a shipping amount in the form of a double. order total. as well as any item or order level discounts. item. which is the sum total of prices of the constituent items. • boolean needsRounding(double pNumber) Determines whether the input number needs to be rounded based on the value of the roundingDecimalPlaces property. RepositoryItem pProfile. • OrderPriceInfo priceOrderTotal(Order pOrder. • OrderPriceInfo priceOrderTotal(Order pOrder. RepositoryItem pProfile. Locale pLocale. Locale pLocale. where N is the value of roundingDecimalPlaces. pTaxPricingModels. Collection pPricingModels.

use ServletUtil. usePassedLocaleAsPricingLocale: if true. • • • Other Classes This section describes the following atg. useDefaultLocaleIfNotSpecified: If true. If false.pricing. If you create one that does not. getCurrencySymbol and getInternationalCurrencySymbol: helper methods for code that calls into PricingTools.Using and Extending Pricing Services . The caller can use this method to quickly get the symbol with which the price that PricingTools returns should be displayed.getUserLocale to determine the locale. atg.commerce. then falling back on the defaultLocale. use the defaultLocale value. defaultLocale: the locale passed in to all of the pricing engines if no other locale is passed into PricingTools. use the locale passed to getPricingLocale rather than determining a locale from the price list. The default is false. Item points to the wrapped CommerceItem. double roundDown(double pNumber) Rounds the input number to the number of decimal places specified by the roundingDecimalPlaces property. first by checking the user’s price list. and if the locale passed into the priceTotalOrder method is null. 196 9 .pricing classes: • • • • • • FilteredCommerceItem PricingModelHolder PricingAdjustment PricingCommerceItem PricingModelProperties PMDLCacheAdapter FilteredCommerceItem Represents a CommerceItem that is currently participating in a rules evaluation in the Qualifier. PricingTools also has some currency and locale properties and methods: • • getPricingLocale: method that determines the locale to use for pricing. All of the existing pricing components round.commerce. All CommerceItem methods call through to the wrapped item except for quantity. Rounds all numbers beyond the specified number of decimal places to zero. This object holds a reference to the object it is wrapping.µ • ATG Commerce Programming Guide adjustment. there may be comparison errors.FilteredCommerceItem adds two properties that are used to determine if and how the wrapped CommerceItem should participate in pricing: • quantityAsQualifierDetails: a map of DetailedItemPriceInfo objects to Range objects which state which units of the details have acted as a qualifier for something.

the PricingModelHolder is resolved from the request. that adjusted the price. Developers should not create an instance of this class and call into the PricingTools class. 197 9 . The PricingTools class uses PricingModelHolder to perform order pricing. If no pricing models are supplied as explicit parameters. This is the pattern that the item pricing servlet beans use. After deployment. which accepts a PricingModelHolder. The PricingAdjustment class contains the following properties: • • adjustmentDescription: A short description of the adjustment that this object recorded.ATG Commerce Programming Guide µ • detailsRangesValidForTarget: a map of DetailedItemPriceInfo objects to the number of each details that are available for discounting basic on the exclusion rules defined by various properties in Qualifier. You can change this time if desired. You should consider changing the reinitializeTime value if new promotions are added frequently.Using and Extending Pricing Services . pricingModel: The ID of the pricing model. If new promotions are given to the customer during the session. these collections are essentially a session cache of promotions. Each pricing engine takes only the collection of pricing models related to its own type as a parameter. and the collection is retrieved. giving a promotion two minutes after a user logs in.PricingModelHolder is a session-scoped component that holds all a customer’s active promotions while he or she is using the Web application. Setting the reinitializeTime property to a smaller value (2 minutes) will affect performance. PricingAdjustment The atg. this service queries each pricing engine and loads the customer’s pricing models. For example. Instantiate an instance of this class only as a session-scoped component that can be resolved through the request. but will minimize the risk of a user missing a promotion that is added during his or her session.PricingAdjustment class represents an element of a price’s audit trail. A PricingAdjustment is created by a pricing calculator when it modifies an AmountInfo object.commerce. this component’s initialization methods should be called so that the PricingModelHolder can query the pricing engines again for the new promotions.pricing. the user’s promotions must be reloaded for the user to see this new discount. order pricing engines take only the pricing models related to order pricing.commerce. If you create a promotion that is designed to give a discount during a user’s session. if any. The PricingTools method. These objects appear in the adjustments list of AmountInfo. PricingModelHolder atg.pricing. A chain of these objects represents all changes made to the price. You should also decrease this value if promotions are being delivered by scenarios with short delays in them. The reinitializeTime property in the pricingModelHolder is set to reload a user’s promotions every 10 minutes by default. for example. extracts individual collections and passes the collections into the appropriate pricing engines. The pricing engine APIs define a method for collecting a customer’s pricing models. Because it can be resource intensive to perform this operation.

if any. the PricingModelRepository holds all pricing models.Using and Extending Pricing Services . By default. There may be times. This CommerceItem cannot be added to an order.pricing. CommerceItems might have an adjustment of more than one. These CommerceItems cannot be used in the default order management system. see the ATG Commerce Service Center User Guide. This problem is most evident when prices are shown for products in the catalog. It contains an item descriptor called pricingModel. The PricingModelProperties class stores these names so that they may be internationalized or otherwise changed to suit a particular installation.PricingCommerceItem is a simple CommerceItem used as a placeholder while pricing items. PricingCommerceItem is an inexpensive CommerceItem class into which you can plug the product and SKU objects. For example.commerce. For example. The pricing engines can only compute prices in the context of a CommerceItem. totalAdjustment: The total adjustment. however.commerce. The total adjustment amount is calculated by multiplying the adjustment property by the quantity of the adjusted object. which are plain RepositoryItems. you must change the corresponding value here as well. when you want to price an entity for a customer and no CommerceItem is available. adjustment: The unit adjustment. The properties of this item descriptor need to appear in the PricingModelProperties class. The price adjustment per quantity of one object. Use the OrderManager APIs to add a CommerceItem to an order. quantityAdjusted: The quantity of the object whose price was adjusted. the properties have the following names: • • • • • • displayName description creationDate startDate endDate media 198 9 .µ • • • • ATG Commerce Programming Guide manualPricingAdjustment: ID of the manual adjustment that was applied to the order. which the pricing engines do not handle. PricingCommerceItem The atg.PricingModelProperties class contains the names of properties of the ItemDescriptor in the Promotions repository that represents pricing models. and “convert” them to CommerceItems.pricing. refer to the ATG API Reference. The item pricing servlet beans deal with input. For more information. Products and SKUs are usually represented by RepositoryItems. This value is calculated by dividing the value of the totalAdjustment property by the value of the quantityAdjusted property. If the name of a property descriptor is changed in the ItemDescriptor that defines the pricing models in the Promotions repository. PricingModelProperties The atg. Manual adjustments are applied by agents using CSC.

ATG Commerce Programming Guide µ • • • • • • • • • • • • • • URL version global priority type pricingCalculatorService adjuster PMDLRule uses beginUsable endUsable giveToAnonymousProfiles discountType allowMultiple PMDLCacheAdapter The atg. The Pricing Servlet Beans This section describes various ATG servlet beans that you can insert on site pages as required and use to perform dynamic pricing.commerce. You can use these implementations as they are or adapt them for your own site development needs.pricing. Default Pricing Engines ATG Commerce includes four preconfigured implementations of its pricing engine classes.PMDLCacheAdapter class is an adapter that stores PricingModels as keys mapped to their Java object representations.Using and Extending Pricing Services . 199 9 . • • • • • • AvailableShippingMethods Servlet Bean ItemPricingDroplet Servlet Bean PriceEachItem Servlet Bean PriceItem Servlet Bean PriceDroplet Servlet Bean ComplexPriceDroplet Servlet Bean Refer to Appendix: ATG Commerce Servlet Beans of the ATG Commerce Guide to Setting Up a Store for detailed information about these servlet beans.

ItemPricingEngineImpl defaultLocale^=PricingTools.ItemPriceInfo pricingModelProperties=PricingModelProperties promotionTools=. It determines the price of one or more items by retrieving applicable promotions from the customer’s profile and invoking one or more ItemPricingCalculators.pricing.. Default Order Pricing Engine The OrderPricingEngine component is a preconfigured implementation of the OrderPricingEngineImpl class. refer to the description of ItemPricingEngineImpl in the Pricing Engine Classes section. It determines the price of an entire order by invoking a series of OrderPricingCalculators.properties file: 200 9 .commerce. The following sample shows the contents of the OrderPricingEngine. It uses the same mechanisms as the ItemPricingEngine component for determining which promotions to apply.pricing.defaultLocale priceInfoClass=atg./promotion/PromotionTools profileProperties=activePromotions promotionsRepository=Promotions promotionItemTypes=\ item-discount globalPromotionsQuery=global=true AND (beginUsable IS NULL OR beginUsable <= ?0) AND (endUsable IS NULL OR endUsable >= ?0) preCalculators=\ calculators/ItemListPriceCalculator scheduler=/atg/dynamo/service/Scheduler updateSchedule=every 15 minutes in 15 minutes You can view and modify this component in the ATG Control Center.Using and Extending Pricing Services . Its location is /atg/commerce/pricing/ItemPricingEngine.µ • • • • Default Item Pricing Engine Default Order Pricing Engine Default Tax Pricing Engine Default Shipping Pricing Engine ATG Commerce Programming Guide Default Item Pricing Engine The ItemPricingEngine component is a preconfigured implementation of the ItemPricingEngineImpl class. The following sample shows the contents of the ItemPricingEngine. For more information on how to use this component.commerce.properties file: # The ItemPricingEngine service # $class=atg.

/promotion/PromotionTools profileProperties=activePromotions promotionsRepository=Promotions promotionItemTypes=\ Order Discount globalPromotionsQuery=global=true AND enabled=true AND (beginUsable IS NULL OR beginUsable <= ?0) AND (endUsable IS NULL OR endUsable >= ?0) preCalculators=\ calculators/OrderSubtotalCalculator scheduler=/atg/dynamo/service/Scheduler updateSchedule=every 15 minutes in 15 minutes You can view and modify this component in the ATG Control Center.defaultLocale priceInfoClass=atg.OrderPriceInfo pricingModelProperties=PricingModelProperties promotionTools=. pricingTools.commerce. The TaxPricingCalculator determines if an item is taxable using pricingTools. It uses the same mechanisms as the ItemPricingEngine component for determining which promotions to apply to tax. refer to the description of OrderPricingEngineImpl in the Pricing Engine Classes section. For more information on how to use this component.OrderPricingEngineImpl defaultLocale^=PricingTools. otherwise it returns the price of the item minus its orderDiscountShare.TaxPriceInfo pricingModelProperties=PricingModelProperties 201 9 .defaultLocale priceInfoClass=atg. all items are taxable. It determines the price of tax for an order by invoking a series of TaxPricingCalculators.calculateTaxableAmount() then determines the tax by returning 0 if isTaxable returns false. If an item is taxable.commerce.pricing.commerce. The following sample shows the contents of the TaxPricingEngine.pricing. Default Tax Pricing Engine The TaxPricingEngine component is a preconfigured implementation of the TaxPricingEngineImpl class.ATG Commerce Programming Guide µ # The OrderPricingEngine service # $class=atg. By default..properties file: # The TaxPricingEngine service # $class=atg.pricing.isTaxable() returns true.pricing.Using and Extending Pricing Services . pricingTools. Its location is /atg/commerce/pricing/OrderPricingEngine.isTaxable() method.commerce.TaxPricingEngineImpl defaultLocale^=PricingTools.

It determines the price of shipping for an order by invoking a series of ShippingPricingCalculators.Using and Extending Pricing Services . The following sample shows the contents of the ShippingPricingEngine.defaultLocale priceInfoClass=atg.ShippingPricingEngineImpl defaultLocale^=PricingTools.. It uses the same mechanisms as the ItemPricingEngine component for determining which promotions to apply.pricing.pricing.commerce./promotion/PromotionTools profileProperties=activePromotions promotionsRepository=Promotions promotionItemTypes=\ Shipping Discount globalPromotionsQuery=global=true AND enabled=true AND (beginUsable IS NULL OR beginUsable <= ?0) AND (endUsable IS NULL OR endUsable >= ?0) preCalculators=\ calculators/FreeShippingCalculator scheduler=/atg/dynamo/service/Scheduler updateSchedule=every 15 minutes in 15 minutes 202 9 ./promotion/PromotionTools #profileProperties=activePromotions #promotionsRepository=Promotions #promotionItemTypes= #globalPromotionsQuery= #preCalculators=\ # calculators/NoTaxCalculator preCalculators=\ calculators/TaxProcessorTaxCalculator scheduler=/atg/dynamo/service/Scheduler updateSchedule=every 15 minutes in 15 minutes You can view and modify this component in the ATG Control Center. For more information on how to use this component.µ ATG Commerce Programming Guide #promotionTools=.commerce.ShippingPriceInfo pricingModelProperties=PricingModelProperties promotionTools=. Default Shipping Pricing Engine The ShippingPricingEngine component is a preconfigured implementation of the ShippingPricingEngineImpl class. Its location is /atg/commerce/pricing/TaxPricingEngine.properties file: # The ShippingPricingEngine service # $class=atg.. refer to the description of TaxPricingEngineImpl in the Pricing Engine Classes section.

Using and Extending Pricing Services .pricing. Property pricingModelProperties Description Specifies a bean that hosts the names of all of the properties of a pricing model repository item.ItemDiscountCalculator pricingModelProperties=/atg/commerce/pricing/PricingModelProperties qualifierService=/atg/commerce/pricing/QualifierService # negativeAmountException= The following table describes the properties of the ItemDiscountCalculator component. refer to the description of ShippingPricingEngineImpl in the Pricing Engine Classes section.commerce. You can use these calculator implementations as they are or adapt them for your own site development needs.ATG Commerce Programming Guide µ For more information on how to use this component.ItemDiscountCalculator.Percent Off Item Discount -. Default Item Discount Calculator The ItemDiscountCalculator component is a preconfigured instance of the class atg.Amount Off Item Discount -.properties file: # The ItemPricingCalculator which calculates a discount # $class=atg. • • • • Default Item Discount Calculator Default Item Discount Multiplier Calculator Default Order Discount Calculator Default Shipping Discount Calculator This section also describes the QualifierService component. It is the default discount calculator for the following types of promotion: • • • Item Discount -.commerce. a preconfigured instance of the Qualifier class.pricing.Fixed Price The following sample shows the contents of the ItemDiscountCalculator. 203 9 . Default Pricing Calculators ATG Commerce includes four preconfigured implementations of its discount pricing calculator classes.

$5) is multiplied by a given factor. This property determines what happens when a discount would cause the amount of an item to be negative. a discount amount (for example. It is the default discount calculator for the following type of promotion: • Item Discount – Multiplier. For more information.0 when a discount causes an amount to be negative. Property pricingModelProperties Description Specifies a bean that hosts the names of all of the properties of a pricing model repository item. False: (default) Log a warning message and set the amount to 0.pricing. True: Throw an exception when a discount causes an amount to be negative. N. ATG Commerce never discounts the price of an item to less than zero. Default Item Discount Multiplier Calculator The ItemDiscountMultiplierCalculator component is a preconfigured instance of the class atg. refer to the description of the ItemDiscountCalculator class.ItemDiscountMultiplierCalculator pricingModelProperties=/atg/commerce/pricing/PricingModelProperties qualifierService=/atg/commerce/pricing/QualifierService The following table describes the properties of the ItemDiscountMultiplierCalculator component.µ qualifierService negativeAmountException ATG Commerce Programming Guide Specifies a Qualifier that performs the actual evaluation of a pmdlRule of the PricingModel against the running environment.Using and Extending Pricing Services . In this type of promotion.ItemDiscountMultiplierCalculator. Its location is /atg/commerce/pricing/calculators/ItemDiscountCalculator. The following sample shows the contents of the ItemDiscountMultiplierCalculator.properties file: # The ItemPricingCalculator which calculates a discount # $class=atg.pricing. 204 9 .commerce.commerce. Double coupon promotions are a common application of this type of discount. You can view and modify this component in the ATG Control Center.

refer to the description of the ItemDiscountMultiplierCalculator class. It is the default discount calculator for the following types of promotion: • • • Order Discount -. Default Order Discount Calculator The OrderDiscountCalculator component is a preconfigured instance of the class atg. You can view and modify this component in the ATG Control Center.Using and Extending Pricing Services .commerce.ATG Commerce Programming Guide µ qualifierService Specifies a Qualifier that performs the actual evaluation of a pmdlRule of the PricingModel against the running environment. qualifierService 205 9 .Amount Off Order Discount -. For more information.OrderDiscountCalculator. Specifies a Qualifier that performs the actual evaluation of a pmdlRule of the PricingModel against the running environment.pricing.OrderDiscountCalculator pricingModelProperties=/atg/commerce/pricing/PricingModelProperties qualifierService=/atg/commerce/pricing/QualifierService # negativeAmountException= The following table describes the properties of the OrderDiscountCalculator component. Its location is /atg/commerce/pricing/calculators/ItemDiscountMultiplierCalculator.commerce. Property pricingModelProperties Description Specifies a bean that hosts the names of all of the properties of a pricing model repository item.pricing.properties file: # # The OrderPricingCalculator which calculates a discount # $class=atg.Percent Off Order Discount -. pricingModelProperties are used so you do not have to hard code the properties into a pricing model.Fixed Price The following sample shows the contents of the OrderDiscountCalculator.

Specifies a Qualifier that performs the actual evaluation of a pmdlRule of the PricingModel against the running environment.properties file: # The ShippingPricingCalculator which calculates a discount # $class=atg. False: (default) Log a warning message and set the amount to 0.Amount Off Shipping Discount -. The component is located in /atg/commerce/pricing/calculators/OrderDiscountCalculator.µ negativeAmountException ATG Commerce Programming Guide Determines what happens when discounts cause the amount of an item to be negative.commerce.Percent Off Shipping Discount -.0 when a discount causes an amount to be negative. True: Throw an exception when a discount causes an amount to be negative. It is the default discount calculator for the following types of promotion: • • • Shipping Discount -. Property pricingModelProperties Description Specifies a bean that hosts the names of all of the properties of a pricing model repository item.ShippingDiscountCalculator pricingModelProperties=/atg/commerce/pricing/PricingModelProperties qualifierService=/atg/commerce/pricing/QualifierService # negativeAmountException= The following table describes the properties of the ShippingDiscountCalculator component. For more information.Fixed Price The following sample shows the contents of the ShippingDiscountCalculator.pricing.ShippingDiscountCalculator. You can view and modify the OrderDiscountCalculator component in the ATG Control Center.pricing.Using and Extending Pricing Services .commerce. qualifierService 206 9 . refer to the description of the OrderDiscountCalculator class. Default Shipping Discount Calculator The ShippingDiscountCalculator component is a preconfigured instance of the class atg.

The default ATG Commerce discount calculators use this component to determine the objects to which they should apply their discount.pricing.pricing. The component is located in /atg/commerce/pricing/calculators/ShippingDiscountCalculator. refer to the description of the ShippingDiscountCalculator class. False: (default) Log a warning message and set the amount to 0.ATG Commerce Programming Guide µ negativeAmountException Determines what happens when discounts cause the amount of an item to be negative. True: Throw an exception when a discount causes an amount to be negative.commerce.Qualifier. 207 9 .commerce. The following sample contains the contents of the QualifierService. For more information. You can view and modify the ShippingDiscountCalculator component in the ATG Control Center.properties file: # The QualifierService which determines whether the running # environment satisfies the preconditions for a discount # and contains objects that qualify for the discount # $class=atg. Property pricingModelProperties Description Specifies a bean that hosts the names of all of the properties of a pricing model repository item.Qualifier pricingModelProperties=PricingModelProperties PMDLCache=PMDLCache The following table describes the properties included in QualifierService.0 when a discount causes an amount to be negative. Default Qualifier Service The QualifierService component is a preconfigured instance of the helper class atg.Using and Extending Pricing Services .

For example. you can extend one or all of the implementations to alter the behavior of a method of PricingEngineService. however. You could create an algorithm that applies promotions in a random order rather than in order of ascending precedence. In a development environment. you can extend ItemPricingEngineImpl to create an algorithm that prices a set of items differently from the current implementation of priceEachItem. You can view and modify the QualifierService component in the ATG Control Center.commerce. For example. The ItemPricingEngine could be extended to get its global promotions from the integration.Using and Extending Pricing Services . The component is located in /atg/commerce/pricing/QualifierService. you could implement the expirePromotion method to send a JMS event enabling the creation of scenarios related to unused and expired promotions. A setting of -1 indicates an unlimited cache size. you may want to disable caching for pricing models so that changes you make to PMDL rules appear on your development site immediately.Cache and set the property to 0. For example. Extending and Creating Pricing Engines ATG Commerce provides several preconfigured pricing engines (see Default Pricing Engines). configure the corresponding pricing engine component to use the class. you can extend the pricing engine to determine global promotions using a Personify or NetPerceptions integration.service.cache. and you can also create new pricing engines if necessary. (For more information. You can extend these engines to fit your site’s requirements. Because each implementation of the PricingEngine interface extends the PricingEngineService class.Cache that maps a Pricing Model to its parsed Java form.ItemPricingEngine 208 9 . After you complete your extensions. For more information. To disable caching for pricing models.service. Extending a Pricing Engine You can extend one or more of the pricing engine implementations to provide new pricing functionality.cache. The relevant interfaces are as follows: • atg. In a production environment. without requiring you to flush the cache.pricing. refer to the description of the Qualifier class. see the description of PricingEngineService.) Each engine can also be extended to leverage existing code. locate the maximumCacheEntries property in the appropriate instance of atg. caching increases site performance by allowing ATG Commerce to evaluate pricing models more quickly.µ PMDLCache ATG Commerce Programming Guide An instance of atg.

if one pair of shoes costs $150 and the second pair only $30. 1. you might want to create a pricing engine that prevents people from using certain discounts at the same time while also making sure they use the best discount available. Create an implementation called HandlingPricingEngineImpl that extends PricingEngineService.pricing.OrderPricingEngine atg. Create properties files for the HandlingPricingEngine and each of the calculators.commerce. the better promotion would be the one that provides a 25% discount on the shoes that cost $150. For example.commerce. you have decided you want to create a new pricing engine that prices handling costs separately from shipping.pricing. 3. 6. you can create an engine that prevents a customer from using a “25% off any full-price item” promotion during the same period. For example. include a getPricingModels method that constructs and returns a Collection in order to aid in the algorithm.TaxPricingEngine atg.commerce.ShippingPricingEngine atg. 4. write a new implementation of its interface.commerce.pricing.pricing.pricing. 2. if your site is running a “Buy one pair of shoes.) Create a calculator called HandlingPricingCalculator and implementations of it that calculate and discount handling as your business requires.PricingModelProperties. For example. For each engine with this behavior. In the new implementation. 209 9 . Creating a New Pricing Engine In the following example.ShippingDiscountCalculator The properties of a promotion Repository Item are in atg. replacing ItemPricingEngineImpl involves implementing ItemPricingEngine.pricing. get a second pair free” promotion.ItemDiscountCalculator atg. see AmountInfo.commerce.pricing.OrderDiscountCalculator atg. Add an item-descriptor for the Handling discount type and sub-descriptors for the various implementations of the HandlingPricingCalculator that you created. 5.xml). the engine could ensure that the customer always uses the promotion that provides the greater savings. Create a HandlingPricingInfo that extends the AmountInfo price holding class. pricingModels.commerce. In addition. In this example.ATG Commerce Programming Guide µ • • • • • • atg.Using and Extending Pricing Services . The Qualifier class that holds helper methods is atg.Qualifier. Modify the Promotions repository definition file (by default. You create a HandlingPricingEngine that acts independently of the ShippingPricingEngine.commerce.commerce. Replacing a Pricing Engine You can replace the standard implementations of the pricing engines with your own. (For more information. Create an interface called HandlingPricingEngine that extends PricingEngine.pricing.

commerce.commerce.pricing.ItemPricingCalculator atg. configure the new engine with some preCalculators that calculate the base cost of handling. None of these three options. assume you have identified a need for a calculator that sets an item’s price to half its current price plus one. Adding a New Pricing Calculator This section explains how to create a new implementation of a pricing calculator interface and how to use the new calculator. implement OrderPricingCalculator. To achieve that result.commerce. you would have to use two different discounts: one to give 50 percent off. easily gives a “half off plus one” discount.Using and Extending Pricing Services . To create the new calculator.ShippingPricingCalculator atg. the ATG Commerce item discount calculators also do the following: • Consult the Qualifier class to determine the items to be discounted from among all the items in the environment. For example. In addition to modifying an item’s price. Extending and Creating Pricing Calculators ATG Commerce provides several preconfigured pricing calculators (see Default Pricing Calculators for more information). or it can set an item’s price to a fixed amount.TaxPricingCalculator Implement the interface that corresponds to the type of price you want to calculate. Creating a New Pricing Calculator Use the following interfaces to create a new pricing calculator that fits into the existing ATG Commerce pricing architecture: • • • • atg. 210 9 .pricing. and another to add 1 to that total. however. The HalfPlusOneDiscountCalculator is an example of a discount calculator that leverages existing ATG Commerce functionality to perform its own unique task. you create a class called HalfPlusOneItemDiscountCalculator that implements the ItemPricingCalculator interface.OrderPricingCalculator atg.pricing. and you can also create new pricing calculators if necessary. In the following example. It can give a percent off a price or an amount off. The existing ATG Commerce tools include an ItemDiscountCalculator that discounts items. A better alternative would be to create a new calculator that discounts an item’s price to half its current price plus one.commerce.µ 7. if you want to make calculations on order prices. You can extend these calculators to fit your site’s requirements.pricing. ATG Commerce Programming Guide Depending on your needs.

not used here * @return a value of type 'double' * @exception PricingException if an error occurs */ public double findAdjustedPrice(DetailedItemPriceInfo pDetailedItemPriceInfo. List pPriceQuotes. Maintain DetailedItemPriceInfo objects. not used here * @param pLocale users locale. * * @param pDetailedItemPriceInfo the details on the item being priced * @param pPriceQuotes list of itemPriceInfo * @param pItems list of commerceItems * @param pPricingModel pricing model being used to calculate price * @param pProfile users profile. not used here * @param pOrder users order. Locale pLocale. return ( currentAmount / 2) + 1. • The HalfPlusOneDiscountCalculator leverages all the above functionality from the ItemDiscountCalculator. } // end findAdjustedPrice 211 9 . List pItems.ATG Commerce Programming Guide µ • • Maintain an audit trail of the changes made to the price using the PricingAdjustments property in the AmountInfo price object.Using and Extending Pricing Services . RepositoryItem pProfile. In this case. Order pOrder. which modifies an input DetailedItemPriceInfo to be the right amount. The only method it overrides is the findAdjustedPrice method. RepositoryItem pPricingModel.getAmount(). not used here * @param pExtraParameters map of extra params. Maintain flags on the items’ prices that state whether each item has acted as a qualifier for any discount (and therefore might not be usable as the qualifier for another discount). the class modifies the price of the detail to half its current price plus one. Map pExtraParameters) throws PricingException { // current price of an item double currentAmount = pDetailedItemPriceInfo. The overridden findAdjustedPrice method is shown below: /** * Override the findAdjustedPrice to allow us to always compute the * new price of the input DetailedItemPriceInfo to be half its current * price plus one.

The pricing calculator can use a pricing model (a promotion) to alter an item’s price conditionally. Subclasses could re-implement the appropriate calculator interface just as easily. This option is appropriate for discount calculators. you should re-implement OrderPricingCalculator. The priceItems method changes the price of input items. Extending the ItemDiscountCalculator The ItemDiscountCalculator can be extended to calculate different discounts. The other calculators. priceQualifyingItems calls priceQualifyingItem once for each input item to be priced. The findQualifyingItems method selects items to be discounted. it marks the item so that it cannot act as a qualifier for another discount. When the pricing model is passed to the ItemPricingEngine. The following list describes the order of calls in ItemDiscountCalculator: 1. 3. It bases item selection on attributes of the input environment as represented by the method’s parameters. They can be extended. if the item acted as a qualifier for this discount calculation. The configuration invokes the calculator on the price of every item that passes through the engine.Using and Extending Pricing Services . the OrderDiscountCalculator is an implementation of OrderPricingCalculator and does not provide additional functionality in its implementation of that interface. however. It also verifies that the item’s audit trail is maintained and. but there is not much functionality for the subclasses to leverage. It provides a number of extension points. In most cases. The priceQualifyingItems method modifies the prices of an input collection of items.or post-calculators. It then calls priceQualifyingItems to change their price. the engine invokes the calculator and modifies the input item’s price. It calls the findQualifyingItems method of the Qualifier. Extending Calculators You can extend any of the pricing calculators. are only implementations of various pricing calculator interfaces. You can do this in either of two ways: Add the calculator to an engine’s list of pre. you must associate it with its corresponding pricing engine. The priceQualifyingItem method modifies the price of the input item. 4. You can set a pricing model’s pricingCalculatorService property to the Nucleus path of an instance of the new calculator. For example. It first calls findQualifyingItems to get items whose prices need changing. The ItemDiscountCalculator can be extended to calculate different discounts. 212 9 . it is easier to replace calculators other than the ItemDiscountCalculator with other implementations of the interfaces rather than extending them. It also verifies that the items’ audit trail is maintained and marks the items that acted as qualifiers for this discount calculation so that they cannot act as a qualifier for another discount. priceQualifyingItem calls each 2. Instead of extending OrderDiscountCalculator.µ Using a New Pricing Calculator • • ATG Commerce Programming Guide After you have created a new calculator.

Override findAdjustedPrice to change how the calculator determines new prices.ATG Commerce Programming Guide µ priceDetailedItemPriceInfo. and it processes a type of object not returned 213 9 .) Extending the Qualifier Class As described in the section Qualifier Class. It calls findAdjustedPrice to find the new price of the details. • Override findQualifyingItems to change the way the calculator finds the items to discount. and it returns the new price. You could extend the Qualifier class for the following reasons: • • • • Adding a Helper Method for a New Calculator Adding New Criteria to the Filter Methods Replacing the Way a PMDL Rule Is Evaluated Replacing the Way the Qualifier Determines the Result Set Adding a Helper Method for a New Calculator Each ATG Commerce calculator type has a helper method in the Qualifier class. The findAdjustedPrice method produces a number that is the new price of a DetailedItemPriceInfo. 5. This calculator computes the difference between an item’s list price and its current price and multiplies that difference by a variable. • • • • For example. If you create a new calculator. You can override any of these methods to provide new functionality while leveraging the existing code. 6. N. It examines the existing price and the input parameters. Override priceQualifyingItem to change how an individual ItemPriceInfo is adjusted. The priceDetailedItemPriceInfo method modifies the price of a detailedItemPriceInfo. Override priceDetailedItemPriceInfo to change how a DetailedItemPriceInfo within an ItemPriceInfo is adjusted. atg. discounting details until the total number of items to discount has been reached. see the description of the ItemDiscountMultiplierCalculator class.pricing. You must override this method if you do not want to use the Qualifier service.Qualifier is a helper class that determines the objects that a calculator should discount. (For more information about this calculator.commerce. Override priceQualifyingItems to change how a group of ItemPriceInfos are adjusted.Using and Extending Pricing Services . Multiple calculators can use the same helper method. the ItemDiscountMultiplierCalculator extends existing ATG Commerce pricing functionality by overriding the findAdjustedPrice method. It maintains the audit trail and marks the details that have acted as qualifiers.

The filterItemsForQualifier and filterItemsForTarget methods correspond to two parts of a PMDL rule: the qualifier rule and the target rule. Because there is an existing method in the Qualifier to process CommerceItems. No helper method exists for determining the handling objects to discount. For new helper methods. A target element is not a mandatory part of the PMDL rule.µ • ATG Commerce Programming Guide in the result set of an existing helper method. You would not need to create an additional helper method for this new calculator. Therefore.) The filterItemsForQualifier and filterItemsForTarget methods in Qualifier implement this behavior. suppose you created a HandlingDiscountCalculator to calculate an order’s handling costs separately from its shipping costs. a MatchingObject object that identifies the order to discount).findQualifyingItems. This behavior prevents a customer from buying just one item and getting that one item free. The findQualifyingShipping method returns ShippingGroups (specifically. • filterItemsForQualifier: Every PMDL rule has a qualifier element that describes the conditions under which a discount is given. use the naming convention findQualifyingXXX.Using and Extending Pricing Services . See the Using PMDL Rules section for more information. (The customer must put two items in the cart in order to get the discount. The qualifier element is always evaluated first. The filtering process prevents problems with pricing rules. Adding New Criteria to the Filter Methods The existing Qualifier helper methods use two methods to filter items out of the environment before comparing it to a promotion’s PMDLRule. you would need to create a new findQualifyingHandling method to help the HandlingDiscountCalculator. In contrast. get one item free. in the promotion “buy one item. where XXX is the name of the object in the result set that the method returns. the HalfPlusOneItemDiscountCalculator could reuse existing ATG Commerce code by calling Qualifier. a list of QualifiedItem objects that map a CommerceItem to the number of times it qualified for a discount). Assume you created a HalfPlusOneItemDiscountCalculator that discounts a set of CommerceItems to half their existing price plus one. filterItemsForTarget: A target element in a PMDL rule identifies objects to be • discounted from a larger pool of all available objects of the same type. • • The following example describes a situation in which a new calculator could use an existing helper method. The findQualifyingOrder method returns Orders (specifically. The following list shows existing helper methods and the type of object they return: The findQualifyingItems method returns a list of CommerceItems (specifically. you must add a new corresponding helper method to the Qualifier class. For example. a MatchingObject object that identifies the shipping group to discount). 214 9 .” most retailers exclude the item that acts as a qualifier from receiving the discount. If the input environment does not match the qualifier element. the target element is not evaluated.

Replacing the Way a PMDL Rule Is Evaluated. the system invokes the target. 215 9 . this method uses the following criteria to remove items from the environment. (For more information on these methods.” The filterItemsForQualifier method is invoked first. ATG Commerce supports discounting multiple orders at the same time.) If the qualifier is satisfied. the evaluateQualifier method is invoked. This method returns a set of items that can receive the discount because they satisfy the target element of the rule. is the only Qualifier method that returns a set of objects rather than a single object. For example. This example uses the rule “for next 1 item that is blue. refer to the next section. If. the filterItemsForTarget method must be invoked. However. For example. to determine which objects among all those available should receive the discount that is enabled by the one blue item. If an item has already received the discount that’s currently being evaluated. After the filterItemsForTarget method is invoked. because only one Order object can be discounted. This prevents the methods from helping to satisfy the constraints specified in the “qualifier rule” portion of the input PMDL rule: • • • If an item’s price is zero. the evaluateTarget method is called. if there is one. If an item has already acted as a qualifier.Using and Extending Pricing Services . The following example shows how the filterItemsForQualifier and filterOrdersForTarget methods work. evaluateQualifier selects one blue item from the environment that acts as a qualifier. the item is removed. You could rewrite the filterItemsForQualifier method to remove that restriction. ATG Commerce currently performs this selection for CommerceItems only. the item is removed.which returns a list of CommerceItems. the item is removed. If an item already received the discount that is currently being evaluated. your filter could allow items with a price of zero to act as qualifiers for a rule.ATG Commerce Programming Guide µ findQualifyingItems. there’s no need for a rule that discounts an order to have a target element. By default. PMDL rules do support the use of target elements to identify Order objects from a pool of available Orders. discount up to 1 item that is green. You can change the criteria by which items are filtered out of the environment before a rule is evaluated. in the future. the item is removed. A PMDL rule that does not deal with CommerceItems does not need to contain a target element because it has no need to select objects from a larger pool. After items are filtered out of the environment. The filterItemsForTarget method uses the following criteria to remove items from the environment against which the target is compared: • • If an item already acted as a qualifier. Before the target element is evaluated. new filterOrdersForQualfiier and filterItemsForTarget methods will have to be added to the Qualifier class. the item is removed.

evaluateQualifier determines which objects acted as qualifiers in satisfying the rule. read the items to discount. discount 1 green item. and the extension needs access to a wrapped item.” In this example.lang. The method returns the shirt item that satisfies the constraint. and findQualifyingShipping methods wrap the input CommerceItems with FilteredCommerceItems. If you extend the Qualifier class. It selects one green item to discount from all the items in the environment. The findQualifyingItems method could access the promotion. that are responsible for evaluating different elements of a PMDL (discount) rule. Promotions can be delivered to users without any action required by the user.” the “green item” element of the rule is evaluated through the evaluateTarget method. discount up to 1 green item. For example. get 1 hat free.) This situation occurs only for discounts on CommerceItems. The input environment is represented by the parameters passed into the method. A 216 9 . You could use a repository query to select the items that a given promotion should discount. evaluateQualifier and evaluateTarget. Creating Promotions Promotions are a way of encouraging a user to make a purchase by highlighting and offering discounts on products and services. In the example “When there is at least 1 blue item. you might not want to use a PMDL rule to determine the objects to discount. (See the information above on filterItems for more details. In this case. and return them. If the constraints are satisfied. Replacing the Way the Qualifier Determines the Result Set You can replace the way that a helper method determines its result set by extending the Qualifier to override any of the existing findQualifyingXXX methods. Accessing FilteredCommerceItems The findQualifyingItems. see the Evaluating Qualifiers Example section For example. the qualifier just returns a java. it can get it by calling the getWrappedItem method of the FilteredCommerceItem. For more information.” the “one shirt” element of the rule is evaluated through evaluateQualifier.Using and Extending Pricing Services . findQualifyingOrder.Boolean indicating whether or not the environment matched the rule. The list of items to discount could be stored in the promotion itself. The rule requires only that one blue item be in the input environment. Not all rules need qualifiers. in the rule “Buy 1 shirt. The evaluateQualifier method determines if the input environment (the pricing context) satisfies the constraints of the qualifier rule. The evaluateTarget method is invoked only in situations where the Qualifier must select objects for discounting from a larger pool of available objects. the qualifier rule does not require a customer to buy one blue item in order to receive a discount on one green item. Consider the PMDL rule “When there is at least 1 blue item.µ ATG Commerce Programming Guide Replacing the Way a PMDL Rule Is Evaluated The Qualifier class contains two protected methods.

The properties of a promotion RepositoryItem are documented in the table below. These properties serve the following functions: • • • Mechanism of discount: discountCalculatorService Under what conditions the promotion should be applied. The new property type unique to promotions is the pmdlRule property that stores the PMDL (Pricing Model Description Language) rule. discountType. including amount. For more information. Types of Promotions There are various ways to offer special prices on products including the following: • • • • • • • Specific amount off a particular product Specific amount off a whole order Percentage amount off a particular product Percentage amount off a whole order Specific amount or percentage off a product based on an attribute Free product or free order Free shipping for a specific product See the Creating and Maintaining Promotions chapter of the ATG Commerce Guide to Setting Up a Store for more information. access the promotions interface by clicking the Promotions link under the Pricing topic. and the mechanism by which the discount is applied. These common types include strings. Using PMDL Rules The promotions user interface consists of the standard repository editor. The PMDL rule editor functions exactly like any other ATG expression editor.Using and Extending Pricing Services . numbers. For more information. refer to the ATG Control Center online help and the Using the Discount Rule Editor to Create PMDL Rules section. and so on. This is defined in the pmdlRule property. see the Creating and Maintaining Promotions chapter of the ATG Commerce Guide to Setting Up a Store. What promotion to give: all other properties. In the ATG Control Center. The PMDL editor allows you to create a sentence out of the available building blocks. Most of the property types should be familiar to anyone who has used an ATG platform repository editor before. under which conditions it should be given. These properties work together to form a description of what discount to give. Also includes the ItemDescriptor type.ATG Commerce Programming Guide µ typical way to deliver a promotion is through the Scenarios module. etc. This property has a custom property editor associated with it in the Promotions section of the ATG Control Center. This sentence describes the circumstances under 217 9 . dates.

If set to false. The available building blocks are listed in pull-down menus in the ATG Control Center. For example.” Boolean true or false allowMultiple none (display name: Give to a customer more than once) Determines whether the promotion is given to a customer only once. string any string none (display name: Description) Provides a short description of the item. Works in conjunction with discountType to specify the discount to be applied. If set to true. Tax. Consequently. Property Name adjuster Type double Values any double Flags none (display name: Discount Price or Percentage. the system adds a copy of the promotion to the customer’s profile every time the customer performs an action that qualifies him or her to receive it.xml. the system delivers the promotion only once. beginUsable date any date none (display name: Usage start date) The date that the promotion becomes effective. The following table describes the pricing model properties available in the Item.jar. Used when the relativeExpiration property is set to false. creationDate date any date readonly (display name: Creation date) description The date when the promotion was created. which is located in <ATG9dir>/DCS/config/config. Note: This property is ignored if the global property is set to true. an adjuster of 15 and a discountType of percentOff produce a discount of “15 percent off. These descriptors are defined in /atg/commerce/pricing/pricingModels. 218 9 .Using and Extending Pricing Services .µ ATG Commerce Programming Guide which a promotion will be delivered. Shipping. and Order descriptors when you create a commerce item. Note: This property is ignored if the global property is set to true. a single order may be discounted by multiple copies of the promotion. depending on the discount type) Number by which the item is discounted.

the promotion never takes effect regardless of the distribution period. Used when the relativeExpiration property is set to false. giveToAnonymousProfiles Boolean true or false none (display name: Give to anonymous customers) If both this property and the global property are false. then anonymous visitors and registered visitors who qualify receive the promotion. you should never delete promotions and instead disable them by setting the enabled property to false.ATG Commerce Programming Guide µ percentOff amountOff fixedPrice discountType string (display name: Discount type) readonly The type of discount this promotion gives. if the collection filtering feature is implemented to use this property. global Boolean true or false none 219 9 . This approach eliminates the possibility of deleting a promotion that has been used in orders on your site. Note: This property is ignored if the global property is set to true. then only registered visitors who qualify receive the promotion. This is set during item creation. If this property is true. Note: As a general rule. Boolean true or false none (display name: Enabled) Specify true to enable the promotion. endDate date any date none (display name: Distribute through) The date that the promotion stops being delivered to people.) displayName string any string none (display name: Name) enabled Specifies the name visible through user interface. Note: This property is ignored if the global property is set to true. (Note that two promotions can have different values for type and the same values for discountType. the promotion takes effect according to the specified distribution period. date any date none endUsable (display name: Usage end date) The date that the promotion stops being effective. If disabled.Using and Extending Pricing Services . See the type property. which produces errors. If enabled. and the global property is false.

to all visitors (including anonymous visitors). during the specified distribution period – regardless of the values set for the following properties: -. The rule is created in the ATG Control Center using the interface designed for promotion creation. see the Using the Discount Rule Editor to Create PMDL Rules section. associated with this discount. If set to false.beginUsable -. string any valid PMDL rule none pmdlRule (display name: Discount rule) This is the Pricing Model Description Language (PMDL) rule describing the conditions under which this promotion should take effect. then only one shipping group in the order can use the promotion. Boolean true or false none (display name: One use per order) A property used for shipping promotions only.Using and Extending Pricing Services .allowMultiple -.giveToAnonymousProfiles -.uses Setting the global property to false indicates that the system delivers and applies the promotion according to all of the values specified for the promotion. 220 9 . enumerated for example. For more information. It determines whether a shipping promotion can discount a single order multiple times.timeUntilExpire -. If set to true.µ (display name: Automatically apply to all orders) ATG Commerce Programming Guide Setting the global property to true indicates that this promotion will be offered an unlimited number of times.endUsable -. for use on an unlimited number of orders. such as icons. then it is possible for each shipping group in the order to be discounted by the promotion. /atg/commerce/pricing/ calculators/ ItemDiscountCalculator pricingCalculatorServic e none (display name: Pricing Calculator) Specifies the calculator that computes and applies this promotion’s discount. media map map of object to object none (display name: Media) oneUsePerOrder The media.relativeExpiration -.

Using and Extending Pricing Services . Used when the relativeExpiration property is set to true.ATG Commerce Programming Guide µ any integer none priority integer (display name: Order of application) The priority of the promotion. If false. the promotion’s usage period is set according to the date it is received by the user (that is. the promotion is added to the list of promotions in the user’s activePromotions profile property. Promotions are applied in order of priority. The end date and time is set by the start date/time and the value of the timeUntilExpire property. relativeExpiration Boolean true or false none (display name: Usage Period) Determines whether the usage period for the promotion is fixed or relative. For example. Note that this property functions within the context of a particular promotion type. but not the order in which the types are applied. Engines sort the value of this property. with low priority numbers applied first. if the collection filtering feature is implemented to use this property. you can specify how a given promotion of Type A is applied compared to other Type A promotions. The expiration date and time is then determined by the number of minutes in timeUntilExpire to the current time. int any int none timeUntilExpire (display name: Redeemable for) Determines the usage period in minutes for the promotion. 221 9 . the promotion’s usage period is determined by the dates set in the beginUsable and endUsable properties. when the promotion is added to the user’s activePromotions profile property). The promotion becomes active as soon as the user receives the promotion. If true. Note: This property is ignored when the global property is set to true. startDate date any date none (display name: Distribute starting) The date that the promotion begins to be able to be delivered to people. that is.. The start date and time is set when the user receives the promotion.

This is set during item creation. (Note that two promotions can have different values for type and the same values for discountType. The following list describes issues to keep in mind when you are creating promotions for your site.jar. If this number hits zero. you must change the values in pricingModels. version long any long hidden (display name: Version) Used by the SQL Repository to protect against data corruption caused by two different threads attempting to modify the same item the same time.xml. Note 1: A promotion can sometimes discount a single order multiple times.Fixed Price Order Discount .xml.Percent Off Shipping Discount. zero none (display name: Number of uses allowed per customer) The number of orders for a given customer to which the promotion can be applied. the promotion can no longer be applied. The enumerated list from which this property value is first set (when the promotions is created via the ACC) is defined in /atg/commerce/pricing/pricingModels. One important part of promotion creation is making sure that the promotion can only be used in the way you intend it to be used. Note 2: This property is ignored when the global property is set to true. This is still considered one “use.Amount Off Shipping Discount .Using and Extending Pricing Services .µ type ATG Commerce Programming Guide enumerated (hidden) Item Discount– Percent Off Item Discount– Amount Off Item Discount– Fixed Price Item Discount– Multiplier Shipping Discount. you can prevent the promotion from discounting a single order multiple times by setting the oneUsePerOrder property to true. See the discountType property. which is located at <ATG9dir>/DCS/config/config.Fixed Price readonly The type of discount this promotion gives. To alter the values in the enumerated list.Amount Off Order Discount .Percent Off Order Discount .) uses int any positive integer.” For shipping promotions only. 222 9 . Incorrectly worded or configured promotions could allow customers to receive greater benefits from the promotion than you intended.

commerce. be aware that a number of factors can cause the promotion to be unusable for x minutes after it is set to be active and to be usable for x minutes after it is set to expire. the session-scoped UserPricingModels component (class atg.PricingModelHolder) stores them in a session cache. To retrieve the list of global promotions. the pricing models in UserPricingModels are then used for all pricing operations during the user’s session. • 223 9 . manually call the pricingModelHolder. if a user’s session was created before you added a new promotion (either targeted or global). evaluate the wording of the discount rule carefully to make sure that only the intended products receive the promotion. • Because it can be resource intensive to collect a user’s list of promotions.initializePromotions method should be called after the pricingEngine. For example. This is because the user’s list of pricing models has already been collected and stored in the user’s UserPricingModels. For more information on the pricing engine APIs. These promotions include both the promotions in the user’s activePromotions profile property and the list of global promotions. Note: When setting the “go live” dates of a promotion.Using and Extending Pricing Services . To prevent this situation.) For more information on the PricingModelHolder class. make sure you create a scenario to remove the promotion at the end of the week.initalizePromotions method when you add any new promotion (targeted or global). UserPricingModels queries each pricing engine for the customer’s promotions. Consequently. Be as specific as possible when creating rules. Use caution when creating “infinite use” promotions (ones that a customer can use an infinite number of times during a specified time period). Once collected. For example. specify the brand in the rule rather than relying on an attribute of the brand that you might think is unique. Additionally. the pricing engine uses its globalPromotionsQuery property to query the Promotions repository for all promotions where the global property is set to true. that user will never receive the new promotion. where x is determined by the schedule set for the pricing engine component. • When creating promotions.pricing. if a user’s session is created after you have added a new global promotion but before the next scheduled job to update the pricing engine’s list of global promotions.loadGlobalPromotions method in order to collect all new global promotions. This is usually set in the ‘start date’ and ‘end date’ properties. if a particular brand is on sale. You can prevent this situation by manually calling the pricingEngine. the user will not receive the new global promotion. or pricing models. and it does so every x minutes as defined by the schedule specified in its updateSchedule property. see the Public Pricing Interfaces and Classes and Default Pricing Engines sections. see the PricingModelHolder section. (Note that the pricingModelHolder.loadGlobalPromotions method when you add the new global promotion.ATG Commerce Programming Guide µ • Check the “go live” dates of all promotions to prevent a promotion from taking effect before you’re ready for it. if you put all sneakers on sale for a given week. The initializePromotions method generates a new list of pricing models to store in the user’s UserPricingModels. When a session starts for a user.

Refer to the following list for more information on the available comparison operators: • • • • is less than = is not greater than or equal to is greater than = is not less than or equal to is not less than = is greater than or equal to is not greater than = is less than or equal to 224 9 . This repository item tracks the number of times a customer can use an individual promotion. A PromotionStatus RepositoryItem is a repository item with an ItemDescriptor that describes the status of the promotion. Click on the field that holds the value of the promotion’s Discount Rule property.µ PromotionStatus Repository Items ATG Commerce Programming Guide When a promotion is associated with a customer’s profile. Access the editor by opening an existing promotion or creating a new promotion. A customer’s profile has an activePromotions property that contains a list of PromotionStatus RepositoryItems.Using and Extending Pricing Services . The number of times that a customer can use the promotion. Using the Discount Rule Editor to Create PMDL Rules The ATG Control Center includes a user interface for creating and editing PMDL (discount) rules. The Discount rule editor provides a series of pull-down menus that allow you to set up a discount: Note: The Discount rule editor uses comparison operators such as “is not less than” to set conditions for promotion delivery. Click on the “…” button to open the Discount rule editor. During the pricing process. pricing engines inspect the customer’s profile to see which promotions should be considered when generating prices. Each PromotionStatus item contains the following information: • • A reference to the underlying promotion that was created in the ATG Control Center’s Promotions editor. it is wrapped inside a PromotionStatus RepositoryItem.

Fixed pricing: Get Y for $0.Using and Extending Pricing Services . You can create an “Item Discount - percent off” promotion. The PMDLRule describes Y. For more examples of PMDL Rules. Item Pricing Model Examples The following table describes how to set up Item pricing models using PMDL rules: Percentage off price: Get Y for 25% off. 225 9 .25 The “$. then set its adjuster to .ATG Commerce Programming Guide µ For example. if Y is something red. The PMDLRule describes Y. You create an “Item Discount - amount off” promotion. if Y is something green. then set its adjuster to 10. Dollar amount off price: Get Y for $10 off The “$10 off” part of this rule is contained at the PricingModel level. The PMDLRule describes Y. The “25% off” part of this rule is contained at the PricingModel level. Examples of PMDL Rules The tables in this section demonstrate how to represent some standard promotions using PMDL rules in the discount rule editor. then set its adjuster to 25.” For more information on creating promotions in the ACC. For example.fixed price” promotion.25” part of this rule is contained at the PricingModel level You create an “Item Discount .” you can define the rule using “if age is not greater than 30. For example. if Y is something blue. to create a condition to deliver a promotion “if age is less than or equal to 30. see the Creating and Maintaining Promotions chapter of the ATG Commerce Guide to Setting Up a Store.25. the following is one possible PMDL representation: “always discount every item whose SKU’s color is blue” This rule is written for items that register their color in the “color” property of their SKU. the following is one possible PMDL representation: “always discount every item whose SKU’s color is green” This rule is written for items that register their color in the “color” property of their SKU. see the Creating and Maintaining Promotions chapter of the ATG Commerce Guide to Setting Up a Store. For example. the following is one possible PMDL representation: “always discount every item whose SKU’s color is red” This rule is written for items that register their color in the “color” property of their SKU.

the items that act to satisfy this precondition are not eligible to receive the discount. they will receive 2 items free.” By default. For example. If this property is not populated. Set the adjuster to Zero. get one free If the free item is “anything blue” then the rule is actually “buy one blue item.ancestorCategoryIds contains categoryIdX. Create the following PMDL representation: “For next 3 items whose SKU color is blue. the productRef needs to have its ancestorCategoryIds populated. By default. discount up to 1 items whose SKU color is blue” The second half of this rule refers to “up to 1 item” means that only one blue item will be discounted for every blue item purchased. To use a rule that discounts based on category. For more information on the product catalog. Quantity Pricing Model Examples The quantity rules have one thing in common: they all depend on a set of items that match the description “X. get one blue item free. discount up to 1 item whose SKU color is blue” 226 9 . you could create a rule that gives a 10% discount to all products that are part of the shoe category. The following table describes how to set up quantity pricing models using PMDL rules: Buy one. they will receive one item free. Set the adjuster to Zero. rules of this type always evaluate to false. Buy three. Create a “Item Discount – fixed price” promotion.” The “free” part of the discount is configured in the promotion itself. Create a “Item Discount – fixed price” promotion. see the Using and Extending the Standard Catalog chapter. etc. Next.productRef.Using and Extending Pricing Services . the productRef is an item from the Product Catalog. create the following PMDL representation: “For next 1 items whose SKU color is blue. This rule is written for items that register their color in the “color” property of their SKU. If they buy 6 items.” A number of X items are needed as a precondition for the rule being applied to any items.µ ATG Commerce Programming Guide Note: You can create a rule that gives a discount to a product that is in a specific category. This rule converts to give a discount to a “CommerceItem whose auxilliaryData. get one free This rule indicates that if a customer buys 3 items.

Next. create the following PMDL rule: “for next 12 items whose SKU’s color is blue.ATG Commerce Programming Guide µ Buy three or more. create the following PMDL rule: “Always. Set the adjuster to Zero.” Create a discount of type “Item Discount – fixed price.” If X is “something blue. Apply discount to up to 1 (product in category named clothing)” Buy 13 of X for the price of 12 X’s This rule could be rewritten as “for every 12 Xs that you buy.Using and Extending Pricing Services . discount up to 5 (sku whose color is blue). create the following PMDL rule: “for next 2 items whose SKU’s color is blue. get 1 X free. In the following example.” or more simply “buy 12. Order of Application: 2” 227 9 . Next.” Tier pricing: Buy the first 5 at $10 each. Next. Create the following PMDL representation: “When order contains at least 3 (product in category named clothing). except that the applied discount is different. get one free. buy the next 5 at $5 each This promotion can be created through a combination of two promotions.” and set its adjuster to zero. This is necessary because the promotion given is different based on the number of items bought. get 1 free” promotion that limits the promotion to one free item per order. discount up to 1 item whose SKU’s color is blue” Buy 2 of X. if you buy six items. Order of Application: 1” 2) Create another “Item Discount . For example. If X is something blue. discount up to 1 item whose SKU’s color is blue. get one free This rule is a version of the “Buy 3.” 1) Create one “Item Discount .fixed price” promotion and set its adjuster to 5. get the 3rd X for 20% off [or $20 off] This example follows the same pattern as the above two examples. Set the adjuster to 20. you still just get one free item.fixed price” promotion and set its adjuster to 10. the item being purchased is “something blue.amount off”). discount up to 5 (sku whose color is blue). Next. create the following PMDL rule: “Always. Create a “Item Discount – percent off” promotion (or “Item Discount . Create a “Item Discount – fixed price” promotion.

” 228 9 . The rule ensures that you only discount next day air. the conditions are that there is at least one blue thing in the order. create the following PMDL rule: “when order contains at least 1 ( sku whose color is blue ) and Shipping Group’s shippingGroupType is ‘Next Day’ discount shipping group” Order Pricing Model Examples The following table describes how to set up Order pricing models using PMDL rules: 10% of the total price of the order This rule requires a condition under which the Y% should be taken off. create the following PMDL rule: “when order contains at least 1 ( sku whose color is blue ). discount shipping group” Upgraded shipping: Upgrade from regular 7-day shipping to next day shipping for the price of 7day shipping. Next. Next. Next. Set the adjuster to 10. the condition is that the order contains a blue item. discount order total. give free shipping.Using and Extending Pricing Services . In the following example.µ Shipping Pricing Model Examples Free shipping ATG Commerce Programming Guide The following table describes how to set up shipping pricing models using PMDL rules: This promotion is written out in the form “under these conditions.” Set its adjuster to 0. This promotion is represented by a “fixed price” promotion. Create a promotion of type “Shipping Discount – fixed price.” Set the adjuster to the price of seven-day shipping. In the following example. the conditions for this promotion taking effect are that the order contains at least one SKU that’s blue.” In the following example. create the following PMDL rule: “when order contains at least 1 ( sku whose color is blue ). Create a new discount of type Order Discount – percent off. Create a promotion of type “Shipping Discount – fixed price.

the longer it takes to generate a price for that customer. there may be a more efficient way of implementing that promotion. Do not rely on promotions to do the bulk of price generation for a site. In the following example. the salePrice property) to provide varied pricing. In the following example. the more promotions a customer has in his or her profile. In general. discount up to 1 ( sku whose color is blue )” Note that this will not automatically add the item to be discounted to the customer’s shopping cart.ATG Commerce Programming Guide µ This rule requires a condition under which the Y% should be taken off. 229 9 . Create a new promotion of type “item Discount fixed price. However. discount order total. performance is noticeably affected when a customer profile contains thousands of promotions. assign customers as few promotions as possible to accomplish the business goals for the site. See the ATG Personalization Guide for Business Users for more information on scenarios. “when order contains at least 1 ( sku whose color is blue). Performance Issues Related to Promotion Delivery In general. create the following PMDL rule: “when order contains at least 1 ( sku whose color is blue ). the condition is that the order contains a blue item.Using and Extending Pricing Services . if a promotion does not refer to information that might change from one request to another.” $10 off the total price of the order 10% off orders of $100 or more This rule is an order discount based in the order’s priceInfo property. discount all items. Create a new discount of type Order Discount – amount off. Next. As a general rule. Free Y with the order This rule is actually an Item Discount because it’s the Y that’s being described and Y’s price that is being discounted. A customer can have hundreds of promotions without it significantly affecting the time it takes to price an item. Set the discount percentage to 10. You must create a scenario to add the item to the cart. Use properties of the SKU (for example. Create a new discount of type “Order Discount – Percent Off.” “when Order’s priceInfo's amount is greater than 100. Y is a blue item.” Set the adjuster to 0.

This way. For example. RFQ and pre-negotiated prices.µ ATG Commerce Programming Guide For example. price lists can be used to implement business to business pricing where each customer can have its own unique pricing for products based on contracts. and configurable SKU IDs. not both. 230 9 . or to other conditions that do not change on a request basis. consider a situation in which you put all black shoes on sale one week. the promotion is still applied. Pricing can be inherited based on products and/or SKUs. Each list has the following properties: • • • • • • • Name Base price list Creation date Last modified date Start date End date Locale The list will display the following information about a product and a SKU: • • • • • • Product ID SKU ID Description Pricing scheme List price Complex price Note: Either the List Price or the Complex Price is required. as part of the promotion evaluation process. referring to a customer’s profile is an efficient way to structure a promotion. Price lists are managed through a single interface in the ACC. For example. SKU IDs. For example. The profile will probably be different for every price being generated throughout the site. you could set the sale price of the black shoes in either the SKU repository or the underlying database. Using Price Lists Price Lists allow you to target a specific set of prices to a specific group of customers. all SKUs that are in product X will be given a price of $9. if a price is defined as $9. which includes a list of product IDs.99 for product X. but no undue load is placed on the promotion evaluation engine.99 unless the price is explicitly overwritten. Rather than creating a promotion that puts black shoes on sale and giving it to every customer.Using and Extending Pricing Services . since many different customers will be using the site. It is not always efficient to refer to the date. Multiple lists can be created and managed.

Using and Extending Pricing Services . Caching Price Lists PriceCache allows you to cache the prices in price lists. There are price list-specific versions of each of the precalculators used by the ItemPricingEngine. see the Managing Price Lists chapter of the ATG Commerce Guide to Setting Up a Store. View a price through JSP code in JSPs. Note: ATG Business Commerce users can also store this price list in the contract used by the customer’s organization. If you do not want the PriceCache to hold all the prices in the prices list. There will be a property called priceList of type priceList.properties. 2. Price an item with a price list. Assign a price list to a user. The price list that is used to price an order is stored in the user’s profile.ATG Commerce Programming Guide µ For more information on setting up price lists using the ACC. ItemPriceListCalculator is the precalculator for list pricing. For more information on the PriceDroplet servlet bean. adjust the PriceCache settings in your liveconfig directory. The PriceCache settings are located in liveconfig/atg/commerce/pricing/priceLists/PriceCache. 231 9 . ConfigurableItemPriceListCalculator is the precalculator for configurable item pricing. The PriceDroplet servlet bean is used for looking up the price of an item. Price lists can contain a large number of prices. 1. 3. see the PriceDroplet section in this chapter in the ATG Commerce Guide to Setting Up a Store. This section contains information on the following price list topics: • • • • • • • • • • Overview of Setting Up Price Lists Description of Volume Pricing Setting up Price List Functionality in ATG Consumer Commerce PriceListManager Price List Calculators Implementing Sale Prices using Price Lists Calculating Prices with a Specific Price List Using the CurrencyConversionFormatter to Convert Currency Price List Security Policy Converting a Product Catalog to Use Price Lists Overview of Setting Up Price Lists The following steps describe how to price items using price lists.

however. Each of the 23 beams would cost $40. after purchasing 10 beams for $50 each and purchasing beams 11 through 20 for $45 each. price lists alone. For example. Bulk pricing calculates the price of a product based on the minimum quantity that is ordered. configure the ItemPriceListCalculator as shown: noPriceIsError=false noPriceCalculator=/atg/commerce/pricing/calculators/ItemListPriceCalculator Note that the component being configured is the PriceListCalculator. create the price lists as normal. purchase any more than 20 beams for $40 each 232 9 . Then configure the following two properties of the atg. you could: • • • purchase up to 10 steel beams for $50 each after purchasing 10 beams for $50 each.µ ATG Commerce Programming Guide Using Price Lists in Combination with SKU-Based Pricing ATG Commerce supports three pricing model options: SKU-based pricing alone.commerce.priceLists. In the combination case. purchase beams 11 through 20 for $45 each. and a combination of both. your pricing system is configured to use price lists. Consider using combined price lists and SKU-based pricing if most of your customers pay the same prices for most of your products.pricing.Using and Extending Pricing Services . For example. Two popular models are bulk pricing and tiered pricing. To use this pricing method. For example. and the path points to the ListPriceCalculator. with only a few variations. if you want to allow missing non-sale prices to use SKU pricing. but if no price is found in the lists you have specified.ItemPriceCalculator component: noPriceIsError=false noPriceCalculator=path_to_an_ItemPricingCalculator Which ItemPriceCalculator component to configure depends on the desired behavior. it falls back to the catalog price. your lists need only include the specific products for which you want to offer multiple prices. the total cost of the order would be $920. Tiered pricing calculates the price of a product using fixed quantity or weight at different pricing levels. you could: • • • purchase up to 10 steel beams for $50 each purchase 11 to 20 steel beams for $45 each purchase 21 or more steel beams for $40 each In this bulk pricing example. Description of Volume Pricing Price lists can be used to implement many pricing models. if you bought 23 steel beams. See the Price List Calculators section of this chapter for further information on these components.

\ calculators/ConfigurableItemPriceListCalculator 233 9 . Configure the ItemPricingEngine to use the appropriate precalculator.v 1. Add the following code to /atg/userprofiling/userProfile. Add a price_list column to dcs_user table. you should: 1. To add price list functionality.xml.xml in your localconfig: <gsa-template> <header> <name>Commerce Related Profile Changes</name> <author>DCS Team</author> <version>$Id: userProfile.1 2001/04/26 </version> </header> <item-descriptor name="user" default="true" sub-type-property="userType"> <table name="dcs_user" type="auxiliary" id-column-name="user_id"> <property category-resource="categoryCommerceContract" name="priceList" item-type="priceList" display-name-resource="priceList" column-name="price_list" repository="/atg/commerce/pricing/priceLists/PriceLists"/> </table> </item-descriptor> </gsa-template> 2. 3. ConfigurableItemPriceListCalculator is the precalculator for configurable item pricing. ItemPriceListCalculator is the precalculator for list pricing. There are price list-specific versions of each of the precalculators used by the ItemPricingEngine.ATG Commerce Programming Guide µ In this tiered pricing example. 23 steal beams would cost $1070: • • • 10 beams (beams 1-10) for $50= $500 10 beams (beams 11-20) for $45= $450 3 beams (beams 21-23) for $40= $120 Setting up Price List Functionality in ATG Consumer Commerce ATG Consumer Commerce users do not have a price list functionality available by default. The following code example shows how the /atg/commerce/pricing/ItemPricingEngine.Using and Extending Pricing Services .properties file should change to use the priceList calculators preCalculators=\ calculators/ItemPriceListCalculator.

calculating the price of an item using bulk pricing. The most important method in PriceListManager is getPrice. Three sub-calculators correspond to the three different pricing schemes. The three different schemes are calculating the list price of an item.µ PriceListManager ATG Commerce Programming Guide Note: The configurable item calculator is optional. The PriceListManager class maintains the price lists. For more information on bulk and tiered pricing. When an item is priced. This is used during pricing of an order to get the correct price for a given product/SKU pair. A price may be retrieved from the PriceListManager from a given price list by product. The major public API exposed by this class includes: • • getPricingScheme: returns the pricing scheme for the CommerceItem priceItem: examines the allowed PricingSchemeNames HashMap.Using and Extending Pricing Services . 234 9 . PriceListManager can be used to assign a default price list (DefaultPriceListId) and a default sale price list(DefaultSalePriceListId) in the event that one cannot be found for a customer. the property name of a default price list can be added as an input parameter. For example: public RepositoryItem getDefaultPriceList(String pPriceListName) Price List Calculators An ItemPriceCalculator class maintains all the functionality common to all the pricing schemes. an exception is thrown to indicate that the pricing scheme is not found. using the defaultPriceListId. The ItemPriceCalculator has the following important properties: • • PriceListManager: holds the reference to PriceListManager PricingSchemeNames: holds the key/Value pair for each allowed pricing scheme and its corresponding Calculator. or by a product/SKU pair. it will call the corresponding Calculator’s priceItem method. see the Using Price Lists section. the pricing calculators will use the price lists defined here to determine what price to use. It only needs to be used if your site supports configurable commerce items. see the Using Price Lists in Combination with SKU-Based Pricing section for properties related to that capability. determining which default list should be displayed. Otherwise. Using DefaultSalePriceListID. When a match is found. and calculating the price of an item using tiered pricing. For example: listPrice corresponds to the PriceListsListCalculator bulkPrice corresponds to the PriceListsBulkCalculator tieredPrice corresponds to the PriceListsTieredCalculator Also. by SKU.

The ItemPriceInfo will might several DetailedItemPriceInfos to reflect different unit prices for each tier. It will check • • each price level of that complex price to decide which unit price is used for each tier. you could have different sale prices for two different users. even if they have the same price list normally.Using and Extending Pricing Services . Implementing Sale Prices using Price Lists By default. This is because of the Range property in both ShipItemRels and DetailedItemPriceInfos. In the price list model. Follow these steps to implement sale pricing using price lists. 1. This section describes how to implement sale pricing with price lists. The SKU also has a boolean onSale property that indicates that the given SKU should be priced using the sale price. The ItemPriceInfo will contain one DetailedItemPriceInfo for each ShippingGroupCommerceItemRelationship in the CommerceItem. there is no sale pricing configured when using price lists. a price repository item has a listPrice (or a complexPrice) but no salePrice.ATG Commerce Programming Guide µ All of these calculators implement the ItemSchemePriceCalculator. The quickest way to implement sale pricing using price lists is to create a sale price list. The ItemPriceCalculator is responsible for setting this value. Each calculator uses a different description for the PricingAdjustment added to the ItemPriceInfo. For example. Using ItemPriceInfo with Price Lists One ItemPriceInfo class fits three different pricing schemes. This set up provides flexibility. you could store all the list prices for a specific user in one price list and all the sale prices for a specific user in another price list. The priceList property of ItemPriceInfo is set to the priceList that was actually used to calculate it. It then multiplies the price by the quantity returned by the getQuantity method of CommerceItem to get the total price. It also allows us to inherit sale prices while overriding the list prices (or vice versa). In the standard pricing model (where the price is stored directly in the SKU in the product catalog) there is a listPrice property and a salePrice property. This is nullable since other calculators other than those mentioned here will not set this. In this situation. ItemBulkPriceCalculator: Calls the getPrice method from the PriceListManager to retrieve the complex price for the CommerceItem. ItemTierPriceCalculator: Calls the getPrice method from the PriceListManager to retrieve the complex price for the CommerceItem. which only has a priceItem method. Creating the sale price list 235 9 . It will check each price level of that complex price based on the quantity of the CommerceItem to decide the correct unit price for the item. The ItemPriceInfo will contain one DetailedItemPriceInfo for each ShippingGroupCommerceItemRelationship. • ItemListPriceCalculator: Calls the getPrice method from the PriceListManager to retrieve the list price of the CommerceItem.

pricing. the following steps occur: There are two precalculators in the ItemPricingEngine. The ItemPriceInfo stores both pieces of information.ItemPriceCalculator. For sale pricing.µ 2. There will need to be an additional property in the user’s profile to store the salePriceList. user’s will need to have two price lists assigned to them. ATG Commerce Programming Guide Create a sale price list the same way you create other price lists. Structurally there is no difference between a sale price list and any other price list. Assign the sale price list to a user.\ bulkPrice=/atg/commerce/pricing/calculators/SalePriceListsBulkCalculator. 3. # The ItemSalePriceCalculator which prices an item on sale # $class=atg.\ tieredPrice=/atg/commerce/pricing/calculators/ SalePriceListsTieredCalculator The following list describes the important properties of ItemSalePriceCalculator: profilePriceListPropertyName=salePriceList This property forces the calculator to use the sale price list for pricing. Pricing an item with a price list If you want to price an item without price lists.pricing.commerce. allowing users to calculate the discount that the user received. Note: ATG Business Commerce users can create an additional property for the user and the contract. Price lists use a similar approach: The first calculator in the list by default is: /atg/commerce/pricing/calculators/ItemPriceListCalculator This is an instance of atg. useDefaultPriceList=false 236 9 . create a new instance of this calculator called ItemSalePriceCalculator.priceLists. Create this new property by copying the priceList property and changing the name. The item is first priced with the list price.commerce.priceLists. Since we want the flexibility of keeping sale prices completely separate from list prices.Using and Extending Pricing Services .ItemPriceCalculator loggingIdentifier=ItemSalePriceCalculator profilePriceListPropertyName=salePriceList useDefaultPriceList=false noPriceIsError=false pricingSchemePropertyName=pricingScheme priceListManager=/atg/commerce/pricing/priceLists/PriceListManager pricingSchemeNames=\ listPrice=/atg/commerce/pricing/calculators/SalePriceListsListCalculator. It configures the name of the profile property that stores the price list as well as the map that configures which calculator to use for each pricingScheme. The item is then priced with the sale price.

and no change is made to the price. Calculating Prices with a Specific Price List You can specify a price list that will be used to price items regardless of what price list is specified in a user’s profile. Sale price calculators add different PricingAdjustments and update salePrice instead of listPrice. 237 9 . Another instance of this servlet bean retrieves the sale price.\ calculators/ItemPriceListSaleCalculator. it is an error if there is no price defined (since we wouldn’t know how much to charge). You also need to price the configurable items. pricingSchemeNames=\ listPrice=/atg/commerce/pricing/calculators/SalePriceListsLis tCalculator.PriceDroplet $scope=global priceListManager=/atg/commerce/pricing/priceLists/PriceListManager profilePriceListPropertyName=salePriceList useDefaultPriceList=false This servlet bean is used in the same way as the PriceDroplet servlet bean.priceLists. this would only mean the item is not on sale.ATG Commerce Programming Guide µ When using list pricing. The ItemPricingEngine defines the following precalculators: preCalculators=\ calculators/ItemPriceListCalculator. you could extend the Customer Service Module to price items in all available price lists or use this method as an alternative if pricing with price lists in the standard way is not sufficient. Using the PriceDroplet servlet bean retrieves the list price. then no error is thrown. A ConfigurableItemPriceListSaleCalculator provided out of the box. This is usually not needed when using sale pricing so this is set to false.pricing.\ calculators/ConfigurableItemPriceListCalculator.\ tieredPrice=/atg/commerce/pricing/calculators/SalePriceListsT ieredCalculator These calculators are provided by default with ATG Commerce because sale price calculators manipulate the ItemPriceInfo in a different way than list price calculators.\ calculators/ConfigurableItemPriceListSaleCalculator 4. View a price through a JSP using JSP code. For example: $class=atg. It is most probably not an error if there is no sale price. For example.commerce. If this is false. you can assign a default price list.\ bulkPrice=/atg/commerce/pricing/calculators/SalePriceListsBul kCalculator. noPriceIsError=false When calculating a list price.Using and Extending Pricing Services .

To use this with pricing. certain objects might 238 9 .processor. Price List Security Policy The ATG Control Center allows users to create. Additionally.service. and ConfigurableItemPriceListSaleCalculator all look in pExtraParameters for the price list before looking in the profile. The amount can be converted from one currency to another. AddExtraParamsEntry adds a string key and string value to the extra parameters map. When a user attempts to view or edit a price list. ConfigurableItemPriceListCalculator.Using and Extending Pricing Services .properties with the following code: $class=atg.pipeline.AddExtraParamsEntry value=200005 key=priceList Then modify the repriceOrderChain in the commercepipeline. For more information on this servlet bean. then the ACC will display the item in gray characters.µ used instead of the profile’s price list. It adds pipeline support for specifying price lists. if extraParameters maps the string priceList to a price list (or a price list ID) and profilePriceListPropertyName is set to priceList (default). and delete price lists. For example. create a properties file in /atg/commerce/pricing/processor/UseDifferentPriceList. if a user does not have write access to a particular item. You can set a specific price list by adding an entry to pExtraParameters with a key of profilePriceListPropertyName and a value of the priceList that you with to use (or the ID of the priceList). the security system checks the security information associated with the object and grants or denies access based on the information. see Appendix B: ATG Servlet Beans in the ATG Page Developer’s Guide.xml as follows: <pipelinechain name="repriceOrder" transaction="TX_REQUIRED" headlink="useDifferentPriceList"> <pipelinelink name="useDifferentPriceList" transaction="TX_MANDATORY"> <processor jndi="/atg/commerce/pricing/processor/UseDifferentPriceList"/> <transition returnvalue="1" link="priceOrderTotal"/> <transition returnvalue="2" link="priceOrderTotal"/> </pipelinelink> <pipelinelink name="priceOrderTotal" transaction="TX_MANDATORY"> <processor jndi="/atg/commerce/pricing/processor/PriceOrderTotal"/> </pipelinelink> </pipelinechain> This causes all orders (regardless of what is in the profile) to be priced with priceList 100012. For example. then the price list in the map is One way to implement this is to use the generic pipeline processor AddExtraParamsEntry. ATG Commerce Programming Guide ItemPriceCalculator. Using the CurrencyConversionFormatter to Convert Currency The CurrencyConversionFormatter servlet bean can be used to convert and format a numeric amount. edit.

The goal of this section is to outline a policy that Commerce implemented. In the following example. users would only need to enter data for some of the items and then other items could derive their security information from these few items. The class needs to has the following signatures: public class PriceListSecurityPolicy extends SecuredRepositorySecurityPolicy { // overridden method from the super class. The price list security policy “walks” up the tree until an item finds the priceList to which it belongs and then retrieves the security information from the price list item. For more information. Note: You can also plug in a different security policy if your business needs are not met by the policy described in this section. This is method // that will perform special logic to get ACLs for a repository // item that lives in the PriceList repository. all objects under Price List A would share the same security information. It should 239 9 . By having a logical policy. The default security policy returns the ACL information stored on each repository item. if only users in the admin group can edit a particular price list. these objects will have the same security information as the priceList.security package.Using and Extending Pricing Services . then those same users would be the only ones that could edit the price entries in the price list. policies can be created that group logical items together. it can place a burden on both the system as well as the administrator entering security information. Therefore. In the price list security policy. To alleviate this burden. see the discussion on security measures for deployment in the ATG Installation and Configuration Guide. Price List A Price Entry for SKU A Price Entry for SKU B Complex Price The PriceListSecurityPolicy Class The PriceListSecurityPolicy class is located in the atg.commerce. all security information flows from a priceList down.ATG Commerce Programming Guide µ not be visible to certain users. This means that if there is a group of price and complexPrice that live in a priceList. This prevents an administrator from having to enter security information for every object in the repository. The ACC is capable of checking this security information for all items contained in the price list repository: • • • • Price List Prices Complex Prices Folders While having the ability to specify security information for each item is a very powerful concept.

Using and Extending Pricing Services . it creates another price that points to the sales price list and set its list price as the SKU’s salePrice. the PriceListMigration component creates a price that points to the list price list and sets its list price as the SKU’s list price.sql 2.) // get ACL for complexPrice repository item protected AccessControlList getACLForComplexPrice(SecuredRepositoryItem pItem). 1. For each SKU in the product catalog. The PriceListMigration component first creates two price lists: one for the list price. public AccessControlList getEffectiveAccessControlList(Object pObject). The methods // it could dispatch to are below. Run the price list SQL script against your catalog database. This script can be found at: <ATG9dir>/DCS/sql/db_components/dbvendor/priceLists_ddl. 3. If the onSale property for the SKU is true. Create a new PriceListSecurityPolicy component located in /atg/dynamo/security/. // get the ACL for a Price repository item protected AccessControlList getACLForPrice(SecuredRepositoryItem pItem. Converting a Product Catalog to Use Price Lists ATG Commerce includes a tool that can be used to convert your existing product catalog without price lists so that it can use price lists. Create a new PriceListSecurityConfiguration component located in /atg/dynamo/security/. This component should reference the PriceListSecurityPolicy component created in the previous step. Edit the configuration of the SecurePriceLists component located in /atg/commerce/pricing/priceLists/. 240 9 . } Configuring the Price List Security Policy Follow these steps to implement the security policy used by the SecuredPriceList repository: Note: These configuration steps should be performed at the Commerce configuration layer.µ ATG Commerce Programming Guide // figure out if the repository item type is "interesting" // and then dispatch to an appropriate method. Point the securityConfiguration property to the PriceListSecurityConfiguration component defined in the previous step. and the other for the sales price. This component should have PriceListSecurityPolicy as its class. Start the /atg/commerce/pricing/priceLists/PriceListMigration component. 2. To use the PriceListMigration component: 1.

ATG Commerce Programming Guide µ 3. Open the component editor for the PriceListMigration component.Using and Extending Pricing Services . Invoke the runMigration method from the methods tab in the component editor. 241 9 .

µ ATG Commerce Programming Guide 242 9 .Using and Extending Pricing Services .

adding shipping methods. Business Layer Classes The business layer classes hold the business logic for tasks like adding an item to an order. For example. ShippingGroup.Working With Purchase Process Objects . It includes the following sections: The Purchase Process Subsystems Creating Commerce Objects Using Relationship Objects Assigning Items to Shipping Groups Assigning Costs to Payment Groups Setting Handling Instructions ATG Commerce States Purchase Process Class Diagrams The Purchase Process Subsystems The purchase process can be broken down into the following subsystems: • Base Commerce Classes and Interfaces The base commerce interface implementations hold and manage other commerce interface implementations. Address Classes While not commerce-specific objects. an Order interface implementation contains implementations of CommerceItem. ShippingGroup. The interfaces define a mechanism for accessing the data stored in an object in a manner that frees it from the underlying implementation. These classes use the base commerce classes and the base commerce interfaces.ATG Commerce Programming Guide µ 10 Working With Purchase Process Objects This chapter includes foundational information on the various commerce objects used in the purchase process and how they interrelate. and Relationship. PaymentGroup. CommerceItem. and adding payment methods. The base commerce interfaces are Order. PaymentGroup. • • 243 10 . retrieving an order. the Address and ContactInfo classes play important roles in the purchase process. and Relationship.

although they are usually hidden from the ATG Commerce user. and payment information. The Relationship interface represents an association between two or more of the commerce objects listed above. pricing information. Interface Order Description The Order interface represents the delivery and payment information for a collection of items. ShippingGroupRelationship. For more information. A ShippingGroup could contain a physical delivery address. PaymentGroups.µ • • ATG Commerce Programming Guide Pipelines The purchase process pipelines execute a series of operations when called by the business layer classes. The interfaces are described below. and OrderRelationship. PaymentGroupRelationship. The CommerceItem interface represents information about a product to be purchased. an expiration date. Base Commerce Classes and Interfaces The base commerce classes and interfaces are the core objects that are used throughout ATG Commerce. These objects store the data that represent shopping carts. The ShippingGroup interface contains information about the delivery of a collection of CommerceItem objects. items to be purchased. A CommerceItem contains the SKU (also called the catalogRefId) and the quantity of the item purchased. shipping information.Working With Purchase Process Objects . CommerceItem ShippingGroup PaymentGroup Relationship 244 10 . and Relationships. Order Repository The Order Repository is the layer between ATG Commerce and the database server. An Order contains CommerceItems. The ATG Commerce class hierarchy is divided into classes and interfaces. ShippingGroups. see the Using Relationship Objects section. All the individual parts of ATG Commerce use these classes. shipping costs. For information on how all the classes and interfaces are related. such as the relationship between a CommerceItem and a ShippingGroup. It is important to understand the concept of relationships. and tax information for each item or the entire Order. The commercespecific interfaces that extend Relationship are CommerceItemRelationship. The interfaces provide access to the data in the objects in a way that frees it from the underlying implementation. This includes information such as a credit card number. refer to the Purchase Process Class Diagrams section. and the amount to be charged. The PaymentGroup interface contains payment information.

It manages collections of CommerceItem.ATG Commerce Programming Guide µ HandlingInstruction The HandlingInstruction interface describes special handling for a CommerceItem within a given ShippingGroup. It contains data structures for managing collections of other commerce objects.Working With Purchase Process Objects . Note1: Order equality is determined by comparing the orderId. and GiftCertificate all implement the PaymentGroup interface. Other interfaces are implemented by more than one class. there may be only one implementation. make sure the code synchronizes on the Order object before it is modified. The following types of classes implement the interfaces described above: Order Classes Item Classes Shipping Classes Payment Classes Relationship Classes Handling Classes In some cases. Item Classes Class CommerceItemImpl Description This class implements CommerceItem. For example. Shipping Classes 245 10 . It stores the data about a specific item in an Order. Note2: If you write any new code that modifies the Order object. PaymentGroup. PaymentGroupImpl. and Relationship objects. and transient properties. the lastModified time. Order Classes Class OrderImpl Description This class implements Order. Gift wrapping is an example of HandlingInstruction. CreditCard. ShippingGroup.

shipping costs. it stores information about how the CommerceItems are to be shipped to a physical street address. such as the carrier and postal address. as well as the Relationships to items in the shipping group. It stores the payment information for CommerceItems. and tax costs are paid for using a gift certificate. CreditCard GiftCertificate StoreCredit 246 10 . but is used through the CreditCard and GiftCertificate subclasses (described below in this table). shipping costs. In addition to storing inherited data. shipping costs. and tax. shipping costs. This class implements ShippingGroup and extends ShippingGroupImpl. shipping costs. This class implements PaymentGroup and extends PaymentGroupImpl. In addition to storing inherited data. HardgoodShippingGroup ElectronicShippingGroup Payment Classes Payment Classes PaymentGroupImpl This class implements PaymentGroup. It stores the data describing where and how to ship CommerceItems. and tax costs are paid for using a store credit. it stores information about how CommerceItems. This class provides no functionality itself. This class provides no functionality itself. In addition to storing inherited data. In addition to storing inherited data. This class implements ShippingGroup and extends ShippingGroupImpl.µ Classes ShippingGroupImpl ATG Commerce Programming Guide Description This class implements ShippingGroup. This class implements PaymentGroup and extends PaymentGroupImpl. In addition to storing inherited data. This class implements PaymentGroup and extends PaymentGroupImpl. it stores information about how CommerceItems are to be delivered electronically. and tax costs are paid for using a credit card. it stores information about how CommerceItems. or tax costs in the PaymentGroup. It also can contain Relationships to those items. it stores information about how CommerceItems. it is used through the HardgoodShippingGroup and ElectronicShippingGroup subclasses (described below). such as an e-mail address.Working With Purchase Process Objects .

it also stores data about which CommerceItems in the Order were added from a gift list. and quantity. In addition to storing all the basic data that it inherits. as well as data about what quantity of CommerceItems in which ShippingGroups need special handling. the tax cost or order cost is paid for using the information in the PaymentGroup.Working With Purchase Process Objects . This Relationship object itself contains data such as the quantity of the item to be paid for using the PaymentGroup. the shipping cost is paid for using the information in the PaymentGroup. GiftlistHandlingInstruction 247 10 . It contains a ShippingGroup ID. When this Relationship is added to a PaymentGroup and ShippingGroup. This Relationship object itself contains data such as the amount of the tax cost to be paid for using the PaymentGroup. Relationship Classes Classes ShippingGroupCommerceItemRelationship PaymentGroupCommerceItemRelationship PaymentGroupShippingGroupRelationship PaymentGroupOrderRelationship Handling Classes Classes HandlingInstructionImpl Description This class implements HandlingInstruction. When this Relationship is added to a PaymentGroup and CommerceItem. This Relationship object itself contains data such as the amount of the shipping cost to be paid for using the PaymentGroup. This class provides no functionality itself. This class implements HandlingInstruction and extends HandlingInstructionImpl. When this Relationship is added to a PaymentGroup and Order. but should be used through a subclass. the CommerceItem is paid for using the information in the PaymentGroup. the CommerceItem is shipped using the information in the ShippingGroup. CommerceItem ID.ATG Commerce Programming Guide µ Description When this Relationship is added to a ShippingGroup and CommerceItem. This Relationship object itself contains data such as the quantity to be shipped.

These objects are referenced when a user checks out a shopping cart. almost all of the business logic resided in the OrderManager class. You may need to extend these objects to track additional information about your users.Working With Purchase Process Objects . The following classes are business layer objects: 248 10 .core. To make this very large class easier to work with. The original structure remains intact to preserve backwards compatibility.Address and atg.µ Address Classes ATG Commerce Programming Guide There are two address classes that are not technically a part of ATG Commerce.core. but they play an important role in many commerce processes. but in the future you should use the new object managers. all calls to alter an Order should be made through these classes.util. They are atg. These methods contain the logic that alters the Order’s data structure and maintains its accuracy. it was broken up into new classes described below. See the Setting Up a Profile Repository chapter in the ATG Personalization Programming Guide for information on adding properties to user profiles.ContactInfo. Note: In previous versions.util. Address Properties • • • • • • • • • • • firstName middleName lastName address1 address2 city state county postalCode country ownerId ContactInfo Properties • • • phoneNumber faxNumber email Business Layer Classes The business layer classes contain the logic and business rules for the purchase process. The methods within these classes are used to make changes to an Order.

Contains functionality for working with a CommerceItem. The methods in this class are higher level than the methods in OrderTools. Contains functionality for working with ShippingGroups. In general.Working With Purchase Process Objects . Contains most of the functionality for working with an Order.ATG Commerce Programming Guide µ Class OrderTools Description Low-level interface containing the logic for editing an Order data structure. Contains functionality for working with PaymentGroups. It is not meant to contain business logic or to be used directly. For more information. including createShippingGroup() and splitShippingGroup(). The default property settings should be suitable for most sites. including methods such as createHandlingInstruction() and removeHandlingInstructionsFromShippingGroup(). only the OrderManager or SimpleOrderManager makes calls to an OrderTools object. only one method call in SimpleOrderManager is required to make a series of changes to an Order. The OrderTools component is located in Nucleus at /atg/commerce/order/. It is a very high-level interface for altering an Order. OrderManager CommerceItemManager ShippingGroupManager HandlingInstructionMa nager PaymentGroupManager OrderQueries SimpleOrderManager OrderTools OrderTools contains a set of properties that you can use to customize the purchase process. but can be changed. including createPaymentGroup() and intializeCreditCard(). as well as properties referencing the other manager classes listed below. including methods such as addCommerceItemToOrder() and addItemQuantityToShippingGroup(). Contains functionality for working with handling instructions. including methods such as createOrder(). For more information. The following OrderTool properties can be customized: orderTypeClassMap defaultOrderType commerceItemTypeClassMap defaultCommerceItemType shippingTypeClassMap 249 10 . This class extends OrderManager. see the OrderTools section. Contains lookup methods such as getOrdersForProfile() and getOrderIdsWithinDateRange(). see the Using the SimpleOrderManager section.

the default type is defined as the string “default. In the example below.defaultOrderType. You can have more than one type of CommerceItem object.) This constructs an instance of an Order class that is mapped to that string. orderTypeClassMap=\ default=atg.) This constructs an instance of a CommerceItem class that is mapped to that string.OrderImpl Note: Prior to version 6. Consequently. when the ShoppingCart constructed an Order. Below is a sample of how a mapping is defined in the properties file. The following code defines the default values. defaultOrderType=default commerceItemTypeClassMap This property defines the type-to-class name mapping for CommerceItem objects.µ defaultShippingGroupType defaultShippingGroupAddressType paymentTypeClassMap defaultPaymentGroupType defaultPaymentGroupAddressType relationshipTypeClassMap beanNameToItemDescriptorMap ATG Commerce Programming Guide You can view the OrderTools component in the ACC to see the configured values for these properties.orderType is set to /atg/commerce/order/OrderTools.0. When creating a new Order. the shoppingcart order type is no longer used and remains defined only for backwards compatibility. a string is passed as a parameter to the create method. When creating a new CommerceItem. orderTypeClassMap This property defines the type-to-class name mapping for Order objects.commerce. You can have more than one type of Order object. the string “default” could be passed.0.order. The following code defines the default value.order. defaultOrderType This property defines the default Order type. (For example. and by default this property was set to shoppingcart. it constructed one of the type specified in ShoppingCart.” which in turn maps to a class in the orderTypeClassMap property. 250 10 . a string is passed as a parameter to the create method. (For example. Beginning with version 6.orderType. the string “default” could be passed.Working With Purchase Process Objects .commerce.OrderImpl.\ shoppingcart=atg. ShoppingCart.

the string hardgoodShippingGroup could be passed. Below is a sample of how a mapping is defined in the properties file. defaultCommerceItemType=default shippingTypeClassMap This property defines the type-to-class name mapping for ShippingGroup objects. shippingTypeClassMap=\ default=atg.commerce. The following code defines the default value. The following code defines the default values.CommerceItemImpl defaultCommerceItemType This property defines the default CommerceItem type.\ hardgoodShippingGroup=atg. (For example. the default type is defined as the string hardgoodShippingGroup. which in turn maps to a class in the shippingTypeClassMap property. a string is passed as a parameter to the create method. 251 10 .order. You can have more than one type of ShippingGroup object.) This constructs an instance of a ShippingGroup class that is mapped to that string. CommerceItemTypeClassMap=\ default=atg.commerce. When creating a new ShippingGroup.order.commerce. The following code defines the default value.ShippingGroupImpl.Working With Purchase Process Objects . In the example below.ATG Commerce Programming Guide µ Below is a sample of how a mapping is defined in the properties file. In the example below. defaultShippingGroupType=hardgoodShippingGroup defaultShippingGroupAddressType This property defines the default ShippingGroupAddressType. defaultShippingGroupAddressType=RepositoryContactinfo To customize your address information. the default type is defined as the string “default. subclass RepositoryContactInfo and use your new class name for the defaultShippingGroupAddressType.HardgoodShippingGroup defaultShippingGroupType This property defines the default ShippingGroup type.” which in turn maps to a class in the commerceItemTypeClassMap property.order.

order. subclass RepositoryContactInfo and use your new class name for the defaultPaymentGroupAddressType. Relationships are not created directly by a user. The relationshipTypeClassMap property maps a name to a class. defaultPaymentGroupAddressType=RepositoryContactinfo To customize your address information.commerce. you can customize the environment to use a Relationship class you have subclassed.CreditCard.) This constructs an instance of a PaymentGroup class that is mapped to that string. paymentTypeClassMap=\ default=atg. You can have more than one type of Relationship object. Relationships are created by methods based on the type of relationship that the method needs.PaymentGroupImpl. By overriding the default values. The following code defines the default value.GiftCertificate. In the example below. This mapping does not need to be modified unless the system is extended.StoreCredit defaultPaymentGroupType This property defines the default PaymentGroup type. which in turn maps to a class in the paymentTypeClassMap property. the default type is defined as the string creditCard .order. 252 10 . the string creditCard could be passed.order. The example below demonstrates how a mapping is defined in the properties file. The following code defines the default values. When creating a new PaymentGroup.order. Below is a sample of how a mapping is defined in the properties file. relationshipTypeClassMap This property defines the type-to-class name mapping for Relationship objects.\ storeCredit=atg.commerce.commerce. You can have more than one type of PaymentGroup object. The following code defines the default values.\ giftCertificate=atg. (For example.commerce. defaultPaymentGroupType=creditCard defaultPaymentGroupAddressType This property defines the default PaymentGroupAddressType.\ creditCard=atg. a string is passed as a parameter to the create method. It is used to configure the class type that will be instantiated when a request to construct a relationship is made.µ paymentTypeClassMap ATG Commerce Programming Guide This property defines the type-to-class name mapping for PaymentGroup objects.Working With Purchase Process Objects .

order.\ atg.\ atg.order. The example below demonstrates how a mapping is defined in the properties file.order.commerce.commerce. The following code defines the default values.commerce.GiftCertificate=giftCertificate.commerce. The format is <bean name>=<repository item descriptor>.order.\ atg. ShippingGroupCommerceItemRelationship.ItemPriceInfo=itemPriceInfo.\ atg.order.commerce.commerce.order.DetailedItemPriceInfo=detailedItemPriceInfo.\ atg.order.HardgoodShippingGroup=hardgoodShippingGroup.CreditCard=creditCard. All objects that can be mapped to an item descriptor are listed in the beanNameToItemDescriptorMap.commerce.commerce.commerce. When saving an Order. PaymentGroupOrderRelationship beanNameToItemDescriptorMap This property maps a bean name to an OrderRepository item descriptor name.pricing.\ paymentGroupCommerceItem=atg.commerce.order. PaymentGroupShippingGroupRelationship.CommerceItemImpl=CommerceItem.commerce.PricingAdjustment=pricingAdjustment Pipelines A pipeline is an execution mechanism that allows for modular code execution.TaxPriceInfo=taxPriceInfo.\ paymentGroupOrder=atg.ShippingGroupImpl=shippingGroup.pricing.\ atg.commerce. 253 10 . saving an Order.Working With Purchase Process Objects .PaymentGroupCommerceItemRelationship=payItemRel.ATG Commerce Programming Guide µ relationshipTypeClassMap =\ shippingGroupCommerceItem=atg.commerce. The PipelineManager implements the pipeline execution mechanism.commerce.commerce.PaymentGroupOrderRelationship=payOrderRel.pricing.order.\ atg. PaymentGroupCommerceItemRelationship.payment.commerce.PaymentGroupShippingGroupRelationship=payShipRel. the processors that contain the code for saving look for an OrderRepository item descriptor with the same name as the bean class.pricing.\ atg.\ atg.\ atg.order.OrderPriceInfo=orderPriceInfo. such as loading an Order.commerce.order.OrderImpl=order.pricing. beanNameToItemDescriptorMap=\ atg.\ atg.PaymentGroupImpl=paymentGroup.order.commerce.\ atg.commerce. The beanNameToItemDescriptorMap property contains this mapping.order.\ paymentGroupShippingGroup=atg.\ atg.ShippingGroupCommerceItemRelationship=shipItemRel.ShippingPriceInfo=shippingPriceInfo.\ atg.\ atg.commerce.\ atg.\ atg.PaymentStatus=paymentStatus. and checking out an Order.order.commerce.pricing. ATG Commerce uses pipelines to execute tasks.order.

add a new element to the XML file that references the new pipeline processor. Additionally.xml. For more information on SQL repositories.µ ATG Commerce Programming Guide The commerce pipeline is defined in an XML file. the PipelineManager is located at /atg/commerce/PipelineManager. When you deploy an application that includes ATG Commerce. The repository is where Orders are saved after processing and stored in between customers’ visits to your site.xml for ATG Consumer Commerce and at <ATG9dir>/B2BCommerce/config/atg/commerce/commercepipeline. define a handle method in a form handler class that calls the PipelineManager. The commerce pipeline configuration file contains the definition for the processOrder chain. The base Order Repository definition file is located at <ATG9dir>/DCS/config/atg/commerce/order/orderrepository. A pipeline should generally be executed from an OrderManager method. 254 10 . there exists a corresponding item descriptor. and processOrder() methods. see the Processor Chains and the Pipeline Manager chapter in this manual.xml.xml for ATG Business Commerce. for every class that is saved. this base file is combined with an additional definition file that is located at <ATG9dir>/B2CCommerce/config/atg/commerce/order/orderrepository. the PipelineManager is below the OrderManager. This is the case for the loadOrder(). Each item descriptor defines a repository item type that describes all the properties that are common to the repository items of that type. which is located at /atg/commerce/order/. In ATG Commerce. To execute a pipeline through JSPs. so it inherits all of the properties of the shippingGroup item descriptor. a new instance is created and the commerce pipeline configuration is loaded. To insert a new link. The Order Repository definition file defines the item descriptors for all commerce classes. For more information. For example.xml. updateOrder(). The new functionality is inserted into the execution chain without affecting the existing code. the processors that save and load an Order look for an item descriptor that is mapped to the corresponding commerce object class. In ATG Consumer Commerce. You can view the mapping by accessing the Pages and Components > Components by Path area of the ATG Control Center and opening the OrderTools component. see the ATG Repository Guide. For more information about the OrderTools component. see the Configuring Purchase Process Services chapter. Order Repository The Order Repository is the layer between ATG Commerce and the database server. the beanNameToItemDescriptorMap property contains this mapping. each item descriptor subtype inherits all of the properties of its parent item descriptor. It is implemented using a SQL repository. The beanNameToItemDescriptorMap property of the OrderTools component maps the Order Repository item descriptors to Bean names. In ATG Business Commerce. the hardgoodShippingGroup item descriptor extends the shippingGroup item descriptor. this base file is combined with an additional definition file that is located at <ATG9dir>/B2BCommerce/config/atg/commerce/order/orderrepository. For more information about saving and loading orders. In the Nucleus hierarchy. In the overall architecture of ATG Commerce.Working With Purchase Process Objects . which can be found at <ATG9dir>/B2CCommerce/config/atg/commerce/commercepipeline. see the OrderTools section of the Working With Purchase Process Objects chapter.

String pOrderId. The type of Order created depends on the method used. ShippingPriceInfo pShippingPriceInfo. OrderPriceInfo pOrderPriceInfo. Otherwise. TaxPriceInfo pTaxPriceInfo. TaxPriceInfo pTaxPriceInfo. To create an Order. By default. A shopping cart is an implementation of the Order interface. It includes the following subsections: • • • • • • • Creating an Order Creating Multiple Orders Creating Commerce Items. you must have a reference to an OrderManager or SimpleOrderManager. String pOrderType) createOrder(String pProfileId. OrderPriceInfo pOrderPriceInfo. Shipping Groups. TaxPriceInfo pTaxPriceInfo. each of which takes a different set of parameters: createOrder(String pProfileId) createOrder(String pProfileId. an Order contains one empty ShippingGroup and one empty PaymentGroup when it is created. OrderPriceInfo pOrderPriceInfo. 255 10 .Working With Purchase Process Objects . ShippingPriceInfo pShippingPriceInfo) createOrder(String pProfileId. If the method takes an orderType parameter. and Payment Groups Adding an Item to an Order via a URL Preventing Commerce Items from Being Added to Types of Shipping Groups Removing Commerce Objects from an Order Using the SimpleOrderManager Creating an Order The first step in working with Commerce objects is to create an Order. String pOrderType) All methods create an Order object and assign it a unique ID. use createOrder() to create the new Order. the defaultOrderType property of the OrderTools component defines the Order type. Once you have the reference. String pOrderType) createOrder(String pProfileId. String pOrderId. that parameter determines the type of object that is constructed.ATG Commerce Programming Guide µ Creating Commerce Objects The ATG Commerce “manager” classes contain methods for creating commerce objects and adding them to and removing them from an Order. and their types are determined by the defaultShippingGroupType and defaultPaymentGroupType properties of the OrderTools component. String pOrderType) createOrder(String pProfileId. There are many versions of the createOrder method. ShippingPriceInfo pShippingPriceInfo. This section describes how to use the manager classes to create the various commerce objects.

They can place items in different shopping carts. you can allow them to switch between any of the Order objects using the following JSP code: <dsp:form action="ShoppingCart. if a customer has several shopping carts saved. Refer to the following JSP example: <dsp:form action="ShoppingCart.µ // Get a reference to the OrderManager ATG Commerce Programming Guide Note: If you do not want to create an empty ShippingGroup and an empty PaymentGroup for every new Order. switch between carts. orders are persistent. By default. a session-scoped component whose handleXXX methods add.createOrder(profileId). delete carts. // Create the Order Order order = orderManager.jsp" method="post"> <dsp:select bean="ShoppingCart. The ShoppingCart component is located in Nucleus at /atg/commerce/. set the persistOrders property in the ShoppingCart component to false. The following example demonstrates how to create an Order: OrderManager orderManager = (OrderManager) request. It switches the current Order object out to the saved collection of orders and sets the current Order to the Order identified by the handlerOrderId property.order. Using multiple orders requires atg.commerce.create" value="Create" type="submit"/> another shopping cart. and can check out one cart’s contents while waiting until later to check out the contents of others.Working With Purchase Process Objects . Creating Multiple Orders Customers can have an unlimited number of orders in existence at one time. The component that utilizes OrderHolder is /atg/commerce/ShoppingCart. delete.jsp" method="post"> <dsp:input bean="ShoppingCart. To disable persistence. and switch between carts.resolveName("/atg/commerce/order/OrderManager"). Any previously existing Order object is placed into the collection of saved carts.handlerOrderId"> <dsp:droplet name="ForEach"> 256 10 .commerce. retrieve a list of saved carts.<BR> </dsp:form> The handleSwitch() method allows customers to switch between shopping carts.Order.OrderHolder in addition to atg. This method creates a new Order and sets it as the currentOrder in the OrderHolder. set the createDefaultShippingGroup and createDefaultPaymentGroup properties in the OrderTools component to false. as explained in the rest of this section. You implement multiple shopping carts using the handleCreate method of the OrderHolder class. For example. This class maintains the current Order object as well as a collection of saved Order objects.order.

String"> <dsp:option value="<%=option12%>"/> </dsp:getvalueof> <valueofparam="SavedOrder. For PaymentGroups. CommerceItemManager. For more information on creating these commerce objects and adding them to an order. and Payment Groups After an Order has been created.id"></dsp:valueof> </dsp:oparam> </dsp:droplet> </dsp:select> <dsp:input bean="ShoppingCart. Shipping Groups. The call returns the type of class specified by the objectType parameter or the default type when the method used does not accept that parameter. First. respectively. The handlerOrderId property would be set to the selected Order ID.createCommerceItem(). After creating the objects.id" idtype="java.Working With Purchase Process Objects . Creating these objects follows the same pattern as creating Orders.addPaymentGroupToOrder() These methods take an Order and their respective object type as parameters. the next step is to add CommerceItems and possibly additional ShippingGroups and PaymentGroups. and the corresponding Order would be set as the current Order.lang.saved" name="array"/> <dsp:param value="SavedOrder" name="elementName"/> <dsp:oparam name="output"> <dsp:getvalueof id="option12" param="SavedOrder.addShippingGroupToOrder() PaymentGroupManager. the order in which they are added to the Order determines their precedence. call create<ObjectType>() in the appropriate manager class. refer to the following subsections: • • • • Creating a Standard Commerce Item Creating a Configurable Commerce Item Creating a Shipping Group Creating a Payment Group 257 10 . Creating Commerce Items.switch" value="Switch" type="submit"/> </dsp:form> The example iterates through the list of saved shopping carts. for example. use the following methods to add them to the Order: • • • CommerceItemManager.addItemToOrder() ShippingGroupManager. and gives the customer the option to select one of the saved carts. The handleDelete() and handleDeleteAll() methods remove a single Order or all orders (both current and saved).ATG Commerce Programming Guide µ <dsp:param bean="ShoppingCart. displays the shopping carts to the customer.

some of which may not have repositories. ATG Commerce Programming Guide Follow these steps to create a new CommerceItem and associate it with an Order: Call CommerceItemManager.setQuantity(3). 3.addItemToOrder(pOrder. Follow these steps to create a new ConfigurableCommerceItem and associate it with an Order: 1.addItemToOrder(pOrder. Call CommerceItemManager. If you want to prevent this behavior. ProductRef. the class includes ProductID. Note: createCommerceItem() will work even if you pass it a nonexistent catalog reference ID. Creating a Configurable Commerce Item Configurable commerce items are items with other items as optional components. such as setting the quantity.resolveName("/atg/commerce/order/OrderManager"). Refer to the following example: // Get a reference to the OrderManager OrderManager orderManager = (OrderManager) request.addSubItemToConfigurableItem() or addAsSeparateSubItemToConfigurableItem() to add options to the base item. // Create the CommerceItem CommerceItem commerceItem = commerceItemManager. Call CommerceItemManager. Call CommerceItemManager. commerceItem). As initially defined.createCommerceItem(). 2. This structure allows arbitrary data to be stored with a CommerceItem. pCommerceItem) to add the CommerceItem to the Order. // Add the CommerceItem to the Order commereceItemManager. This data could be the options for a CommerceItem such as size and color. Auxiliary data is a construct that exists in a CommerceItem object.createCommerceItem() to create the base commerce item. 258 10 .createCommerceItem(pCatalogRefId). the classes must be defined as serializable. you must institute a check. The example below illustrates how to programmatically create a ConfigurableCommerceItem with subSKU items and then add it to an Order. 2.µ Creating a Standard Commerce Item 1. An important concept is that any data that is inserted into the auxiliary data can be serialized at any time in a system that contains remote components. PropertyValue. and CatalogRef properties.Working With Purchase Process Objects . Make any changes to the CommerceItem. This allows you to use ATG Commerce as an ordering system with multiple catalogs. and are described in the Using and Extending the Standard Catalog chapter of this manual. It could also refer to the product reference in the catalog. When defining AuxiliaryData objects. commerceItem.

(For more information. "sku10001". "prod10001". subskuItem = (SubSkuCommerceItem) getCommerceItemManager(). these items automatically become part of the default ShippingGroup. null. null. subskuItem). getCommerceItemManager(). SubSkuCommerceItem subskuItem = (SubSkuCommerceItem) getCommerceItemManager(). Relationships must now be created to associate the items with shipping groups. null. null. all the items in the Order are removed from the default ShippingGroup and must be explicitly added to one of two shipping groups. such as setting the address. null. Once a second ShippingGroup is added to the Order. null. null. 259 10 . null. configurableItem).createShippingGroup().addSubItemToConfigurableItem(configurableItem. "sku20002". shippingGroup). getCommerceItemManager(). Make any changes to the ShippingGroup. subskuItem).Working With Purchase Process Objects . // Add the ShippingGroup to the Order shippingGroup. new ItemPriceInfo()).createCommerceItem("subSkuCommerceItem". Call ShippingGroupManager. 1. As items are added to the Order. 2. "prod20002". 1. see Assigning Items to Shipping Groups.resolveName("/atg/commerce/order/OrderManager").ATG Commerce Programming Guide µ ConfigurableCommerceItem configurableItem = (ConfigurableCommerceItem) getCommerceItemManager().addItemToOrder(order. null.) Follow these steps to create a new ShippingGroup and add it to an Order: 1.addSubItemToConfigurableItem(configurableItem. a new Order has one default ShippingGroup. Creating a Shipping Group A ShippingGroup contains information on the shipping address and delivery method for a group of commerce items. "prod20001".addShippingGroupToOrder(pOrder. 1. By default. 3.createCommerceItem("configurableCommerceItem".addShippingGroupToOrder(pOrder.createShippingGroup().createCommerceItem("subSkuCommerceItem". new ItemPriceInfo()). new ItemPriceInfo()). Refer to the following example: // Get a reference to the OrderManager OrderManager orderManager = (OrderManager) request. pShippingGroup) to add the ShippingGroup to the Order. null. null. getCommerceItemManager(). // Create the ShippingGroup ShippingGroup shippingGroup = shippingGroupManager. "sku20001". Call ShippingGroupManager. null.

but do not want to subclass RepositoryContactInfo (see defaultShippingGroupAddressType in the Order Tools section). Orders with requisition numbers are automatically assumed to require approval. such as UPS or US Postal. Call PaymentGroupManager. pPaymentGroup) to add the payment group to the order. After the customer selects a shipper. The following assumptions were made regarding Multishipment: • • Customers want to ship various parts of their orders to different addresses. 3. a ShippingGroup is created. see the Assigning Costs to Payment Groups section. a new Order has one default PaymentGroup. 2. normally you pass a RepositoryContactInfo object to setShippingAddress() or setBillingAddress(). suppose a customer enters the checkout process on a site that supports multiple shipping methods for a single order. 260 10 . By default.addPaymentGroupToOrder(pOrder. and so on). Creating a Payment Group A PaymentGroup contain information about the payment method that will be used to purchase a group of commerce items. As items are added to the Order.) Payment groups also contain a requisitionNumber property for orders that require approval before a means of payment can be specified. The customer chooses to have the items shipped to different locations. all the items in the Order are removed from the default PaymentGroup and must be explicitly added to one of the two payment groups. you could set the credit card number and expiration date. UPS. If there is only one shipping group. then the customer must decide which items go into which group. Call PaymentGroupManager.createPaymentGroup(). these items automatically become part of the default PaymentGroup. The site must provide a UI that allows the customer to enter an address. Creating Multiple Shipping Groups Multiple shipping groups (which implement Multishipment) on a commerce site permit a customer to ship parts of an order to different addresses using different methods of delivery.) Follow these steps to create a new PaymentGroup and add it to an Order: 1. The site must then provide a UI that allows the customer to associate items with that shipping group. then all the items to be shipped will go into that shipping group.Working With Purchase Process Objects . For example. you must modify some Nucleus components. List the properties of your address object in the saveProperties property of /atg/commerce/order/processor/SaveShippingGroupObjects and the loadProperties property of atg/commerce/order/processor/LoadShippingGroupObjects. If you want to use a ContactInfo object instead. Make any changes to the PaymentGroup. For example.µ ATG Commerce Programming Guide When setting the shipping and billing addresses. If more than one shipping group is associated with the order. (See the Managing the Order Approval Process chapter for more information on approvals. and then associate it with a shipper. (For more information. Customers want to ship various parts of their orders using different shipping methods (FedEx. Once a second PaymentGroup is added to the Order. Relationships must now be created to associate the items with payment groups.

The base commerce classes have built-in support for multiple payment methods. a customer can choose to pay for an order using two or more credit cards and a gift certificate. you can allow a user to add an item to his or her order by clicking a URL. or any combination of the two. The product UI for this component is entirely JSP-based.Working With Purchase Process Objects .ATG Commerce Programming Guide µ Refer to the following example: // Get a reference to the OrderManager OrderManager orderManager = (OrderManager) request.jsp?dcs_action=additemtocart&url_catalog_ref_ id=sku10001&url_product_id=prod10001&url_quantity=1&dcs_ci_catalogKey=en_ US&dcs_subsku=sku10001.com/yourpage.2&dcs_subsku=sku10002.createPaymentGroup(). and additional parameters give the specifics for the action. if necessary. // Create the PaymentGroup PaymentGroup paymentGroup = paymentGroupManager. Consider the following example request URL: http://yoursite. Creating Multiple Payment Groups Multiple payment groups (which implement Multipayment) on a commerce site permit a customer to split the cost of an order by amount and/or items.resolveName("/atg/commerce/order/OrderManager"). paymentGroup). amount level.prod10002. the request will be checked to see if it includes commerce item information. Adding an Item to an Order via a URL The CommerceCommandServlet provides a foundation for URL-based actions.addPaymentGroupToOrder(pOrder.prod10001. While customers can select payment methods by item level. Because this process is part of the Request-handling pipeline (which handles all ATG requests and responses). Gift certificates are implemented as payment methods. Out of the box. Multipayment allows customers to pay for purchases using multiple payment methods. The following assumptions were made regarding Multipayment: • • • Customers can divide payment for an order or individual items by item quantity. For example. Customers can pay for part of a purchase using one payment method and use another payment method for the rest of the purchases. you can limit the ways in which an order’s costs can be split. each time a page is requested. The following table explains the URL elements: 261 10 .1 The dcs_action flag notifies the request-handling pipeline of the action to be performed. // Add the PaymentGroup to the Order paymentGroupManager. The customer then chooses to pay for the remaining $250 using points earned on the site during previous visits. suppose a customer begins the checkout process on a site that supports multiple payment methods for a single order. or amount. percentage. For example. The customer chooses to partition payment by putting the first $1000 of a $1250 order on a Visa credit card.

dcs_subsku=sku10001. SubSkuCommerceItem is a subclass of CommerceItemImpl. If this parameter is supplied.prod1000 2. The ID of the ShippingGroup to which to add the item. If you need to add two different computer configurations. the servlet creates a CommerceItem and adds it to the cart. ATG Commerce handles the multiplication. product id. 262 10 .prod10001. A string specifying which CommerceItem type to use. then this is a reconfiguration. For example. the individual quantity would still be 2. the first four parameters listed in the table above are required. You can extend the CommerceCommandServlet and the pipeline to let the user trigger some other action by clicking a URL. The format is: dcs_subsku=<sku id.2&dcs_subsku=sku10002. url_catalog_ref_ id url_product_id url_quantity url_shipping_gro up_id url_item_type url_commerce_ite m_id dcs_ci_* (Required) The SKU of the product to add to the cart. If you were adding 1000 computers. For example. The individual quantity portion of this parameter reflects the quantity of the item which will be added to a single ConfigurableCommerceItem. (Required) The quantity of the SKU to add to the cart. The ID of the CommerceItem which this configuration should replace. Example dcs_ci_catalogKey=en_US would cause the property catalogKey to be set to the value “en_US”.” it calls the AddItemToCartServlet. prod10001 and quantity 2 and SKU/product combination sku10002. If a dcs_subsku parameter is in the URL. each with 2 hard drives. (Required) The product ID of the product to add to the cart. then the base SKU/product is represented in a ConfigurableCommerceItem object and the subSKU is represented in a SubSkuCommerceItem object. As indicated. if you are adding a computer with 2 hard drives. the individual quantity would be 2.Working With Purchase Process Objects . individual quantity>. If no other parameters are supplied. An identifier for a configurable property of a CommerceItem. An identifier for setting a CommerceItem property.prod10002 and quantity 1 to the ConfigurableCommerceItem. you must issue two separate requests to ATG Commerce to add each of the configurations as separate ConfigurableCommerceItems.µ Element dcs_action ATG Commerce Programming Guide Function (Required) When CommerceCommandServlet receives the dcs_action “additemtocart.1 causes the servlet to add a CommerceItem with SKU/product dcs_subsku combination sku10001.

then the item is added to the ShippingGroup with the specified ID. However. list the names of the ShippingGroup types to which a CommerceItem is not allowed.ATG Commerce Programming Guide µ If all required parameters and shipping_group_id are supplied. It does not make sense for a box of golf balls to be shipped electronically. you could create a shippingGroupsNotAllowed property for the SKU item descriptor in the product repository. The object ID is found in the id property of the CommerceItem. Follow these steps to prevent commerce items from being added to specific types of shipping groups: 1.removeShippingGroupFromOrder() PaymentGroupManager. Override any necessary methods to make sure the shippingGroupsAllowed property in the SKU that this CommerceItem represents matches the shippingGroupClassType property of the ShippingGroup to which the CommerceItem is being added. To remove subitems from configurable commerce items. Removing Commerce Objects from an Order The counterparts to the add methods are the methods for removing commerce items. These methods are addItemToShippingGroup() in the ShippingGroupManager. Add a new shippingGroupsAllowed property to the SKU item descriptor in the product repository.removePaymentGroupFromOrder() These methods take an Order and their respective object ID as parameters.removeItemFromOrder() ShippingGroupManager. or PaymentGroup. The shippingGroupsAllowed property should contain a list of shipping groups to which the SKU that this CommerceItem represents can be added.removeSubItemFromConfigurableItem() CommerceItemManager. only certain types of items can be assigned to an ElectronicShippingGroup. and addItemQuantityToShippingGroup and addRemainingItemQuantityToShippingGroup() in the CommerceItemManager. all items are allowed to go into any type of ShippingGroup. shipping groups. In this property.removeAllSubItemsFromConfigurableItem() 263 10 . Preventing Commerce Items from Being Added to Types of Shipping Groups By default.Working With Purchase Process Objects . They are: • • • CommerceItemManager. Note: The available ShippingGroup types are listed in the shippingTypeClassMap property of the OrderTools component. For example. it might be necessary to prevent specific commerce items from being added to certain types of shipping groups. ShippingGroup. and payment groups from an Order. Alternatively. 2. use one of these methods: • • CommerceItemManager.

getSimpleOrderManager(). The PaymentGroup contains the credit card information.addRemainingOrderCostToPaymentGroup(pOrder. Logically. which represents a relationship between an Order and the PaymentGroup responsible for the whole or partial cost of the Order. the SimpleOrderManager sits above the OrderManager and provides higher-level functionality. and the quantity of this item to ship to the address in the ShippingGroup. While you never explicitly add a Relationship to an Order. Using Relationship Objects A Relationship represents an association between two other objects. The Relationship indicates that the CommerceItem will be handled according to the information in the ShippingGroup. quantity. Unlike most business objects.Working With Purchase Process Objects . What takes several lines of code to do in the OrderManager takes only a single line of code in the SimpleOrderManager. // Get a reference to the OrderManager OrderManager om = (OrderManager) request. ShippingGroup shippingGroup = getShippingGroup(). When you create these additional associations. You can use SimpleOrderManager in place of OrderManager to simplify your code. one default shipping group. the ShippingGroup.resolveName("/atg/commerce/order/OrderManager").µ Using the SimpleOrderManager ATG Commerce Programming Guide SimpleOrderManager extends OrderManager. The Relationship contains the CommerceItem to ship. String productId = getProductId(). A PaymentGroupOrderRelationship is constructed implicitly. By default. relationships handle the details of which payment or shipping method to use for which items.addItemToShippingGroup(order. productId. and the Order. the PaymentGroup. Another Relationship example is a PaymentGroupOrderRelationship. as the example below shows. // Creates a PaymentGroupOrderRelationship implicitly om. Relationship objects do not have their own “manager” class. Methods where the operator is a Relationship are placed in the operand’s manager class. Below is a code sample that associates part of an order’s cost with a specific PaymentGroup. String skuId = getSkuId(). a method 264 10 . you do so implicitly by calling methods like addItemQuantityToShippingGroup() or addShippingCostAmountToPaymentGroup(). The PaymentGroupOrderRelationship contains the amount to charge. pPaymentGroup). skuId. long quantity = getQuantity(). and no Relationships. For example. For example. shippingGroup). a SimpleOrderManager object is configured in Nucleus at /atg/commerce/order/OrderManager. a ShippingGroupCommerceItemRelationship represents a relationship between a CommerceItem and a ShippingGroup. a new Order has one default payment group. In ATG Commerce.

This section describes the following Relationship objects and their possible relationship types: • • • • ShippingGroupCommerceItemRelationship Object PaymentGroupOrderRelationship Object PaymentGroupCommerceItemRelationship Object PaymentGroupShippingGroupRelationship Object For details on assigning items to relationships of specific types. then all the CommerceItems are shipped to the location in the ShippingGroup. see the next two sections. ShippingGroupCommerceItemRelationship Object A ShippingGroupCommerceItemRelationship represents a relationship between a CommerceItem and a ShippingGroup. a given CommerceItem cannot have more than one PaymentGroupRelationship of a “remaining” type. For example. These relationship types assign CommerceItems to ShippingGroups that specify which items in the Order will be shipped to which destinations. The following list describes the relationship types: • ShippingQuantity: This relationship type indicates that a specific quantity of the item will be shipped using the information in the ShippingGroup. as well as what types the relationship’s member variables have. Methods that operate on a subclass of a given commerce object are placed in the superclass’s manager class. 6 of those items will be paid for using the PaymentGroup that the relationship references. and the quantity purchased is stored inside the CommerceItem. and a method for assigning a CommerceItem to a ShippingGroup is in the CommerceItemManager. However. if the relationship contained quantity 15. quantities and amounts designated by a number are processed as “up to and including” the given number. Assigning Items to Shipping Groups and Assigning Costs to Payment Groups.Working With Purchase Process Objects . For example. The remaining 4 will be handled by the next relationship whose priority is less than the first relationship. The quantity to ship is stored inside the Relationship. 265 10 . If the quantity in the Relationship is greater than the quantity in the CommerceItem. ShippingQuantityRemaining: This relationship type indicates that the remaining • quantity of the item unaccounted for by other ShippingGroupCommerceItemRelationship objects will be shipped using the information in the ShippingGroup. This relationship can be assigned the relationship type ShippingQuantity or ShippingQuantityRemaining.ATG Commerce Programming Guide µ for adding an Order to a ShippingGroup is in the OrderManager. it can have a PaymentGroupRelationship and a ShippingGroupRelationship – both of a “remaining” type – because the two relationships are separate entities. then all 10 items will be paid for using that first PaymentGroup. if a PaymentAmount relationship exists with quantity 6 and references an item with quantity 10. Relationship Types Relationship objects have associated types. On the other hand. These types determine what happens when an Order is checked out. Note: For all of the following relationship types. Also note that it is not possible to have more than one Relationship of a specific “remaining” type (described below) in any given object.

The amount must be greater than zero. The customer wants 3 apples shipped to his home. Range information is calculated when the end user checks out. For example. then the new items default to the ShippingGroup in that relationship.Working With Purchase Process Objects . ensuring correct pricing for each CommerceItem regardless of any changes the user may make to ShippingGroups while browsing. This relationship type is ShippingQuantity and the quantity to ship is 3. If the second relationship is of type ShippingQuantityRemaining. or the relationship type ShippingQuantityRemaining. For example. Setting the lowBound to 3 and the highBound to 6 means the last four are shipping using this relationship. The following list describes the relationship types: • OrderAmount: This relationship type indicates that a specific amount of the total cost of the Order (including CommerceItems. A CommerceItem can have only one Relationship of type ShippingQuantityRemaining. Bounds are inclusive. This relationship can have either the relationship type ShippingQuantity with quantity 7. These relationship types assign the order and tax amounts to different PaymentGroups.util. tax) to separate PaymentGroups. if the quantity of CI1 increases. Both relationship types use an atg. The difference between creating a second relationship with type ShippingQuantity and using ShippingQuantityRemaining is that.Range object to determine which particular CommerceItems to include for a given quantity. Two ShippingGroups already exist.µ ATG Commerce Programming Guide Note: Any ShippingQuantityRemaining relationships have the lowest priority. and tax) will be paid using the information in the PaymentGroup. then the new items would not be assigned to a ShippingGroup. 266 10 . The customer wants the remaining apples (7) shipped to his office. using ShippingQuantity. then the cost of the entire Order will be paid using the referenced PaymentGroup. There are two ways to split the cost of an Order across PaymentGroups. so a ShippingGroupCommerceItemRelationship is created between CI1 (apple) and SG1 (home). A ShippingGroupCommerceItemRelationship is created between CI1 (apple) and SG2 (office). Set the Range’s lowBound and highBound to indicate which items to include. a customer places an order for CommerceItem Apple with quantity 10. setting the lowBound to 1 and the highBound to 4 means the first four CommerceItems are shipped using this relationship. ShippingGroups. or TaxAmountRemaining. SG1 (home) and SG2 (office). If the relationship amount is greater than the total amount of the Order. A PaymentGroupOrderRelationship can be assigned the type OrderAmount. if one CommerceItemShippingGroupRelationship accounts for four out of six CommerceItems. TaxAmount. Either split the entire cost by using PaymentGroupOrderRelationships. OrderAmountRemaining. PaymentGroupOrderRelationship Object A PaymentGroupOrderRelationship represents a relationship between an Order and a PaymentGroup. or assign different types of costs (such as item cost vs.core.

A PaymentGroupOrderRelationship is created between the PaymentGroup that represents the credit card and the Order.Working With Purchase Process Objects . then all the tax will be paid for using the referenced PaymentGroup. The relationship type is set to OrderAmountRemaining. PaymentGroupCommerceItemRelationship Object A PaymentGroupCommerceItemRelationship represents a relationship between a CommerceItem and a PaymentGroup. • One PaymentGroupOrderRelationship is created between the MasterCard’s PaymentGroup and the Order. When the Order is charged. The relationship type is set to OrderAmount. and the amount is set to $400. The relationship can have the relationship type PaymentAmount or PaymentAmountRemaining. which covers whatever the tax amount turns out to be. A different PaymentGroup represents each credit card. A customer places an Order with a total of $600.ATG Commerce Programming Guide µ • OrderAmountRemaining: This relationship type indicates that the remaining cost of the Order unaccounted for by other PaymentGroupOrderRelationship objects will be paid using the information in the PaymentGroup. • TaxAmountRemaining: This relationship type indicates that the tax cost unaccounted for by other PaymentGroupOrderRelationship objects will be paid using the information in the referenced PaymentGroup. The relationship type is set to TaxAmountRemaining. This relationship type is used to split payment for a single CommerceItem between multiple payment groups. Example # 2 The following example describes how to use the TaxAmountRemaining type. • TaxAmount: This relationship type indicates that a specific amount of the tax charged for the Order will be paid using the information in the PaymentGroup. Example #1 The following example describes how to use the OrderAmount and OrderAmountRemaining types. The customer wants to pay for the order using two credit cards (Visa and MasterCard). Two relationships are created to split the payment: • One PaymentGroupOrderRelationship is created between the Visa’s PaymentGroup and the Order. If the relationship amount is greater than the total amount of the Order. $400 will be charged on the Visa and $200 will be charged on the MasterCard. A customer places an order with a total tax of $100. Note: An Order can have only one Relationship of type OrderAmountRemaining. Note: An Order can have only one Relationship of type TaxAmountRemaining. The amount must be greater than zero. The customer wants to pay for the tax with a separate credit card than the rest of the order payment. The following list describes the relationship types: 267 10 .

The amount must be greater than zero. Note: A CommerceItem can have only one Relationship of type PaymentAmountRemaining.µ • • ATG Commerce Programming Guide PaymentAmount: This relationship type indicates that a specific amount of the item’s cost will be paid for using the information in the PaymentGroup. This relationship can be assigned the relationship types ShippingAmount or ShippingAmountRemaining. A different PaymentGroup represents each credit card.Working With Purchase Process Objects . MasterCard. If the amount is greater than the total amount of the item stored in the CommerceItem. The relationship type is set to PaymentAmount. The customer wants to split the payment of this item between three credit cards (Visa. The relationship type is set to PaymentAmount. and the amount is set to $4000. The second PaymentGroupCommerceItemRelationship connects the CommerceItem (car) and the second PaymentGroup (MasterCard). If there is only one relationship between a given CommerceItem and a PaymentGroup of type PaymentAmountRemaining. and the amount is set to $4000. then the cost of the entire item will be paid using the referenced PaymentGroup. This type of Relationship is used to assign shipping costs in a ShippingGroup to PaymentGroups. The relationship type is set to PaymentAmountRemaining. a customer places an order for a CommerceItem (Car) with the total cost $10. The amount must be greater than zero. PaymentAmountRemaining: This relationship type indicates that any remaining payment amount unaccounted for by other PaymentGroupCommerceItemRelationship objects will be paid using the information in the PaymentGroup. • ShippingAmountRemaining: This relationship type indicates that any remaining shipping cost amount unaccounted for by other PaymentGroupShippingGroupRelationship objects will be paid using the information in the PaymentGroup. If the amount is greater than the total amount of the item stored in the ShippingGroup. The third PaymentGroupCommerceItemRelationship connects the CommerceItem (car) and the third PaymentGroup (American Express). To split the item between three payment groups. • • PaymentGroupShippingGroupRelationship Object A PaymentGroupShippingGroupRelationship represents a relationship between a ShippingGroup and a PaymentGroup. then the entire cost of that item will be paid for using the information in the PaymentGroup. For example. then the entire cost of the item will be paid for using the referenced PaymentGroup. The following list describes the relationship types: • ShippingAmount: This relationship type indicates that a specific amount of the shipping cost will be paid using the information in the PaymentGroup.000. PaymentGroupCommerceItemRelationships must be created between the CommerceItem (Car) and the three PaymentGroup objects: • The first PaymentGroupCommerceItemRelationship connects the CommerceItem (car) and the first PaymentGroup (Visa). If there is only one relationship between a given 268 10 . and American Express).

then the entire shipping cost will be paid using the information in the PaymentGroup. get/setRange() ShippingQuantityRemaining OrderAmount OrderAmountRemaining PaymentAmount PaymentAmountRemaining ShippingAmount ShippingAmountRemaining TaxAmount TaxAmountRemaining get/setRange() get/setAmount() N/A get/setAmount() N/A get/setAmount() N/A get/setAmount() N/A Relationship Priority The priority of a Relationship is important during order processing. A PaymentGroupShippingGroupRelationship of type ShippingAmount is created. the returned value is undefined. Note: A ShippingGroup can have only one Relationship of type PaymentAmountRemaining. The table below summarizes which methods are valid with which relationship types. Relationship Type ShippingQuantity Valid Methods get/setQuantity(). If an invalid method is called. contains a set of numeric methods (get/setQuantity(). The shipping costs are $10. 269 10 . an order is shipped to one location stored in a ShippingGroup. The credit card information is stored in the only PaymentGroup. Certain method calls are valid depending on the relationship type. the priority is determined by the order in which the relationships were created. and the amount is set to $10.Working With Purchase Process Objects . get/setRange()). For example. Commerce Item Relationships The CommerceItemRelationship interface. which is implemented by ShippingGroupCommerceItemRelationship and PaymentGroupCommerceItemRelationship objects as described previously. A relationship’s type determines its priority.ATG Commerce Programming Guide µ ShippingGroup and a PaymentGroup of type PaymentAmountRemaining. If relationships are the same types. The customer wants to pay for the shipping costs with a credit card. get/setAmount().

in specific. all of the order’s commerce items must be a part a ShippingGroup. the system moves through the relationships of CommerceItems. Shipping Priority ShippingQuantity ShippingQuantityRemaining ATG Commerce Programming Guide When an Order is being processed or fulfilled. any items that were in the default ShippingGroup are no longer a part of any ShippingGroup. and PaymentGroups in the following order: 2. Each processor in the validateForCheckout pipeline validates a different part of the Order as complete. validates the shipping groups in the Order. this property is set to hardgoodShippingGroup in ATG Consumer Commerce and b2bHardgoodShippingGroup in ATG Business Commerce. However. which serves as the default ShippingGroup for the Order. all items are a part of that group. The type of default ShippingGroup that is created is determined by the defaultShippingGroupType property of the OrderTools component. Tax Cost Payment Priority: TaxAmount TaxAmountRemaining 5. The validateShippingGroupsForCheckout processor. that item is automatically a part of the default ShippingGroup because it is assumed that when there is only one ShippingGroup. By default. Before the Order is checked out. the existing CommerceItem and any new commerce items must be explicitly assigned to one of the two shipping groups. it has an empty ShippingGroup. Shipping Cost Payment Priority: ShippingAmount ShippingAmountRemaining 4. Order Cost Payment Priority OrderAmount OrderAmountRemaining Assigning Items to Shipping Groups When an Order is first created. Commerce Item Payment Priority PaymentAmount PaymentAmountRemaining 3.µ 1. once a second ShippingGroup is added to the Order. The shipping groups are considered complete if the following criteria are met: 270 10 . which is executed by the processOrder pipeline. ShippingGroups. This requirement is checked during the checkout process by the validateForCheckout pipeline.Working With Purchase Process Objects . When a CommerceItem is added to the Order.

This requirement must be met according to the following rules: If there is only one ShippingGroup in the Order and no relationships exist between that ShippingGroup and the commerce items in the Order.ATG Commerce Programming Guide µ 1. or if there is more than one ShippingGroup in the Order. Note: The priority of a Relationship in an Order. The range property in the ShippingGroupCommerceItemRelationship identifies which particular items out of the total quantity of a CommerceItem are associated with a given ShippingGroup. address. then the item’s shipping is accounted for regardless of whether it has other shipping relationships. see the Relationship Priority subsection of the Using Relationship Objects section in the Working With Purchase Process Objects chapter. then the total quantity of the CommerceItem covered by the relationships must be equal to or greater than the quantity in the CommerceItem. city. see the Checking Out an Order section of the Configuring Purchase Process Services chapter. For more information on the processOrder and validateForCheckout pipelines. as follows: If a CommerceItem has a ShippingGroupCommerceItemRelationship of type ShippingQuantityRemaining. then the shipping of all commerce items in the Order implicitly is accounted for by that ShippingGroup. For more on relationship types and priority. plays a role in when the Relationship is processed as the Order proceeds through the checkout process. For more information on ShippingGroupCommerceItemRelationship objects. see the Relationship Types section in this chapter. then every CommerceItem in the Order must have its shipping explicitly accounted for with one or more ShippingGroupCommerceItemRelationship objects. None of the required fields (name. If a CommerceItem has one or more ShippingGroupCommerceItemRelationship objects of type ShippingQuantity. 2. The type of default PaymentGroup that is created is determined by the defaultPaymentGroupType property of the OrderTools component. and postal code) are empty in any ShippingGroup. 271 10 . state. which serves as the default PaymentGroup for the Order. this property is set to CreditCard.Working With Purchase Process Objects . Assigning Costs to Payment Groups When an Order is first created. This is because a “remaining” relationship type covers any quantity of the CommerceItem that is not accounted for by other shipping relationships. which is determined by the relationship’s type. but no relationship of type ShippingQuantityRemaining. it has an empty PaymentGroup. By default. If there is only one ShippingGroup in the Order and relationships exist between that ShippingGroup and the commerce items in the Order. All of the commerce items in the Order are assigned to a ShippingGroup.

are a part of that group. see the Checking Out an Order section of the Configuring Purchase Process Services chapter. see the Relationship Priority subsection of the Using Relationship Objects section in the Working With Purchase Process Objects chapter. all of the order’s costs must be a part of a PaymentGroup. However. • For more information on the processOrder and validateForCheckout pipelines.µ ATG Commerce Programming Guide When a CommerceItem is added to the Order. all CommerceItem costs – along with all shipping and tax costs -. For more on relationship types and priority. Assigning an Order’s Total Cost to Payment Groups To assign the total cost of the Order to one or more payment groups. This approach is more frequently used. if the Order has more than one payment group. None of the required fields (name. and postal code) are empty in any PaymentGroup. plays a role in when the Relationship is processed as the Order proceeds through the checkout process. The payment groups in the Order are considered complete if the following criteria are met: 1. 272 10 . For information on the PaymentGroupCommerceItemRelationship and PaymentGroupShippingGroupRelationship objects that are described in the following subsections. You can do so using one of following methods: • Assign the total cost of the Order to one or more payment groups. These methods add PaymentGroupOrderRelationship objects (of type OrderAmount or OrderAmountRemaining. You should use this method if you need more control over where to assign the component costs of an Order. 2. If the Order has only one payment group. the existing CommerceItem. once a second PaymentGroup is added to the Order. address. which include the commerce item costs. See Assigning an Order’s Total Cost to Payment Groups. and tax. any new commerce items. and all shipping and tax costs must be explicitly assigned to one of the two payment groups. use the addOrderAmountToPaymentGroup() and addRemainingOrderAmountToPaymentGroup() methods in the OrderManager. Each processor in the validateForCheckout pipeline validates a different part of the Order as complete. which is executed by the processOrder pipeline. any items that were in the default PaymentGroup are no longer a part of any PaymentGroup. city. Note: The priority of a Relationship in an Order. are accounted for by one or more payment groups. However.Working With Purchase Process Objects . shipping costs. respectively) to the Order.the commerce item costs. then the assignment of Order costs is automatic. and tax -. shipping costs. see the Relationship Types section in this chapter. See Assigning an Order’s Component Costs to Payment Groups. you must explicitly assign the Order costs to the payment groups. which is determined by the relationship’s type. state. This requirement is checked during the checkout process by the validateForCheckout pipeline. All of the costs associated with the Order.to one or more payment groups. and it is the most straightforward way to account for an order’s payment because you are dealing with the Order costs as a whole. Before the Order is checked out. Assign the component costs of the Order -. that item is automatically a part of the default PaymentGroup because it is assumed that when there is only one PaymentGroup.

The order’s total cost is $20.90. Call addRemainingOrderAmountToPaymentGroup().00 for the amount parameter. (The total amount of an Order is the sum of its CommerceItem costs.ATG Commerce Programming Guide µ Example 1 This example assigns an order’s total cost to a single PaymentGroup.or -• addOrderAmountToPaymentGroup() and passing in the value 20. Follow these steps to assign the amounts to the different payment groups: 1. -. and there are two payment groups in the Order. You want to assign $10. If an Order contains one or more PaymentGroupOrderRelationship objects of type OrderAmount. The disadvantage to calling addOrderAmountToPaymentGroup() instead of addRemainingOrderAmountToPaymentGroup() is that if the order’s total amount increases above $20. then during checkout the order’s total cost is accounted for according to the following rules: • If the Order contains a PaymentGroupOrderRelationship of type OrderAmountRemaining. You can account for the total cost of the Order by calling: • addRemainingOrderAmountToPaymentGroup() and passing in the required parameters. The order’s total cost is $20. or call addOrderAmountToPaymentGroup() and pass in the second PaymentGroup and 10. 2. You can assign these various costs to payment groups using the following methods: 273 10 . Example 2 This example assigns an order’s total cost to more than one PaymentGroup. Call addOrderAmountToPaymentGroup() and pass in the first PaymentGroup and 10. This is because a “remaining” relationship covers everything not accounted for by other payment relationships. Accounting for an Order’s Total Cost If the total cost of an Order is assigned to one or more payment groups.Working With Purchase Process Objects .) • Assigning an Order’s Component Costs to Payment Groups An order’s component costs include its commerce item costs. then the order’s total cost is accounted for regardless of whether or not the Order has other payment relationships. shipping costs. ShippingGroup costs.90 for the amount parameter. and tax.90 for the amount parameter.90.90 to the second PaymentGroup.00 to the first PaymentGroup and $10. and tax. then the sum of the amounts in the relationships must be equal to or greater than the total amount of the Order to account for the order’s total cost. then you must call removeOrderAmountFromPaymentGroup() and then call addOrderAmountToPaymentGroup() again and pass in the new amount.90.

You might account for the order’s costs by doing the following: 1. The tax for the order is $0. or if there is more than one PaymentGroup in the Order.99.addRemainingItemAmountToPaymentGroup() ShippingGroupManager. shipping costs. then during checkout the order’s CommerceItem costs are accounted for according to the following rules: • If there is only one PaymentGroup in the Order and no relationships exist between that PaymentGroup and the commerce items in the Order. 4. Accounting for Commerce Item Costs If the CommerceItem costs of an Order are assigned to one or more payment groups. The cost of the first item is $5. then that relationship accounts for the cost of the CommerceItem regardless of whether the CommerceItem has other payment relationships.addItemAmountToPaymentGroup() CommerceItemManager. If there is only one PaymentGroup in the Order and relationships exist between that PaymentGroup and the commerce items in the Order.80 for the amount parameter to the second payment group. suppose an Order has two commerce items. 3. then the cost of all commerce items in the Order implicitly is accounted for by that PaymentGroup. This is because a “remaining” relationship covers everything not accounted for by other payment relationships.99. and tax have all been assigned to a payment group. and the shipping cost is $5. and one shipping group.addRemainingTaxAmountToPaymentGroup() For example.µ • • • • • • ATG Commerce Programming Guide CommerceItemManager. Call addShippingCostAmountToPaymentGroup() for the shipping group and pass 5. If a CommerceItem has one or more PaymentGroupCommerceItemRelationship objects of type PaymentAmount.00 for the amount parameter to the first payment group. 274 10 . Call addItemAmountToPaymentGroup() for the second item and pass 9.addRemainingShippingCostToPaymentGroup() OrderManager. Both items are in the shipping group.99 for the amount parameter to the second payment group.Working With Purchase Process Objects . 2.99 for the amount parameter to the first payment group. Call addItemAmountToPaymentGroup() for the first item and pass 5. but no PaymentGroupCommerceItemRelationship of type PaymentAmountRemaining.addTaxAmountToPaymentGroup() OrderManager. The order’s costs are now accounted for because the commerce item costs.00.addShippingCostAmountToPaymentGroup() ShippingGroupManager. and the cost of the second item is $9. then every CommerceItem in the Order must have its costs explicitly accounted for with one or more PaymentGroupCommerceItemRelationship objects. as follows: • If a CommerceItem has a PaymentGroupCommerceItemRelationship of type PaymentAmountRemaining. two payment groups.80. Call addTaxAmountToPaymentGroup() for the order’s tax and pass 0.

This is because a “remaining” relationship covers everything not accounted for by other payment relationships. then that relationship accounts for the cost of the ShippingGroup regardless of whether the ShippingGroup has other payment relationships.ATG Commerce Programming Guide µ then the total cost covered by all of the relationships must be equal to or greater than the total cost of the CommerceItem.Working With Purchase Process Objects . a customer could set handling instructions for gift wrapping. Accounting for Shipping Costs If the shipping costs of an Order are assigned to one or more payment groups. then every ShippingGroup in the Order must have its costs explicitly accounted for by one or more PaymentGroupShippingGroupRelationship objects. then the sum of the amounts in the relationships must be equal to or greater than the total tax amount of the Order to account for tax payment. or if there is more than one PaymentGroup in the Order. If there is only one PaymentGroup in the Order and relationships exist between that PaymentGroup and the shipping groups in the Order. then during checkout the order’s tax cost is accounted for according to the following rules: • If the Order contains a PaymentGroupOrderRelationship of type TaxAmountRemaining. 275 10 . Setting Handling Instructions Handling instructions are specific instructions that can be associated with the commerce items in a shipping group. then during checkout the order’s shipping costs are accounted for according to the following rules: • If there is only one PaymentGroup in the Order and no relationships exist between that PaymentGroup and the shipping groups in the Order. If a ShippingGroup has one or more PaymentGroupShippingGroupRelationship objects of type ShippingAmount. Accounting for Tax If the tax of an Order is assigned to one or more payment groups. For example. then the total cost covered by all of the relationships must be equal to or greater than the total cost of the ShippingGroup. This is because a “remaining” relationship covers everything not accounted for by other payment relationships. but no PaymentGroupShippingGroupRelationship of type ShippingAmountRemaining. as follows: • If a ShippingGroup has a PaymentGroupShippingGroupRelationship of type ShippingAmountRemaining. • If the Order contains one or more PaymentGroupOrderRelationship objects of type TaxAmount. then the order’s tax cost is accounted for regardless of whether or not the Order has other payment relationships. then the shipping costs for the Order implicitly are accounted for by that PaymentGroup.

In the above example.Working With Purchase Process Objects . detailed examples of how to extend the purchase process to support new commerce objects. A quantity of 1. Adding Handling Instructions to a Shipping Group Handling instructions can be added to either shipping groups or individual commerce items. After the object is created and populated with the required data. two HandlingInstructions must be created – one for the gift wrapping and another for the gift list. see the ATG API Reference. For more information on HandlingInstruction. The sum of HandlingInstruction quantities cannot exceed the quantity in the ShippingGroup for a particular HandlingInstruction class. This section provides an example of how to create handling instructions for gift wrapping one item in a shipping group. see the SQL Repository Data Models chapter in the ATG Repository Guide. see the Extending the Purchase Process section in this guide. see the Configuring Merchandising Services chapter. For information on how to create new item descriptors in a repository. Each HandlingInstruction would be of a different class type: GiftwrapHandlingInstruction and GiftlistHandlingInstruction. call the addHandlingInstructionToShippingGroup() method to add the handling instructions to the ShippingGroup that contains the commerce item(s) whose IDs are specified in the HandlingInstruction. For details on GiftListHandlingInstructions. 276 10 . Any other necessary fields of GiftwrapHandlingInstruction and GiftlistHandlingInstruction. respectively. there can be a GiftlistHandlingInstruction in the ShippingGroup that references the same item because the two HandlingInstruction objects are different types. For example: public String getWrappingPaperId().µ HandlingInstruction Objects ATG Commerce Programming Guide HandlingInstruction objects are constructed using one of the createHandlingInstruction() methods in the HandlingInstructionManager. Each HandlingInstruction would contain: • • • • The ID of the ShippingGroup that contains the CommerceItem. there can be only one GiftwrapHandlingInstruction with a quantity of 1 in the ShippingGroup because there is only one item in the ShippingGroup. The example also uses a repository with a wrapping paper item descriptor. However.order. if an Order contains a single CommerceItem that was added to a user’s shopping cart from another user’s gift list and needs to be gift wrapped. The ID of the CommerceItem to which the handling instruction applies.HandlingInstructionImpl class.commerce. public void setWrappingPaperId(String pWrappingPaperId). For additional. Add a property to identify the wrapping paper. Step 1: Create a GiftwrapHandlingInstruction class that extends the atg. For example. A customer can set more than one handling instruction for a given CommerceItem in a ShippingGroup.

properties: handlingTypeClassMap+=giftwrapHandlingInstruction= mypackage. First.xml in the configpath. For example.GiftwrapHandlingInstruction beanNameToItemDescriptorMap+=mypackage.ATG Commerce Programming Guide µ Step 2: Add support for this class to the OrderTools component.xml. in the localconfig directory add the following lines to /atg/commerce/order/OrderTools. add the new type to the handlingInstruction item descriptor: <table name="dcspp_hand_inst" type="primary" id-column-name="handling_inst_id"> <property name="type" data-type="enumerated" default="handlingInstruction" expert="true" display-name="Type"> <attribute name="useCodeForValue" value="false"/> <option value="handlingInstruction" code="0"/> <option value="giftlistHandlingInstruction" code="1"/> </property> . The orderrepository. .Working With Purchase Process Objects . . add the new item descriptor: <item-descriptor name="giftwrapHandlingInstruction" super-type="handlingInstruction" sub-type-value="giftwrapHandlingInstruction" cache-mode="locked" display-name="Gift wrap Handling Instruction"> <attribute name="writeLocksOnly" value="true"/> <table name="dcspp_wrap_inst" id-column-name="handling_inst_id"> <property name="wrappingPaperId" column-name="wrap_id" data-type="string" display-name="Wrapping Paper Id"/> </table> </item-descriptor> Step 4: Create a method that adds the handling instruction to the order in a class that extends the HandlingInstructionManager: 277 10 . </table> Second.xml file is located in /atg/commerce/order/orderrepository.GiftwrapHandlingInstruction= giftwrapHandlingInstruction Step 3: Add support for the new item descriptor to orderrepository.

For example: // set the state of shippingGroup to the integer value of the // PENDING_SHIPMENT state. ATG Commerce States In ATG Commerce.getQuantity()).PENDING_SHIPMENT)).commerce.String pWrappingPaperId) { GiftwrapHandlingInstruction giftwrap = (GiftwrapHandlingInstruction) handlingInstructionManager. The properties files of these state objects configure the following properties.getStateValue(sgStates.CommerceItemStates class represents the possible states of a CommerceItem.µ ATG Commerce Programming Guide public wrapCommerceItemInShippingGroup(ShippingGroup pGiftShippingGroup. pGiftShippingGroup. CommerceItem pWrappedItem. and ATG Commerce code uses the state name to set the state of a given object. For example.states. and so on. pWrappedItem. the subclasses of atg. The state names are defined in static String variables in each state class. ShippingGroupStates: indicates the states of ShippingGroup.getId(). pGiftShippingGroup. which are located in Nucleus at /atg/commerce/states/: • • • • • OrderStates: indicates the states of an Order. the atg. ATG Commerce provides the following configured instances of the state classes. } Step 5: Add any additional processors. For example. the atg. sgStates.setWrappingPaperId(wrappingId). shippingGroup.states. PaymentGroupStates: indicates the states of a PaymentGroup.PaymentGroupStates class represents the possible states of a PaymentGroup. ShipItemRelationshipStates: indicates the states of a ShippingGroupCommerceItemRelationship.setState(sgStates.Working With Purchase Process Objects . CommerceItemStates: indicates the states of a CommerceItem.commerce.addHandlingInstruction(giftwrap).commerce.getId().PENDING_SHIPMENT is the // name of the state ShippingGroupStates sgStates = getShippingGroupStates().states. giftwrap. you could add a processor to the validateForCheckout pipeline to validate the wrapping paper type.ObjectStates represent the possible states for the order objects. which provide mappings of the order object’s state names to corresponding String values (for easy reading) and integer values (for easy comparisons): 278 10 .createHandlingInstruction( "giftwrapHandlingInstruction". pWrappedItem.

Given a state’s Integer value or display name. The following table describes these methods: Method name getStateValue Description Given a state name. Note that a state’s name and display name are two different values.properties or CommerceItemStates. as described below.Working With Purchase Process Objects . this method returns its Integer value. display name. this method returns its description. OrderStates. CommereItemStates. as described below. this method returns its Integer value. for example. this method returns its display name. This is the String value that users see and that is stored in the repository.ATG Commerce Programming Guide µ • • • stateValueMap: maps each state name to an Integer value. or description from the state mappings. Given a state’s Integer value.properties). Given a state’s Integer value or display name (as configured in the properties file of the relevant states component. stateStringMap: maps each state’s Integer value to a display name. getStateFromString getStateString getStateDescription getStateAsUserResource getStateDescriptionAsUserResource Given a state’s Integer value or display name (as configured in the properties file of the relevant states component. 279 10 . Note: Used for internationalization. Given a state’s display name. this method returns the state’s description that is defined in the resource file that is appropriate for the current locale. stateDescriptionMap: maps each state’s Integer value to a String description of the state. for example.properties or CommerceItemStates. OrderStates. this method returns the display name that is defined in the resource file that is appropriate for the current locale.properties). and so on) contains several methods for retrieving a requested state’s Integer value. Each state class (OrderStates. Note: Used for internationalization.

then you should specify those values in ResourceBundle. • If your commerce site is internationalized.properties.properties.properties. Similarly.properties file named StateResources. call CommerceItemImpl. By default. for the state of the order object.INCOMPLETE=The order is incomplete ORDERDESC. call OrderImpl.PENDING_REMOVE=PENDING_REMOVE • For the descriptions of states: ORDERDESC.properties. call OrderImpl.properties. Additionally. 280 10 .properties. Similarly.INITIAL=INITIAL ITEM. getStateDetail For example.getStateDetail to retrieve the description for the state of the CommerceItem from CommerceItemStates.properties file maps each state’s configured display name to a translated display name and description using the following key-value format: • For the display names of states: ORDER. need to provide one or more translations of the display names and descriptions for the states of the ATG Commerce order objects. call OrderImpl. For example.FAILED=The shipping group has failed ITEMDESC. and you.SUBMITTED=The order has been submitted to Fulfillment SHIPPINGDESC.Working With Purchase Process Objects . these methods retrieve a value specified in the properties file of the relevant states component: • getStateAsString For example. and so on). Consequently. use the following order object methods to retrieve the display name or description. Similarly.INITIAL=The shipping group has been initialized SHIPPINGDESC.INITIAL=The item has been initialized ITEMDESC. therefore.getStateDetail to retrieve the description for the state of the Order object from OrderStates.µ ATG Commerce Programming Guide The methods in the preceding table are called by several methods in the implementation classes of the order objects. respectively.properties.properties files that are placed in the CLASSPATH.getStateAsString to retrieve the display name for the state of the Order object from OrderStates. ATG Commerce provides a base ResourceBundle.INCOMPLETE=INCOMPLETE ORDER.getStateAsString to retrieve the display name for the state of the CommerceItem from CommerceItemStates.PROCESSING=PROCESSING ITEM. Also note that.properties.INITIAL=INITIAL SHIPPING. which is used when a locale-specific resource file isn’t found during a request. call CommerceItemImpl.SUBMITTED=SUBMITTED SHIPPING. call CommerceItemImpl. ShippingStates. Like the getState method.getState to retrieve the corresponding Integer value for the state of the Order from OrderStates.getState to retrieve the corresponding Integer value for the state of the CommerceItem from CommerceItemStates. to retrieve the Integer value for the state of an order object.properties. The StateResources. if your commerce site isn’t internationalized. you can simply call the getState method of that order object.PENDING_REMOVE=The item is pending remove request Note that the keys are the display names of the states as configured in the properties files of the states components (OrderStates.

(You can refer to that chapter for more information on working with ResourceBundles. if the locale is fr_FR.StateResources. place the resource file in the CLASSPATH.properties file. call OrderImpl. StateResources. and so on). note that in ATG Business Commerce. and the requested value is retrieved.properties is located in the CLASSPATH at atg.StateResources. the code first looks for a StateResources_fr_FR.resourceFileName.resourceFileName. namely the getStateAsUserResource and getStateDescriptionAsUserResource methods.states.properties file. and so on). using any appropriate language. for the state of the order object: • getStateAsUserResource For example. If the file doesn’t exist. it then looks for a StateResources_fr.Working With Purchase Process Objects .getStateAsUserResource to retrieve a locale-specific display name for the state of the Order object from the appropriate StateResources_XX. StateResources. You can refer to the subsections that follow for descriptions of these states: • • • • CommerceItem States Order States PaymentGroup States ShippingGroup States 281 10 . By default. Given the current locale and the basename specified in the resourceFileName property of the states component (OrderStates. CommerceItemStates.properties resource files. CommerceItemStates. and each states component refers to this file in its resourceFileName property (OrderStates. it retrieves the default resource file.states. OrderStates.properties file. • Like the other order object methods. Once the appropriate resource file is obtained. use the following order object methods to retrieve a locale-specific display name or description. CommerceItemStates. and so on). and variant suffixes. each key is prepended with a prefix to avoid conflict.ObjectStates represent the possible states for the order objects.commerce.) Finally.properties. these latter methods use ResourceBundle inheritance rules to retrieve the most appropriate resource file for the current locale. in ATG Commerce the subclasses of atg.resourceFileName only is set to atg. these methods call through to the methods in the states classes (OrderStates. therefore. getStateDescriptionAsUserResource For example. the appropriate prefix is appended to the key. As previously mentioned .commerce.states. copy StateResource.getStateDescriptionAsUserResource to retrieve a locale-specific description for the state of the Order object from the appropriate StateResources_XX.resourceFileName. Then translate the file according to the translation guidelines provided in the Internationalizing a Dynamo Web Site chapter in the ATG Programming Guide. If your commerce site is internationalized and.properties and rename the file according to Java naming guidelines for ResourceBundle inheritance.properties. country. which includes resources for some additional Order object states.b2bcommerce. If that file doesn’t exist.properties file. For example. call OrderImpl.properties. However. makes use of StateResources. To add an additional resource file.resourceFileName. respectively.ATG Commerce Programming Guide µ because different order objects may use the same display name for a given state.

The item has been removed from the order. The item will be removed pending verification that all item relationships referring to it can be removed.µ • ATG Commerce Programming Guide ShippingGroupCommerceItemRelationship States CommerceItem States The following table describes the possible states of a CommerceItem: State Name BACK_ORDERED DISCONTINUED FAILED INITIAL Description The item isn’t available in the inventory. and the order has been approved. FAILED FAILED_APPROVAL INCOMPLETE 282 10 . The item isn’t available in the inventory. it has been preordered. The item isn’t available in the inventory. it is not yet associated with any shipping group. The item is available in the inventory. (Used in ATG Business Commerce only) The approval process for the order is complete. it cannot be backordered. The item is in an initial state. The item isn’t available in the inventory. The item has failed. it has been backordered. and it is being prepared for shipment to the customer. The order failed. and it has not been backordered. and the order has been rejected.Working With Purchase Process Objects . The order is in the purchase process. ITEM_NOT_FOUND OUT_OF_STOCK PENDING_REMOVE PRE_ORDERED REMOVED SUBITEM_PENDING _DELIVERY Order States The following table describes the possible states of an Order: State Name APPROVED Description (Used in ATG Business Commerce only) The approval process for the order is complete. that is. The item could not be found in the inventory.

The payment group has been authorized and can be debited. This is an unused state. such as an incorrect customer address. The payment group hasn’t been acted on yet. and order payment has been settled. Processing of the order requires merchant attention for some reason. The order has been removed successfully. NO_PENDING_ACTION PENDING_APPROVAL PENDING_CUSTOMER_ACTION PENDING_CUSTOMER_RETURN PENDING_MERCHANT_ACTION PENDING_REMOVE PROCESSING QUOTED REMOVED SUBMITTED TEMPLATE PaymentGroup States The following table describes the possible states of a PaymentGroup: State Name AUTHORIZE_FAILED AUTHORIZED CREDIT_FAILED INITIAL Description Authorization of the payment group has failed. The order is placed in this state until all shipping groups in the order are set to a PENDING_REMOVE state. The order is being processed by Fulfillment. It is placed in the list of states for the convenience of those who might want to implement this state.Working With Purchase Process Objects . A request was made to remove the order. The order has completed the purchase process and has been submitted to Fulfillment.ATG Commerce Programming Guide µ The order has been fulfilled. This is an unused state. and processing of the order is complete. such as the failure of a payment group in the order. Credit of the payment group has failed. The order is a template order used by a scheduled order. All shipping groups in the order are in a NO_PENDING_ACTION or REMOVED state. (Used in ATG Business Commerce only) The order requires approval (or an additional approval) by an authorized approver. Processing of the order requires the customer’s attention for some reason. 283 10 . It is placed in the list of states for the convenience of those who might want to implement this state.

A request for the removal of the entire order was made. The item has been delivered. This is used by ATG Commerce to determine which shipping groups are ready to be shipped. The item isn’t available in the inventory.Working With Purchase Process Objects . it cannot be backordered. The shipping group has failed to process. The item relationship failed. The shipping group has been removed. An error occurred while trying to process the shipping group. ShippingGroup States The following table describes the possible states of a ShippingGroup: State Name INITIAL PROCESSING PENDING_REMOVE Description The shipping group is in a pre-fulfillment state. The payment group has been debited successfully. the error requires the merchant’s attention.µ REMOVED SETTLE_FAILED SETTLED ATG Commerce Programming Guide The payment group has been removed. it has been backordered. The shipment of all the items in the shipping group is complete. Debit of the payment group has failed. The shipping group awaits shipment. and the removal of this shipping group is possible. The shipping group has started the fulfillment process. This state occurs when the shipping group containing this relationship has shipped. DISCONTINUED FAILED 284 10 . REMOVED FAILED PENDING_SHIPMENT NO_PENDING_ACTION PENDING_MERCHANT_ACTION ShippingGroupCommerceItemRelationship States The following table describes the possible states of a ShippingGroupCommerceItemRelationship: State Name BACK_ORDERED DELIVERED Description The item isn’t available in the inventory.

The item isn’t available in the inventory. no inherited properties are listed. Order Interfaces Diagrams The diagrams in this section represent the order interface inheritance hierarchy and the containment interface inheritance hierarchy in ATG Commerce. see the ATG API Reference.ATG Commerce Programming Guide µ INITIAL The order fulfillment framework has not acted on the item relationship. The following diagram represents the order interface inheritance hierarchy. and the items have not yet shipped. The item is available in the inventory. and it has not been backordered. The item has been allocated in the inventory system and is ready to be delivered. Note that. The item relationship has been removed.Working With Purchase Process Objects . and it is being prepared for shipment to the customer. A request to remove the shipping group was made. for a subinterface. The item could not be found in the inventory. It is placed in the list of states for the convenience of those who might want to implement this state. ITEM_NOT_FOUND OUT_OF_STOCK PENDING_DELIVERY PENDING_REMOVE PENDING_RETURN PENDING_SUBITEM _DELIVERY PRE_ORDERED REMOVED RETURNED Purchase Process Class Diagrams This section contains the following diagrams: • • • Order Interfaces Diagrams Order Classes Diagram Order Containment Diagram Note: Classes provided in only ATG Business Commerce are shaded in light blue. For additional information. This is an unused state. see the superinterface for these properties. 285 10 . it has been preordered. This is an unused state. Refer to the tables that follow for information on the properties of each interface. The item isn’t available in the inventory. It is placed in the list of states for the convenience of those who might want to implement this state.

286 10 .Working With Purchase Process Objects . see the ATG API Reference. For additional information.µ id:String Order PaymentGroup ATG Commerce Programming Guide CommerceIdentifier Relationship CostCenter HandlingInstruction Relationship CommerceItem ShippingGroup OrderRelationship B2BCommerceItem B2BShippingGroup CommerceItemRelationship PaymentGroupRelationship ShippingGroupRelationship B2BOrderRelationship CostCenterRelationship B2BShippingGroupRelationship B2BOrder B2BCommerceItemRelationship The following diagram represents the containment interface inheritance hierarchy.

Working With Purchase Process Objects .ATG Commerce Programming Guide µ ShippingGroupRelationshipContainer CommerceItemContainer ShippingGroupContainer PaymentGroupContainer RelationshipContainer PaymentGroupRelationshipContainer CommerceItemRelationshipContainer OrderRelationshipContainer HandlingInstruction Container Order CommerceItem ShippingGroup PaymentGroup B2BShippingGroup CostCenterContainer CostCenterRelationshipContainer B2BOrderRelationshipContainer B2BCommerceItemRelationshipContainer B2BOrder B2BCommerceItem B2BShippingGroupRelationshipContainer B2BShippingGroup CostCenter B2BCommerceItem All properties are inherited. B2BCommerceItemRelationship Property b2BCommerceItem Data Type B2BCommerceItem B2BCommerceItemRelationshipContainer 287 10 .

B2BShippingGroupRelationship Property amount Data Type double 288 10 .µ Property commerceItemRelationshipCount commerceItemRelationships ATG Commerce Programming Guide Data Type int List B2BOrder Property approvalSystemMessages approverIds approverMessages authorizedApproverIds Data Type List List List List B2BOrderRelationship Property amount order Data Type double B2BOrder B2BOrderRelationshipContainer Property orderRelationship orderRelationshipCount Data Type B2BOrderRelationship int B2BShippingGroup All properties are inherited.Working With Purchase Process Objects .

Working With Purchase Process Objects .ATG Commerce Programming Guide µ B2BShippingGroup shippingGroup B2BShippingGroupRelationshipContainer Property shippingGroupRelationshipCount shippingGroupRelationships Data Type int List CommerceIdentifier Property id Data Type String CommerceItem Property auxiliaryData catalogId catalogKey catalogRefId commerceItemClassType priceInfo quantity returnedQuantity state stateDetail Data Type AuxiliaryData String String String String ItemPriceInfo long long int String CommerceItemContainer 289 10 .

Working With Purchase Process Objects .µ Property commerceItemCount commerceItems totalCommerceItemCount ATG Commerce Programming Guide Data Type int List long CommerceItemRelationship Property amount commerceItem quantity returnedQuantity state stateDetail Data Type double CommerceItem long long int String CommerceItemRelationshipContainer Property commerceItemRelationshipCount commerceItemRelationships Data Type int List CostCenter Property amount costCenterClassType description identifier Data Type double String String String 290 10 .

Working With Purchase Process Objects .ATG Commerce Programming Guide µ Data Type int List CostCenterContainer Property costCenterCount costCenters CostCenterRelationship Property amount costCenter Data Type double CostCenter CostCenterRelationshipContainer Property costCenterRelationshipCount costCenterRelationships Data Type int List HandlingInstruction Property commerceItemId handlingInstructionClassType handlingMethod quantity shippingGroupId Data Type String String String long String HandlingInstructionContainer 291 10 .

Working With Purchase Process Objects .µ Property handlingInstructionCount handlingInstructions ATG Commerce Programming Guide Data Type int List Order Property agentId changed completedDate completedTime createdByOrderId creationDate creationTime description explicitlySaved lastModifiedDate lastModifiedTime orderClassType originOfOrder priceInfo profileId relatedOrders salesChannel specialInstructions state stateDetail submittedDate submittedTime Data Type String boolean Date long String Date long String boolean Date long String String OrderPriceInfo String List String Map int String Date long 292 10 .

ATG Commerce Programming Guide µ TaxPriceInfo taxPriceInfo transient boolean OrderRelationship Property amount order Data Type double Order OrderRelationshipContainer Property orderRelationship orderRelationshipCount Data Type OrderRelationship int PaymentGroup Property amount amountAuthorized amountCredited amountDebited authorizationStatus creditStatus currencyCode debitStatus paymentGroupClassType paymentMethod requisitionNumber specialInstructions Data Type double double double double List List String List String String String Map 293 10 .Working With Purchase Process Objects .

Working With Purchase Process Objects .µ state stateDetail submittedDate ATG Commerce Programming Guide int String Date PaymentGroupContainer Property paymentGroupCount paymentGroups Data Type int List PaymentGroupRelationship Property amount paymentGroup Data Type double PaymentGroup PaymentGroupRelationshipContainer Property paymentGroupRelationshipCount paymentGroupRelationships Data Type int List Relationship Property relationshipClassType relationshipType Data Type String int RelationshipContainer 294 10 .

Working With Purchase Process Objects .ATG Commerce Programming Guide µ Data Type int List Property relationshipCount relationships ShippingGroup Property actualShipDate description priceInfo shipOnDate shippingGroupClassType shippingMethod specialInstructions state stateDetail submittedDate Data Type Date String ShippingPriceInfo Date String String Map int String Date ShippingGroupContainer Property shippingGroupCount shippingGroups Data Type int List ShippingGroupRelationship Property amount shippingGroup Data Type double ShippingGroup 295 10 .

µ ShippingGroupRelationshipContainer Property shippingGroupRelationshipCount shippingGroupRelationships ATG Commerce Programming Guide Data Type int List Order Classes Diagram The following diagram represents the order class inheritance hierarchy in ATG Commerce. no inherited properties are listed. Note that for a subclass. Refer to the tables that follow for information on the properties of each class. 296 10 . see the superclass for these properties. For additional information. see the ATG API Reference.Working With Purchase Process Objects .

Working With Purchase Process Objects .ATG Commerce Programming Guide µ CommerceIdentifierImpl OrderImpl id:String PaymentGroupImpl B2BOrderImpl CreditCard CreditCardInfo GiftCertificate GiftCertificateInfo CostCenterImpl CommerceItemImpl B2BCommerceItemImpl PaymentGroupOrderRelationship CostCenterOrderRelationship PaymentGroupCommerceItemRelationship CostCenterCommerceItemRelationship CostCenterShippingGroupRelationship PaymentGroupShippingGroupRelationship ShippingGroupCommerceItemRelationship HandlingInstructionImpl ShippingGroupImpl B2BShippingGroupImpl ElectronicShippingGroup B2BElectronicShippingGroup HardgoodShippingGroup B2BHardgoodShippingGroup B2BCommerceItemImpl 297 10 .

µ Property costCenterRelationship costCenterRelationshipCount costCenterRelationships ATG Commerce Programming Guide Data Type CostCenterRelationship int List B2BElectronicShippingGroup Property costCenterRelationship costCenterRelationshipCount costCenterRelationships Data Type CostCenterRelationship int List B2BHardgoodShippingGroup Property costCenterRelationship costCenterRelationshipCount costCenterRelationships Data Type CostCenterRelationship int List B2BOrderImpl Property approvalSystemMessages approverIds approverMessages authorizedApproverIds costCenter costCenterCount costCenterRelationship Data Type List List List List CostCenter int CostCenterRelationship 298 10 .Working With Purchase Process Objects .

ATG Commerce Programming Guide µ int List List costCenterRelationshipCount costCenterRelationships costCenters B2BShippingGroupImpl Property costCenterRelationship costCenterRelationshipCount costCenterRelationships Data Type CostCenterRelationship int List CommerceItemImpl Property auxiliaryData catalogKey catalogRefId changed changedProperties commerceItemClassType paymentGroupRelationshipCount paymentGroupRelationships priceInfo priceInfoRepositoryItem quantity repositoryItem returnedQuantity saveAllProperties shippingGroupRelationship shippingGroupRelationshipCount Data Type AuxiliaryData String String boolean Set String int List ItemPriceInfo MutableRepositoryItem long MutableRepositoryItem long boolean String int 299 10 .Working With Purchase Process Objects .

Working With Purchase Process Objects .µ shippingGroupRelationships state stateAsString stateDetail ATG Commerce Programming Guide List int String String CostCenterCommerceItemRelationship Property amount b2BCommerceItem changed changedProperties commerceItem costCenter propertyValue quantity relationshipClassType relationshipType relationshipTypeAsString repositoryItem returnedQuantity saveAllProperties state stateDetail Data Type double B2BCommerceItem boolean Set CommerceItem CostCenter Object long String int String MutableRepositoryItem long boolean int String CostCenterImpl Property amount changed Data Type double boolean 300 10 .

ATG Commerce Programming Guide µ Set B2BCommerceItemRelationship int List String String String B2BOrderRelationship int Object MutableRepositoryItem boolean B2BShippingGroupRelationship int List changedProperties commerceItemRelationship commerceItemRelationshipCount commerceItemRelationships costCenterClassType description identifier orderRelationship orderRelationshipCount propertyValue repositoryItem saveAllProperties shippingGroupRelationship shippingGroupRelationshipCount shippingGroupRelationships CostCenterOrderRelationship Property amount changed changedProperties costCenter order propertyValue relationshipClassType relationshipType relationshipTypeAsString repositoryItem Data Type double boolean Set CostCenter B2BOrder Object String int String MutableRepositoryItem 301 10 .Working With Purchase Process Objects .

µ saveAllProperties ATG Commerce Programming Guide boolean CostCenterShippingGroupRelationship Property amount changed changedProperties costCenter propertyValue relationshipClassType relationshipType relationshipTypeAsString repositoryItem saveAllProperties shippingGroup Data Type double boolean Set CostCenter Object String int String MutableRepositoryItem boolean B2BShippingGroup CreditCard and CreditCardInfo Property billingAddress creditCardNumber creditCardType expirationDayOfMonth expirationMonth expirationYear order paymentId Data Type Address String String String String String Order String 302 10 .Working With Purchase Process Objects .

Working With Purchase Process Objects .ATG Commerce Programming Guide µ Data Type String ElectronicShippingGroup Property emailAddress GiftCertificate and GiftCertificateInfo Property giftCertificateNumber profileId Data Type String String HandlingInstructionImpl Property changed changedProperties commerceItemId handlingInstructionClassType quantity repositoryItem saveAllProperties shippingGroupId Data Type boolean Set String String long MutableRepositoryItem boolean String HardgoodShippingGroup Property shippingAddress trackingNumber Data Type Address String 303 10 .

Working With Purchase Process Objects .µ OrderImpl Property changed changedProperties commerceItemCount commerceItems commerceItemsByCatalogRefId completedDate completedTime creationDate creationTime description lastModifiedDate lastModifiedTime orderClassType paymentGroupCount paymentGroupRelationshipCount paymentGroupRelationships paymentGroups priceInfo priceInfoRepositoryItem profileId relationshipCount relationships repositoryItem saveAllProperties shippingGroupCount shippingGroups specialInstructions ATG Commerce Programming Guide Data Type boolean Set int List List Date long Date long String Date long String int int List List OrderPriceInfo MutableRepositoryItem String int List MutableRepositoryItem boolean int List Map 304 10 .

ATG Commerce Programming Guide µ int String String Date long TaxPriceInfo MutableRepositoryItem long boolean state stateAsString stateDetail submittedDate submittedTime taxPriceInfo taxPriceInfoRepositoryItem totalCommerceItemCount transient PaymentGroupCommerceItemRelationship Property amount changed changedProperties commerceItem paymentGroup quantity relationshipClassType relationshipType relationshipTypeAsString repositoryItem returnedQuantity saveAllProperties state stateDetail Data Type double boolean Set CommerceItem PaymentGroup long String int String MutableRepositoryItem long boolean int String PaymentGroupImpl 305 10 .Working With Purchase Process Objects .

util.Working With Purchase Process Objects .Date PaymentGroupOrderRelationship 306 10 .µ Property amount amountCredited amountDebited authorizationStatus changed changedProperties commerceItemRelationshipCount commerceItemRelationships creditStatus currencyCode debitStatus orderRelationship orderRelationshipCount paymentGroupClassType paymentMethod repositoryItem saveAllProperties shippingGroupRelationshipCount shippingGroupRelationships specialInstructions state stateAsString stateDetail submittedDate ATG Commerce Programming Guide Data Type double double double List boolean Set int List List String List OrderRelationship int String String MutableRepositoryItem boolean int List Map int String String java.

Working With Purchase Process Objects .ATG Commerce Programming Guide µ Data Type double boolean Set Order PaymentGroup String int String MutableRepositoryItem boolean Property amount changed changedProperties order paymentGroup relationshipClassType relationshipType relationshipTypeAsString repositoryItem saveAllProperties PaymentGroupShippingGroupRelationship Property amount changed changedProperties paymentGroup relationshipClassType relationshipType relationshipTypeAsString repositoryItem saveAllProperties shippingGroup Data Type double boolean Set PaymentGroup String int String MutableRepositoryItem boolean ShippingGroup ShippingGroupCommerceItemRelationship Property amount Data Type double 307 10 .

Working With Purchase Process Objects .µ changed changedProperties commerceItem percentage quantity relationshipClassType relationshipType relationshipTypeAsString repositoryItem returnedQuantity saveAllProperties shippingGroup state stateAsString stateDetail ATG Commerce Programming Guide boolean Set CommerceItem double long String int String MutableRepositoryItem long boolean ShippingGroup int String String ShippingGroupImpl Property actualShipDate changed changedProperties commerceItemRelationshipCount commerceItemRelationships description handlingInstructionCount handlingInstructions paymentGroupRelationshipCount paymentGroupRelationships Data Type Date boolean Set int List String int List int List 308 10 .

they appear on the diagram more than once.ATG Commerce Programming Guide µ ShippingPriceInfo MutableRepositoryItem MutableRepositoryItem boolean Date String String Map int String String Date priceInfo priceInfoRepositoryItem repositoryItem saveAllProperties shipOnDate shippingGroupClassType shippingMethod specialInstructions state stateAsString stateDetail submittedDate Order Containment Diagram The following diagram represents the object containment model in ATG Commerce. no inherited properties are listed. see the superclass for these properties. Because some classes are used as member variables by more than one class. Arrows indicate that the class being pointed to contains the pointing class as a member variable. Refer to the tables that follow for information on the properties of each class. 309 10 . Note that. for a subclass. For additional information. see the ATG API Reference.Working With Purchase Process Objects .

CommerceItemRelationshipContainerImpl ShippingGroupRelationshipContainerImpl CostCenterRelationshipContainer CommerceItemContainerImpl 310 10 . PaymentGroupRelationshipContainerImpl HandlingInstructionContainerImpl CommerceItemRelationshipContainerImpl CommerceItemRelationshipContainerImpl OrderImpl B2BOrderImpl For details on B2BOrderImpl. PaymentGroupRelationshipContainerImpl PaymentGroupContainerImpl ShippingGroupRelationshipContainerImpl ShippingGroupContainerImpl RelationshipContainerImpl CommerceIdentifierImpl PaymentGroupImpl For details on PaymentGroupImpl. see the Order Classes diagram in the previous section. see the Order Classes diagram in the previous section. PaymentGroupRelationshipContainerImpl OrderRelationshipContainerImpl CommerceIdentifierImpl ShippingGroupImpl For details on ShippingGroupImpl. see the Order Classes diagram in the previous section. see the Order Classes digram in the previous section. see the Order Classes diagram in the previous section. CostCenterRelationshipContainerImpl OrderRelationshipContainerImpl CommerceItemImpl B2BcommerceItemImpl For details on B2BcommerceItemImpl.Working With Purchase Process Objects . CommerceItemContainerImpl ATG Commerce Programming Guide CommerceIdentifierImpl CommerceItemImpl For details on CommerceItemImpl. see the Order Classes diagram in the previous section. see the Order classes diagram in the previous section. PaymentGroupRelationshipContainerImpl CostCenterContainerImpl CommerceIdentifierImpl CostCenterImpl For details on CostCenterImpl.µ CommerceIdentifierImpl OrderImpl For details on OrderImpl.

ATG Commerce Programming Guide µ Data Type int List long Property commerceItemCount commerceItems totalCommerceItemCount CommerceItemRelationshipContainerImpl Property commerceItemRelationshipCount commerceItemRelationships Data Type int List CostCenterContainerImpl Property costCenterCount costCenters Data Type int List CostCenterRelationshipContainerImpl Property costCenterRelationshipCount costCenterRelationships Data Type int List HandlingInstructionContainerImpl Property handlingInstruction handlingInstructionCount handlingInstructions Data Type HandlingInstruction int List 311 10 .Working With Purchase Process Objects .

Working With Purchase Process Objects .µ OrderRelationshipContainerImpl Property orderRelationship orderRelationshipCount ATG Commerce Programming Guide Data Type OrderRelationship int PaymentGroupContainerImpl Property paymentGroupCount paymentGroups Data Type int List PaymentGroupRelationshipContainerImpl Property paymentGroupRelationshipCount paymentGroupRelationships Data Type int List RelationshipContainerImpl Property relationshipCount relationships Data Type int List ShippingGroupContainerImpl Property shippingGroupCount shippingGroups Data Type int List 312 10 .

ATG Commerce Programming Guide µ Data Type int List ShippingGroupRelationshipContainerImpl Property shippingGroupRelationshipCount shippingGroupRelationships 313 10 .Working With Purchase Process Objects .

µ ATG Commerce Programming Guide 314 10 .Working With Purchase Process Objects .

removing items from an Order. and modifying item quantities in an Order. Modifying Orders Describes how to modify an Order using the catalogRefId of a CommerceItem or the ID of a ShippingGroupCommerceItemRelationship. 315 11 . whether simple or complex. In contrast. Scheduling Recurring Orders Describes how to create recurring Orders that automatically submit themselves on a schedule. and actually checking out the Order. You can use ATG Commerce to customize and implement a purchase process that fills all the requirements of your site. Repricing Orders Describes how to reprice and update an Order using the RepriceOrderDroplet servlet bean. Saving Orders Describes the process involved in saving an Order to the Order Repository. Canceling Orders Describes the process involved in deleting an Order from the user’s shopping cart. A simple purchase process might provide customers with a single shopping cart. Processing Payment of Orders Describes how payment of Orders is processed. payment methods. Includes information on adding items to an Order. and shipping locations. Checking Out Orders Describes the process involved in preparing a simple or complex Order for checkout. This chapter includes information on the following purchase process services: Loading Orders Describes the process involved in loading an Order from the Order Repository.Configuring Purchase Process Services . Includes information on how the purchase process manages refreshing Orders. submitting the Order for checkout. and enable customers to purchase products using a single payment method and to ship those products to a single location. Also describes how to extend the system to support new payment operations and payment methods.ATG Commerce Programming Guide µ 11 Configuring Purchase Process Services ATG Commerce enables you to build sites that support simple or complex purchasing processes. a more complex purchase process might include multiple shopping carts.

such as the CommerceItems or ShippingGroups. the rest of the objects in the Order are loaded. PipelineLink name loadOrderObject Description Given an Order ID supplied by the PipelineManager. Working with ATG Commerce Form Handlers Describes how the ATG Commerce form handlers manage transactions. this processor creates an Order object and loads its properties from the Order Repository. by calling a method like getCommerceItems() or getShippingGroups() in the Order). which creates and populates the Order object. See Refreshing Orders below for details.µ ATG Commerce Programming Guide Setting Restrictions on Orders Describes how to set restrictions on placing Orders. Handling Returned Items Describes how the purchase process handles returned items. when an Order property is accessed (for example. Later.order. For detailed information on the various classes and interfaces used in the ATG Commerce purchase process. Note that while the Order object is loaded. Troubleshooting Order Problems Provides important information if you have modified the OrderManager and are now experiencing problems with orders. The atg. The following table describes the individual processors in the loadOrder pipeline. The loadOrder() method calls into the PipelineManager to execute the loadOrder pipeline.Configuring Purchase Process Services . Also provides information to assist you when extending them. none of the contained objects.processor.commerce. are loaded. Loading Orders The actual loading of an Order object occurs by calling the loadOrder() method in the OrderManager. They are listed in order of execution. see the Working With Purchase Process Objects chapter.ProcLoadOrderObject class implements this functionality. Tracking the Shopping Process Describes how to track stages an Order goes through in the purchase process. 316 11 .

see the Commerce Processor Chains section. by calling getCommerceItems() or getPriceInfo()). the PipelineManager. this processor reloads its properties from the Order Repository.commerce. Note that only the OrderPriceInfo and TaxPriceInfo objects are loaded at this point. as well as its OrderPriceInfo and TaxPriceInfo objects. The following table describes the individual processors in the refreshOrder pipeline. the rest of the AmountInfo objects in the Order are loaded. For more information about PriceInfo objects. the purchase process controls the refreshing of Orders. when an Order property is accessed (for example.) Later.ATG Commerce Programming Guide µ loadPriceInfoObjects Creates OrderPriceInfo and TaxPriceInfo objects for the given Order and loads their properties from the Order Repository. (See Loading Orders above for details. The atg. The refreshOrder pipeline is called only when the Order is first accessed and subsequently when an Order is invalidated and.commerce. the loadOrder() method in the OrderManager calls into the PipelineManager to execute the loadOrder pipeline. Refreshing Orders In ATG Commerce.ProcLoadPriceInfoObjects class implements this functionality. such as the ItemPriceInfo objects in the CommerceItems and the ShippingPriceInfo objects in the ShippingGroups. For more information about pipelines.processor. see the Using and Extending Pricing Services chapter.order.ProcLoadOrderObj ect class implements this functionality. therefore. PipelineLink name loadOrderObjectForRefresh Description Given an Order object supplied by the PipelineManager. 317 11 . When an Order is loaded from the Order Repository. the refreshOrder pipeline is invoked. and the transactional modes and transitions of the processors in the loadOrder pipeline. For more information about the OrderManager. by calling getPriceInfo() or getCommerceItems() in the Order). Later. See Refreshing Orders below for details. see the Working With Purchase Process Objects chapter. which creates and loads the Order object. needs to be reloaded from the Order Repository.Configuring Purchase Process Services . The atg.order.processor. They are listed in order of execution. which creates and loads the rest of the contained objects in the Order. when an Order property is accessed (for example.

see the Using and Extending Pricing Services chapter.ProcLoadPaymentG roupObjects class implements this functionality. 318 11 .order. The atg.ProcLoadHandling InstructionObjects class implements this functionality.commerce.order. and loads their properties from the Order Repository.processor. loadRelationshipObjects Creates Relationship objects for the Order and loads the properties for those Relationship objects from the Order Repository.order.ProcLoadPriceInf oObjects class implements this functionality.commerce.commerce. The atg. The atg.commerce.ProcLoadPaymentS tatusObjects class implements this functionality.processor.commerce.Configuring Purchase Process Services . Creates ShippingGroup objects for the Order and loads the properties for those ShippingGroup objects from the Order Repository.order.processor. loadPaymentStatusObjects Creates PaymentStatus objects for all the payment groups in the Order and loads the properties for those PaymentStatus objects from the Order Repository.processor.ProcLoadRelation shipObjects class implements this functionality.µ loadCommerceItemObjects loadShippingGroupObjects ATG Commerce Programming Guide Creates CommerceItem objects for the Order and loads the properties for those CommerceItem objects from the Order Repository.order. such as the ItemPriceInfo objects in the CommerceItems and the ShippingPriceInfo objects in the ShippingGroups.processor. loadHandlingInstructionObjects Creates HandlingInstruction objects for the ShippingGroups in the Order and loads the properties for those HandlingInstruction objects from the Order Repository.commerce. Also creates the rest of the AmountInfo objects for the Order. The atg. The atg.ProcLoadShipping GroupObjects class implements this functionality.processor. The atg. loadPaymentGroupObjects Creates PaymentGroup objects for the Order and loads the properties for those PaymentGroup objects from the Order Repository.order. loadPriceInfoObjects Reloads the OrderPriceInfo and TaxPriceInfo objects in the given Order. The atg.order.processor.ProcLoadCommerce ItemObjects class implements this functionality.commerce. For more information about AmountInfo objects.

setCatalogRefs setProductRefs Sets the productRef property in the AuxiliaryData object of each CommerceItem in the Order.commerce.ProcSetProductRe fs class implements this functionality.substituteDeletedSkuId. Note that.substituteRemovedSku is true. see Managing Orders that Contain Deleted Products and SKUs below. This processor looks up the catalog reference in the Catalog Repository using the catalogRefId in the CommerceItem. this processor removes from the Order any CommerceItem that contains a “dummy” SKU or product that was substituted by SetCatalogRefs or SetProductRefs. see Managing Orders that Contain Deleted Products and SKUs below. If the state of the Order is one that is defined in RemoveExpiredCommerceItems. removeExpiredCommerceItems Used in conjunction with SetCatalogRefs and SetProductRefs.removeItemsWithDel etedProducts is set to true.ProcRemoveExpire dCommerceItems class implements this functionality. Note that.processor. A “dummy” SKU is automatically removed. this processor replaces all deleted products in the Order with the “dummy” product defined by SetProductRefs.substituteDeletedProductId. For more information. For more information.substituteRemovedProduct is true.processor.ATG Commerce Programming Guide µ Sets the catalogRef property in the AuxiliaryData object of each CommerceItem in the Order. The atg.commerce.openOrderStates. The atg. For more information.order.processor.ProcSetCatalogRe fs class implements this functionality.commerce. The atg.order. this processor replaces all deleted SKUs in the Order with the “dummy” SKU defined by SetCatalogRefs. A “dummy” product is removed only if RemoveExpiredCommerceItems. if SetCatalogRefs.Configuring Purchase Process Services . This processor looks up the catalog reference in the Catalog Repository using the productRefId in the AuxiliaryData object.order. if SetProductRefs. 319 11 . see Managing Orders that Contain Deleted Products and SKUs below. the default is true.

Set the SetCatalogRefs. RemoveExpiredCommerceItems. If this property is true. To configure the refreshOrder pipeline to manage deleted products. Refreshing Orders. all dummy SKUs in the Order are removed automatically by a later processor in the refreshOrder pipeline. 5. Managing Orders that Contain Deleted Products and SKUs As described in the previous section. To configure the refreshOrder pipeline to manage deleted SKUs.) 4.µ ATG Commerce Programming Guide For more information about pipelines. make sure to add a “dummy” SKU to all existing catalogs. (See RemoveExpiredCommerceItems in the table above for more information. the last three processors in the refreshOrder pipeline can be used to operate on the commerce items in an order that refer to products and/or SKUs that have been deleted from the catalog. set its removeItemsWithDeletedProducts property to true. Create a new SKU in the product catalog. See RemoveExpiredCommerceItems in the table above for more information. Note: If you’re running the Customer Service Module. Note: If you’re using custom catalogs. If you’re using custom catalogs. this “dummy” product will be substituted for any product that has been deleted from the catalog. make sure to add a “dummy” product to all existing catalogs. see the Commerce Processor Chains section. and the transactional modes and transitions of the processors in the refreshOrder pipeline. 2. 4. this is particularly important because the Customer Service Module cannot display orders that contain deleted products or SKUs.substituteDeletedProductId property to the ID of the dummy product you created in step 1. 2.Configuring Purchase Process Services .substituteRemovedProduct property to true. If this property is true. 3. If you want all dummy products in an Order (in an open state) to be removed later on in the refreshOrder pipeline by the RemoveExpiredCommerceItems processor. the PipelineManager. do the following: 1. If the Order is in an open state. you should configure these processors to handle affected orders appropriately. this “dummy” SKU will be substituted for any SKU that has been deleted from the catalog. 3. 320 11 . Set the SetProductRefs. In an Order. the processor replaces any deleted product found in the Order with the product defined in the substituteDeletedProductId property. Set the SetCatalogRefs. do the following: 1. Create a new product in the product catalog.substituteRemovedSku property to true. In an Order.substituteDeletedSkuId property to the ID of the dummy SKU you created in step 1. Set the SetCatalogRefs. If your catalog administrators delete products and/or SKUs in the ongoing management of the product catalog. the processor replaces any deleted SKU found in the Order with the SKU defined in the substituteDeletedSkuId property.

CartModifierFormHandler is an instance of class atg. Site pages that render order histories typically draw order information (descriptions.updateOrder() to save the Order in its present state to the Order Repository. These orders will display description information for the “dummy” SKUs and products instead of for the actual items that were purchased. and prepare the Order for the checkout process. If you need to remove products and SKUs from your database (for example. However.Configuring Purchase Process Services . Many of the methods (described below) in CartModifierFormHandler call OrderManager.updateOrder() and the updateOrder pipeline that it executes. such as the form handlers that create and manage 321 11 . modify the quantity of items in the Order. because of a high turnover rate).CartModifierFormHandler.ATG Commerce Programming Guide µ It’s important to note that deleting products and SKUs is not recommended because of its impact on customers’ order histories. Removing all historical orders that contain products or SKUs that have been removed. CartModifierFormHandler is provided to support these modification processes.commerce.purchase. you should note that users can also make changes to their orders through other purchase process form handlers that do not reprice orders. Note that this will cause a significant duplication of information across multiple items. you should implement a strategy that addresses its impact on order histories. order histories cannot be rendered accurately. Modifying Orders You can modify an Order by adding items to it. media. and so on) from product and SKU repository items. If those items are deleted.order. it is located in Nucleus at /atg/commerce/order/purchase/CartModifierFormHandler. For information on OrderManager. see the Updating an Order with the Order Manager subsection of Saving Orders in this chapter. Possible strategies include: • • • Storing the relevant description information in the CommerceItem. and changing the quantities of the items in the Order. the handleAddXXX and handleRemoveXXX methods of CartModifierFormHandler automatically reprice the Order whenever the user makes changes to it. As can be seen from the method descriptions that follow. The following sections describes the important methods in CartModifierFormHandler. Keeping all historical orders that contain products or SKUs that have been removed. removing items from it. This section includes information about the following: • • Understanding the CartModifierFormHandler Modifying the Current Order Understanding the CartModifierFormHandler The CartModifierFormHandler is used to add items to and remove items from an Order.

See the modifyOrder() and runProcessSetOrder() methods for more information. handleSetOrder Performs the actual work necessary to save an Order. The handle method calls modifyOrder() to validate the user’s changes and modify the Order.µ getQuantity ATG Commerce Programming Guide shipping groups. It then calls runProcessSetOrder(). the key is the user’s locale and the value is the corresponding repository to use (for example.setOrderChainId. It then calls OrderManager. which is obtained from the Request object. fr_FR=FrenchCatalog). handleSetOrderByRelationshipId Performs the actual work necessary to save an Order. It calls modifyOrder() to validate the user’s changes and modify the Order. where the user can change the current Order in ways that affect its price. getCatalogKey Retrieves a string that identifies the catalog to use when obtaining a catalogRef and productRef for the creation of a CommerceItem. Finally. The string is determined by the user’s locale. you should use the RepriceOrderDroplet servlet bean to reprice the Order before displaying its price to the user. Finally. For more information on RepriceOrderDroplet. Unlike handleSetOrder() and handleSetOrderByRelationshipId(). It calls modifyOrderByRelationshipId() to validate the user’s changes and modify the Order.updateOrder(). handleAddItemToOrder Adds items to an order by calling addItemToOrder(). Consequently.setOrderChainId. en_US=ProductCatalog. see Repricing Orders section of the ATG Commerce Guide to Setting Up a Store. which executes the pipeline set in CartModifierFormHandler. it also verifies that the Order is ready for checkout. handleMoveToPurchaseInfo Performs the actual work necessary to save an Order. See the addItemToOrder() method for more information. Retrieves the quantity for the given item. In these situations.updateOrder(). which executes the pipeline set in 322 11 . it calls OrderManager. and where the form handler used to process those changes does not reprice the Order. which actually adds the items to the Order.updateOrder(). See the modifyOrderByRelationshipId() and runProcessSetOrder() methods for more information. getShippingGroupCommerceItemRelationships Retrieves the list of ShippingGroupCommerceItemRelationships within the order. It then calls runProcessSetOrder(). it calls OrderManager.Configuring Purchase Process Services . which executes the pipeline set in CartModifierFormHandler. /atg/commerce/catalog/CatalogTools maintains the key-to-catalog mapping. It then calls runProcessMoveToPurchaseInfo().

giftlistId. it calls OrderManager. and calls CartModifierFormHandler. Then the method copies the values returned by the following CartModifierFormHandler. it calls OrderManager. See the modifyOrder() and runProcessMoveToPurchaseInfo() methods for more information. If the initial CartModifierFormHandler. addItemToOrder Invoked by handleAddItemToOrder(). which executes the pipeline set in CartModifierFormHandler.getValueDictionary() with each items array element’s value Dictionary. the method uses the PurchaseProcessHelper class to do the following: 323 11 . It then calls runProcessMoveToPurchaseInfo(). Then. See the mergeItemInputForAdd() and doAddItemToOrder() methods for more information. commerceItemType. the method constructs an items array whose size matches the size of the return value from CartModifierFormHandler. the method then calls doAddItemToOrder().ATG Commerce Programming Guide µ CartModifierFormHandler.moveToPurchaseInfoChainId. productId or productIds. The method also calls CartModifierFormHandler.getItems(). Finally.mergeValueDictionaries() to combine the Dictionary returned by CartModifierFormHandler.moveToPurchaseInfoChainId. The method retrieves the list of items to add by calling CartModifierFormHandler. mergeItemInputForAdd Invoked by addItemToOrder() to unify the way input values are made available to doAddItemToOrder() and to validate input values.getCommerceItemType() to every items array element whose commerceItemType subproperty was null.Configuring Purchase Process Services .updateOrder().getItems() call retrieves a non-null value. Finally. If all input values are valid.getXXX methods into the items array elements: quantity. value. The method calls mergeItemInputForAdd().updateOrder(). The handle method calls modifyOrderByRelationshipId() to validate the user’s changes and modify the Order. Unlike handleSetOrder() and handleSetOrderByRelationshipId(). See the modifyOrderByRelationshipId() and runProcessMoveToPurchaseInfo() methods for more information.getItems(). and giftlistItemId. doAddItemToOrder Invoked by addItemToOrder(). If the returned value is null.getCatalogKey() to determine which catalog to use. the method copies the value returned by CartModifierFormHandler. handleMoveToPurchaseInfoByRelId Performs the actual work necessary to save an Order. The method first calls CartModifierFormHandler. The method copies the values from getCatalogRefIds() into the items array elements.getCatalogRefIds(). it also verifies that the Order is ready for checkout. for each item to add to the Order.

ATG Commerce Programming Guide Creates a CommerceItem using the commerceItemType. Adds the created CommerceItem to the order. addItemToOrder() calls runProcessRepriceOrder(). Copies custom values from the current item’s value Dictionary to the new Calls the PurchaseProcessHelper. catalogRefId. After the above steps have been taken for all the new items. set the addItemToDefaultShippingGroup property of the /atg/commerce/order/purchase/PurchaseProcessHelper component to false. Use the first shipping group of the passed-in type (if that information is available) or the first shipping group on the order. productId and quantity found in the current array element from getItems(). Then. 324 11 . Calls processGiftAddition(). For information on the SHIPPINGQUANTITY type of ShippingGroupCommerceItemRelationship. • Calls PurchaseProcessHelper.getItems()[ ]. which executes the pipeline set in CartModifierFormHandler. the method fires a scenario event of type ItemAddedToOrder for each new item. see Relationship Types in the Using Relationship Objects section of the Working With Purchase Process Objects chapter.addGiftToOrder() to perform additional gift list processing.repriceOrderChainId. PurchaseProcessHelper can determine the correct group from the item type (based on the SKU’s fulfiller property value) and gift information.getShippingGroupForItem() method to get a shipping group of the appropriate type. shippingGroupType.µ • • • • CommerceItem. and the default is always the correct type). regardless of the item type. set the addItemToDefaultShippingGroup property of the /atg/commerce/order/purchase/PurchaseProcessHelper component to true.addItemToShippingGroup(). which calls CommerceItemManager.addItemToOrderChainId. for each new item addItemToOrder() calls runProcessAddItemToOrder(). If this is the desired behavior (perhaps you only sell goods with one shipping group type. the item’s input giftlistId or giftlistItemId property is nonnull). This property is set to true by default. Passed in to PurchaseProcessHelper from the CartModifierFormHandler. The passed-in type is used along with the item’s gift information (if any) to determine the correct shipping group to which the item should be added. which is an empty method that can be overridden as needed by sites that use configurable commerce items. which reprices the Order by executing the pipeline set in CartModifierFormHandler.Configuring Purchase Process Services . processGiftAddition() calls GiftListManager.addItemQuantityToShippingGroup() which in turn takes the given quantity of the CommerceItem and the given ShippingGroup and creates a ShippingGroupCommerceItemRelationship of type SHIPPINGQUANTITY. • • Calls createConfigurableSubitems(). To use this behavior. If the item is a gift. The type can be determined in one of three ways. Finally. which checks if the item that was added to the order is a gift (that is.

then it removes the CommerceItem and any associated Relationship objects from the Order. it retrieves the current quantity by calling getQuantity() and passing in the catalogRefId (SKU ID) of the item. the method retrieves the current quantity of the ShippingGroupCommerceItemRelationship by calling getQuantity() and passing in the ShippingGroupCommerceItemRelationship ID. the method checks if the ID of the ShippingGroupCommerceItemRelationship is in the removalRelationshipIds list. then the ShippingGroupCommerceItemRelationship is removed from the Order and the quantity of the associated CommerceItem is adjusted appropriately. If the quantity is less than or equal to zero. If it is not.Configuring Purchase Process Services . • For more information on the SHIPPINGQUANTITY type of ShippingGroupCommerceItemRelationship. If it is. the method checks if the catalogRefId of the current item is in the removalCatalogRefIds list. then the quantity of the current item is set to zero. then an exception is thrown. the quantity of the current item is assessed and one of two actions occurs: • • If the quantity is greater than zero. see Relationship Types in the Using Relationship Objects section of the Working With Purchase Process Objects chapter. the quantity of the current ShippingGroupCommerceItemRelationship is assessed and one of two actions occurs: • If the quantity is greater than zero. modifyOrder Invoked by handleSetOrder() and handleMoveToPurchaseInfo(). it first checks to make sure the Relationship is of type SHIPPINGQUANTITY. For each ShippingCommerceItemRelationship. It iterates over each ShippingGroupCommerceItemRelationship in the Order. If it is. The modifyOrder() method modifies the Order based on the changes made in the request. Then. the method sets the quantity in the CommerceItem and the corresponding ShippingGroupCommerceItemRelationship. Then. 325 11 . If the quantity is less than or equal to zero. It iterates over each CommerceItem in the Order.ATG Commerce Programming Guide µ See the runProcessRepriceOrder() and runProcessAddItemToOrder() methods for more information. then the quantity of the current ShippingGroupCommerceItemRelationship is set to zero. The modifyOrderByRelationshipId() method updates the Order based on the changes made in the request and the existing ShippingGroupCommerceItemRelationships in the Order. Next. modifyOrderByRelationshipId Invoked by handleSetOrderByRelationshipId() and handleMoveToPurchaseInfoByRelId(). Then. then the quantity of the ShippingGroupCommerceItemRelationship and the quantity of the associated CommerceItem are adjusted appropriately. For each CommerceItem. Next.

326 11 .repriceOrderChainId. Next. then the CommerceItem and all associated Relationships are removed from the Order. See the runProcessRepriceOrder() method for more information. the method fires a scenario event of type ItemRemovedFromOrder. This handle method calls deleteItems() to delete the items from the Order and then calls OrderManager. Finally. It iterates through the IDs in the removalShippingGroupCommerceItemRelIds property. but the CommerceItem has Relationships to other ShippingGroups. For each ID. it first ensures that the Relationship type is of type SHIPPINGQUANTITY (logging an error if it is not).updateOrder(). The method also removes all associated ShippingGroupCommerceItemRelationships and calls runProcessRepriceOrder(). and then it removes the HandlingInstructions associated with the ShippingGroup.repriceOrderChainId. this property is set to addItemToOrder. The method then calls runProcessRepriceOrder(). Finally. deleteItems Deletes from the Order all CommerceItems whose IDs are in the removalCommerceIds property. which reprices the Order by executing the pipeline set in CartModifierFormHandler. (See the runProcessRepriceOrder() method in this table for more information. then the quantity in the CommerceItem is reduced and the given ShippingGroupCommerceItemRelationship removed. See the deleteItems() method for more information. By default. deleteItemsByRelationshipId This method deletes CommerceItems from the Order by ShippingGroupCommerceItemRelationship ID. This method runs the pipeline set in CartModifierFormHandler.Configuring Purchase Process Services . • runProcessAddItemToOrder Invoked by the handleAddItemToOrder() method. one of two conditions can exist: • If the quantity in the ShippingGroupCommerceItemRelationship is greater than or equal to the quantity in the CommerceItem.µ handleRemoveItemFromOrder ATG Commerce Programming Guide Removes items from the Order by CommerceItem ID.) If the quantity in the ShippingGroupCommerceItemRelationship is less than the quantity in the CommerceItem. See the deleteItemsByRelationshipId() method for more information.updateOrder().addItemToOrderChainId. which reprices the Order by executing the pipeline set in CartModifierFormHandler. This handle method calls deleteItemsByRelationshipId() to delete the items from the Order and then calls OrderManager. handleRemoveItemFromOrderByRelationshipId Removes items from the Order by ShippingGroupCommerceItemRelationship ID. the method fires a scenario event of type ItemRemovedFromOrder.

should you need to include additional functionality. It is provided for extension purposes. It is recommended that you modify an Order by ShippingGroupCommerceItemRelationship ID. Modifying the Current Order To modify an Order. The pipeline to run is set in CartModifierFormHandler. this property is set to moveToPurchaseInfo. executes the validateForCheckout pipeline.xml. which verifies that the Order is ready for checkout. For example. The moveToPurchaseInfo pipeline.Configuring Purchase Process Services . should you need to include additional functionality. By default. the commerce pipeline configuration file. in turn. It is provided for extension purposes. This method runs the pipeline set in CartModifierFormHandler. runProcessSetOrder Invoked by handleSetOrder() and handleSetOrderByRelationshipId(). runProcessRepriceOrder Runs the pipeline to execute whenever the order needs to be repriced. the addItemToOrder pipeline is commented out of commercepipeline.) runProcessMoveToPurchaseInfo Invoked by handleMoveToPurchaseInfo() and handleMoveToPurchaseInfoByRelId(). see the Repricing Shopping Carts section of the ATG Commerce Guide to Setting Up a Store. Note: By default. this property is set to setOrder.xml. The following subsections describes both order modification methods: • • Modifying an Order by catalogRefId Modifying an Order by ShippingGroupCommerceItemRelationship ID 327 11 . By default. (For more information about pricing operations. you must supply either a CatalogRefId of a CommerceItem or a ShippingGroupCommerceItemRelationship ID.repriceOrderChainId. By default. to remove the items being shipped to the work address. this method executes an ORDER_TOTAL pricing operation. By default. For more information on both pipelines. such as multiple CommerceItems with the same catalogRefId (SKU ID) or multiple shipping groups. such as scenario events. the setOrder pipeline is commented out of commercepipeline. see the Commerce Processor Chains section.ATG Commerce Programming Guide µ Note: By default. This method runs the pipeline set in CartModifierFormHandler. this property is set to repriceOrder. a customer could order 5 of a given item and choose to ship a quantity of 3 to a home address and the remaining 2 to a work address.setOrderChainId. especially if you intend to support complex productSKU relationships. the commerce pipeline configuration file. such as scenario events. In this example.moveToPurchaseInfoChainId. you would modify (and ultimately remove) the ShippingGroupCommerceItemRelationship instead of modifying the CommerceItem.

µ Modifying an Order by catalogRefId ATG Commerce Programming Guide Modifying orders by catalogRefId works for very simple sites. edit the JSPs that invoke the CartModifierFormHandler handle methods that delete items from the Order. You can use the following CartModifierFormHandler methods to modify an Order by catalogRefId: • • • handleSetOrder() handleRemoveItemFromOrder() handleMoveToPurchaseInfo() Refer to Understanding the CartModifierFormHandler for more information on these handle methods. Because it does not provide the granularity necessary to delete just a part of a CommerceItem. For example. then the CommerceItem is removed from the Order. it is not recommended for sites with complex features.removalCatalogRefIds" paramvalue="CommerceItem. multiple CommerceItems with the same catalogRefId) or multiple shipping groups. then it is recommended that you modify an Order using the IDs of the ShippingGroupCommerceItemRelationship objects in the Order.catalogRefId" type="checkbox"/> Modifying an Order by ShippingGroupCommerceItemRelationship ID If your site supports complex product-SKU relationships (for example. such as multiple CommerceItems with the same catalogRefId or multiple shipping groups. To change the quantities of items in an Order using the catalogRefIds of CommerceItems. To remove items from an Order using the catalogRefIds of CommerceItems.handleSetOrder() method for each CommerceItem whose quantity you want to change and pass in the catalogRefId and quantity for the CommerceItem. This is illustrated in the following JSP code: <dsp:input value='<dsp:valueof param="CommerceItem.quantity"/>' type="text" name='<dsp:valueof param="CommerceItem. call the CartModifierFormHandler.Configuring Purchase Process Services .catalogRefId"/>'> Note that if no quantity is found for a CommerceItem. You can use the following CartModifierFormHandler methods to modify an Order by ShippingGroupCommerceItemRelationship ID: • • • handleSetOrderByRelationshipId() handleRemoveItemFromOrderByRelationshipId() handleMoveToPurchaseInfoByRelId() 328 11 . Doing so makes the changes at the CommerceItem-to-ShippingGroup level. you can populate the array using following JSP code: <dsp:input bean="CartModifierFormHandler. Populate the form handler’s removalCatalogRefIds array with the catalogRefIds of the CommerceItems to be removed.

pipeline. which is used to modify orders by adding and removing items and changing item quantities. pass the ID of the associated ShippingGroupCommerceItemRelationship into the form handler’s removalRelationshipIds property. By default. as shown in the following JSP example: <dsp:input value='<dsp:valueof param="SgCiRelationship.removalRelationshipIds" paramvalue="SgCiRelationship. by making shipping changes via the form handlers that create and manage shipping groups). ATG Commerce provides an instance of RepriceOrder. or if the orders are modified through some other means in ways that affect order price. However.service.RepriceOrder. The RepriceOrder class provides the required objects for executing a repricing pipeline as convenient properties. execution of a repricing pipeline requires the Order.purchase. pass the new quantity into the ShippingpingGroupCommerceItemRelationship.Configuring Purchase Process Services .order. Typically. The RepriceOrderDroplet servlet bean is an instance of atg. two form handlers in the ATG Commerce purchase process have handle methods that you can use to reprice an Order: • • CartModifierFormHandler.PipelineChainInvocation.Id" type="checkbox"/> Repricing Orders As described in Modifying Orders and Checking Out Orders in this chapter.servlet. the 329 11 . as shown in the following JSP example: <dsp:input bean="CartModifierFormHandler.updateOrder(). which extends atg. such as the delivery of a promotion via a scenario. the Profile. which is located in Nucleus at /atg/commerce/order/purchase/RepriceOrderDroplet.quantity"/>' type="text" name='<dsp:valueof param="SgCiRelationship.commerce.ATG Commerce Programming Guide µ Refer to Understanding the CartModifierFormHandler for more information on these handle methods. the servlet bean is configured to invoke the repriceAndUpdateOrder pipeline. ExpressCheckoutFormHandler. If your site has any pages where you need to reprice an Order.Id"/>'> To delete an item from the Order. you’ll need to reprice orders via some other mechanism if customers can make order changes that affect order price through other form handlers that do not reprice orders (for example. which manages and expedites the pre-checkout processing of orders. To change the quantity of an item in the Order. use the RepriceOrderDroplet servlet bean. but you cannot do so through a form action and corresponding handle method. which reprices the Order by calling the repriceOrder pipeline and then updates the Order by calling OrderManager.

current profile=/atg/userprofiling/Profile orderManager=/atg/commerce/order/OrderManager userPricingModels=/atg/commerce/pricing/UserPricingModels This default configuration enables a page developer to include the RepriceOrderDroplet servlet bean on any shopping cart page that requires the repricing and updating of Orders with the following JSP code: <dsp:droplet name="RepriceOrderDroplet"> <dsp:param value="ORDER_SUBTOTAL" name="pricingOp"/> </dsp:droplet> 330 11 .OP_REPRICE_ORDER_TOTAL PricingConstants.Configuring Purchase Process Services .commerce.pricing.RepriceOrder $scope=request defaultPipelineManager=/atg/commerce/PipelineManager defaultChainId=repriceAndUpdateOrder order^=/atg/commerce/ShoppingCart.OP_REPRICE_ORDER PricingConstants.properties and indicates its default configuration: $class=atg.OP_REPRICE_ORDER_SUBTOTAL_TAX PricingConstants. the only required parameter that must be supplied is the pricing operation to execute.PricingConstants interface. Acceptable pricing operations are defined in the atg. RepriceOrder is conveniently configured to reference these objects. Consequently.order.OP_REPRICE_TAX PricingConstants.OP_REPRICE_SHIPPING PricingConstants. which means that a page developer doesn’t need to supply them as input parameters every time the RepriceOrderDroplet servlet bean is invoked.purchase.OP_REPRICE_ITEMS PricingConstants.OP_REPRICE_ORDER_SUBTOTAL PricingConstants.µ ATG Commerce Programming Guide OrderManager. and the user’s PricingModelHolder. they are the following: Pricing Operation ORDER_TOTAL ORDER_SUBTOTAL ORDER_SUBTOTAL_SHIPPING ORDER_SUBTOTAL_TAX ITEMS SHIPPING ORDER TAX NO_REPRICE Pricing Constant PricingConstants.commerce.OP_NO_REPRICE The following code sample is taken from RepriceOrderDroplet.OP_REPRICE_ORDER_SUBTOTAL_SHIPPING PricingConstants.

the method adds the Order to the list of saved orders in the ShoppingCart. The updateOrder() method calls into the PipelineManager to execute the updateOrder pipeline. Each processor in the pipeline saves a different type of commerce object. Additionally. Method handleSaveOrder Description This handle method first calls the empty preSaveOrder() method.purchase. which is located in Nucleus at /atg/commerce/order/purchase/SaveOrderFormHandler.commerce.updateOrder() method and the updateOrder pipeline. empty Order and sets it as the user’s current Order. If no description is provided. it constructs a new. For information on the OrderManager. the PipelineManager. see Updating an Order with the OrderManager below. see the RepriceOrder reference entry in Appendix: ATG Commerce Servlet Beans of the ATG Commerce Guide to Setting Up a Store. and the transactional modes and transitions of the processors in the repriceOrder pipeline. Saving Orders The SaveOrderFormHandler (class atg.ATG Commerce Programming Guide µ For information on all of the input. the method sets the description using the date and time as represented by the user’s locale. Finally. output. see the Commerce Processor Chains section. For more information on OrderManager. The following table describes the individual processors in the updateOrder pipeline.SaveOrderFormHandler) saves the user’s current Order and adds the Order to the ShoppingCart’s list of saved orders.saved property. see Updating an Order with the Order Manager in this chapter.Configuring Purchase Process Services . the method saves the Order to the repository by calling the OrderManager. and constructs a new. empty Order that is set as the user’s current order. They are listed in order of execution. and open parameters of RepriceOrderDroplet. then calls the saveOrder() method to save the order.updateOrder(). This method first sets the current Order’s description based on the provided String description.order. and finally calls the empty postSaveOrder() method. saveOrder Updating an Order with the OrderManager The actual saving of an Order object occurs by calling the updateOrder() method in the OrderManager. 331 11 . For more information about pipelines.updateOrder() method. The following table describes the important methods in SaveOrderFormHandler. Next. ATG Commerce includes an instance of SaveOrderFormHandler.

commerce.commerce. These are the authorizationStatus. updateCommerceItemObjects Saves the CommerceItem properties for the items in the Order. The class that implements this functionality is atg.processor. The class that implements this functionality is atg.processor. The class that implements this functionality is atg.ProcSaveShippi ngGroupObjects.processor. 332 11 .ProcSaveHandli ngInstructionObjects. updateHandlingInstructionObjects Saves the HandlingInstruction properties for the handling instructions in the Order.commerce.processor.ProcSavePaymen tGroupObjects.commerce.order. The class that implements this functionality is atg.Configuring Purchase Process Services .µ PipelineLink name updateOrderObject ATG Commerce Programming Guide Description Saves an Order object’s properties to the repository. The Order is supplied in the optional user parameter of the PipelineManager. and creditStatus properties in the PaymentGroup class.ProcSaveOrderO bject.ProcSaveRelati onshipObjects. The class that implements this functionality is atg. The class that implements this functionality is atg.commerce.order. The class that implements this functionality is atg.order.processor. debitStatus. updatePaymentGroupObjects Saves the PaymentGroup properties for the payment groups in the Order. updateRelationshipObjects Saves the Relationship properties for the Relationships in the Order.processor.ProcSaveCommer ceItemObjects.order.order. updatePaymentStatusObjects Saves the PaymentStatus properties for the PaymentStatus objects in all the payment groups in the Order.order. updateShippingGroupObjects Saves the ShippingGroup properties for the shipping groups in the Order.commerce.order.commerce.processor.ProcSavePaymen tStatusObjects.

see the Commerce Processor Chains section. then the deleteOrder() method deletes the current Order from the user’s ShoppingCart. For more information about pipelines. The properties saved are in Order (priceInfo and taxPriceInfo). Canceling Orders The CancelOrderFormHandler (class atg. which is located in Nucleus at /atg/commerce/order/purchase/CancelOrderFormHandler.deleteStates property.processor.order.Configuring Purchase Process Services . ATG Commerce includes an instance of CancelOrderFormHandler. If no changes were made. deleteOrder preserveOrder 333 11 .ProcSavePaymen tGroupObjects. and CommerceItems (priceInfo). then the preserveOrder() method simply sends a ModifyOrder GenericRemove notification message to Fulfillment for any action deemed appropriate. If the state of the current Order isn’t one of the configured states in the CancelOrderFormHandler.CancelOrderFormHandler) cancels the user’s current Order.commerce. If the state of the current Order is one of the configured states in the CancelOrderFormHandler.ATG Commerce Programming Guide µ Saves the PriceInfo properties for the PriceInfo in the Order.processor. ShippingGroup (priceInfo).commerce.purchase. Method handleCancelOrder Description This handle method calls either the deleteOrder() method or the preserveOrder() method (depending on whether the Order can be deleted). which deletes the Order from the ShoppingCart.order. The following table describes the important methods in CancelOrderFormHandler. The class that implements this functionality is atg. the PipelineManager.order.ProcSetLastMod ifiedTime. and the transactional modes and transitions of the processors in the updateOrder pipeline.deleteStates property.commerce. then the lastModifiedTime is not changed. updatePriceInfoObjects setLastModifiedTime Sets the lastModifiedTime property in the Order object if any changes were made to the Order. The class that implements this functionality is atg.

updateOrder() to save the Order in its present state to the Order Repository. then calls OrderManager. For more information on OrderManager.Configuring Purchase Process Services . ExpressCheckoutFormHandler supports the use of a single Profile-derived HardgoodShippingGroup and a single Profile-derived CreditCard.ExpressCheckoutFormHandler).commerce. This section describes the checkout process for both simple and complex sites and includes the following sections: Preparing a Simple Order for Checkout Describes the use of ExpressCheckoutFormHandler. see the Updating an Order with the Order Manager subsection of Saving Orders in this chapter. Checking Out an Order Describes the processing of an Order after the customer has supplied all necessary information for the Order and has submitted it for checkout.purchase. or any number or type of payment group. if your site supports any number or type of shipping group. ATG Commerce provides an instance of ExpressCheckoutFormHandler. 334 11 .µ Checking Out Orders • ATG Commerce Programming Guide The order checkout process can vary depending on the requirements and complexities of your site. which is located in Nucleus at /atg/commerce/order/purchase/ExpressCheckoutFormHandler. then you must use the form handlers described in Preparing a Complex Order for Checkout. The following table describes its important methods: Method handleExpressCheckout Description This handle method first invokes the runRepricingProcess() method to reprice the Order. However. or any number or type of payment group.order. which manages and expedites the pre-checkout processing of orders. Intended for sites that support any number or type of shipping group. Note that the form handlers described in that section also work with simple Orders that have a single HardgoodShippingGroup and a single CreditCard. Preparing a Complex Order for Checkout Describes the various form handlers that manage the pre-checkout processing of orders. and finally calls commitOrder() to submit the Order for checkout.updateOrder() and the updateOrder pipeline that it executes. you can manage and expedite the pre-checkout process for Orders using the ExpressCheckoutFormHandler (class atg. • • Preparing a Simple Order for Checkout If your site supports the use of only a single HardgoodShippingGroup and a single CreditCard for a given Order. Intended for sites that support only a single HardgoodShippingGroup and CreditCard.

see Preparing a Complex Order for Checkout.shippingGroup property. see the Commerce Processor Chains section.repriceOrderChainId. and it constructs a new. then the user can supply the HardgoodShippingGroup information in a form through the ExpressCheckoutFormHandler. which executes the processOrder pipeline (See Checking Out an Order later in this chapter. The method then calls the OrderManager.handleExpressCheckout() method submits the Order for checkout.current).ATG Commerce Programming Guide µ runRepricingProcess Reprices the Order by running the pipeline specified in ExpressCheckoutFormHandler. commitOrder This method first ensures that the user isn’t trying to double-submit the Order by checking if the ID of the current Order is equal to the ID of the user’s last Order (in ShoppingCart. as necessary. Note: Recall that.paymentGroup property.processOrder() method. empty preXXX and postXXX methods are provided so you can extend ExpressCheckoutFormHandler. empty Order and sets it as the user’s current Order (in ShoppingCart.last). To implement a system that requires a more complex checkout process. By shippingGroupNeeded commitOrder default. then the current Order can be submitted for checkout. 335 11 .). the method sets the submitted Order as the user’s last Order (in ShoppingCart. If True. this property is set to repriceOrder.last). The following boolean properties of the ExpressCheckoutFormHandler govern its behavior: Property Name paymentGroupNeeded Description If True. If True. then a HardgoodShippingGroup is automatically taken from the Profile.Configuring Purchase Process Services . You can set this property to False if you want to display a confirmation page before committing the Order. See Checking Out an Order for detailed information on the order checkout process. then the user can supply the CreditCard information in a form through the ExpressCheckoutFormHandler. as with all shopping cart-related form handlers. Finally. then a CreditCard payment group is automatically taken from the Profile. For more information on the repriceOrder pipeline. this property is set to False. then the ExpressCheckoutFormHandler. If False. If False. By default. If the IDs are not equal.

the user can then select from among them for use in the current Order. see Preparing a Simple Order for Checkout.purchase. which actually creates the shipping group. this property is set to hardgoodShippingGroup. The form handler’s hardgoodShippingGroupType property determines the type of shipping group to create. CreateHardgoodShippingGroupFormHandler is configured to use /atg/commerce/util/AddressValidator to validate the shipping address before creating the shipping group. as referenced in the ShippingGroupMapContainer.Configuring Purchase Process Services . The two default implementations of CreateShippingGroupFormHandler are: • CreateHardgoodShippingGroupFormHandler This form handler class creates a HardgoodShippingGroup and exposes it via a getHardgoodShippingGroup() method. by default. These form handler classes create the ShippingGroups and optionally add them to the ShippingGroupMapContainer.CreateHardgoodShippingGroupFormHandler.commerce. The form handler’s hardgoodShippingGroupName property determines the name of the new shipping group. it is located in Nucleus at /atg/commerce/order/purchase/CreateHardgoodShippingGroupFormHandler .order.µ ATG Commerce Programming Guide Preparing a Complex Order for Checkout ATG Commerce provides several form handlers to support a checkout process that uses any number or type of shipping group and payment group. Separate form handlers exist to support the following tasks: • • • • • Creating shipping groups Associating shipping groups with an Order and its items Creating payment groups Associating payment groups with an Order and its items Submitting an Order for checkout Creating Shipping Groups ATG Commerce provides two implementations of the CreateShippingGroupFormHandler interface to support the form-driven creation of hard good and electronic shipping groups. The default configuration is: validateFirstName=true 336 11 . then you should use the form handlers described in this section instead of ExpressCheckoutFormHandler. the handleNewHardgoodShippingGroup() method invokes the createHardgoodShippingGroup() method. To create the HardgoodShippingGroup. Once the shipping groups are added to the ShippingGroupMapContainer.) The form handlers described in this section manage different subprocesses in the pre-checkout process. which makes it possible for users to edit its properties directly via JSP forms. ATG Commerce provides an instance of atg. If your site has this type of complex checkout process. (For more information on ExpressCheckoutFormHandler. which makes it easier for you to extend them when necessary.

Finally. the 337 11 . The form handler’s electronicShippingGroupType property determines the type of shipping group to create.Configuring Purchase Process Services . the form handler’s addToContainer property determines whether the new shipping group is added to the ShippingGroupMapContainer and made the default shipping group. updateOrder—Updates the HardgoodShippingGroup in the order. by default.purchase. Finally. based on these properties: updateContainer—Updates the HardgoodShippingGroup in the ShippingGroupMapContainer. this property is set to True. UpdateHardgoodShippingGroupFormHandler can update this information in any or all of three places. After creating the HardgoodShippingGroup. you can use the UpdateHardgoodShippingGroupFormHandler to handle shipping address changes. the user can use it when checking out the Order.ATG Commerce Programming Guide µ validateLastName=true validateAddress1=true validateCity=true validateCounty=false validateState=true validatePostalCode=true validateCountry=true validateEmail=false validatePhoneNumber=false validateFaxNumber=false This validation can be performed every time the shipping group is updated. updateProfile—Updates the shipping address in the profile. To create the ElectronicShippingGroup. which actually creates the shipping group and sets the shipping group’s emailAddress property. via the UpdateHardgoodShippingGroupFormHandler class. The form handler’s electronicShippingGroupName property determines the name of the new shipping group.order. Once the HardgoodShippingGroup is added to the ShippingGroupMapContainer.CreateElectronicShippingGroupFormHandle r.commerce. this property is set to electronicShippingGroup. as referenced in the ShippingGroupMapContainer. ATG Commerce provides an instance of atg. it is located in Nucleus at /atg/commerce/order/purchase/CreateElectronicShippingGroupFormHandl er. which makes it possible for users to edit its properties directly via JSP forms. • CreateElectronicShippingGroupFormHandler This form handler class creates an ElectronicShippingGroup and exposes it via a getElectronicShippingGroup() method. the handleNewElectronicShippingGroup() method invokes the createElectronicShippingGroup() method. by default.

Its initializeShippingGroups() method should gather the user’s ShippingGroups by type and add them to the ShippingGroupMapContainer referenced by the ShippingGroupFormHandler. the ElectronicShippingGroupInitializer queries the Profile’s email property and applies the result to a new ElectronicShippingGroup. see the Adding Shipping Information to Shopping Carts section of the Implementing Order Retrieval chapter of the ATG Commerce Guide to Setting Up a Store. For a detailed list of these input parameters. Finally. register a Nucleus component for the new ShippingGroupInitializer implementation and add it to the ServiceMap in ShippingGroupDroplet. which is keyed by ShippingGroup type. and the latter creates ElectronicShippingGroups based on the existence of an e-mail address in the user’s Profile. by default. the user can use it when checking out the Order. For example. The input parameters passed into ShippingGroupDroplet determine what types of ShippingGroups are created (hard good. open parameters.µ ATG Commerce Programming Guide form handler’s addToContainer property determines whether the new shipping group is added to the ShippingGroupMapContainer and made the default shipping group. its corresponding ShippingGroupInitializer is obtained from the ServiceMap in ShippingGroupDroplet. first. 338 11 . and a code example. this property is set to True. After creating the ElectronichippingGroup. or both) and whether the ShippingGroupMapContainer is cleared before they are created.commerce. which is subsequently added to the ShippingGroupMapContainer. The former creates HardgoodShippingGroups based on their existence in the user’s Profile. electronic. Once the ElectronicShippingGroup is added to the ShippingGroupMapContainer. the service method of ShippingGroupDroplet calls initializeUsersShippingMethods(). which initializes one or more ShippingGroups for the current user and adds them to the ShippingGroupMapContainer. To use this framework with a new ShippingGroup type that you create. namely HardgoodShippingGroupInitializer and ElectronicShippingGroupInitializer.ShippingGroupDroplet). as well as output parameters.order.shippingGroupInitializers (keyed by ShippingGroup type). For each entry in ShippingGroupDroplet. UpdateShippingGroupFormHandler can update shipping group information in the container and/or the order.purchase.shippingGroupTypes (which is supplied via an input parameter).Configuring Purchase Process Services . Second. write a new ShippingGroupInitializer implementation. based on these properties: updateContainer—Updates the ElectronicShippingGroup in the ShippingGroupMapContainer.shippingGroupInitializers. To initialize the ShippingGroup objects. include the new ShippingGroup type in the ShippingGroupDroplet. The initializeShippingGroups() method of the ShippingGroupInitializer is then used to initialize the ShippingGroup and add it to the ShippingGroupMapContainer. you can use the UpdateShippingGroupFormHandler to handle updates to the shipping group. Note that ATG Commerce provides two implementations of the ShippingGroupInitializer interface.shippingGroupTypes parameter on those site pages where the new ShippingGroup type is utilized. You can also create Profile-derived ShippingGroups and add them to the ShippingGroupMapContainer by using the ShippingGroupDroplet servlet bean (class atg. updateOrder—Updates the ElectronicShippingGroup in the order.

To learn more about the pipeline chain.CommerceItemShippingInfoContainer.order. • Additionally. see the validateShippingInfo Pipeline Chain section.order.order. ATG Commerce provides a request-scoped instance of atg. This container stores the user’s potential ShippingGroups for the Order.commerce. These objects store the information needed to create ShippingGroupCommerceItemRelationships for the Order. which is used to associate handling instruction information with each CommerceItemShippingInfo object.purchase. this form handler invokes the validateShippingInfo pipeline chain to validate ShippingGroup information. the ShippingGroupFormHandler can be used to create and manage the associations between the ShippingGroups and the items in the Order.HandlingInstructionInfo. The resulting collections of ShippingGroups and CommerceItemShippingInfos are exposed via the output • 339 11 .ShippingGroupFormHandler.ATG Commerce Programming Guide µ Associating Shipping Groups with an Order and Its Items When the user has supplied the shipping information for an Order.order.CommerceItemShippingInfo. and relationshipType. which defines a Map of CommerceItems to CommerceItemShippingInfo Lists.commerce. which contains a reference to both the ShippingGroupMapContainer and CommerceItemShippingInfoContainer.commerce. which represents the association between a CommerceItem and its shipping information and includes properties such as quantity.purchase. set the validateShippingGroups property to false. atg.Configuring Purchase Process Services .commerce. The ShippingGroupDroplet servlet bean is used to initialize ShippingGroup objects and CommerceItemShippingInfo objects for use by the ShippingGroupFormHandler. the ShippingGroupFormHandler uses the following helper classes: • atg. To skip validation. By default. you should then reprice the given Order using the RepriceOrderDroplet servlet bean before displaying its price to the customer. The ShippingGroupFormHandler is composed of the following containers: • atg. Handling Instructions and their relationships to CommerceItems and ShippingGroups are also manipulated based on the relationship between each CommerceItem and the ShippingGroups.purchase.ShippingGroupMapContainer. For more information on RepriceOrderDroplet.commerce. which is located in Nucleus at /atg/commerce/order/purchase/ShippingGroupFormHandler. if you enable customers to make order changes that affect order price through this form handler. which defines a Map of user-assigned ShippingGroup names to ShippingGroups.order. HandlingInstructionInfo is stored in a handingInstructionInfos list property of the CommerceItemShippingInfo object. The ShippingGroupFormHandler works in conjunction with the ShippingGroupDroplet to manipulate the relationships between CommerceItems and ShippingGroups in the order.purchase.purchase. atg. see Repricing Orders section of the ATG Commerce Guide to Setting Up a Store. Consequently.commerce. This container stores the user’s CommerceItemShippingInfo objects for the CommerceItems in the Order.ShippingGroupDroplet.purchase.order. It should be noted that ShippingGroupFormHandler does not reprice the given Order. • atg. splitQuantity.

CommerceItemShippingGroupTools includes the includeGifts flag.purchase. which sets the defaultShippingGroupName in the ShippingGroupMapContainer. Creating Shipping Groups. In turn. Setting the default ShippingGroup can facilitate simpler applications that permit only one ShippingGroup per Order.order.µ • ATG Commerce Programming Guide parameters of the servlet bean. performs validation. For each CommerceItemShippingInfo. it retrieves the quantity and the splitQuantity.CommerceItemShippingInfoTools. splitCommerceIdentifierShippingInfoByQuantity() creates a new CommerceIdentifierShippingInfo object. The following table describes the handle methods used in these processes: Method handleSplitShippingInfos Description of Functionality This handle method splits the quantities of CommerceItems across several CommerceItemShippingInfo objects.Configuring Purchase Process Services . For more information on using the ShippingGroupDroplet to initialize ShippingGroup objects.commerce. With these helper classes and containers. If the splitQuantity is greater than zero and not greater than the quantity. The handle method calls splitShippingInfos(). as well as advanced applications that apply a default ShippingGroup to any remaining items not explicitly covered by other ShippingGroups. the ShippingGroupFormHandler adds the necessary ShippingGroups to the Order. which retrieves the list of CommerceItemShippingInfo objects from the CommerceItemShippingInfoContainer. removing and applying the CommerceItemShippingInfo and ShippingGroup objects in the CommerceItemShippingInfoContainer and ShippingGroupMapContainer containers respectively. modifying. then the method calls splitCommerceIdentifierShippingInfoByQuantity(). The method then iterates through the list. and updates the Order. atg. adjusts the properties of both the new and existing objects. and adds the new object to the CommerceItemShippingInfoContainer. which contains helper methods for creating. handleApplyShippingGroups This handle method adds the ShippingGroups to the Order. see below. which determines how gift items are handled when split across shipping groups. The method calls specifyDefaultShippingGroup(). It 340 11 . see the previous section. handleSpecifyDefault ShippingGroup This handle method is used to let the user specify a default ShippingGroup to use for shipping. For more information on initializing CommerceItemShippingInfo objects. establishes their relationships to the CommerceItems.

For information on the validateShippingInfo pipeline. this property is set to validateShippingInfo. see the Commerce Processor Chains section. which first calls ShippingGroupManager. For more information on OrderManager. Finally. the associated ShippingGroup is retrieved and added to the Order (if it isn’t already in the Order). the handle method calls runProcessValidateShippingGroups() to validate the ShippingGroups in the Order. For each CommerceItemShippingInfo object.addItemQuantityToShippingGrou p() or CommerceItemManager. This adds the appropriate quantity of the CommerceItem to the ShippingGroup. depending on the relationshipType (SHIPPINGQUANTITY OR SHIPPINGQUANTITYREMAINING). This ensures a clean Order. The applyShippingGroups() method then calls applyCommerceItemShippingInfo(). The handle method calls applyShippingGroups().updateOrder() and the updateOrder pipeline that it executes.Configuring Purchase Process Services . Then. then the remaining quantity of all CommerceItems in the Order is added to the default shipping group. Next. if the form handler’s applyDefaultShippingGroup property is True.ATG Commerce Programming Guide µ is used when the customer has supplied the necessary shipping information for the Order and is ready to proceed with the next checkout phase.validateShippingGroupsCh ainId. This executes the shipping validation pipeline specified in ShippingGroupFormHandler. see the Updating an Order with the 341 11 .removeAllShippingGroupsFromO rder() to remove any existing ShippingGroups from the Order.updateOrder() to save the Order in its present state to the Order Repository. then the applyShippingGroups() method checks for a default shipping group in the ShippingGroupMapContainer. If one exists.addRemainingItemQuantityToShi pping(). which applies all CommerceItemShippingInfo objects to the Order. by default. the handle method calls OrderManager. The applyCommerceItemShippingInfo() method iterates through the list of CommerceItemShippingInfo objects in the CommerceItemShippingInfoContainer. Then the method retrieves the Relationship type of the current CommerceItemShippingInfo object and calls either CommerceItemManager.

however. and a code example. For example. by default. For a detailed list of these input parameters. HandlingInstructionInfo objects are automatically generated for any handling instructions currently in the Order. so they can be used by the ShippingGroupFormHandler. and 1 is a gift. a CommerceItemShippingInfo will be created for a quantity of 2. An additional parameter controls whether the CommerceItemShippingInfoContainer is cleared before the objects are created.µ ATG Commerce Programming Guide Order Manager subsection of Saving Orders in this chapter. These HandlingInstructionInfo objects are then associated with the appropriate CommerceItemShippingInfo objects based on the CommerceItem referenced in the handling instruction. has several input parameters that control whether and how CommerceItemShippingInfo objects are created. 342 11 . as well as ShippingGroupDroplet output parameters. it has the following effects: • CommerceItemShippingInfo objects don’t include the quantity of the items designated as gifts. and after applying. Each new CommerceItemShippingInfo references the default ShippingGroup in the ShippingGroupMapContainer. and apply handling information along with the CommerceItemShippingInfo objects with which it is associated. open parameters. they remain unchanged in the Order. the ShippingGroupDroplet servlet bean is used to initialize CommerceItemShippingInfo objects and add them to the CommerceItemShippingInfoContainer. creates and initializes a CommerceItemShippingInfo for each CommerceItem in the Order and adds them to the CommerceItemShippingInfoContainer. The HandlingInstructionInfo class makes it possible to split. The droplet.Configuring Purchase Process Services . and therefore the ShippingGroupDroplet and ShippingGroupFormHandler automatically handle splitting and merging of gift items in the order. When the ShippingGroupDroplet initializes a container based on the current contents of an Order. • • GiftHandlingInstructions are not included in the HandlingInstructionInfos associated with the CommerceItemShippingInfos ShippingGroups that contain only gifts are not added to the ShippingGroupMapContainer The result is that none of the gift-related objects in the Order are added to the CommerceItemShippingInfoContainer and ShippingGroupMapContainer when initializing based on the Order. Gift items in an order are identified by a special handling instruction (GiftHandlingInstruction). To initialize the CommerceItemShippingInfo objects. the service method calls initializeCommerceItemShippingInfos() which. As previously mentioned. see the Adding Shipping Information to Shopping Carts section of the Implementing Order Retrieval chapter of the ATG Commerce Guide to Setting Up a Store. merge. If the CommerceItemShippingInfoTools includeGifts property is set to false (the default). The paragraph above describes the default behavior of the ShippingGroupDroplet. if an item is quantity 3.

b2bcommerce.purchase. the form handler’s copyToProfile property determines whether the payment group is copied to the Profile. UpdateCreditCardFormHandler can update this information in any or all of three places.CreateCreditCardFormHandler.ATG Commerce Programming Guide µ Creating Payment Groups ATG Commerce provides two implementations of the CreatePaymentGroupFormHandler interface to support the form-driven creation of credit card and invoice payment groups.CreateInvoiceRequestFormHandler. you can use the UpdateCreditCardFormHandler to deal with any changes the user makes to their credit card information. as referenced in the PaymentGroupMapContainer.purchase. by default. this property is set to true. • CreateInvoiceRequestFormHandler (ATG Business Commerce only) This form handler creates an InvoiceRequest payment group and exposes it via a getInvoiceRequest() method. based on these properties: updateContainer—Update the credit card in the PaymentGroupMapContainer. The form handler’s addToContainer property determines whether the new payment group is added to the PaymentGroupMapContainer and made the default payment group. which makes it possible for users to edit its properties directly via JSP forms. the handleNewCreditCard() method invokes the createCreditCard() method. Finally. which makes it possible for users to edit its properties directly via JSP forms. it is 343 11 .order. The form handler’s creditCardType property determines the type of CreditCard payment group to create. by default. which actually creates the payment group. the user can then select from among them for use in the current Order.Configuring Purchase Process Services . ATG Business Commerce provides an instance of atg. this property is set to True. These form handler classes create the payment groups and optionally add them to the PaymentGroupMapContainer. by default. After creating the credit card information. this property is set to creditCard.order.commerce. (Once the payment group is added to the PaymentGroupMapContainer. ATG Commerce provides an instance of atg.) CreateCreditCardFormHandler can optionally validate credit card information using the credit card’s verification number. To create the CreditCard payment group. To validate credit cards. the user can use it when checking out the Order. Once the payment groups are added to the PaymentGroupMapContainer. The default implementations of the CreatePaymentGroupFormHandler are: • CreateCreditCardFormHandler This form handler creates a CreditCard payment group and exposes it via a getCreditCard() method. set the validateCreditCard property to true. updateProfile—Update the credit card in the profile. The form handler’s creditCardName property determines the name of the new payment group. updateOrder—Update the credit card in the order. it is located in Nucleus at /atg/commerce/order/purchase/CreateCreditCardFormHandler.

first. the user can use it when checking out the Order. They are: • • • • CreditCardInitializer GiftCertificateInitializer StoreCreditInitializer InvoiceRequestInitializer (ATG Business Commerce only) To use this framework with a new PaymentGroup type that you create. see the Adding Payment Information to Shopping Carts section of the Implementing Shopping Carts chapter of the ATG Commerce Guide to Setting Up a Store.commerce. write a new PaymentGroupInitializer implementation. To create the InvoiceRequest payment group. which initializes one or more PaymentGroups for the current user and adds them to the PaymentGroupMapContainer. For a detailed list of these input parameters. The form handler’s addToContainer property determines whether the new payment group is added to the PaymentGroupMapContainer and made the default payment group.PaymentGroupDroplet). this property is set to invoiceRequest. the form handler’s invoiceRequestProperties property determines what additional Profile properties to dynamically add to the InvoiceRequest.µ located in Nucleus at ATG Commerce Programming Guide /atg/commerce/order/purchase/CreateInvoiceRequestFormHandler. Its initializePaymentGroups() method should gather the user’s PaymentGroups by type and add them to the PaymentGroupMapContainer referenced by the 344 11 .paymentGroupInitializers (keyed by PaymentGroup type). this property is set to True. as well as its output parameters. the handleNewInvoiceRequest() method first invokes the checkRequiredProperties() method. its corresponding PaymentGroupInitializer is obtained from the ServiceMap in PaymentGroupDroplet.paymentGroupTypes (which is supplied via an input parameter). which actually creates the payment group.Configuring Purchase Process Services . (Once the payment group is added to the PaymentGroupMapContainer. The handle method then calls createInvoiceRequest(). For each entry in PaymentGroupDroplet. this method checks that a poNumber for the invoice has been specified and throws an exception if one has not been provided.purchase. By default. this property is set to defaultBillingAddress.order. The input parameters passed into PaymentGroupDroplet determine what types of PaymentGroups are created (credit card. open parameters. gift certificate) and whether the PaymentGroupMapContainer is cleared before they are created. Finally. The initializePaymentGroups() method of the PaymentGroupInitializer is then used to initialize the PaymentGroup and add it to the PaymentGroupMapContainer. by default. and a code example. To initialize the PaymentGroup objects. store credit. by default. You can also create Profile-derived PaymentGroups and add them to the PaymentGroupMapContainer by using the PaymentGroupDroplet servlet bean (class atg. Note that ATG Commerce provides four implementations of the PaymentGroupInitializer interface. by default. the service method of PaymentGroupDroplet calls initializeUserPaymentMethods(). The form handler’s invoiceRequestType property determines the type of InvoiceRequest payment group to create.) The form handler’s billingAddressPropertyName determines the billing address Profile property to copy into the InvoiceRequest.

set the priceListId property to the appropriate pricelist. which is typically order confirmation. (For more information on using PaymentGroupDroplet to • 345 11 . When it is finished. which is located in Nucleus at /atg/commerce/order/purchase/PaymentGroupFormHandler. Associating Payment Groups with an Order and Its Items When the user has supplied the payment information for an Order. include the new PaymentGroup type in the PaymentGroupDroplet. atg.commerce. the PaymentGroupFormHandler can used to create and manage the associations between the PaymentGroups and the various parts of the Order.order.commerce.purchase. instantiates objects for them.purchase.ATG Commerce Programming Guide µ PaymentGroupFormHandler.order.order. which represents the association between a CommerceIdentifier and its payment information and includes properties that allow the cost of a given quantity or even a single item to be spread across multiple payment groups. the PaymentGroupFormHandler uses the following helper classes: • atg.order. which implements both the PaymentGroupMapContainer and CommerceIdentifierPaymentInfoContainer interfaces. the Order is ready to proceed to the next step in the purchase process. Any Order that has been successfully processed by the PaymentGroupFormHandler is ready for the next phase of the purchase process.purchase. • Additionally.PaymentGroupDroplet.PaymentGroupFormHandler.commerce. This container stores the user’ potential PaymentGroups for the Order. atg. For example. This container stores the user’s CommerceIdentifierPaymentInfo objects for the Order. Second. the StoreCreditInitializer queries the Claimable Repository for the user’s StoreCredit PaymentGroups. ShippingGroups.purchase. If you’d prefer for items to be priced according to a pricelist rather than the default behavior provided by the pricing engine. register a Nucleus component for the new PaymentGroupInitializer implementation and add it to the ServiceMap in PaymentGroupDroplet. ATG Commerce provides a request-scoped instance of atg.commerce. and finally saves the Order in its present state to the Order Repository. which typically is Order checkout. Finally. cost amount and cost remaining information to the PaymentGroups. The PaymentGroupFormHandler adds the PaymentGroups to the Order.order. which is keyed by PaymentGroup type. which defines a Map of CommerceIdentifiers to CommerceIdentifierPaymentInfo Lists. and then adds them to the PaymentGroupMapContainer.CommerceIdentifierPaymentInfo. adds the CommerceItems. (See Submitting an Order for Checkout.commerce.CommerceIdentifierPaymentInfoContainer.) The PaymentGroupFormHandler is composed of the following containers: • atg. The PaymentGroupDroplet servlet bean is used to initialize PaymentGroup objects and CommerceIdentifierPaymentInfo objects for use by the PaymentGroupFormHandler.PaymentGroupMapContainer.Configuring Purchase Process Services .paymentGroupTypes parameter on those site pages where the new PaymentGroup type is utilized.paymentGroupInitializers. which defines a Map of user-assigned PaymentGroup names to PaymentGroups. The resulting collections of PaymentGroups and CommerceIdentifierPaymentInfo objects are exposed via the output parameters of the servlet bean. These objects store the information need to create payment Relationships for the Order. validates the PaymentGroup information. tax.purchase.

The splitPaymentInfos() method then iterates through the list and calls splitCommerceIdentifierPaymentInfo() on each object.) With these helper classes and containers. the PaymentGroupFormHandler adds the necessary PaymentGroups to the Order. For more information on initializing CommerceIdentifierPaymentInfo objects. The method calls specifyDefaultPaymentGroup(). 346 11 . the user might request to split $50 of an original CommerceIdentifier amount of $100 to a separate payment method. It is used when the user has supplied the necessary payment information for the Order and is ready to proceed with the next checkout phase. as well as advanced applications that apply a default PaymentGroup to any remaining Order amount not explicitly covered by other PaymentGroups. Setting the default PaymentGroup can facilitate simpler applications that permit only one PaymentGroup per Order. and adjusts the amount of both the original and the new CommerceIdentifierPaymentInfo objects to add up to the original CommerceIdentifier total amount. The method creates a new CommerceIdentifierPaymentInfo object. validates them. adjusts the properties of both the existing and new objects. see below in this section.µ handle methods used in these processes: ATG Commerce Programming Guide initialize PaymentGroup objects. and updates the Order. This creates a separate CommerceIdentifierPaymentInfo object. The handle method calls splitPaymentInfos(). The following table describes the Method handleSplitPaymentInfos Description of Functionality This handle method is used when the user wants to split a particular CommerceIdentifierPaymentInfo by amount across multiple PaymentGroups. handleApplyPaymentGroups This handle method adds the PaymentGroups to the Order.Configuring Purchase Process Services . which retrieves the list of CommeceIdentifierPaymentInfo objects from the CommerceIdentifierPaymentInfoContainer. which sets the defaultPaymentGroupName in the PaymentGroupMapContainer. and adds the new object to the CommerceIdentifierPaymentInfoContainer. handleSpecifyDefault PaymentGroup This handle method is used to let the user specify a default PaymentGroup to use for payment. In a form. splitCommerceIdentifierPaymentInfo() calls splitCommerceIdentifierPaymentInfoByAmount() to split the CommerceIdentifierPaymentInfo object. In turn. see Creating Payment Groups.

ATG Commerce Programming Guide µ The handle method calls applyPaymentGroups().validatePaymentInformationC hainId. For each CommerceIdentifierPaymentInfo object. which first calls PaymentGroupManager.recalculatePaymentGroupAmount() to recalculate the payment groups. Next. this property is to moveToConfirmation.updateOrder() to save the Order in its present state to the Order Repository. then the remaining order amount is added to the default payment group. This ensures a clean Order.Configuring Purchase Process Services . the associated PaymentGroup is retrieved and added to the Order (if it isn’t already in the Order). see the Commerce Processor Chains section. see the Assigning Costs to PaymentGroups section of the Working With Purchase Process Objects chapter. The moveToConfirmation pipeline both prices and validates a given Order. see the Updating an Order with the Order Manager subsection of Saving Orders in this chapter. if the form handler’s applyDefaultPaymentGroup property is True. which applies the CommerceIdentierPaymentInfo objects to the Order. The applyCommerceIdentifierPaymentInfo() method iterates through the list of CommerceIdentifierPaymentInfo objects in the CommerceIdentifierPaymentInfoContainer. This executes the payment validation pipeline specified in PaymentGroupFormHandler.updateOrder() and the updateOrder pipeline that it executes. then the applyPaymentGroups() method checks for a default payment group in the PaymentGroupMapContainer. 347 11 . the handle method calls runProcessValidatePaymentGroups() to validate the PaymentGroups in the Order. the applyPaymentGroups() method calls applyCommerceIdentifierPaymentInfo(). If one exists.removeAllPaymentGroupsFromOrder () to remove any existing PaymentGroups from the Order. For more information on OrderManager. by default. the handle method calls OrderManager. Then. For more information. Finally. For more information. Then the method retrieves the Relationship type of the current CommerceIdentifierPaymentInfo object and calls the appropriate method in the appropriate “Manager” to add the amount to the PaymentGroup. Next. Next. applyPaymentGroups() calls PaymentGroupManager.

For a detailed list of these input parameters. The processing of an Order begins with a call to OrderManager.) If no errors occur during the validation or checkout of the Order. by default. In ATG Consumer Commerce. and tax. as well as its output parameters. These objects are then added to the CommerceIdentifierPaymentInfoContainer. The expiration date for all cards can be any date in the future. you must modify the pipeline accordingly. 348 11 .µ ATG Commerce Programming Guide As previously mentioned. ShippingGroups. The form handler’s handleCommitOrder() method ensures that the user is not trying to double-submit the order by checking if the ID of the current Order is equal to the ID of the user’s last Order (in ShoppingCart. the PaymentGroupDroplet servlet bean is used to initialize CommerceIdentifierPaymentInfo objects and add them to the CommerceIdentifierPaymentInfoContainer.Configuring Purchase Process Services . To initialize the CommerceIdentifierPaymentInfo objects.commerce. which creates and initializes CommerceIdentifierPaymentInfo objects for the Order. which is located in Nucleus at /atg/commerce/order/purchase/CommitOrderFormHandler.current.xml.order.CommitOrderFormHandler) submits the user’s current Order for checkout. which executes the processOrder pipeline. ATG Commerce includes an instance of CommitOrderFormHandler. and a code example. the related XML configuration file is defined in /<ATG9dir>/B2BCommerce/config/atg/commerce/commercepipeline. empty Order and sets it as the user’s current Order in ShoppingCart. Note that. then the current Order can be submitted. To allow the processing of incomplete Orders. The PipelineManager Nucleus component for ATG Commerce is located at /atg/commerce/PipelineManager. so they can be used by the PaymentGroupFormHandler. (See Checking Out an Order below. which calls into the PipelineManager to execute the processOrder pipeline. the service method of PaymentGroupDroplet calls initializePaymentInfos(). and it constructs a new. open parameters. The input parameters passed into PaymentGroupDroplet determine whether the CommerceIdentifierPaymentInfo objects are created and whether the CommerceIdentifierPaymentInfoContainer is cleared before they are created. ATG Commerce does not process an incomplete Order. the related XML configuration file is defined in /<ATG9dir>/B2CCommerce/config/atg/commerce/commercepipeline.xml. In ATG Business Commerce. Checking Out an Order Order processing occurs when a customer has supplied all the necessary information for the Order and has submitted it for checkout.processOrder(). see the Adding Payment Information to Shopping Carts section of the Implementing Order Retrieval chapter of the ATG Commerce Guide to Setting Up a Store.last. then handleCommitOrder() sets the submitted Order as the user’s last Order in ShoppingCart.last). as well as the Order’s CommerceItems.processOrder() method. The handle method then calls the OrderManager. Submitting an Order for Checkout The CommitOrderFormHandler (class atg.purchase. Note: You can use the credit card information listed below to process payments during testing of the order checkout process. The processOrder pipeline first validates the Order and then processes it. If the IDs are not equal.

349 11 . See the Managing the Order Approval Process chapter for more information. They are listed in order of execution.processor. executeApproveOrderChain (ATG Business Commerce only) Executes the approveOrder pipeline. this property is set to validateForCheckout.ProcExecuteCha in class implements this functionality.commerce. execution of the processOrder pipeline stops.Configuring Purchase Process Services .) The atg. PipelineLink name executeValidateForCheckoutChain Description Executes the validateForCheckout pipeline (Refer to the next table in this section. execution of the processOrder pipeline stops. which begins the approval process. Its properties file defines the execution chain to run in the chainToRun property.commerce.order. By default. If the Order did not require approval. The atg.order. the pipeline continues with executeValidateNoApprovalChain. the processOrder pipeline continues with executeValidatePostApprovalChain. The atg.commerce. If any errors occur during the execution of this processor. If the Order requires approval and has not been approved yet.ProcDispatchOn OrderState class implements this functionality.ATG Commerce Programming Guide µ • • • • Visa: 4111111111111111 MasterCard: 5555555555554444 American Express: 378282246310005 Discover: 6011111111111117 The following table describes the processors in the processOrder pipeline. stopChainIfOrderRequiresApproval (ATG Business Commerce only) Checks the state of the Order.order. If the Order required approval and has been approved.processor.ProcExecuteCha in class implements this functionality. See the Managing the Order Approval Process chapter for more information.processor.

order. by default the pipeline validates InvoiceRequests. This processor executes the validateNoApproval pipeline.ProcCheckForEx piredPromotions class implements this functionality.ProcExecuteCha in class implements this functionality. removeEmptyShippingGroups Removes any empty (unused) shipping groups from the Order.commerce. checkForExpiredPromotions Checks that expired promotions are not used in Order that is being checked out. which validates information intentionally skipped by the executeValidateForCheckout pipeline processor. See the Managing the Order Approval Process chapter for more information. The atg. The atg. See the Managing the Order Approval Process chapter for more information.processor. executeValidateNoApprovalChain (ATG Business Commerce only) For Orders that didn’t require approval.order.commerce.ProcExecuteCha in class implements this functionality. Specifically.ProcRemoveEmpt yShippingGroups class implements this functionality. The atg.order.processor. This processor executes the validatePostApproval pipeline. removeEmptyPaymentGroups Removes any empty (unused) payment groups from the Order.Configuring Purchase Process Services . An empty ShippingGroup is one without any CommerceItemRelationships. which are intentionally skipped by the validateForCheckout pipeline until it is determined that the Order requires approval.commerce.order.processor.commerce. ShippingGroupRelationships.µ executeValidatePostApprovalChain ATG Commerce Programming Guide (ATG Business Commerce only) For Orders that have been approved.ProcRemoveEmpt yPaymentGroups class implements this functionality. the pipeline revalidates payment information (all payment groups and cost centers) and checks that all Order and shipping costs are accounted for.processor. The atg.commerce.order. Specifically. and OrderRelationships.processor. which revalidates information the approver may have changed. 350 11 . The atg. An empty PaymentGroup is one without any CommerceItemRelationships.

ATG Commerce Programming Guide µ Validates the special case of an Order having one ShippingGroup and/or one PaymentGroup and no Relationships. setCostCenterAmount (ATG Business Commerce only) Determines and sets the amount to assign to each cost center in the Order.commerce.commerce. See the Implementing Cost Centers chapter of the ATG Commerce Guide to Setting Up a Store for more information.order.ProcSetPayment GroupAmount class implements this functionality. or GiftCertificate. moveUsedPromotions Moves all promotions that a customer used in the Order to the usedPromotions list in the customer’s profile.processor.ProcAuthorizeP ayment class implements this functionality.commerce.ProcCreateImpl icitRelationships class implements this createImplicitRelationships functionality.commerce. The atg.processor.ProcMoveUsedPr omotions class implements this functionality. or StoreCredit) in the Order.order.Configuring Purchase Process Services .processor.order. The atg. see Preventing Payment Authorization for Unfulfilled Orders later in this section. it is also removed from the activePromotions list and added to the customer’s inactivePromotions list. the processor actually creates relationships between all the CommerceItems and the ShippingGroup.order.processor. If the promotion is a single-use promotion.order. Note: For information on how to prevent the authorization of a user’s credit card under certain circumstances. such as when the items in the Order don’t exist in inventory. authorizePayment Authorizes all PaymentGroups (CreditCard.processor.b2bcommerce. setPaymentGroupAmount Determines and sets the amount to charge in each PaymentGroup based on the Relationships in the Order.ProcSetCost CenterAmount class implements this functionality. In this situation. The atg. It also creates a relationship between the PaymentGroup and the Order. The atg. The atg. 351 11 .

The atg.order.commerce.ProcValidateO rderForCheckout class implements this functionality.updateOrder() to save the Order to the Order Repository.order. (See Updating an Order with the Order Manager.commerce.order. The message can then be used to execute scenarios. sendPromotionUsedMessage Sends a message to the messaging system that describes the promotions that were used in the Order. The first processor in the processOrder pipeline. and PaymentGroup.processor.commerce. The atg.ProcSendGiftPu rchasedMessage class implements this functionality.ProcSendPromot ionUsedMessage class implements this functionality.order. The following table describes the processors in the validateForCheckout pipeline.ProcVerifyOrd erAddresses class implements this functionality. named executeValidateForCheckoutChain. sendFulfillmentMessage Sends a message that includes the Order to the fulfillment system. This message indicates to the fulfillment system that it can fulfill the Order. The message can then be used to execute scenarios.processor.processor.processor.processor.commerce. ShippingGroup. The atg.processor. The atg. They are listed in order of execution.commerce. in turn executes the validateForCheckout pipeline. The atg.commerce.Configuring Purchase Process Services . PipelineLink name ValidateOrderForCheckout Description Verifies that the Order contains at least one CommerceItem.) The atg. 352 11 .ProcSendFulfil lmentMessage class implements this functionality.µ updateGiftRepository sendGiftPurchasedMessage ATG Commerce Programming Guide Updates the Gift List Repository to reflect the purchase of any gifts in the order.order. addOrderToRepository This processor first calls OrderManager.order.processor.ProcUpdateGift Repository class implements this functionality Sends a message to the messaging system that describes the gifts that were purchased.ProcAddOrderTo Repository class implements this functionality. The atg.order.commerce. VerifyOrderAddresses Verifies the addresses for shipping groups and payment groups.

commerce. validateHandlingInstructionsForChe ckout Verifies that all HandlingInstructions are assigned to a valid ShippingGroup and CommerceItem combination.processor. The atg. The atg. The atg. The atg. validatePaymentGroupsForCheckout Verifies that all CommerceItems in the Order can account for their costs.commerce.ATG Commerce Programming Guide µ Verifies that all CommerceItems in the Order are assigned to a ShippingGroup. It also verifies that all required fields have been supplied to all PaymentGroups in the Order.ProcCreditCar dModCheck class implements this functionality.commerce.ProcValidateH andlingInstructionsForCheckout class implements this functionality. The credit card is not authorized by a processing system at this point.processor. which means that the processor verifies all PaymentGroupShippingGroupRelationships.processor.order.ProcValidateP aymentGroupsForCheckout class implements this functionality. validateShippingCostsForCheckout Verifies that all ShippingGroups can account for their costs.order. which describes the processors in the processOrder pipeline. The atg. (See the previous table. The processor also verifies that all required fields have been supplied to all ShippingGroups in the Order.commerce.order. creditCardModCheck Verifies that the credit card number and expiration date are valid.processor.Configuring Purchase Process Services .commerce.ProcValidateO rderCostsForCheckout class implements this functionality.ProcValidateS hippingGroupsForCheckout class that implements validateShippingGroupsForCheckout this functionality is.order. which means that the processor verifies all PaymentGroupCommerceItemRelationships. validateOrderCostsForCheckout Verifies the Order can account for its cost. 353 11 .order.commerce.processor. which means the processor verifies all PaymentGroupOrderRelationships.order.processor.ProcValidateS hippingCostsForCheckout class implements this functionality. The atg. the processor applies a simple algorithm to the credit card number to determine if it is valid.) Rather. It then checks the date to determine if the card has expired.

xml. the PipelineManager Nucleus component for ATG Commerce is located at /atg/commerce/PipelineManager. For more information about pipelines. see the Processor Chains and the Pipeline Manager chapter. You can modify the processOrder pipeline to prevent credit card authorization under certain conditions. the PipelineManager. As previously mentioned. when the order contains items that do not exist in inventory. the pipeline might redirect the user to a page that indicates which items could not be allocated from inventory and allows the user to change the Order. The atg.processor.Configuring Purchase Process Services . If they do. and credit of PaymentGroups in an Order. Also validates that all the items. Preventing Payment Authorization for Unfulfilled Orders The processOrder pipeline performs several checkout functions. and order have been priced.commerce. If the items do not exist in inventory. To do so. debit. For information on how to set up a branching pipeline. tax. you may want to prevent the authorization of a credit card.xml. It includes the following sections: 354 11 . In ATG Business Commerce. In this example. This section provides information on how the payment of orders is processed in ATG Commerce and describes how to extend the system to add functionality or to support a new payment method.order. The important concept is that the processOrder pipeline branches so that the user’s credit card is not authorized. you need to modify the pipeline to include a branch. Processing Payment of Orders The PaymentManager manages the authorization. including authorizing a user’s credit card for the amount of the order. and the transactional modes and transitions of the processors in the processOrder and validateForCheckout pipelines. and it tracks the results of those payment operations using PaymentStatus objects.ProcValidateC urrencyCodes class implements this functionality. see the Commerce Processor Chains section. then the Order should branch to an alternate pipeline that does not authorize the user’s credit card. Under certain circumstances. then the Order should continue through the pipeline for checkout (and authorization of the user’s credit card). In ATG Consumer Commerce.µ validateCurrencyCodes ATG Commerce Programming Guide Validates that all the currency codes in the PriceInfo objects are the same. the related XML configuration file is defined in /<ATG9dir>/B2BCommerce/config/atg/commerce/commercepipeline. One processor in the pipeline should check that the items being purchased do exist in inventory. the related XML configuration file is defined in /<ATG9dir>/B2CCommerce/config/atg/commerce/commercepipeline. for example. shipping. Instead. the user could be alerted of the lack of inventory and allowed to modify the order before checkout.

which uses the class name of the given PaymentGroup as the key to look up the appropriate pipeline to run in PaymentManager. the giftCertificateProcessorChain pipeline handles authorization. the creditCardProcessorChain pipeline handles authorization.paymentGroupToChainNameMap.StoreCredit=storeCreditProcessorChain Thus.CreditCard class. this method calls getChainName(PaymentGroup). This Dictionary object contains the information required to perform the transaction. debiting. each of the pipelines in PaymentManager.CreditCard=creditCardProcessorChain. and credit work for the atg. debit. This property stores a map of PaymentGroup class types to the names of the pipelines that perform the payment actions for the payment methods.commerce.commerce. Once the appropriate pipeline to run has been obtained (for example. To obtain the appropriate pipeline to run. This second authorize/credit/debit method performs the actual payment operation for the current PaymentGroup by looking up the pipeline appropriate for the current PaymentGroup class type and then calling that pipeline.ATG Commerce Programming Guide µ • • • • Overview of the Payment Process Extending the Payment Operations of a Payment Method Extending the Payment Process to Support a New Payment Method Extending Order Validation to Support New Payment Methods Overview of the Payment Process When the PaymentManager’s authorize/credit/debit method is called. The second processor performs the actual operation – authorizing. It then calls its authorize/credit/debit method that takes an additional amount parameter.\ atg. debit. Note that while a single pipeline exists to perform authorize. the creditCardProcessorChain pipeline). It passes in the PaymentManagerPipelineArgs Dictionary object as an argument to the runProcess() method of the pipeline.GiftCertificate=giftCertificateProcessorChain. the authorize/credit/debit method calls getXXXChainName(PaymentGroup). CreditCardInfo) for use in that action.order.order. and so on. this property is configured as follows: paymentGroupToChainNameMap=\ atg.commerce.order. or crediting the appropriate payment method.order. debit. getCreditChainName(PaymentGroup). for example.GiftCertificate class.paymentGroupToChainNameMap is composed of two processors.Configuring Purchase Process Services .commerce. and credit actions for a single PaymentGroup type. you can split these actions into separate pipelines if your processing needs for a given payment action are unusual. the authorize/credit/debit method calls into the PaymentPipelineManager to execute the pipeline. it takes the Order and a single PaymentGroup or List of PaymentGroups as parameters. By default. and credit work for the atg. which is as follows: • • Order PaymentManager 355 11 . The first processor aggregates the necessary information for performing the requested payment action (for example. passing in the amount in the current PaymentGroup.order. By default.commerce. In turn. CREDIT) and creates an XXXInfo object (for example.\ atg.

ProcProcessPaymentGroup. this property points to an object instantiated from a class that implements the atg. transactionId.commerce. errorMessage. using the CreditCard payment method as an example. creditCardProcessorChain is composed of two processors.Configuring Purchase Process Services . The specific object used to perform the actual operations is retrieved from PaymentManager. and credits a CreditCard PaymentGroup by calling through to a CreditCardProcessor object to perform the actual operations.µ • • • • • PaymentGroup ATG Commerce Programming Guide Payment amount Action (PaymentManagerAction.creditCardProcessor. then create 356 11 . Like all of the default payment pipelines. The PaymentStatus object is discussed in more detail at the end of this section. and the InvoiceRequest payment method (ATB Business Commerce only) works in the same fashion.CreditCardProcessor interface. write a new class that implements the CreditCardProcessor interface and provides the additional functionality your site requires. credit. the method performs the payment operation and then adds a PaymentStatus object to the given PaymentGroup. CreditCardInfo) for use in that action. As described in the previous section.CREDIT. When the PaymentManager’s authorize/credit/debit method is called. This section provides information on how to extend the way payment operations work for a given payment method.aggregates the necessary information for performing the requested payment action (for example. the GiftCertificate payment method. and it is instantiated from class atg.DEBIT) Generic Info object (for example. The process to extend the payment operations of the StoreCredit payment method. The first processor – CreateCreditCardInfo -.payment.creditCard. the PaymentManager. For information about the Fulfillment system. or PaymentManagerAction. debiting. you may have an unusual credit operation that you want to perform on credit cards. The ProcessCreditCard processor authorizes. or debit transaction performed by the pipeline. To change the way credit cards are operated on. debits.commerce. or crediting the appropriate payment method. The second processor – ProcessCreditCard --performs the actual operation – authorizing. and transactionTimestamp.processor. For example. PaymentManagerAction.payment. which extends atg.AUTHORIZE. CreditCardInfo and GiftCertificateInfo)) PaymentStatus The PaymentStatus object represents the results of the authorize. CREDIT) and creates an XXXInfo object (for example. it contains properties such as amount.ProcProcessCreditCard. The ProcessCreditCard processor is located in Nucleus at /atg/commerce/payment/processor/ProcessCreditCard. transactionSuccess. Note: The PaymentManager is also used by the Fulfillment system. Extending the Payment Operations of a Payment Method Sometimes you may find that you need to extend the way a given payment operation works.processor.payment.properties file at /atg/commerce/payment/PaymentManager is configured to map CreditCard objects to the creditCardProcessorChain pipeline. see the Configuring the Order Fulfillment Framework chapter.

See Integrating the New Payment Processors into the PaymentManager. 3. customers earn store points when they purchase items. and credits. you can extend the payment process to support a new payment method. using an example called the StorePoints payment method. GiftCertificate. and finally change the PaymentManager. The following diagram shows the relationships between the objects involved in processing a payment transaction. StoreCredit.Configuring Purchase Process Services .ATG Commerce Programming Guide µ and configure an instance of the new class in Nucleus. and they can later redeem those points on other purchases. This section provides information on how to create and support a new payment method. See Creating a New PaymentGroup. Create a new repository item type for the StorePointsPaymentGroup. Detailed instructions are provided in the referenced subsections that follow. 4. and configure the PaymentManager to invoke it when appropriate. 1. Implement the payment processors involved in operating on the StorePoints PaymentGroup. In this example. The StorePoints system is implemented using the following basic steps. 357 11 . The StorePoints system is just one example of the many new payment methods you can implement. Extend the Order validation process to validate the StorePoints PaymentGroup during checkout. See Implementing Processors for the New PaymentGroup. by default the CreditCard. Define the pipeline that processes the StorePoints PaymentGroup for authorization. and InvoiceRequest (ATG Business Commerce only) systems are provided. 2. Associate the new item type to the new class by adding an entry to the beanNameToItemDescriptorMap property of the OrderTools component. See Integrating a New Commerce Object: Using a New Item Descriptor.creditCardProcessor property to point to the new component. In ATG Commerce. Extending the Payment Process to Support a New Payment Method If your site requires it. 5. See Extending Order Validation to Support New Payment Methods in the next section. debits. Create the new StorePoints PaymentGroup. Add the new class to the paymentTypeClassMap.

Configuring Purchase Process Services . import atg.order.*. package store. The following code sample is an example of the StorePoints PaymentGroup. 358 11 .commerce. public class StorePoints extends PaymentGroupImpl { public StorePoints() { } public String getUserId() { return (String) getPropertyValue("userId"). The new PaymentGroup allows you to distinguish StorePoints from other payment groups and to store data relating to the store points system.some.µ CreditCardInfo CreditCardStatus GiftCertificateInfo ATG Commerce Programming Guide CreditCardProcessor Custom Code External Credit Card Processing System GiftCertificateProcessor GiftCertificateStatus Custom Code Gift Certificate Processing System StoreCreditInfo PaymentGroup PaymentManager StoreCreditStatus StoreCreditProcessor Custom Code StoreCredit Processing System InvoiceRequestInfo InvoiceRequestProcessor InvoiceRequestStatus Custom Code InvoiceRequest Processing System StoreCreditInfo StoreCreditProcessor StoreCreditStatus Custom Code StoreCredit Processing System Creating a New PaymentGroup The first step in creating and supporting a new StorePoints payment method is to create a new PaymentGroup named StorePoints.package.

payment. which represents the transaction on the StorePoints PaymentGroup.creditcard.payment.ProcCreateCreditCardInfo) and the ProcessCreditCard processor (class atg.*. import atg.payment. } public void setNumberOfPoints(int pNumberOfPoints) { setPropertyValue("numberOfPoints". and credit the StorePoints PaymentGroup. as shown in the following code example. new Integer(pNumberOfPoints)).ATG Commerce Programming Guide µ } public void setUserId(String pUserId) { setPropertyValue("userId". package store.processor. debit. public interface StorePointsProcessor { /** 359 11 . write the StorePointsProcessor interface that defines the authorize().creditCardProcessor. CREDIT) and creates an XXXInfo object (for example. a second pipeline processor to authorize. and a processor that implements a StorePointsProcessor interface and actually performs the payment operations. } public int getNumberOfPoints() { return ((Integer) getPropertyValue("numberOfPoints")).commerce.payment.intValue(). pUserId). For the StorePoints PaymentGroup.commerce. you need to implement similar processors -.processor. the default payment pipelines are composed of two processors. } } Implementing Processors for the New PaymentGroup As previously mentioned.a pipeline processor to create the XXXInfo object for the StorePoints PaymentGroup. which points to an object instantiated from a class that implements the atg.ProcProcessCreditCard). or crediting the appropriate payment method. CreditCardInfo) for use in that action. This object is discussed in more detail later in this section.CreditCardProcessor interface. For example. debit. The specific object used to perform the actual operations is retrieved from PaymentManager. debiting. and credit() methods for the StorePoints PaymentGroup. Note that the authorize.Configuring Purchase Process Services . and credit methods of the StorePointsProcessor interface all return a StorePointsStatus object. The second processor actually performs the operation – authorizing. First. The first processor aggregates the necessary information for performing the requested payment action (for example.package.some. The ProcessCreditCard processor calls through to a CreditCardProcessor object to perform the actual operations. debit(). the creditCardProcessorChain pipeline is composed of the CreateCreditCardInfo processor (class atg.

This should be the object * which was returned from debit(). StorePointsProcessorImpl must work with the resources needed to 360 11 .Configuring Purchase Process Services . /** * Credit the amount in StorePoints outside the context of an Order * * @param pStorePointsInfo the StorePointsInfo reference which contains * all the credit data * @return a StorePointsStatus object detailing the results of the * credit */ public StorePointsStatus credit(StorePointsInfo pStorePointsInfo).µ ATG Commerce Programming Guide * Authorize the amount in StorePoints * * @param pStorePointsInfo the StorePointsInfo reference which contains * all the authorization data * @return a StorePointsStatus object detailing the results of the * authorization */ public StorePointsStatus authorize(StorePointsInfo pStorePointsInfo). * @return a StorePointsStatus object detailing the results of the debit */ public StorePointsStatus debit(StorePointsInfo pStorePointsInfo. StorePointsStatus pStatus). write an implementation of the StorePointsProcessor interface named StorePointsProcessorImpl. This should be the object * which was returned from authorize(). /** * Debit the amount in StorePoints after authorization * * @param pStorePointsInfo the StorePointsInfo reference which contains * all the debit data * @param pStatus the StorePointsStatus object which contains * information about the transaction. * @return a StorePointsStatus object detailing the results of the * credit */ public StorePointsStatus credit(StorePointsInfo pStorePointsInfo. /** * Credit the amount in StorePoints after debiting * * @param pStorePointsInfo the StorePointsInfo reference which contains * all the credit data * @param pStatus the StorePointsStatus object which contains * information about the transaction. } Second. StorePointsStatus pStatus).

} /** * This method will obtain the <code>StorePointsInfo</code> object from * the pParams parameter and invoke the {@link #debit<code>debit</code>} * method.getName()). You can assume that StorePointsProcessorImpl extends GenericService and. * 361 11 .Configuring Purchase Process Services . errorMessage. * @return a PaymentStatus object that will detail the authorize details * @exception CommerceException if an error occurs */ public PaymentStatus authorizePaymentGroup(PaymentManagerPipelineArgs pParams) throws CommerceException { StorePointsInfo spi = null. which represents the results of transaction performed by the pipeline. For a different custom payment method.getPaymentInfo(). debit. the implementation must work with whatever 3rd-party resources are needed to carry out the transactions. and credit methods of StorePointsProcessorImpl all return a PaymentStatus object. an example of an implementation of the StorePointsProcessor interface. transactionSuccess. } catch (ClassCastException cce) { if (isLoggingError()) logError("Expecting class of type StorePointsInfo but got: " + pParams. throw cce. The following code sample is taken from the StorePointsProcessorImpl class. therefore. /** * This method will obtain the <code>StorePointsInfo</code> object from * the pParams parameter and invoke the * {@link #authorize<code>authorize</code>} method. } return authorize(spi). if the customer’s points data are stored in a database table. and transactionTimestamp. transactionId.ATG Commerce Programming Guide µ carry out the transactions. then its methods must operate against that table.getClass(). try { spi = (StorePointsInfo)pParams. For example. Note in the code sample that the authorize. It is discussed in more detail later in this section. can use standard ATG Commerce logging calls.getPaymentInfo(). * * @param pParams PaymentManagerPipelineArgs object which contains the * StorePointsInfo object. reading and writing values to reflect the operation. Recall that a PaymentStatus object contains properties such as amount.

getPaymentInfo().getPaymentManager(). } catch (ClassCastException cce) { if (isLoggingError()) logError("Expecting class of type StorePointsInfo but got: " + pParams.getName()).Configuring Purchase Process Services . } StorePointsStatus authStatus = null.getPaymentInfo().getLastAuthorizationStatus(pg).getPaymentGroup(). try { authStatus = (StorePointsStatus) pParams.getClass(). } throw cce.getLastAuthorizationStatus(pg). } catch (ClassCastException cce) { if (isLoggingError()) { String authStatusClassName = pParams. authStatus).getN ame(). 362 11 . * * @param pParams PaymentManagerPipelineArgs object which contains the * StorePointsInfo.getClass(). * @return a PaymentStatus object that will detail the debit details * @exception CommerceException if an error occurs */ public PaymentStatus debitPaymentGroup(PaymentManagerPipelineArgs pParams) throws CommerceException { StorePointsInfo spi = null. PaymentGroup and StorePointsStatus object. PaymentGroup pg = pParams. throw cce. try { spi = (StorePointsInfo)pParams. } /** * This method will obtain the <code>StorePointsInfo</code> object from * the pParams parameter and invoke the * {@link #credit<code>credit</code>} method. logError("Expecting class of type StorePointsStatus but got: " + authStatusClassName).getPaymentManager(). } return debit(spi.µ ATG Commerce Programming Guide * @param pParams PaymentManagerPipelineArgs object which contains the * StorePointsInfo and StorePointsStatus objects.

getPaymentInfo().Configuring Purchase Process Services . } catch (ClassCastException cce) { if (isLoggingError()) logError("Expecting class of type StorePointsInfo but got: " + pParams. throw cce. logError("Expecting class of type StorePointsStatus but got: " + debitStatusClassName). By extending ProcProcessPaymentGroup.service.getPaymentManager(). Because the implementation will be called within the context of a pipeline.getPaymentManager(). ATG Commerce provides an abstract class that implements both the PipelineProcessor interface and several other helper methods that determine what action is requested (authorize. This abstract class is atg. try { debitStatus = (StorePointsStatus) pParams. } catch (ClassCastException cce) { if (isLoggingError()) { String debitStatusClassName = pParams. implement a pipeline processor that performs the payment transactions for the StorePoints PaymentGroup by calling through to StorePointsProcessorImpl. try { spi = (StorePointsInfo)pParams. PaymentGroup pg = pParams.PipelineProcessor interface.getPaymentInfo(). You might call this pipeline processor class ProcProcessStorePoints.payment. } throw cce. it must also implement the atg. debitStatus).processor. } StorePointsStatus debitStatus = null.commerce.getClass(). } return credit(spi. debit.getPaymentGroup().ProcProcessPaymentGroup. } Third.getName()).getLastDebitStatus(pg). or credit) and then dispatch to the appropriate method call.getLastDebitStatus(pg).pipeline. you only need to define three abstract methods: 363 11 .getName().getClass().ATG Commerce Programming Guide µ * @return a PaymentStatus object that will detail the credit details * @exception CommerceException if an error occurs */ public PaymentStatus creditPaymentGroup(PaymentManagerPipelineArgs pParams) throws CommerceException { StorePointsInfo spi = null.

public String getUserId() { return mUserId.µ ATG Commerce Programming Guide authorizePaymentGroup(). package store. public class StorePointsInfo { public StorePointsInfo() { } private String mUserId = null. It might hold a user ID (Profile ID) and the number of points for the operation. and finally add the XXXInfo object to the PaymentManagerPipelineArgs Dictionary object.storePointsProcessor would be set StorePointsProcessorImpl. the XXXInfo object might be called StorePointsInfo. In this example. As 364 11 . and the processor that creates it might be called ProcCreateStorePointsInfo. These methods should call through to their respective methods in the StorePointsProcessorImpl object. a previous pipeline processor must aggregate the necessary information for performing the requested payment action. debitPaymentGroup() and creditPaymentGroup(). Recall from the previous code example of StorePointsProcessorImpl that the StorePoints PaymentGroup itself is not passed as a parameter to the StorePointsProcessorImpl processor. passing in the data from the PaymentManagerPipelineArgs object that is supplied as a parameter. create an XXXInfo object for use in that action. before the ProcProcessStorePoints pipeline processor is invoked.Configuring Purchase Process Services . public int getNumberOfPoints() { return mNumberOfPoints. ProcProcessStorePoints should include an additional property named storePointsProcessor that can be set to the StorePointsProcessor object that actually performs the payment operations. } public void setNumberOfPoints(int pNumberOfPoints) { mNumberOfPoints = pNumberOfPoints.some. The Dictionary object is then passed as an argument “downstream” to the ProcProcessStorePoints pipeline processor and on to the StorePointsProcessorImpl processor. } private int mNumberOfPoints = 0. This keeps the payment processors independent of the commerce objects in ATG Commerce. In this StorePoints example. } } Next. Additionally. The following code sample is an example of the StorePointsInfo class.package. } public void setUserId(String pUserId) { mUserId = pUserId. ProcProcessStorePoints. implement the ProcCreateStorePointsInfo processor that must construct the StorePointsInfo object and add it to the PaymentManagerPipelineArgs Dictionary object. The StorePointsInfo object must hold all of the data required by the methods in StorePointsProcessorImpl. Instead.

service. /** * Return the class to instantiate when creating a new StorePointsInfo * object. atg.GenericService.payment.some. * * <p>This processor is designed so that the StorePointsInfo class can * easily be extended. * */ public class ProcCreateStorePointsInfo extends GenericService implements PipelineProcessor { /** The possible return value for this processor.order.package.PipelineProcessor interface because the implementation will be called within the context of a pipeline.commerce.pipeline.nucleus.commerce.some.PipelineProcessor.pipeline. import import import import import atg.service. The following code sample is an example of the ProcCreateStorePointsInfo class. **/ public static final int SUCCESS = 1.PipelineResult. atg.pipeline. the ProcCreateStorePointsInfo class must implement the atg.service.getPaymentInfo()</code>. package store. //--------------------------------------------------------------------// property: StorePointsInfoClass String mStorePointsInfoClass = "store.package. atg. See * {@link #setStorePointsInfoClass "<code>setStorePointsInfoClass</code>"} * and * {@link #addDataToStorePoints "<code>addDataToStorePointsInfo</code>"} * for more information.ATG Commerce Programming Guide µ with the StorePointsProcessorImpl class. It places them into the pipeline argument dictionary so * that downstream pipeline processors can retrieve them by calling * <code>PaymentManagerPipelineArgs. 365 11 .*.*.StorePointsInfo". **/ public String getStorePointsInfoClass() { return mStorePointsInfoClass. atg.Configuring Purchase Process Services . /** * This pipeline processor element is called to create generic * StorePointsInfo objects from instances of the StorePoints * payment group.

} //---------------------------------------------------------------------/** * This method populates the <code>StorePointsInfo</code> object with * data.setUserId(pPaymentGroup.Configuring Purchase Process Services . PaymentManagerPipelineArgs pParams. StorePoints pPaymentGroup.setNumberOfPoints(pPaymentGroup. the <code>storePointsInfoClass</code> property can be * changed to specify the new class. * * @param pOrder * The order being paid for. StorePointsInfo pStorePointsInfo) { pStorePointsInfo. **/ public void setStorePointsInfoClass(String pStorePointsInfoClass) { mStorePointsInfoClass = pStorePointsInfoClass. } //---------------------------------------------------------------------/** 366 11 . double pAmount. this property can be changed to reflect the * new class. If the additional data is required. **/ protected void addDataToStorePointsInfo(Order pOrder. a subclass of * <code>StorePointsInfo</code> can be created with additional * properties. debited.µ } ATG Commerce Programming Guide /** * Specify the class to instantiate when creating a new StorePointsInfo * object. and this method can be overridden * to add data for the new properties (or another pipeline processor * could be added after this processor to populate the additional * properties).getNumberOfPoints()).getUserId()). or credited * @param pParams * The parameter dictionary passed to this pipeline processor * @param pStorePointsInfo * An object that holds information understood by the store * points payment processor. pStorePointsInfo. * @param pPaymentGroup * The payment group being processed. * @param pAmount * The amount being authorized. If the <code>StorePointsInfo</code> class is extended to * include more information.

StorePointsInfo spi = (StorePointsInfo) Class. PipelineResult pResult) throws Exception { 367 11 . * * @param pParam * Parameter dictionary of type PaymentManagerPipelineArgs. return spi. * @throws Exception * If any error occurs creating or populating the store points info * object. * @param pResult * Pipeline result object. The class * that is created is that specified by the * <code>storePointsInfoClass</code> property. and must be a subclass * of <code>store.package. * @return * An integer value used to determine which pipeline processor is * called next. populate it with data from a * <code>StorePoints</code> payment group by calling * <code>addDataToStorePointsInfo</code>. **/ public int runProcess(Object pParam.ATG Commerce Programming Guide µ * Factory method to create a new StorePointsInfo object.forName(getStorePointsInfoClass()). not used by this method. and add it to the pipeline * argument dictionary so that downstream pipeline processors can access * it. } //---------------------------------------------------------------------/** * Generate a StorePointsInfo object of the class specified by * <code>StorePointsInfoClass</code>.some.StorePointsInfo</code> * * @return * An object of the class specified by * <code>storePointsInfoClass</code> * @throws Exception * if any instantiation error occurs when creating the info object **/ protected StorePointsInfo getStorePointsInfo() throws Exception { if (isLoggingDebug()) logDebug("Making a new instance of type: " + getStorePointsInfoClass()).newInstance().Configuring Purchase Process Services .

PaymentStatus Property transactionId Type String Description A unique ID for the transaction that is generated by the payment processor. amount. Order order = params.getAmount().payment. } This processor As previously mentioned. it adds it to one of the authorizationStatus. * always returns a success code. if (isLoggingDebug()) logDebug("Putting StorePointsInfo object into pipeline: " + spi.getOrder().getPaymentGroup(). the StorePointsStatus object represents a transaction on a StorePoints PaymentGroup. you should extend PaymentStatusImpl. addDataToStorePointsInfo(order. storePoints. all operations must return an object that implements the PaymentStatus interface.setPaymentInfo(spi). debitStatus. When the PaymentManager gets this object. spi). The following table describes the properties in the PaymentStatus interface. or creditStatus List objects in the PaymentGroup. Therefore.Configuring Purchase Process Services . 368 11 . Because none of the StorePointsProcessor methods throw exceptions. as PaymentStatusImpl does. which implements the atg. StorePoints storePoints = (StorePoints)params. **/ public int[] getRetCodes() { int retCodes[] = {SUCCESS}. The specific list to which it is added depends on the operation. } //---------------------------------------------------------------------/** * Return the possible return values for this processor. return SUCCESS. // create and populate store points info class StorePointsInfo spi = getStorePointsInfo(). params. double amount = params.toString()). params. Follow the steps in Extending the Purchase Process to ensure that objects are persisted properly. return retCodes.PaymentStatus interface. when you implement StorePointsStatus.µ ATG Commerce Programming Guide PaymentManagerPipelineArgs params = (PaymentManagerPipelineArgs)pParam.

Creating the Pipeline To create the pipeline that creates the StorePointsInfo objects and performs actions on the StorePoints PaymentGroup: 369 11 . and credits. } } Integrating the New Payment Processors into the PaymentManager Integrating the new payment processors that you created in step 2 for the StorePoints PaymentGroup. } public void setConfirmationNumber(String pConfirmationNumber) { mConfirmationNumber = pConfirmationNumber. False indicates that it failed. The most important property is transactionSuccess. True indicates that the transaction succeeded.*. debits. public String getConfirmationNumber() { return mConfirmationNumber. A detailed error message about the failure. then an exception is thrown with the message in the errorMessage property. The time that the transaction was executed. Configure the PaymentManager to invoke the pipeline when an operation is requested on a StorePoints PaymentGroup.ATG Commerce Programming Guide µ The amount of the transaction.payment. This involves two steps: 1. See the sections that follow for details.Configuring Purchase Process Services . public class StorePointsStatus extends PaymentStatusImpl { public StorePointsStatus() { } private String mConfirmationNumber = null. package store. 2. Indicates whether the transaction was successful.some. If transactionSuccess is false. amount transactionSuccess double boolean errorMessage transactionTimestamp String Date Below is an example of the StorePointsStatus class.package. All properties in this object must have values. import atg. Create the pipeline that creates StorePointsInfo objects and processes the StorePoints PaymentGroup for authorization.

package.some.StorePointsProcessorImpl $scope=global 4. To do this.ProcCreateStorePointsInfo $scope=global storePointsInfoClass=store. To do this.StorePointsInfo 2. To create a Nucleus component located at /store/payment/StorePointsProcessor. It also creates the StorePointInfo object--> <pipelinechain name="storePointProcessorChain" transaction="TX_REQUIRED" headlink="createStorePointInfo"> <pipelinelink name="createStorePointInfo" transaction="TX_MANDATORY"> <processor jndi="/store/payment/processor/CreateStorePointInfo"/> <transition returnvalue="1" link="processStorePoints"/> 370 11 . and credit the StorePoints payment method.xml. Configure a pipeline processor to authorize.Configuring Purchase Process Services .package.storePointsProcessor property is set to the StorePointsProcessor object that actually performs the payment operations. place the following properties file into Nucleus at that path: $class=store. create a paymentpipeline. Define the storePointsProcessorChain pipeline and add it to the pipelines used by the /atg/commerce/payment/PaymentPipelineManager.This single chain knows how to auth/credit/debit a --> <!-. create a Nucleus component for the ProcProcessStorePoints object. To create a Nucleus component located at /store/payment/processor/CreateStorePointsInfo. To do this.xml file in Nucleus at /atg/commerce/payment/paymentpipeline. The following is a code example of the storePointsProcessorChain pipeline: <pipelinemanager> <!-. 3. place the following properties file into Nucleus at that path: $class=store. ATG Commerce Programming Guide Configure a pipeline processor to create the StorePointsInfo object. create a Nucleus component for the ProcCreateStorePointsInfo object. This is the object that actual performs the payment operations on the StorePoints payment method.This chain is used to process a store point payment group--> <!-. it would be set to the StorePointsProcessorImpl Nucleus component.package.some.some.ProcProcessStorePoints $scope=global storePointsProcessor=/store/payment/StorePointsProcessorImpl Note that the ProcessStorePoints. This XML file should define the single pipeline that operates on StorePoints PaymentGroups. Create a Nucleus component for the StorePointsProcessorImpl object. ProcessStorePoints calls through to this object to perform the operations.payment group. place the following properties file into Nucleus at that path: $class=store.µ 1. To create a Nucleus component located at /store/payment/processor/ProcessStorePoints. In this example.package.some. debit. it will be combined with the existing XML definition of payment pipelines using XML file combination.

some. for the StorePoints payment method you might want to make sure that the number of points specified is greater than zero. you need to add a new entry to PaymentManager.package. which is defined in commercepipeline.ATG Commerce Programming Guide µ </pipelinelink> <pipelinelink name="processStorePoints" transaction="TX_MANDATORY"> <processor jndi="/store/payment/processor/ProcessStorePoints"/> </pipelinelink> </pipelinechain> </pipelinemanager> Configure the PaymentManager to Invoke the StorePointsProcessorChain To configure the PaymentManager to invoke the storePointsProcessorChain pipeline when an operation is requested on a StorePoints PaymentGroup. To add a new entry to PaymentManager. Credit cards are checked by one processor. The paymentGroupToChainNameMap property stores a mapping of PaymentGroup class names to the names of the pipelines to invoke when an operation for those PaymentGroups is requested. and that store points may not be used to pay for more than 25% of the order price. You might also want to include other validation logic – for example. The new configuration file would be located in Nucleus at /atg/commerce/payment/PaymentManager and would look like the following: PaymentGroupToChainNameMap+=Store. You can test all of these conditions in a custom validation component for the StorePoints payment group. layer on a configuration file that makes an additional entry to the paymentGroupToChainNameMap property.paymentGroupToChainNameMap. Adding validation for your new payment method involves four steps: 371 11 . you might decide that users cannot apply more than 500 store points to any order.Configuring Purchase Process Services . When a user checks out an Order.StorePoints=storePointsProc essorChain Extending Order Validation to Support New Payment Methods Note: You can also follow this process to extend shipping group validation. store credits by still another. If you have implemented a custom payment method. The validateForCheckout pipeline includes a ValidatePaymentGroupsForCheckout processor. such as the StorePoints payment method described in detail in the previous section. For example. You can add your own pipeline processor to check the custom payment groups that you create. you may want to perform validation on the custom payment method during checkout. The validatePaymentGroup pipeline begins with a processor that examines the type of the current PaymentGroup and transfers control to a pipeline processor appropriate to that type. which iterates over the payment groups in the Order and calls the validatePaymentGroup pipeline for each one to verify that the payment group is ready for checkout. the ATG Commerce purchase process performs validation checks on all of the payment groups in the Order by executing the validateForCheckout pipeline. gift certificates by another.paymentGroupToChainNameMap.xml.

Step 4: Add the custom payment method to the validatePaymentGroup pipeline.payment. } /** 372 11 . import import import import atg. private static int[] RETURN_CODES = { SUCCESS_CODE }.nucleus.pipeline.pipeline. A validation processor for StorePoints might look similar to the following: package store. This processor always returns a single value * indicating success.checkout. Step 3: Add the custom payment method to the ValidatePaymentGroupByType processor.processor.µ ATG Commerce Programming Guide Step 1: Implement a validation pipeline processor.*. **/ public int[] getRetCodes() { return RETURN_CODES. atg. Step 2: Create an instance of the processor.service. In case of errors. public class ValidateStorePoints extends GenericService implements PipelineProcessor { private static int SUCCESS_CODE = 1. /** * Return the list of possible return values from this * processor. using the StorePoints payment group that you created in the previous section as an example.commerce.service. Step 1: Implement a validation pipeline processor The first step in validating your custom payment method is to write a pipeline processor that examines a payment group and determines whether it meets the criteria for use in the Order.PipelineProcessor. public int runProcess(Object pParam. PipelineResult pResult) throws Exception. store. Recall that your processor must implement the interface atg.ValidatePaymentGroupArgs.StorePoints.Configuring Purchase Process Services . This subsections that follow describe each step in detail. which consists of two methods: • • public int[] getRetCodes(). it adds messages * to the pipeline result object.order.GenericService. atg.

373 11 . "A maximum of 500 points can be used per order.getNumberOfPoints(). try { StorePoints points = (StorePoints)pg."). Order order = args. // Log some debugging info about the number of points // and the total order price.getTotal().getPaymentGroup(). args = (ValidatePaymentGroupPipelineArgs)pParam. int nPoints = points. "The number of points should be greater than zero. add an error to the pipeline result so the order manager will abort the checkout process. PaymentGroup pg = args.addError( "NoPointsUsed"."). If the payment group is of the wrong type. double orderPrice = order.ATG Commerce Programming Guide µ * Perform validation for a StorePoints payment group.25) pResult. else if (nPoints > 500) pResult. if (nPoints <= 0) pResult.addError( "PointsValueExceeded".Configuring Purchase Process Services ."). add an error // to the pipeline result before returning.getOrder(). PipelineResult pResult) { ValidatePaymentGroupPipelineArgs args. or if anything else goes wrong. if (isLoggingDebug()) logDebug("Applying " + nPoints + " store points " + " to an order totaling " + orderPrice).getPriceInfo(). "Store points cannot pay for more than 25% of an order.addError( "TooManyPointsUsed". // // // // // Now try casting the payment group to the type we expect and validating the fields. **/ public int runProcess(Object pParam. // Are we using more than 500 points or trying to pay // for more than 25% of the order? If so. else if (nPoints > orderPrice * . // Dynamo guarantees that the pipeline parameter object // passed to a payment group validation processor will be // of type ValidatePaymentGroupPipelineArgs.

but got " + pg.getName() + " instead.").Configuring Purchase Process Services . which examines the type of each payment group and returns an Integer that identifies the payment method. The pipeline then dispatches control to one of a number of different processors based on this return code. } return SUCCESS_CODE. When the OrderManager validates payment groups. This example uses a value of 10. For the StorePoints example. and the server’s Locale from the pipeline parameter map. and it is configured with the following properties file: # Store Points validation processor $class=store.addError( "ClassNotRecognized". The validatePaymentGroup pipeline begins with a pipeline processor called ValidatePaymentGroupByType. it guarantees that the pipeline arguments passed to your processor are an instance of this class. the validation processor might be located at /store/checkout/ValidateStorePoints.getClass(). You can use any return value as long as it isn’t used by any other payment method. This provides you with a convenient way to retrieve items like the Order.checkout. you must configure an instance of the processor in Nucleus.ValidateStorePoints loggingDebug=true In this simple example the processor doesn’t require any additional property settings. the PaymentGroup. which maps your payment method’s name (storePoints in this example) to a unique return value. Step 2: Create an instance of the processor After implementing your pipeline processor. Configure the property by creating a file as follows in localconfig/atg/commerce/order/processor/ValidatePaymentGroupByType. you must add an entry to ValidatePaymentGroupByType’s returnValues property. the OrderManager.properties: # Add a return code for the storePoints payment method returnValues+=\ storePoints=10 374 11 . "Expected a StorePoints payment group. Step 3: Add the custom payment method to the ValidatePaymentGroupByType processor Recall that payment groups are validated at checkout by invoking the validatePaymentGroup pipeline for each payment group in the order. } } Note the use of the ValidatePaymentGroupPipelineArgs class in the runProcess() method.µ ATG Commerce Programming Guide } catch (ClassCastException cce) { pResult. To add support for your payment method.

Modify the validatePaymentGroup chain to include --> <!-. but it has a state of TEMPLATE. add a new transition tag to the dispatchOnPGType pipeline link in order to specify the pipeline link to use when ValidatePaymentGroupByType returns a value of 10. or to construct and save orders to be placed at a later date. 375 11 . Modify the pipeline using the following code in localconfig/atg/commerce/commercepipeline. and a template Order object maintains the order information for the scheduled order. define the new pipeline link and configure it to invoke your ValidateStorePoints component. the template order is cloned. Step 4: Add the custom payment method to the validatePaymentGroup pipeline The final step in adding validation for your StorePoints payment method is to reconfigure the validatePaymentGroup pipeline so it invokes the ValidateStorePoints processor when ValidatePaymentGroupByType returns a value of 10. the template Order is never processed. a scheduled Order object (of type scheduledOrder) maintains the schedule information for the scheduled order. and the cloned order is checked out and sent to Fulfillment. The template Order object is a typical Order in the orderRepository.ATG Commerce Programming Guide µ Note that the payment method name. When a scheduled order is placed.validation for payment groups of type storePoints --> <pipelinemanager> <pipelinechain name="validatePaymentGroup"> <pipelinelink name="dispatchOnPGType"> <transition returnvalue="10" link="validateStorePoints"/> </pipelinelink> <pipelinelink name="validateStorePoints"> <processor jndi="/store/checkout/ValidateStorePoints"/> </pipelinelink> </pipelinechain> </pipelinemanager> ATG Commerce will now perform validation on your StorePoints payment method. You can do both steps using XML combination facilities. This requires two changes to the pipeline configuration. it is not the name of your payment group’s implementation class. Second.xml: <!-. Consequently. storePoints. First. In ATG Commerce. is the name you added to the paymentTypeClassMap in the OrderTools component. Scheduling Recurring Orders Sites often require the functionality to create orders to be fulfilled repeatedly on a specific schedule. You can use ATG Commerce to support these requirements through the use of scheduled orders.Configuring Purchase Process Services . but simply serves as a prototype.

Modifying. A string describing the Order’s placement schedule. stored in the Order Repository. The profile ID of the user who created the scheduled Order. as well as extra information as defined by the scheduledOrder item descriptor (for example. By default. The date and time that the scheduled Order becomes inactive. name and state). and Deleting Scheduled Orders For an example implementation of scheduled orders. This section describes the ATG Commerce framework that supports scheduled orders and includes the following subsections: Understanding the scheduledOrder Repository Item Submitting Scheduled Orders Creating. The date and time that the scheduled Order becomes active.Configuring Purchase Process Services . The state of the scheduled Order (active. a scheduledOrder repository item contains the following properties: Property name profileId templateOrderId Description The name that the user has assigned to the scheduled Order. see the Scheduling Orders section of the My Account chapter in the ATG Business Commerce Reference Application Guide. Understanding the scheduledOrder Repository Item The scheduled Order objects. the scheduled Order is repeatedly placed indefinitely. The ID of the template Order that is cloned whenever the scheduled order is placed. The date and time that the scheduled Order was created. The next date and time that the scheduled Order should be placed. inactive. or error). such as all necessary shipping and payment information. A previously processed order or even the user’s shopping cart (once the shipping and payment information has been specified) can be used to create a template order. state clonedOrders schedule nextScheduledRun createDate startDate endDate 376 11 .µ ATG Commerce Programming Guide Template orders must include enough information. The list of scheduled orders that have been placed. Note: If unset. to process the cloned Order without further user interaction. maintain the schedule information for scheduled orders. The scheduledOrder item descriptor is defined in /<ATG9dir>/B2BCommerce/atg/commerce/order/orderRepository. These Orders are clones of the template Order that have been checked out.xml.

and sets the nextScheduledRun property of the scheduled Order to the next date and time it should be checked out. the ScheduledOrderService. For each scheduled Order it finds due for checkout.Configuring Purchase Process Services . maxThreads Submitting Scheduled Orders The ScheduledOrderService is the back-end service that polls the Order Repository at a periodic interval and submits scheduled Orders according to their schedules. The ScheduledOrderService then attempts to obtain a global write lock from the server lock manager. the Scheduler calls ScheduledOrderService.ATG Commerce Programming Guide µ id type Version The ID of the scheduled Order object.performScheduledTask(). checks out the cloned Order. The following table describes the various methods of ScheduledOrderService that support this process: 377 11 .schedule. By setting the parameter maxThreads to a number greater than 1. At a general level. This is set to scheduledOrder. then it calls doScheduledTask(). the remaining scheduled Orders are processed. A read-only property. The optimal number of threads depends on a variety of factors. A value used to protect against data corruption that might be caused if two users attempt to edit this repository item at the same time.doScheduledTask() method polls the Order Repository for all scheduled Orders that should be checked out. If an error occurs when processing an individual scheduled Order. including server load. you can specify the number of threads that are started to process scheduled orders. a PlaceScheduledOrders task is scheduled with the /atg/dynamo/service/Scheduler. The system updates this read-only property automatically. The type of repository item. then a CommerceException is thrown. When the scheduled task is run. The current implementation of the scheduled order service can be configured to employ multiple threads when placing orders. machine and database speed and the complexity of the scheduled order templates. If the lock is obtained successfully. the state of the scheduled Order is set to Error. and the state of the cloned Order is set to PENDING_MERCHANT_ACTION. However. This scheduled task is run at the interval specified in ScheduledOrderService. When an application that includes ATG Commerce deploys. all orders will be processed in the main thread. it then clones the template Order associated with the scheduled Order. If the maxThreads parameter is kept at the default of 1.

When this method is called. It then iterates through the array and calls processDueScheduledOrder() on each scheduled Order. 378 11 . Therefore. and if the schedule property of a given scheduled Order is set to “every 12 hours. the ATG Commerce server is redeployed every 11 hours. the ScheduledOrderService attempts to obtain a global write lock from the server lock manager. The method returns an array of scheduled Orders that need to be checked out.” For information on how to specify a schedule. Note: Be aware that the defined interval specified in ScheduledOrderService. set to scheduledOrder). it is recommended that you set it to “every 1 day. as a general rule.Configuring Purchase Process Services . This method calls pollForNewOrders() to retrieve the list of scheduled Orders that need to be checked out. If the lock is obtained successfully.) processDueScheduledOrders pollForNewOrders Uses the query defined in the ScheduledOrderService. Other objects can call this method to trigger on demand a poll of the Order Repository for due scheduled Orders. The placeScheduledOrders task is run at the interval defined in ScheduledOrderService.schedule begins when an application that includes ATG Commerce deploys.pollQuery property to poll the Order Repository defined in the ScheduledOrderService. doScheduledTask Calls processDueScheduledOrders() to process any scheduled Orders that need to be checked out.µ Method performScheduledTask ATG Commerce Programming Guide Description Called when the Scheduler finds that the placeScheduledOrders task is scheduled to run. While the schedule that you set depends on the business needs of your site.” then the scheduled Order is never placed. for example.schedule. see the Scheduler Services section of the Core Dynamo Services chapter in the ATG Programming Guide.orderRepository property with the repository view defined in the itemDescriptorName property (by default. if. (See the methods described later in this table for details. Processes all scheduled Orders that need to be checked out. the ScheduledOrderService calls its own doScheduledTask() method.

ScheduledOrderTools. If the scheduled Order is successfully checked out. (For more information on the updateOrder pipeline. it is passed on to Fulfillment.cloneOrder(). then it rolls back to its original state. if the ScheduledOrderTools. The pipeline to execute is set in ScheduledOrderTools. Second. the template Order is retrieved by calling ScheduledOrderTools. This method calls placeScheduledOrder() to check out the scheduled Order.updateOrder(). Third. see Updating an Order with the Order Manager in this chapter. Fourth. which in turn calls OrderManager.processOrderChainId. then the cloned order is repriced by calling ScheduledOrderTools. When the order placeScheduledOrder has been checked out successfully.Configuring Purchase Process Services .getTemplateOrder() and passing in the current scheduled Order.UseOrderPriceListsFirst identifies if price list information should be extracted from an order template. see Checking Out an Order in this chapter.) Finally.repriceOnClone property is set to True. This method checks out the current scheduled Order using the following process: First.processScheduledOrder(). The default is false. (For more information on the processOrder pipeline.ATG Commerce Programming Guide µ Processes the current scheduled Order.) 379 11 . which executes the updateOrder pipeline. then the method calls getNextScheduledRun() to set its nextScheduledRun property to the next date and time that it should be checked out. the cloned Order is checked out by calling ScheduledOrderTools. the template Order is cloned by calling ScheduledOrderTools.repriceScheduledOrder(). If the scheduled Order fails to be checked out. by default.processOrder() and passes in the cloned Order and pipeline to execute. Fifth. this property is set to processOrder. the cloned Order is saved to the Order Repository in its present state by calling OrderManager. It will be retrieved again for processing the next time that pollForNewOrders() is executed. processDueScheduledOrder getNextScheduledRun Sets the next time that the scheduled Order should be checked out.

which extends atg. the startDate and endDate properties in the value Dictionary are both mapped to Year. namely remapValueFromScheduledOrder() and remapValueFromUserInputField(). such as name and state. which extends atg. deleting. This provides a degree of protection from server failures. activating.b2bcommerce.µ repriceScheduledOrder ATG Commerce Programming Guide Reprices the cloned Order. The ScheduledOrderFormHandler. you must run a server lock manager and point all client lock managers at it. It is located in Nucleus at /atg/commerce/order/scheduled/ScheduledOrderFormHandler. and deactivating scheduled orders.scheduled. (For more information on the repriceOrder pipeline. ATG Commerce provides an instance of atg.service. It is located in Nucleus at /atg/commerce/order/scheduled/ScheduledOrderService.SingletonSchedulableService.repriceOrderChainId.order. other complex properties map to a large number of user input fields. A scheduled Order has some complex properties that are incapable of being mapped directly from the user interface to the value Dictionary defined in the RepositoryFormHandler (of which ScheduledOrderHandler is a subclass). Similarly.scheduler.ComplexScheduledOrderProperty or one of its subclasses. For example.scheduled. The repriceScheduledOrder() method calls ScheduledOrderTools. while guaranteeing that only one instance of the service will perform the scheduled task at any given time. To use a SingletonSchedulableService like ScheduledOrderService on multiple ATG Commerce instances.scheduler. see the Scheduler Services section of the Core Dynamo Services chapter in the ATG Programming Guide. Date.service.Configuring Purchase Process Services .) ATG Commerce provides an instance of class atg. Month. Simple properties. the schedule property maps to a large number of input fields.repository. For more information on SingletonSchedulableService. and Hour input fields.servlet. can be handled by the superclass RepositoryFormHandler. and Deleting Scheduled Orders The ScheduledOrderHandler is responsible for creating. Creating. updating.order.scheduled. this property is set to repriceOrder.SingletonSchedulableService enables multiple ATG Commerce servers to run the same scheduled service. The keys to the Map are the names of the 380 11 . Each property of a scheduled Order that maps to more then one form element or needs special processing is represented by an instance of the abstract class atg. see the Commerce Processor Chains section. The ComplexScheduledOrderProperty class has two methods that facilitate the mapping between the property in the value Dictionary and the corresponding user input fields in a form. which executes the repricing pipeline specified in ScheduledOrderTools.ScheduledOrderHandler.order.RepositoryFormHandler.repriceScheduledOrder(). since the loss of any single ATG Commerce server will not prevent the scheduled service from running on some other ATG Commerce server.complexScheduledOrderProperties property is a Map that specifies the complex properties in the scheduled Order.commerce. Class atg.b2bcommerce. However. Modifying.ScheduledOrderService. By default.

the existing Order is copied.\ endDate=atg.scheduled.\ templateOrderId=atg.order. When the user later views the scheduled Order. ScheduledOrderInfo can provide a reference to scheduled objects. the scheduled order item and a readable string representation of the schedule.order. this property loads the associated template Order represented by the templateOrderId. The following table describes the important handle methods of ScheduledOrderFormHandler: 381 11 .scheduled. and the new template Order is assigned a new ID.b2bcommerce. The templateOrderId property contains a reference to the repository ID of the new template Order. Once a scheduled order template has been modified.scheduled.order.ATG Commerce Programming Guide µ complex properties.scheduled.DateProperty.b2bcommerce. When a user designates an existing Order as a template Order.ScheduledOrderHandler $scope=session #From RepositoryFormHandler itemDescriptorName=scheduledOrder repository=/atg/commerce/order/OrderRepository requireIdOnCreate=false clearValueOnSet=true #From ScheduledOrderFormHandler localeService=/atg/userprofiling/LocaleService profile=/atg/userprofiling/Profile orderManager=/atg/commerce/order/OrderManager transactionManager=/atg/dynamo/transaction/TransactionManager scheduledOrderTools=ScheduledOrderTools complexScheduledOrderProperties=\ calendarSchedule=atg. template ID (templateId) or profile ID (profileId).CalendarSchedu leProperty.Configuring Purchase Process Services . Output parameters include scheduledOrders and count. which extends ComplexScheduledOrderProperty.order. Output parameters to ScheduledOrderInfo are scheduledOrderItem. Scheduling information can be displayed in different formats. ScheduledOrderLookup can be used to provide information on scheduled orders for a scheduled order ID (itemId).b2bcommerce. readableSchedule and schedule.\ startDate=atg.DateProperty.TemplateOrderProperty Note that the templateOrderId property is represented by the TemplateOrderProperty class. as shown in the following ScheduledOrderFormHandler. Using a scheduled order item or ID.properties file: $class=atg. and the values are the names of the classes that represent those properties.order.scheduled.b2bcommerce.b2bcommerce.

see the Using Repository Form Handlers chapter of the ATG Page Developer’s Guide.name" type="text"/><br> <dsp:input bean="ScheduledOrderHandler. It then populates the value Dictionary with the properties and finally remaps all the complex properties from the Order Repository to the user interface.µ Method handleRepositoryId ATG Commerce Programming Guide Description Called when the user wants to review or update a scheduled Order. handleVerify Called when the user wants to review the input data for the scheduled Order before it is created in the Order Repository. (For more information on using the RepositoryFormHandler.update" value="update name" type="submit"/> </dsp:form> Complex properties of the scheduled Order are set according to the configuration of ScheduledOrderFormHandler.complexScheduledOrderProperties property. and nextScheduledRun can all be set in the following manner: <dsp:form action="setName. Inactivates an existing scheduled Order in the Order Repository by changing the state of the Order from ACTIVE to INACTIVE. using the month in the startDate as an example: 382 11 . Using the scheduledOrderFormHandler is very similar to using the RepositoryFormHandler. Deletes an existing scheduled Order from the Order Repository. This method validates the submitted values.value. Activates an existing scheduled Order in the Order Repository by changing the state of the Order from INACTIVE to ACTIVE.) Simple properties like name. Updates an existing scheduled Order in the Order Repository. The method retrieves all of the property values for the scheduled Order with the ID set in ScheduledOrderFormHandler.repositoryId. This method is called before the user interface is rendered to the user.properties file above. the startDate and endDate complex properties of a scheduled Order are represented by the DateProperty class. Creates a scheduled Order in the Order Repository. throwing a form exception if one is invalid. The following JSP example illustrates how to change these properties. state.jsp"> new name : <dsp:input bean="ScheduledOrderHandler. As shown in the ScheduleOrderFormHandler. handleCreate handleUpdate handleDelete handleRemove handleRestore Note that the ScheduledOrderFormHandler uses ScheduledOrderTools to fire events for all of the actions that are associated with these handle methods.Configuring Purchase Process Services .

<dsp:option value="biMonthly"/>every two months. the schedule property is represented by a PeriodicSchedule. the frequency of a schedule whose scheduledMode is Monthly is updated: <dsp:form action="setSchedule. A PeriodicSchedule specifies a task that occurs at regular intervals (for example.ATG Commerce Programming Guide µ <dsp:form action="setStartDateMonth. • atg.complexScheduledOrderMap. In this example. The following JSP example illustrates how to change the schedule property. every 10 seconds in 20 minutes without catch up). userInputFields.update" value="update month" type="submit"/> </dsp:form> You can modify the schedule property of a scheduled Order in a similar manner.commerce.order. A CalendarSchedule specifies a task that occurs according to units of the calendar and clock (for example. the schedule property is represented by a CalendarSchedule.CalendarScheduleProperty If used.scheduled. at 2:30 AM on the 1st and 15th of every month).jsp"> … <dsp:select bean="ScheduledOrderFormHandler.jsp"> New start month : <dsp:input bean="ScheduledOrderFormHandler. and the schedule property is mapped to the user input form fields used by the PeriodicSchedule. <dsp:option value="quarterly"/>every quarter. and the schedule property is mapped to the user input form fields used by the CalendarSchedule.startDate.value. Two classes in package atg.order. </dsp:select> … <dsp:input bean="ScheduledOrderFormHandler.order.month" type="text"/> <br> <dsp:input bean="ScheduledOrderFormHandler.commerce.commerce.scheduleMode" size="1" name="select"> <dsp:option value="onceMonthly"/>once a month.Configuring Purchase Process Services .calendarSchedule.PeriodicScheduleProperty If used.update" value="Update" type="submit"/> </dsp:form> 383 11 .scheduled.scheduled can represent the schedule property of a scheduled Order: • atg.

see the Scheduler Services section of the Core Dynamo Services chapter in the ATG Programming Guide.expression: • • • • Rule.size != 1000 384 11 .id = null Order.ExpressionParser class is used to parse expressions. ProcPropertyRestriction.expression. a given item might be prohibited from sale in certain locations. or you may want to designate some items as requiring approval for purchase.shippingInfo.expression. or you may want to ensure that customers order a minimum quantity of a given item. which evaluates the expression to either to True or False.commerce. ExpressionParser supports the following operators: =. The ExpressionParser. which together are evaluated to either True or False.parseExpression() method takes a string containing an expression to parse.Rule class represents a rule. ExpressionParser The atg. ExpressionParser. !=.amount > Profile. The functionality for this Order restriction system relies on the following ATG Commerce classes in package atg. RuleEvaluator. see the ATG API Reference.priceInfo. It does not support & (and) or | (or). Rule The atg.Configuring Purchase Process Services . which parses the expression (rule). thereby setting restrictions on certain kinds of orders. which evaluates the rule using the ExpressionParser and RuleEvaluator. This section describes the order restriction system in ATG Commerce and includes the following subsections: Understanding the Order Restriction Classes Implementing Order Restrictions Understanding the Order Restriction Classes You set restrictions on Orders by specifying the criteria or “rules” that an Order must meet if it is to be placed.commerce.commerce. You can use ATG Commerce to specify criteria that orders must meet if they are to be placed. and containsKey.maxAmountAllowed Profile. In some situations you may want to prevent an order from being placed. contains.µ Setting Restrictions on Orders ATG Commerce Programming Guide For more information on CalendarScheduleProperty and PeriodicScheduleProperty. which represents the rule. <. A Rule object contains RuleExpressions (operands) and an operator. For example. >=.specialInstructions. such as the following: Order. >. <=.approvalRequired = true Order. For more information on CalendarSchedule and PeriodicSchedule.

ExpressionParser for its use. The RuleEvaluator class supports all primitive data types in Java.commerce.evaluateRule() method then evaluates the rule to True or False.expression. if the expression evaluates to True and the addErrorToResultOnTrueEval property is set to True. short. RuleEvaluator The atg.0.priceInfo. If two incompatible data types are evaluated. such as a double and boolean. The specific value returned is determined by its returnValueForTrueEvaluation and returnValueForFalseEvaluation properties. and String. The RuleEvaluator. expressionParser 385 11 . which is then passed to the RuleEvaluator for evaluation.commerce. ATG Commerce provides a globally-scoped instance of RuleEvaluator. Additionally.expression. int.RuleEvaluator class is used to evaluate a given rule. ProcPropertyRestriction The atg. The ExpressionParser Nucleus component. float. which is located in Nucleus at /atg/commerce/util/. If null.ATG Commerce Programming Guide µ After parsing the expression. the ProcPropertyRestriction processor creates a new instance of atg. then an EvaluationExpression is thrown.Configuring Purchase Process Services . boolean. double.commerce. then the value in the errorMessage property is added to the PipelineResult object. it returns a Rule object and passes it to the RuleEvaluator. ATG Commerce provides a globally-scoped instance of ExpressionParser. char. keyed by the string in the pipelineResultErrorMessageKey property. such as Order. which is located in Nucleus at /atg/commerce/util/.ruleExpression using the ExpressionParser and then evaluates the rule using the RuleEvaluator.expression. (See the table below for more information on these properties.ProcPropertyRestriction class resolves all references in the rule set in ProcPropertyRestriction. the parseExpression() method returns a Rule object.amount > 1000. This is the rule against which the processor evaluates the Order.) The ProcPropertyRestriction processor has the following properties: Property ruleExpression Description The expression that is passed to the ExpressionParser. These are long. The processor then returns a value based on whether the rule evaluates to True or False. After the ExpressionParser parses an expression.

defining the rule by which Orders are to be evaluated in ProcPropertyRestriction. The key to use when adding the errorMessage to the PipelineResult object.Configuring Purchase Process Services .expression.) Then add the processor at any point in any pipeline. The integer to return when the expression evaluates to False. To do so.ProcPropertyRestrictions.service. returnValueForTrueEvaluation addErrorToResultOnTrueEval errorMessage pipelineResultErrorMessageKey Implementing Order Restrictions You can set restrictions on Orders by adding a ProcPropertyRestriction processor to any pipeline. for example. . the validateForCheckout pipeline. you might check Orders against certain restrictions before checkout by adding a link to the validateForCheckout pipeline in <ATG9dir>/DCS/src/config/atg/commerce/commercepipeline. add a new element to the XML file that references atg.commerce.µ ruleEvaluator returnValueForFalseEvaluation ATG Commerce Programming Guide The RuleEvaluator Nucleus component.PipelineResultImpl"> <pipelinelink name="propertyRestrictions" transaction="TX_MANDATORY"> <processor jndi="/atg/commerce/expression/ProcPropertyRestrictions"/> .pipeline.commerce.RuleEvaluator for its use. the ProcPropertyRestriction processor creates a new instance of atg. A boolean property that controls whether the errorMessage is added to the PipelineResult object when the expression evaluates to True. The integer to return when the expression evaluates to True. . 386 11 .commerce.service.xml.expression. create an instance of atg. To insert a new link. (See the table in the previous section for more information on the properties of ProcPropertyRestriction. For example.pipeline. If null. as follows: <pipelinechain name="validateForCheckout" transaction="TX_REQUIRED" headlink="validateOrderForCheckout" classname="atg. The error message to add to the PipelineResult object when the expression evaluates to True.PipelineChain" resultclassname="atg.ProcPropertyRestriction.expression.ruleExpression and setting the remaining properties as necessary.

You can also use shopping process tracking to modify a customer’s experience. The duplication mode determines what happens if an order reaches a business stage for the second or subsequent time. to final check out. or undesirable pricing schemes. see the Processor Chains and the Pipeline Manager chapter. that may be an indication of poor or confusing application page design. track activity within the business process.Configuring Purchase Process Services . the shopping process. For example. if all goes well. In ATG Commerce. and report on the activity for a specified time frame. The ShoppingProcessConfiguration component also specifies the duplication mode for the shopping process. from browsing for products to. we’ve defined the lifecycle of an order (through the point the customer checks out) as a business process. purchasing and checking out. including information about how to create new business processes. which means an order is marked as having reached a new stage in the shopping process only the first time it reaches that stage. see the Defining and Tracking Business Processes chapter in the ATG Personalization Programming Guide Shopping Process Stages ATG Commerce has one business process configured out-of-the-box. to completing shipping and billing information. The stages of the shopping process in ATG Commerce are defined as: Browsed AddedToCart ShippingInfoComplete ShippingPriceDisplayed RequestedBillingInfo BillingInfoCompleted CartSummaryViewed These stages are defined in the stageNames property of the /atg/commerce/bp/ShoppingProcessConfiguration component. you could offer special promotions to customers who stall at a particular point in the shopping process. allowing you to track stages in the shopping process from browsing. Tracking the Shopping Process ATG’s Adaptive Customer Engine includes a business tracking feature that lets you define a business process as a series of stages. No change is made if the order reaches the same stage again. For example. to adding items to the shopping cart.ATG Commerce Programming Guide µ </pipelinechain> For more information on pipelines and how to extend them. The shopping process is made up of a series of stages that a customer follows. By default. 387 11 . the duplication mode of the ShoppingProcessConfiguration component is NO_DUPLICATES. if reports show that many customers are abandoning their purchases at the stage where you display the shipping price. For more information about business process tracking. You can use the information gathered by tracking the stages of the shopping process to understand better how your customers react to their experience with your site.

remove. and check shopping process stages. For the shopping process. these include the following servlet beans and scenario elements: Task Add a shopping process stage Remove a shopping process stage Check if a shopping process stage has been reached Check the most recent shopping process stage that has been reached Servlet Bean AddShoppingProcessStageDroplet Scenario Element Add Stage Reached RemoveShoppingProcessStageDroplet Remove Stage(s) Reached HasShoppingProcessStageDroplet Has Reached Stage MostRecentShoppingProcessStageDro plet Most Recent Stage Reached These servlet beans are instances of classes in the atg. you need to track them by adding servlet beans to your checkout pages or defining scenarios to mark when a stage is reached. The business process stages that are defined by default in ATG Commerce may not fit the needs of your site. Whether you use the default business process stages or define your own. You can as an alternative use the corresponding scenario elements in a scenario.droplets package. and check for business process stages. See Appendix: ATG Commerce Servlet Beans in the ATG Commerce Guide to Setting Up a Store for reference information about these servlet beans. You can use the servlet beans to the checkout pages of a Commerce application to add. You can define whatever business process stages you want by setting the stageNames property of the /atg/commerce/bp/ShoppingProcessConfiguration component.markers. For example. you could create a scenario like this: The business stage scenario elements are described in the Creating Scenarios chapter of the ATG Personalization Guide for Business Users.µ ATG Commerce Programming Guide Every commerce site is different. Working with Shopping Process Stages ATG includes page-based and scenario-based tools that let you add. remove.Configuring Purchase Process Services . each with the default process name set to ShoppingProcess. 388 11 . as described in the rest of this section.bp.

) • • If errors occur when a user logs in. The handleMoveToPurchaseInfoByRelId method and all other handle methods of atg.updateOrder(). or monthly basis. weekly.Configuring Purchase Process Services . you must call the updateOrder() method.commerce. (For more information on the updateOrder() method.) updateOrder() must always be called within a transaction. The reports give a summary of the number of orders that reach each stage in the shopping process. (For more information on transactions. see Updating an Order with the Order Manager in the Saving Orders section of this chapter. see the Transaction Management chapter in the ATG Programming Guide. Note that by default the shopping process is configured with the NO_DUPLICATES setting. 389 11 . there are shoppingProcessActivity chart templates you can use to generate reports on the shopping process on a daily. set the persistOrders property of the ShoppingCart component to true. which means that we only track the first time an order reaches a stage in the shopping process. for orders that started the process in the given timeframe. Troubleshooting Order Problems If you modify the functionality of the OrderManager or its related components. Turning Off Recording of Shopping Process Tracking If you don’t want to generate reports on the shopping process.purchase. you should make sure to follow these guidelines: • When making changes to an Order.order. you can disable shopping process events by setting the generateEvents property of the /atg/commerce/bp/ShoppingProcessConfiguration component to false. In the ACC Analysis > Chart Templates section.CartModifierFormHandler provide good examples of how and when to call getOrderManager.ATG Commerce Programming Guide µ Shopping Process Recorder Data about stages reached in the shopping process is recorded by the shoppingprocess scenario recorder: This recorder makes a record in the Shopping Process Stage Reached Dataset whenever an order reaches a new stage in the shopping process.

createClaimableStoreCredit() method (atg. the quantity of the CommerceItem reflects the final quantity that was purchased. For more information on the Claimable Repository. see the Configuring Merchandising Services chapter. Call CommerceItemManager. Increases the returnedQuantity property in the ShippingGroupCommerceItemRelationship by the quantity returned.commerce. and its returnedQuantity reflects that quantity of the CommerceItem that was returned. including gift certificates. Note that only one store credit account can exist for a given user or organization.commerce. The Claimable Repository contains a storeCreditClaimable item that includes the following properties: • • • • • amount (double) – the original amount of the credit amountAuthorized (double) – the amount of credit authorized for use amountRemaining (double) – the current amount of the store credit ownerId (String) – the ID of the user or organization for which the credit was issued lastUsed (date) – the date the credit was last accessed To modify an existing store credit account (for example. This method does the following: Reduces the quantity property in the CommerceItem by the quantity returned.updateClaimableStoreCredit() method. The store credit system in ATG Commerce can also manage the return of items.Configuring Purchase Process Services .returnCommerceItem() to mark a given CommerceItem as returned. to increase the amount of remaining credit). call the ClaimableManager. After the item is returned.CommerceItemManager) to manage the return of items in an Order. you can use the CommerceItemManager (class atg. To create a new store credit account for a user or organization. Working with ATG Commerce Form Handlers This section provides you with information on working with and extending the form handlers that are provided with ATG Commerce. call the ClaimableManager. Reduces the quantity property in the ShippingGroupCommerceItemRelationship by the quantity returned. The quantity property of the ShippingGroupCommerceItemRelationship reflects the quantity that was shipped.order.ClaimableManager) to create the new store credit and then call the ClaimableManager.initializeClaimableStoreCredit() method to set its initial values. It includes the following sections: Managing Transactions in the ATG Commerce Form Handlers Extending the ATG Commerce Form Handlers 390 11 .µ Handling Returned Items • • • ATG Commerce Programming Guide In ATG Commerce.claimable.

beforeSet Method This method is called once before any form handler property is set or handler method is called. see atg. This form handler. Managing Transactions in the ATG Commerce Form Handlers Most of the ATG Commerce form handlers extend atg. afterSet Method This method is called once after all form handler processing is completed. Commit or roll back any transaction that was created in the beforeSet method. 3.purchase. is an abstract class which implements a transaction management pattern that should be followed by any form handler that works with Order objects.) 2. the CartModifierFormHandler subclass has a handleAddItemToOrder method that executes the logic of adding an item to an order.order. For more information. more general information. If the transaction was already in place before the beforeSet method was called.util. the afterSet method does not end the transaction automatically. It implements the following transactional steps: 1. It implements the following transactional steps: 1. If the form handler’s useLocksAroundTransactions property is true (the default). End the synchronization. Synchronize on the Order object. which is a subclass of atg. Call the OrderManager object’s updateOrder method to save the order data to the repository.Configuring Purchase Process Services .TransactionLockFactory. create one. 2.commerce.droplet. 4. Execute logic for modifying the Order object. see the Working with Forms and Form Handlers chapter in the ATG Programming Guide. For example. this is the application’s responsibility. obtain a transaction lock before the transaction is created. Check for an existing transaction and.GenericFormHander.commerce.ATG Commerce Programming Guide µ For related. If a transaction lock was acquired in the beforeSet method. afterSet. release the lock. and handler methods. if no transaction exists. This prevents a user from modifying an order in multiple concurrent threads. 2. Handler Methods The handler methods implement the following transactions steps: 1. 391 11 . The lock name used defaults to the current profile ID. This transaction management pattern is implemented through the form handler’s beforeSet. (Note that use of locking has a small performance impact.PurchaseProcessFormHandler.

you can mark a transaction for rollback by calling the setTransactionToRollbackOnly method. after all computation is complete but before returning any information. be aware that these methods do not take any input parameters. Your form handler will then inherit the beforeSet and afterSet methods. Extending the ATG Commerce Form Handlers If you write a form handler that modifies the Order object. The easiest way to do this is to extend either PurchaseProcessFormHandler or a subclass of PurchaseProcessFormHandler. For more information on PurchaseProcessFormHandler and its subclasses. when a customer adds an item to their shopping cart using CartModifierFormHandler. you should implement the transactionhandling pattern described above. any new handler methods you write will need to implement the transaction logic described in the Handler Methods section.Configuring Purchase Process Services . the submit button on the form submits to the handleAddItemToOrder method.µ ATG Commerce Programming Guide If you’re extending an ATG Commerce form handler and your code makes its own decisions about errors. the handleAddItemToOrder method invokes the preAddItemToOrder method. They are provided so you can easily extend the form handlers to support additional functionality. so you won’t need to replicate their portion of the transaction logic. However. Before any computation is done. By default these preXXX and postXXX methods have no functionality. However. the handleAddItemToOrder method invokes the postAddItemToOrder method. you can examine the source files at <ATG9dir>\DCS\src\Java\atg\commerce\order\purchase and refer to the ATG API Reference. 392 11 . Additionally. For example. Note that the handleXXX methods of the ATG Commerce form handlers invoke preXXX and postXXX methods before and after any computation is performed.

Customizing the Purchase Process Externals . These messages are generated automatically during the purchase process. Purchase Process Event Messages Describes the event messages sent by the purchase process. Event ItemAddedToOrder Description Sent when an item is added to an order. Extending the Purchase Process Describes how to store purchasing information that is not included in the out-of-thebox functionality of ATG Commerce. and JMS message type Sent when an item is removed from an order. These include messages that are sent when a product or category is browsed. It also contains information on how to extend the existing purchase framework. Merging Orders Describes how to merge orders when you’ve extended ATG Commerce classes to store additional information. Includes the order ID. Includes order ID.ATG Commerce Programming Guide µ 12 Customizing the Purchase Process Externals This chapter contains information on ATG Commerce features that operate outside the actual process of creating and placing orders. Integrating with Purchase Process Services Describes the integration points in the purchase process and how to add a new credit card type to a payment system integration. Note: This section is for reference. commerce item ID and the JMS message type ItemRemovedFromOrder 393 12 . commerce item ID. when an item is added or removed from the order and when an order has been submitted for fulfillment (checkout complete). Purchase Process Event Messages The event messages generated by the purchase process are sent at various points in the purchase process.

the PaymentManager is configured to use the ATG Commerce gift certificate processing system. Integrating with Purchase Process Services This section contains the following information: Purchase Process Integration Points Adding Credit Card Types to ATG Commerce Purchase Process Integration Points There are several points in the purchase process where specialized components can be integrated into the system. confirmation e-mail is sent through a scenario that is listening for the Submitorder message. • VerifyOrderAddresses. the JMS message type Sent when a product or a category is browsed. The gift certificate processing system must implement the atg. atg. the repository id and the serialized repository item object. includes the repository name. • PaymentManager.addressVerificationProcessor 394 12 .payment. By default. The PaymentManager is located in Nucleus at /atg/commerce/payment/. the item type. the PaymentManager is configured to use a dummy processing system. ATG Commerce actions include giving promotions to customers when they add a particular item to their order or browse a particular product or category. To integrate a component. The PaymentManager is located in Nucleus at /atg/commerce/payment/.giftCertificateProcessor Use this property of the PaymentManager to integrate with a gift certificate processing system. atg. By default.commerce.DummyCreditCardProcessor.GiftCertificateProcessorImpl.µ SubmitOrder ViewItem ATG Commerce Programming Guide Sent when an order has been submitted for fulfillment (checkout complete).payment.creditcard.creditCardProcessor Use this property of the PaymentManager to integrate with a credit card processing system.commerce.payment.Customizing the Purchase Process Externals . Includes the serialized order. The credit card processing system must implement the atg.GiftCertificateProcessor interface. Additionally.giftcertificate. configure a property of a Nucleus component to reference an object that implements an interface (as described below). The following list describes the integration points in the purchase process: • PaymentManager.CreditCardProcessor interface.payment.

Create a subclass of atg. } 395 12 . such as Switch/Solo.avs. By default.setPropertyValue(). CyberSource. is configured to use a dummy processing system.payment.DummyAddressVerificationProcessor. 3. The address verification system must implement the atg.getPropertyValue() and super.ATG Commerce Programming Guide µ Use this property of the ProcVerifyOrderAddresses object to integrate with an address verification system. Many of these other cards have more validation parameters than the standard cards.payment. etc. The following sections describe the three parts to extending ATG Commerce to include new credit card types: 1. For more information on integrating ATG Commerce with Payflow Pro. For example. If your commerce site needs to accept these cards. For general information on extending a class and modifying the ATG Commerce purchase process. The get and set methods need to use super. (pIssueNumber == null ? pIssueNumber : StringUtils. see the Integrating Third-Party Software With ATG Commerce chapter of this manual. and TAXWARE. the VerifyOrderAddresses component. These cards include Visa.AddressVerificationProcessor interface. so that the underlying repository item is updated correctly. By default. Extending the ATG Commerce CreditCard Class Extending the ATG Commerce CreditCardInfo Class Extending the Payment System Integration Extending the ATG Commerce CreditCard Class The following steps describe how to extend the CreditCard class and modify ATG Commerce to use the new class. the following code sample creates a property for the issue number of the credit card: //-----------------------------------------------------// property:IssueNumber //-----------------------------------------------------public void setIssueNumber(String pIssueNumber) { setPropertyValue("issueNumber". see the Extending the Purchase Process section of this chapter. 2. Add get/set methods for each of these properties. MasterCard.commerce. atg. Many payment systems handle many other credit and debit cards. you can extend ATG Commerce to handle these card types. which is located in Nucleus at /atg/commerce/order/processor/. 1.commerce.CreditCard and include any new properties you need for the credit card type.Customizing the Purchase Process Externals . Adding Credit Card Types to ATG Commerce This section describes how to extend ATG Commerce and a payment system integration (such as CyberSource) to use the additional credit card types that the payment system might accept.removeWhiteSpace(pIssueNumber))). ATG Commerce considers only common credit cards valid.order.

paymentGroupToChainNameMap to contain a pointer to your new class: paymentGroupToChainNameMap+=\ my.xml to add the new properties in your CreditCard subclass to the existing creditCard item descriptor.creditcard. 3.creditCardInfo Class to point to the new subclass. Create a new class that extends atg.commerce. with any necessary new properties. 396 12 . Modify /atg/commerce/payment/PaymentManger. 1. Add columns to the dcspp_credit_card table to store your new properties for the CreditCard subclass. 3. Modify /atg/commerce/order/OrderTools to make ATG Commerce use your new CreditCard subclass instead of the default class.dir.payment.Customizing the Purchase Process Externals . 2.ProcCreateCreditCardInfo.GenericCreditCardInfo.class. In this class.class.myCreditCard=creditCard paymentTypeClassMap+=\ creditCard=my.myCreditCard=creditCardProcessorChain 6. Modify /atg/commerce/payment/processor/CreateCreditCardInfo. 4.processor.dir. Create a subclass of atg.dir.myCreditCard 5. Refer to the payment system’s documentation for information on what properties it needs to process the new credit card type. For example: beanNameToItemDescriptorMap+=\ my.class. } 2.µ ATG Commerce Programming Guide /** * The issue number of this credit card * @beaninfo description: The issue number of this credit card **/ public String getIssueNumber() { return (String) getPropertyValue("issueNumber"). Extend orderrepository. Edit the following properties of /atg/commerce/payment/CreditCardTools to include appropriate values for your new CreditCard: cardCodesMap cardLengthsMap cardPrefixesMap cardTypesMap Extending the ATG Commerce CreditCardInfo Class The following steps describe how to extend the CreditCardInfo class to accommodate the new credit card type.payment.

Customizing the Purchase Process Externals .ATG Commerce Programming Guide µ extend the addDataToCreditCardInfo method to call the superclass.payment.CyberSourceCreditCard uses the credit card info in the authorize. build a CyberSource request.creditcard. the 397 12 . adding logic to use the new properties you added. see the Processing Payment of Orders section in the Configuring Purchase Process Services chapter. 4. The payment system integration will have an implementation of atg. This means that you need to extend this class and recreate most of the methods. and send the request to CyberSource. followed by code that adds your new properties (added in step 1) to the CreditCardInfo object. For example. /atg/commerce/payment/CyberSourceCreditCard must be changed. For example. If using CyberSource.cybersource. Extending the Purchase Process Extending the purchase process is necessary when you want to store purchasing information that is not included in the out-of-the-box functionality of ATG Commerce. you don’t need to write any code to save the properties to or load the properties from the Order Repository. credit and debit methods.CreditCardProcessor. the $class line in the properties file for the credit card processor must be changed to use your new subclass.integrations. Adding a Subclass with Primitive Data Type Properties You can extend the commerce object hierarchy by subclassing an existing object and adding new primitive data type properties. See the following sections for details: Adding a Subclass with Primitive Data Type Properties Adding a Subclass with Object Data Type Properties Manipulating Extended Objects Note: For information on extending the ATG Commerce payment process to support a new payment method or additional operations for an existing payment method.properties to point to your new subclass. When you add primitive data type properties. Modify the class of CreditCreditCardInfo. You extend the purchase process by first subclassing an existing object in the commerce object hierarchy to add new properties and then integrating that new class into ATG Commerce. the class atg. Extending the Payment System Integration The final part of the process of adding a new credit card type is to extend the credit card processor for your payment system to use your new card type’s properties in its validation mechanisms. Using introspection. you could extend the purchase process to store that information. if you are integrating with CyberSource. In addition. All of these methods get data from the ATG Commerce creditCardInfo object. if you want to allow customers to specify a box size for their purchases.

As an example. you now need to integrate the new commerce object into ATG Commerce. the call to setPropertyValue("shortDescription". every get() method needs to call the getPropertyValue() method.commerce. pShortDescription) in the setShortDescription() method causes the shortDescription repository item property to be set directly when the method is called. These methods retrieve and set the values of properties directly on the repository item objects. note the calls to getPropertyValue() and setPropertyValue(). In a commerce object that supports the ChangedProperties interface.order. all commerce objects implement the ChangedProperties interface except for atg. they are part of the atg. } } In the code example above.µ ATG Commerce Programming Guide processors in the updateOrder and loadOrder pipelines handle this automatically for primitive data type properties.commerce. In ATG Commerce. The ChangedProperties interface enhances performance when saving an Order to the Order Repository.commerce. public String getShortDescription() { return (String) getPropertyValue("shortDescription").pricing. pShortDescription).ChangedProperties interface. the following code creates a new class called MyCommerceItemImpl.updateOrder() is called to save the Order to the repository. This approach reduces the amount of processing when OrderManager. This approach is recommended because it eliminates the need to change property values that contain item descriptor names throughout ATG Commerce. import atg. You can do so using one of two approaches: • (Recommended) Add the new properties to an existing item descriptor and then map the new object to that item descriptor. With the MyCommerceItemImpl subclass created. see Integrating a New Commerce 398 12 .order. The call to getPropertyValue("shortDescription") retrieves the property directly from the repository item and eliminates the need to create a member variable in the class to store the value.order. In the example above. and similarly every set() method needs to call the setPropertyValue() method. } public void setShortDescription(String pShortDescription) { setPropertyValue("shortDescription".AuxiliaryData and all subclasses of atg.AmountInfo. It extends CommerceItemImpl and adds a new String property called shortDescription.CommerceItemImpl.commerce. Performance is enhanced because you set the values directly to the repository item and only save the properties that have actually been changed in the class. For more information. public class MyCommerceItemImpl extends CommerceItemImpl { public MyCommerceItemImpl() { } // property: shortDescription private String mShortDescription = null.Customizing the Purchase Process Externals .

you can integrate the new class into ATG Commerce using either process described in this section.xml.xml file is found in the CONFIGPATH at /atg/commerce/order/orderrepository.) However.Extend the Order Repository Definition File Extend the Order Repository definition file. follow these steps: Step 1 of 3 .xml file at /atg/commerce/order/ in your localconfig directory. For more information. see the Nucleus: Organizing JavaBean Components chapter in the ATG Programming Guide. During deployment.xml files in the CONFIGPATH into a single composite XML file. If you do so. The new file should define the shortDescription property for the commerceItem item descriptor. • Create a new item descriptor subtype that includes the new properties and map the new object to it. The orderrepository. see Integrating a New Commerce Object: Using a New Item Descriptor.) The orderrepository. In this example.xml. which holds auxiliary data for a CommerceItem. orderrepository.Customizing the Purchase Process Externals . (Recall that AuxiliaryData does not implement the ChangedProperties interface. } • • Ensure the new properties of the subclass are defined within the XML definition for the new commerce object. (For more information on XML file combination. to add the new properties in MyCommerceItemImpl to the existing commerceItem item descriptor. Note: You can also extend the commerce object hierarchy by subclassing AuxiliaryData.ATG Commerce Programming Guide µ Object: Using an Existing Item Descriptor. the ATG platform uses XML file combination to combine the orderrepository. create a new orderrepository. To extend the file. Ensure the database columns that store the new properties of the subclass go into the table that represents the new commerce object. which continues the example of MyCommerceItemImpl. which continues the example of MyCommerceItemImpl. Integrating a New Commerce Object: Using an Existing Item Descriptor To integrate MyCommerceItemImpl into ATG Commerce using an existing item descriptor. as follows: protected void createAuxiliaryData() { if (mAuxiliaryData == null) { mAuxiliaryData = new MyAuxiliaryData(getRepositoryItem()). you should take the following additional steps: • Override the createAuxiliaryData() method in the subclass so that it creates an instance of that new class. the new property to add is the shortDescription property.xml file that you create might look as follows: <gsa-template xml-combine="append"> <item-descriptor name="commerceItem"> <table name="dcspp_my_item" id-column-name="commerce_item_id"> 399 12 .

Customizing the Purchase Process Externals . Step 2 of 3 – Modify the Order Repository Database Schema In step 1. The OrderTools.order.class.properties file might look as follows: beanNameToItemDescriptorMap-=\ atg.xml file that you created in step 1. Step 3 of 3 – Modify the OrderTools Configuration File The OrderTools component controls many aspects of the purchase process.CommerceItemImpl=commerceItem beanNameToItemDescriptorMap+=\ my. For more information on setting up a repository and defining item descriptors. as well as the database table and column that store that property.MyCommerceItemImpl=commerceItem 400 12 . You need to modify the OrderTools configuration file to support the new MyCommerceItemImpl class. you defined the new shortDescription property of the commerceItem item descriptor. see the ATG API Reference. NOT NULL NULL. such as mapping between commerce object types and class names.properties file at /atg/commerce/order/ in your localconfig directory. and mapping between commerce objects and item descriptors. Now you need to modify accordingly the Order Repository database schema. layer on a configuration file by creating an OrderTools. defining the default commerce object types. The next section defines the shortDescription property of a commerceItem repository item. short_description VARCHAR(254) PRIMARY KEY(commerce_item_id) ). To modify the OrderTools configuration file. specifying the database table and column that store that property.µ </gsa-template> ATG Commerce Programming Guide <property name="shortDescription" column-name="short_description" data-type="string"/> </table> </item-descriptor> The first line in the above XML example begins the GSA template and instructs the XML combiner to append the contents of the tags in this file to the contents of the tags in the file with which it is combined.commerce. CREATE TABLE dcspp_my_item ( commerce_item_id VARCHAR(40) REFERENCES dcspp_item(commerce_item_id).dir. The following DDL statement creates the database table and columns specified in the orderrepository.

The my. The new file should define the new item descriptor subtype. create a new orderrepository. The my.) The following orderrepository. the ATG platform uses XML file combination to combine the orderrepository.dir prefix indicates some Java package in which the class exists. which. the defaultCommerceItemType property is set to the type default. the beanNameToItemDescriptorMap property contains this mapping. the commerceItemTypeClassMap property maps CommerceItem types to class names. Integrating a New Commerce Object: Using a New Item Descriptor To integrate MyCommerceItemImpl into ATG Commerce using a new item descriptor subtype. By default. the method constructs and returns an instance of the corresponding class. Additionally.class. the processors that save and load an Order look for an item descriptor that is mapped to the corresponding commerce object class. The configuration file above first removes the out-of-the-box configuration. then remaps the existing commerceItem item descriptor to the new Bean class.xml.xml. <gsa-template xml-combine="append"> <item-descriptor name="commerceItem"> <table name="dcspp_item"> <property name="type"> 401 12 . shortDescription. myCommerceItem inherits all of the properties of commerceItem.xml file at /atg/commerce/order/ in your localconfig directory. it defines one new property.xml file is found in the CONFIGPATH at /atg/commerce/order/orderrepository. As a subtype of the commerceItem item descriptor.Extend the Order Repository Definition File Extend the Order Repository definition file. During deployment. To extend the file.xml files in the CONFIGPATH into a single composite XML file.xml file defines a new item descriptor named myCommerceItem.Customizing the Purchase Process Externals . to create a new item descriptor subtype that supports the new properties in MyCommerceItemImpl.defaultCommerceItemType.MyCommerceItemImpl The beanNameToItemDescriptorMap property maps Order Repository item descriptors to Bean names. follow these steps: Step 1 of 4 . This mapping is used by the createCommerceItem() method in the CommerceItemManager. The orderrepository. MyCommerceItemImpl. Because you can have more than one type of CommerceItem object.class.dir prefix specifies some Java package in which the class exists. (For more information on XML file combination. in turn. see the Nucleus: Organizing JavaBean Components chapter in the ATG Programming Guide. orderrepository.ATG Commerce Programming Guide µ commerceItemTypeClassMap+=\ default=my. the method constructs and returns an instance of the type specified in OrderTools.class. When one of the createCommerceItem() methods that does not take a type parameter is called. In ATG Commerce. by passing it a type parameter (such as the string “default”).dir. is mapped to the new MyCommerceItemImpl class in the commerceItemTypeClassMap property in the configuration file above.

Customizing the Purchase Process Externals . In this case. is specified. The next section defines myCommerceItem as a subtype of the commerceItem item descriptor. CREATE TABLE dcspp_my_item ( commerce_item_id VARCHAR(40) REFERENCES dcspp_item(commerce_item_id). specifying commerceItem as the super-type (or parent item descriptor) and myCommerceItem as the sub-type-value. shortDescription. 402 12 . a single property. as well as the database table and columns that store those properties.xml file that you created in step 1. short_description VARCHAR(254) NOT NULL NULL. see the ATG Repository Guide. The last section of the XML file defines the myCommerceItem item descriptor.xml file contains the other options for the type property of commerceItem. In this case. you created the new myCommerceItem item descriptor. Step 2 of 4 – Modify the Order Repository Database Schema In step 1. You do this by adding a new string value for myCommerceItem to the type enumerated property of commerceItem. defining both its properties and the database table and columns that store those properties. its parent item descriptor. the new type is called myCommerceItem. and its corresponding integer value is 1. The base orderrepository. Now you need to modify accordingly the Order Repository database schema. The following DDL statement creates the database table and columns specified in the orderrepository. recall that myCommerceItem inherits all of the properties of commerceItem.µ ATG Commerce Programming Guide <option value="myCommerceItem" code="1"/> </property> </table> </item-descriptor> <item-descriptor name="myCommerceItem" super-type="commerceItem" sub-type-value="myCommerceItem"> <table name="dcspp_my_item" id-column-name="commerce_item_id"> <property name="shortDescription" column-name="short_description" data-type="string"/> </table> </item-descriptor> </gsa-template> The first line in the above XML example begins the GSA template and instructs the XML combiner to append the contents of the tags in this file to the contents of the tags in the file with which it is combined. For more information on setting up a repository and defining item descriptors. The section then specifies the properties of a myCommerceItem repository item. However.

the defaultCommerceItemType property is set to the type default.class.Customizing the Purchase Process Externals . In ATG Commerce. When one of the createCommerceItem() methods that does not take a type parameter is called. The item descriptor’s id-space-name attribute specifies which IdSpace supplies repository IDs for items of that item type. in turn.defaultCommerceItemType. the beanNameToItemDescriptorMap property contains this mapping.dir. 403 12 .MyCommerceItemImpl The beanNameToItemDescriptorMap property maps Order Repository item descriptors to Bean names. This mapping is used by the createCommerceItem() method in the CommerceItemManager. layer on a configuration file by creating an OrderTools. By default. Because you can have more than one type of CommerceItem object. Step 3 of 4 – Modify the OrderTools Configuration File The OrderTools component controls many aspects of the purchase process. this step is not required for the example. mapping the myCommerceItem item descriptor that you created in step 1 to the MyCommerceItemImpl class. defining the default commerce object types. which. To modify the OrderTools configuration file.class. In the latter case. the commerceItemTypeClassMap property maps CommerceItem types to class names. The my.class. The configuration file above adds a new entry.class. Step 4 of 4 – Extend the ID Spaces Definition File Note: Because the example provided throughout this section involves an item descriptor subtype rather than a root item descriptor. the method constructs and returns an instance of the type specified in OrderTools. When an ID is requested for a new repository item.dir prefix indicates some Java package in which the class exists. By default. The OrderTools. The my. is mapped to the new MyCommerceItemImpl class in the commerceItemTypeClassMap property in the configuration file above.properties file might look as follows: beanNameToItemDescriptorMap+=\ my.dir prefix specifies some Java package in which the class exists. the method constructs and returns an instance of the corresponding class. such as mapping between commerce object types and class names.properties file at /atg/commerce/order/ in your localconfig directory. It is provided here for information when defining root item descriptors.dir. by passing it a type parameter (such as the string “default”). the items use the ID space name of the root item descriptor in the super-type hierarchy. You need to modify the OrderTools configuration file to support the new MyCommerceItemImpl class and myCommerceItem item descriptor.ATG Commerce Programming Guide µ PRIMARY KEY(commerce_item_id) ). the processors that save and load an Order look for an item descriptor that is mapped to the corresponding commerce object class.MyCommerceItemImpl=myCommerceItem commerceItemTypeClassMap+=\ default=my. it is requested from the appropriate IdSpace for that repository item. all items use the item descriptor’s name as the ID space unless their item type inherits from another item type. and mapping between commerce objects and item descriptors.

in order to define an ID space for that item descriptor. import import import import import import atg. which is a subtype of the commerceItem item descriptor. you need to extend the ID spaces definition file. It extends CommerceIdentifierImpl and adds a new String property called miscInformation. atg. Because the example used throughout this section involves the myCommerceItem item descriptor subtype. if myCommerceItem were a root item descriptor. A subsequent code example creates a new class called MyOrder. The ATG Commerce IdGenerator guarantees that IDs within a named ID space are unique. the following code creates a new class called OrderData. it doesn’t require a defined ID space. During deployment.repository.order.Customizing the Purchase Process Externals .commerce.CommerceIdentifierImpl.commerce.xml file might look as follows: <id-spaces xml-combine="append"> <id-space name="myCommerceItem" seed="1" batch-size="10000" prefix="mci"/> </id-spaces> For more information on defining ID spaces and its impact on repository item IDs.ChangedProperties.xml definition file. see the ID Generators section of the Core Dynamo Services chapter in the ATG Programming Guide.order.MutableRepositoryItem. java.util. package my_package. you would define an ID space for it by creating a new idspaces. (For more information on XML file combination.util.xml. public class OrderData extends CommerceIdentifierImpl 404 12 . As an example. Adding a Subclass with Object Data Type Properties You can extend the commerce object hierarchy by subclassing an existing commerce object and adding new object data type properties.) The idspaces. idspaces.xml file at /atg/dynamo/service/ in your localconfig directory. see the Nucleus: Organizing JavaBean Components chapter in the ATG Programming Guide. java.util. Note that the OrderData class implements the ChangedProperties interface. which is explained in detail after the code example. the ATG platform uses XML file combination to combine the idspaces.Observable.µ ATG Commerce Programming Guide If the new item descriptor that you’ve defined is a root item descriptor.HashSet. atg.xml files in the CONFIGPATH into a single composite XML file. java. which extends OrderImpl and adds a new OrderData property named orderData.Set. However. Unlike with adding new primitive data type properties (see Adding a Subclass with Primitive Data Type Properties). and each root item descriptor defines the characteristics of its ID space in the idspaces. adding new object data type properties requires that you write code to save and load the object’s properties.

Object arg) { if (arg instanceof String) { addChangedProperty((String) arg). } else { throw new RuntimeException("Observable update for " + getClass().Customizing the Purchase Process Externals .ATG Commerce Programming Guide µ implements ChangedProperties { public OrderData() { super(). pMiscInformation).getName() + " was received with arg type " + arg. public boolean isChanged() { return (mChanged || (mChangedProperties != null && ! getChangedProperties(). } } // // ChangedProperties implementation // // property: saveAllProperties private boolean mSaveAllProperties = false. } // property: miscInformation public String getMiscInformation() { return (String) getPropertyValue("miscInformation"). 405 12 .isEmpty())).getClass().getName() + ":" + arg). public boolean getSaveAllProperties() { return mSaveAllProperties. } public void setMiscInformation (String pMiscInformation) { setPropertyValue("miscInformation". } // // Observer implementation // public void update(Observable o. } public void setSaveAllProperties(boolean pSaveAllProperties) { mSaveAllProperties = pSaveAllProperties. } // property: changed private boolean mChanged = false.

public MutableRepositoryItem getRepositoryItem() { return mRepositoryItem. } // property: changedProperties private HashSet mChangedProperties = new HashSet(7). if (mutItem == null) throw new RuntimeException("Null repository item: " + getId()). if (mutItem == null) throw new RuntimeException("Null repository item: " + getId()).add(pPropertyName). } public void addChangedProperty(String pPropertyName) { mChangedProperties.getPropertyValue(pPropertyName). pPropertyValue). } public void setRepositoryItem(MutableRepositoryItem pRepositoryItem) { mRepositoryItem = pRepositoryItem.µ } ATG Commerce Programming Guide public void setChanged(boolean pChanged) { mChanged = pChanged. return mutItem. } // setPropertyValue/getPropertyValue methods public Object getPropertyValue(String pPropertyName) { MutableRepositoryItem mutItem = getRepositoryItem(). setChanged(true). } public void setPropertyValue(String pPropertyName. } public void clearChangedProperties() { mChangedProperties. Object pPropertyValue) { MutableRepositoryItem mutItem = getRepositoryItem().clear().setPropertyValue(pPropertyName. 406 12 . public Set getChangedProperties() { return mChangedProperties. } // property: repositoryItem private MutableRepositoryItem mRepositoryItem = null. mutItem.Customizing the Purchase Process Externals .

The interface contains the properties described in the following table. Having the object contain the repository item eliminates the need to look up the item in the repository when saving it.MutableRepositoryItem. The property is implemented as a Set to include each property only once. The following code creates a new class called MyOrder. The class contains the getId() and setId() methods and implements the CommerceIdentifier interface. The purpose of the id property is to store the repository ID for the given commerce object. A boolean property that marks all properties as changed.commerce.repository. it is the base class for all commerce object classes. Property changed Description A boolean property that returns true if the object has changed since the last update and returns false if it has not. which contains only the getId() method. changedProperties repositoryItem saveAllProperties With the OrderData class created.Customizing the Purchase Process Externals . package my_package.OrderImpl.order. import atg. and adds a new String property called miscInformation. the next step is to add the OrderData property to the Order. which extends OrderImpl and adds a new OrderData property called orderData. import atg.ATG Commerce Programming Guide µ } } As previously mentioned. A Set that contains the names of all changed properties. implements the ChangedProperties interface. The ChangedProperties interface enhances performance when saving the object by allowing the object’s property values to be set directly to the repository item. regardless of whether or not they have changed. the code above creates a new OrderData class that extends CommerceIdentifierImpl. The CommerceIdentifierImpl class is an abstract class that contains a single property called id. Contains the repository item that refers to the object. public class MyOrder extends OrderImpl { public MyOrder() { } 407 12 . The CommerceIdentifier interface provides a standard way for ATG Commerce systems to access the repository IDs of items. This causes all properties to be saved to the repository.

<gsa-template xml-combine="append"> <item-descriptor name="order"> <table name="dcspp_order"> <property name="type"> <option value="myOrder" code="1"/> </property> 408 12 . Additionally. to create new item descriptors that support the new properties in OrderData and MyOrder. extend the Order Repository definition file. see the Nucleus: Organizing JavaBean Components chapter in the ATG Programming Guide. To extend it. To do so. setPropertyValue("orderData". which supports the miscInformation property in OrderData. you now need to integrate the new commerce object into ATG Commerce.xml files in the CONFIGPATH into a single composite XML file.) The following orderrepository.xml file defines an item descriptor named myOrder.getRepositoryItem()).xml. (For more information on XML file combination.µ // property: orderData private OrderData mOrderData = null. pOrderData.xml.xml file is found in the CONFIGPATH at /atg/commerce/order/orderrepository. As a subtype of the order item descriptor. it defines one new property. myOrder inherits all of the properties of order. orderrepository. } } With the MyCommerceItemImpl subclass created.Customizing the Purchase Process Externals . } return mOrderData. The new file should define the new item descriptors. add a new orderrepository. The orderrepository. orderData. you now need to integrate the new commerce objects into ATG Commerce.xml file at /atg/commerce/order/ in your localconfig directory. During deployment. ATG Commerce Programming Guide public OrderData getOrderData() { if (mOrderData == null) { mOrderData = new OrderData(). perform the following steps: Step 1 of 7 – Extend the Order Repository Definition File First. setRepositoryItem((MutableRepositoryItem) getPropertyValue("orderData")). With the OrderData and MyOrder classes created. } public void setOrderData(OrderData pOrderData) { mOrderData = pOrderData. the ATG platform uses XML file combination to combine the orderrepository. The definition file also defines a root item descriptor named orderData.

and its corresponding integer value is 1. the new type is called myOrder. The subsequent section of XML defines the myOrder item descriptor. the following properties are specified: type. declaring order as the super-type (or parent item descriptor) and myOrder as the sub-type-value. In this case.) In this case. The sub-type-value refers to the type property in the order item descriptor. The base orderrepository. You do this by adding a new string value for myOrder to the type enumerated property of order. In this case. The next section defines myOrder as a subtype of the order item descriptor. version. The section then specifies the properties of an orderdata repository item. (Note that each property of a repository item is stored in a database column that has the same name as the property.Customizing the Purchase Process Externals . The type and version properties are defined as readonly (writable="false" in the XML) because they are used primarily by 409 12 . the table is called dcspp_my_order.ATG Commerce Programming Guide µ </table> </item-descriptor> <item-descriptor name="myOrder" super-type="order" sub-type-value="myOrder"> <table name="dcspp_my_order" id-column-name="order_id"> <property name="orderData" column-name="order_data" item-type="orderData"/> </table> </item-descriptor> <item-descriptor name="orderData" sub-type-property="type" version-property="version"> <table name="dcspp_order_data" type="primary" id-column-name="order_data_id"> <property name="type" column-name="type" data-type="enumerated" default="orderData" writable="false"> <attribute name="useCodeForValue" value="false"/> <option value="orderData" code="0"/> </property> <property name="version" column-name="version" data-type="int" writable="false"/> <property name="miscInformation" column-name="misc_information" data-type="string"/> </table> </item-descriptor> </gsa-template> The first line in the above XML example begins the GSA template and instructs the XML combiner to append the contents of the tags in this file to the contents of the tags in the file with which it is combined. The last section of the XML file defines orderData as a root item descriptor. and miscInformation. and it stores a single property named orderData. Subsequent lines define the name of the table in the database schema that stores the properties of myOrder and then define those properties.xml file contains the other options for the type property. unless otherwise specified using the column-name attribute. as well as the database table and columns that store those properties.

Subclass OrderTools and SimpleOrderManager to Create the New Object When an Order is created. NULL. Step 3 of 7 . (For more information on the SimpleOrderManager. meaning it defines a column that stores repository IDs. Subclass atg.SimpleOrderManager (which extends atg. NOT NULL. defining both their properties and the database tables and columns that store those properties.OrderManager) and override its createOrder() method. Now you need to modify accordingly the Order Repository database schema. The new createOrder() method should first call the createOrder() method of the superclass to create the Order object. NOT NULL.µ ATG Commerce Programming Guide the repository. then call the createOrderData() method that you created in step 1 to create the OrderData object. you created the new orderData and myOrder item descriptors.commerce. CREATE TABLE dcspp_my_order ( order_id VARCHAR(40) REFERENCES dcspp_order(order_id). the new OrderData object must also be created and added to the Order object. CREATE TABLE dcspp_order_data ( order_data_id VARCHAR(40) type integer version integer misc_information VARCHAR(254) PRIMARY KEY(order_data_id) ).order.xml file that you created in step 1. order_data VARCHAR(40) PRIMARY KEY(order_id) ).order. This functionality requires the following two steps: 1. and finally add the OrderData object to the Order. NOT NULL. All three properties are stored in the dcspp_my_order database table. The following code example subclasses OrderTools and adds a new createOrderData() method.Customizing the Purchase Process Externals .OrderTools and add a new createOrderData() method that instantiates an OrderData object and creates an OrderData repository item in the Order Repository. see the Using the SimpleOrderManager section of the Working With Purchase Process Objects chapter.commerce. 410 12 . The dcspp_my_order table is declared a primary table. The following DDL statements create the database tables and columns specified in the orderrepository.) 2.order. In this case. Subclass atg.commerce. Step 2 of 7 – Modify the Order Repository Database Schema In step 1. that column is order_data_id. NOT NULL NULL.

public class MyOrderManager extends SimpleOrderManager { public MyOrderManager() { } 411 12 . // create the OrderData in the repository and set its id to the // repository's id try { MutableRepository mutRep = (MutableRepository) getOrderRepository(). overriding its createOrder() method in order to call the createOrderData() method in the OrderTools object. import atg.ATG Commerce Programming Guide µ package my_package. MutableRepositoryItem mutItem = mutRep.*.Customizing the Purchase Process Externals .commerce. package my_package.order. import atg.*. import atg. import atg.pricing.setSaveAllProperties(true). public class MyOrderTools extends OrderTools { public MyOrderTools() { } public OrderData createOrderData() throws ObjectCreationException { // instantiate the orderData object OrderData orderData = new OrderData().setRepositoryItem(mutItem).repository. } } The following code example subclasses SimpleOrderManager.commerce.*. orderData.*. } return orderData.commerce.setId(mutItem. import atg.*.commerce. if (orderData instanceof ChangedProperties) ((ChangedProperties) orderData). import atg. if (orderData instanceof ChangedProperties) ((ChangedProperties) orderData).commerce.*. } catch (RepositoryException e) { throw new ObjectCreationException(e).createItem("orderData").order.getRepositoryId()).

pOrderType). ShippingPriceInfo pShippingPriceInfo.OrderData=orderData. layer on a configuration file by creating an OrderTools. pOrderPriceInfo.createOrder( pProfileId.Customizing the Purchase Process Externals . configure an instance of MyOrderManager in Nucleus by modifying the existing OrderManager configuration file. order.setOrderData(orderData). configure an instance of MyOrderTools in Nucleus by modifying the existing OrderTools configuration file. return order. defining the default commerce object types.properties file at /atg/commerce/order/ in your localconfig directory.µ ATG Commerce Programming Guide public Order createOrder(String pProfileId. The OrderTools component controls many aspects of the purchase process.dir. The OrderManager. layer on a configuration file by creating an OrderManager. The OrderTools.class. TaxPriceInfo pTaxPriceInfo.MyOrderTools beanNameToItemDescriptorMap+=\ my. OrderPriceInfo pOrderPriceInfo.dir. To do so.properties file should look as follows (Note that no properties need to be configured.MyOrder=myOrder orderTypeClassMap+=\ default=my.dir.): $class=my_package. } } Step 4 of 7 – Modify the OrderTools and OrderManager Configuration Files In step 3.properties file should look as follows: $class=my_package. pTaxPriceInfo. OrderData orderData = ((MyOrderTools)getOrderTools()). String pOrderType) throws CommerceException { MyOrder order = (MyOrder)super. you subclassed OrderTools and SimpleOrderManager to create the new OrderData object and add it to the Order. String pOrderId.properties file at /atg/commerce/order/ in your localconfig directory.class. such as mapping between commerce object types and class names.createOrderData(). pShippingPriceInfo. Now you need to configure instances of these new classes in Nucleus. You need to modify the OrderTools configuration file to support the new commerce objects and item descriptors that you have created. First.\ my. To modify the OrderTools configuration file.MyOrder 412 12 . and mapping between commerce objects and item descriptors.MyOrderManager Second. pOrderId.class.

atg. atg.CommerceException. the method constructs and returns an instance of the type specified in OrderTools.” which. The my.class. package my_package. ProcSaveOrderDataObject. This mapping is used by the createOrder() method in the OrderManager. see Saving Orders in the Configuring Purchase Process Services chapter. The processors in the updateOrder pipeline. serves as an example.order.*. /* This class extends a class called SavedProperties. Because you can have more than one type of Order object.processor.Customizing the Purchase Process Externals . This class also implements the PipelineProcessor interface.dir prefix specifies the Java package in which the class exists. This interface includes the runProcess() and getRetCodes() methods.*.defaultOrderType. by passing it a type parameter (such as the string “default”). However. use the Dynamic Beans mechanism to read and write the values of a bean using their property names. to save the data in the OrderData object itself.java. the orderTypeClassMap property maps Order types to class names. import import import import import import atg. the processors that save and load an Order look for an item descriptor that is mapped to the corresponding commerce object class. atg.commerce.*.repository. The my.*. which perform the actual saving of the Order object to the Order Repository.*.beans.order. is mapped to the new MyOrder class in the orderTypeClassMap property in the configuration file above.commerce. In ATG Commerce. atg. in turn.commerce.*.util. import java.class. the beanNameToItemDescriptorMap property contains this mapping. you must create a new processor that saves the OrderData object to the Order Repository and insert that new processor into the updateOrder pipeline. mapping the orderData and myOrder item descriptors that you created in step 1 to their corresponding classes. (For more information on the updateOrder pipeline. This functionality corresponds to the savedProperties property and the propertyDescriptorToBeanPropertyMap property in the properties file which corresponds the this object. When one of the createOrder() methods that does not take a type parameter is called. atg. write the Java source code for the new processor. the method constructs and returns an instance of the corresponding class.) First.service. The configuration file above adds two new entries. Step 5 of 7 – Add a Processor to Save the New Object You do not need to write new code to save the orderData reference in the MyOrder object.ATG Commerce Programming Guide µ The beanNameToItemDescriptorMap property maps Order Repository item descriptors to Bean names. By default. All pipeline processors must 413 12 . The following Java source file.dir prefix indicates some Java package in which the class exists.pipeline. the defaultOrderType property is set to the type “default. SavedProperties provides a set of properties and a way to retrieve a mapped property.

OrderTools orderTools = (OrderTools) orderManager. // The constructor public ProcSaveOrderDataObject() { } // Returns the set of all valid return codes for this processor. MutableRepositoryItem mutItem = null. 414 12 . FAILURE}.ORDERMANAGER). Order order = (Order) map.ORDERREPOSITORY).Customizing the Purchase Process Externals .get(PipelineConstants. MutableRepository mutRep = null.getOrderTools(). } // property: orderDataProperty // This is the order data property.ORDER). This code extracts the required parameters for this processor. */ public class ProcSaveOrderDataObject extends SavedProperties implements PipelineProcessor { // These are the two valid return codes for this pipeline processor private final int SUCCESS = 1. } public void setOrderDataProperty(String pOrderDataProperty) { mOrderDataProperty = pOrderDataProperty. } public int runProcess(Object pParam. public String getOrderDataProperty() { return mOrderDataProperty.get(PipelineConstants. private final int FAILURE = 2. public int[] getRetCodes() { int[] ret = {SUCCESS.get(PipelineConstants. Repository repository = (Repository) map. */ HashMap map = (HashMap) pParam. OrderManager orderManager = (OrderManager) map. PipelineResult pResult) throws Exception { /* The pParam parameter contains the data required for executing this pipeline processor.µ ATG Commerce Programming Guide implement this interface. Object value = null. private String mOrderDataProperty = "orderData". return ret.

*/ try { mutRep = (MutableRepository) repository. If getSaveChangedPropertiesOnly() returns false. otherwise it sets the list of properties to save to the savedProperties property. then a check is done to determine whether the orderData object implements ChangedProperties. if (orderManager == null) throw new InvalidParameterException(). The saveChangedPropertiesOnly property is inherited from SavedProperties. If so. In most cases it will be a GSA Repository which is mutable. or take advantage of ChangedProperties. String mappedPropName = null. then the local variable savedProperties is set to the entire list of properties defined in the SaveOrderDataObject. } /* This code is taking advantage of the ChangedProperties interface methods.properties file. // Check for null parameters if (order == null) throw new InvalidParameterException(). if (getSaveChangedPropertiesOnly()) { if (orderData instanceof ChangedProperties && (! ((ChangedProperties) orderData).ATG Commerce Programming Guide µ Object[] savedProperties = null. /* Try to cast the repository and make sure that it is a MutableRepository. } catch (ClassCastException e) { throw e. */ CommerceIdentifier orderData = (CommerceIdentifier) DynamicBeans.Customizing the Purchase Process Externals .toArray(). then it gets the list of properties whose value has changed. The first check is checking whether this processor is configured to save all properties always. If it returns true. } /* Next a check is done to get the repositoryItem property from the object if it has 415 12 .getPropertyValue(order. getOrderDataProperty()).getSaveAllProperties())) savedProperties = ((ChangedProperties) orderData). if (repository == null) throw new InvalidParameterException(). } else { savedProperties = getSavedProperties(). else savedProperties = getSavedProperties().getChangedProperties().

"repositoryItem").getPropertyValue(order.getItemForUpdate(orderData. If it does not have the repositoryItem property or its value is null.setPropertyValue(orderData. 416 12 . mutItem = (MutableRepositoryItem) DynamicBeans. orderTools. orderData. if (hasProperty) DynamicBeans.hasProperty("repositoryItem")) { hasProperty = true.getId(). "repositoryItem". then this for loop can be eliminated. then a lookup is done in the repository for the item and set if it has the property. The OrderRepositoryUtils class provides functionality which parses mapped property values and either gets the property values.µ ATG Commerce Programming Guide a repositoryItem property defined. mappedPropName). */ boolean hasProperty = false. if (! OrderRepositoryUtils. etc. mappedPropName)) continue.hasProperty(order. */ for (int i = 0. // should not happen } if (orderManager. i < savedProperties.getId() + "]").getName())). orderData. then the property will be saved to the repository.length. } catch (PropertyNotFoundException e) { continue. This code is preserved so it will allow classes created for DCS 5.getMappedItemDescriptorName( orderData.isLoggingDebug()) orderManager. If your classes do not use the addChangedProperties() method in the set() methods of your beans.getClass().Customizing the Purchase Process Externals .getClass().logDebug("save property[" + (String) savedProperties[i] + ":" + value + ":" + orderData. try { value = OrderRepositoryUtils. if (DynamicBeans.0 to still work.getPropertyValue(orderData. i++) { mappedPropName = getMappedPropertyName((String) savedProperties[i]). determines if the property exists. } if (mutItem == null) { mutItem = mutRep.getBeanInfo(orderData). } /* This section loops through all the properties in the savedProperties array and if they exist in the object being saved.getName() + ":" + orderData. mutItem).

(String) savedProperties[i]. } /* Finally. } // for /* Here the repository item is updated to the repository. mutItem. value. This is done here to catch any Concurrency exceptions. This resets the object for more edits. */ if (orderData instanceof ChangedProperties) { ChangedProperties cp = (ChangedProperties) orderData. cp.properties file to your localconfig directory at /atg/commerce/order/processor/. the ChangedProperties Set is cleared and the saveAllProperties property is set to false.updateItem(mutItem). Nothing needs to be defined for this property 417 12 . This requires that when a property is changed that it be marked # for saving.ProcSaveOrderDataObject # This property tells the processor to only save the properties which have # changed. saveChangedPropertiesOnly=true # # # # # # # These are the properties of the OrderData object which will be saved to the repository.ATG Commerce Programming Guide µ OrderRepositoryUtils. If the name in the bean and repository are not the same then it can be mapped in the property propertyDescriptorToBeanPropertyMap below. } } Next.setSaveAllProperties(false). */ try { mutRep.Customizing the Purchase Process Externals . orderTools). All properties which should be saved should be listed here. The configuration file might look as follows: $class=my_package. e). cp. configure an instance of ProcSaveOrderDataObject by adding a SaveOrderDataObject. } return SUCCESS. Then the SUCCESS value is returned.clearChangedProperties(). By default a property name listed here will be saved to the corresponding repository item property with the same name. } catch (ConcurrentUpdateException e) { throw new CommerceException("Concurrent Update Attempt".saveRepositoryItem(mutRep.

By convention.java serves as an example. setLastModifiedTime. updateOrderObject.service. # The format is repository_property_descriptor=bean_property_name propertyDescriptorToBeanPropertyMap= orderDataProperty=orderData Finally. to load the data into the OrderData object itself. refer to Processor Chains and the Pipeline Manager chapter. which performs the actual loading of most of the contained objects in the Order. the most appropriate place would be immediately after the updateOrderObject processor. import atg. However. The loadOrderObject processor in the loadOrder pipeline knows how to load all of the properties of the Order object. For more information on XML file combination. ProcLoadOrderDataObject. For more information on how to add a processor to an existing pipeline. the ATG platform uses XML file combination to combine the commercepipeline. it is located at /<ATG9dir>/B2BCommerce/config/atg/commerce/.commerce.xml file by creating a new commercepipeline. this file is located at /<ATG9dir>/B2CCommerce/config/atg/commerce/. Step 6 of 7 – Add a Processor to Load the New Object You do not need to write new code to load the orderData reference in the Order object.*. they can be mapped here. commercepipeline. By default the processor will look for an OrderRepository # property descriptor which is the same as the bean property name. In ATG Business Commerce.repository. import atg. and before the last processor. package my_package.µ savedProperties= ATG Commerce Programming Guide # This property maps a OrderRepository property descriptor to an OrderData # bean property. The following Java source file. regardless of whether the commerce object hierarchy has been extended. see Loading Orders in the Configuring Purchase Process Services chapter. If # there are any properties whose names differ. import atg. insert the SaveOrderDataObject processor into the updateOrder pipeline. you must create a new processor that loads the data from the repository into the OrderData object and insert that new processor into the refreshOrder pipeline. see the Nucleus: Organizing JavaBean Components chapter in the ATG Programming Guide.*. (For more information on loading and refreshing orders. 418 12 . you should insert the processor into the pipeline immediately after the processor that references the new object.) First. extend the commercepipeline. The updateOrder pipeline is defined in the commerce pipeline definition file.*. write the Java source code for the new processor. In ATG Consumer Commerce.Customizing the Purchase Process Externals .xml.order. Insert the new processor into the pipeline somewhere after the first processor. To insert the SaveOrderDataObject processor into the updateOrder pipeline.xml files in the CONFIGPATH into a single composite XML file. In this example.pipeline.xml file that defines the new processor and placing it in your localconfig directory at /atg/commerce/. During deployment.

/* This class extends a class called LoadProperties. return ret.*.*.order. This class also implements the PipelineProcessor interface. FAILURE}. } public int runProcess(Object pParam. 419 12 . // The constructor public ProcLoadOrderDataObject() { } // Returns the set of all valid return codes for this processor. All pipeline processors must implement this interface. private final int FAILURE = 2.processor.*.ATG Commerce Programming Guide µ import atg.util. LoadProperties provides a set of properties and a way to retrieve a mapped property. */ public class ProcLoadOrderDataObject extends LoadProperties implements PipelineProcessor { // These are the two valid return codes for this pipeline processor private final int SUCCESS = 1. } // property: orderDataProperty private String mOrderDataProperty = null. public int[] getRetCodes() { int[] ret = {SUCCESS.Customizing the Purchase Process Externals . import atg. public String getOrderDataProperty() { return mOrderDataProperty. This code extracts the required parameters for this processor. import java. PipelineResult pResult) throws Exception { /* The pParam parameter contains the data required for executing this pipeline processor. This functionality corresponds to the loadProperties property and the propertyDescriptorToBeanPropertyMap property in the properties file which corresponds the this object.beans.commerce. This interface includes the runProcess() and getRetCodes() methods. } public void setOrderDataProperty(String pOrderDataProperty) { mOrderDataProperty = pOrderDataProperty.

if (orderManager == null) throw new InvalidParameterException(). MutableRepositoryItem orderItem = (MutableRepositoryItem) map. OrderTools orderTools = orderManager. "id". String className = orderTools.get(PipelineConstants.setPropertyValue(ci. */ MutableRepositoryItem mutItem = (MutableRepositoryItem) orderItem. RepositoryItemDescriptor desc = mutItem. /* This section loops through all the properties in the loadProperties array and 420 12 .getMappedBeanName(desc. the item descriptor is set to it.forName(className).µ */ ATG Commerce Programming Guide HashMap map = (HashMap) pParam.setPropertyValue(ci. DynamicBeans. Next it gets the orderData item descriptor.get(PipelineConstants. /* Next. loadProperties lists all the properties which must be loaded for this object.hasProperty("repositoryItem")) DynamicBeans. mutItem). String[] loadProperties = getLoadProperties(). Order order = (Order) map. */ String mappedPropName. OrderManager orderManager = (OrderManager) map.Customizing the Purchase Process Externals .getBeanInfo(ci). and if the object has a repositoryItem property.getRepositoryId()).getOrderTools().getItemDescriptor(). // Check for null parameters if (order == null) throw new InvalidParameterException(). */ CommerceIdentifier ci = (CommerceIdentifier) Class. /* This section of code first gets the orderData item descriptor from the order repository item.ORDERREPOSITORYITEM).newInstance(). its id property set to the repository item's id. The third line of code does a lookup in the OrderTools object and returns the class mapped to the orderData item descriptor. if (orderItem == null) throw new InvalidParameterException(). Object value. if (DynamicBeans. an instance of OrderData is constructed. "repositoryItem".ORDERMANAGER).ORDER).get(PipelineConstants.getPropertyValue(getOrderDataProperty()). mutItem.getItemDescriptorName()). /* Local variables.

value). etc. loadProperties= 421 12 . This code is preserved so it will allow classes created for DCS 5. return SUCCESS. return SUCCESS. configure an instance of ProcLoadOrderDataObject by adding a LoadOrderDataObject.ATG Commerce Programming Guide µ loads the property values from the repository into the object. if (desc. First we look for a mapping to the property value and then look to see if the property exists in the item descriptor. DynamicBeans. If the # name in the bean and repository are not the same then it can be mapped # in the property propertyDescriptorToBeanPropertyMap below.hasProperty(loadProperties[i])) { value = mutItem. */ for (int i = 0.properties file to your localconfig directory at /atg/commerce/order/processor/. The configuration file might look as follows: $class=my_package. If so. ci. then this for loop can be eliminated. If your classes use the getPropertyValue() method in the get() methods of your beans. getOrderDataProperty().clearChangedProperties().setPropertyValue(order.getClass().ProcLoadOrderDataObject # These are the properties of the Order which will be loaded from the # repository.Customizing the Purchase Process Externals . ci).isLoggingDebug()) orderManager. then we load it.getName() + ":" + ci. */ if (ci instanceof ChangedProperties) ((ChangedProperties) ci). determines if the property exists.setPropertyValue(order. } } Next.getPropertyValue(loadProperties[i]). } } /* If the loaded object implements ChangedProperties. then clear the changedProperties Set. Nothing needs # to be defined for this property.logDebug("load property[" + loadProperties[i] + ":" + value + ":" + ci. if (orderManager. The OrderRepositoryUtils class provides functionality which parses mapped property values and either gets the property values. i < loadProperties. mappedPropName.0 to still work. i++) { mappedPropName = getMappedPropertyName(loadProperties[i]).length.getId() + "]"). By default a property name listed here will be loaded from # the corresponding repository item property with the same name. OrderRepositoryUtils. Finally. Then set the orderData property in the Order object to ci.

the items use the ID space name of the root item descriptor in the super-type hierarchy. In ATG Business Commerce. propertyDescriptorToBeanPropertyMap= orderDataProperty=orderData Finally. If # there are any properties whose names differ. refer to the Processor Chains and the Pipeline Manager chapter. the ATG platform uses XML file combination to combine the commercepipeline. commercepipeline.µ ATG Commerce Programming Guide # This property maps a OrderRepository property descriptor to an Order # bean property. loadOrderObjectForRefresh. The item descriptor’s id-space-name attribute specifies which IdSpace supplies repository IDs for items of that item type. orderData. you need to modify the ID spaces definition file. By default. In the latter case. the most appropriate place would be immediately after the loadOrderObjectForRefresh processor. As previously mentioned. The refreshOrder pipeline is defined in the commerce pipeline definition file. If a new item descriptor that you’ve defined is a root item descriptor. see the Nucleus: Organizing JavaBean Components chapter in the ATG Programming Guide. create a new idspaces.xml files in the CONFIGPATH into a single composite XML file. By convention. Insert the new processor into the pipeline somewhere after the first processor. you need to define an ID space for that descriptor. you’ve defined a single root item descriptor. Consequently. For more information on XML file combination. it is requested from the appropriate IdSpace for that repository item.xml file by creating a new commercepipeline. idspaces.xml. all items use the item descriptor’s name as the ID space unless their item type inherits from another item type. ATG Commerce IdGenerator guarantees that IDs within a named ID space are unique. it is located at /<ATG9dir>/B2BCommerce/config/atg/commerce/. In this example. extend the commercepipeline. this file is located at /<ATG9dir>/B2CCommerce/config/atg/commerce/. you should insert the processor into the pipeline immediately after the processor that references the new object.xml file that defines the new processor and placing it in your localconfig directory at /atg/commerce/. In ATG Consumer Commerce. for more information on how to add a processor to an existing pipeline.Customizing the Purchase Process Externals . It does not need to be performed when the new item descriptor is a subclass of an item descriptor. they can be mapped here.xml file at /atg/dynamo/service/ in your localconfig directory.xml. To insert the LoadOrderDataObject processor into the refreshOrder pipeline. and each root item descriptor defines the characteristics of its ID space in the idspaces.xml definition file.xml files in the CONFIGPATH into a single 422 12 . During deployment. Step 7 of 7 – Extend the ID Spaces Definition File Note: This step is only necessary when the new item descriptor is a root item descriptor. In the example used throughout this section. # The format is repository_property_descriptor=bean_property_name # The repository_property_descriptor name must be listed above in # loadProperties. To do so. the ATG platform uses XML file combination to combine the idspaces. During deployment. By default the processor will look for an OrderRepository # property descriptor which is the same as the bean property name. insert the LoadOrderDataObject processor into the refreshOrder pipeline. in order to define an ID space for that item descriptor. When an ID is requested for a new repository item.

Manipulating Extended Objects Regardless of the method you use to extend purchase process objects (using an existing or new item descriptor). • If you’ve extended CommerceItem. Other types of extensions require extensions to the form handler. and calling ShippingGroupManager. mergeOrdersCopyShippingGroup. if you’ve extended certain ATG Commerce classes to store additional information. Merging Orders The standard process for merging orders involves OrderManager.Customizing the Purchase Process Externals . in turn. However. you may need to make additional changes as described in Merging Orders in this chapter. you should subclass CommerceItemManager and override the mergeOrdersCopyCommerceItem method to first call the superclass method to do the basic copy and then copy your extended commerce item data. you may need to override portions of CartModifierFormHandler. see the Nucleus: Organizing JavaBean Components chapter in the ATG Programming Guide.xml file might look as follows: <id-spaces xml-combine="append"> <id-space name="orderData" seed="1" batch-size="10000" prefix="od"/> </id-spaces> For more information on defining ID spaces and its impact on repository item IDs. you must change the methods used for merging orders so the additional information is copied to the destination order when merging orders. calls either mergeOrdersCopyHardgoodShippingGroup or mergeOrdersCopyElectronicShippingGroup. you may need to extend some additional areas as well: • • If you extend an implementation of CommerceItem or ShippingGroup.ATG Commerce Programming Guide µ composite XML file. See Handling Custom Commerce Item Properties in the Implementing Shopping Carts chapter of the ATG Commerce Guide to Setting Up a Store for more information. (For more information on XML file combination. This form handler is capable of handling new primitive data type properties automatically. In the ShippingGroupManager.mergeOrdersCopyCommerceItem() to copy existing commerce items from a source order to a destination order. see the ID Generators section of the Core Dynamo Services chapter in the ATG Programming Guide. depending on the type of the shipping group.mergeOrders() calling CommerceItemManager. If you add custom properties to a CommerceItem.mergeOrdersCopyShippingGroup to copy existing shipping groups from the source order to the destination order. you should subclass ShippingGroupManager and override the • 423 12 .) The idspaces. If you’ve extended HardgoodShippingGroup.

If the shipping group is of the new type you created.Customizing the Purchase Process Externals . then the subclass should copy it to the destination order. you should subclass ShippingGroupManager and override the mergeOrdersCopyElectronicShippingGroup method to first call the superclass method to do the basic copy and then copy your extended commerce item data. Otherwise. you should subclass ShippingGroupManager and override the mergeOrdersCopyShippingGroup method to examine the class of the shipping group. If you’ve extended ElectronicShippingGroup.µ • • ATG Commerce Programming Guide mergeOrdersCopyHardgoodShippingGroup method to first call the superclass method to do the basic copy and then copy your extended commerce item data. 424 12 . If you’ve created a new shipping group type that is neither a subclass of HardgoodShippingGroup nor ElectronicShippingGroup. the method can call the superclass mergeOrdersCopyShippingGroup method to handle the standard shipping group types.

which are linked in processor chains.ATG Commerce Programming Guide µ 13 Processor Chains and the Pipeline Manager The Pipeline Manager is a system that executes a series of processors.Processor Chains and the Pipeline Manager . The status code can determine which processor to execute next. The Pipeline Manager enables you to dynamically add and remove processors and chains of processors. You can imagine a tree structure of processor chains as below: 425 13 . The Pipeline Manager does so in a transactionally aware way. Each processor in the processor chain is a component that performs a specific function and returns a status code. but it is used primarily by ATG Commerce. The status code determines which processor in the chain to execute next. The pipeline functionality is part of the main Dynamo Application Framework. supporting a subset of the transactional modes that EJB supports. which make up a processor chain. A processor is a component that executes a piece of functionality and returns a status code. This chapter includes the following sections: Pipeline Manager Overview Using the Pipeline Editor Running a Processor Chain Creating a Processor Pipeline Pipelines and Transactions Extending the Processor Pipeline Classes Adding a Commerce Processor Using XML Combination Commerce Processor Chains Pipeline Manager Overview The Pipeline Manager controls a series of processors.

and executes the code for InventoryReserve. viewing and editing pipeline chains. It might include a processor chain that is invoked when users add an item to their shopping cart. then the Pipeline Manager either commits or rolls back the InventoryReserve transaction. then the Pipeline Manager creates a new one. which would be the one that was passed to the pipeline manager. This Add to Cart chain might contain the following elements in the given order: InventoryCheck. Next. creates a new transaction. the InventoryReserve processor uses its own transaction to access the inventory. InventoryReserve. For example. suppose you have a commerce site.µ Processor C1 Processor A Processor B Processor C2 ATG Commerce Programming Guide Processor D0 Processor D1 Processor E Processor D2 The processors in the processor chain illustrated above would be executed from left to right. it will simply use that transaction for executing the pipeline. it calls each processor in sequence from InventoryCheck to AddToOrder without altering the transaction in any way. the Pipeline Manager suspends the current transaction. FraudDetection. Using the Pipeline Editor The Pipeline Editor in the ATG Control Center provides a graphical user interface for creating. When the request reaches InventoryReserve. If there was already an existing transaction. An element in a processor chain can specify that it should be executed in the context of its own transaction. and then resumes the original transaction before it executes the FraudDetection processor.Processor Chains and the Pipeline Manager . when it reaches the Pipeline Manager. When the InventoryReserve processor completes execution of its transaction. If a transaction had not been created. Notice that chains are allowed to split and merge together. The following section covers the following topics: • • • Accessing the Pipeline Editor Opening an Existing Pipeline Definition Creating a New Pipeline Definition 426 13 . and AddToOrder. For a more concrete example.

Processor Chains and the Pipeline Manager . 427 13 . To access the pipeline editor. select Utilities > Pipeline Editor from the navigation menu of the ACC. Select the Pipeline Manager that you want to open from the list and click on the Open Pipeline Definition button. The Pipeline Editor opens: Opening an Existing Pipeline Definition The following steps describe how to open an existing pipeline definition. If you have problems loading an existing definition. 1. Click on the Open Pipeline Definition icon.ATG Commerce Programming Guide µ • • • • • Editing Existing Pipeline Definitions Printing a Pipeline Definition Activating Verbose Mode Changing the Display Font of the Pipeline Editor Reinitializing the Pipeline Manager Accessing the Pipeline Editor The pipeline editor is part of the ATG Control Center. Note: The pipeline manager component must be running for its definition to be loaded. make sure its manager is running. The pipeline definition displays in the ACC. 2.

Type a new Pipeline Chain name and select a new Transaction Mode.Processor Chains and the Pipeline Manager . Click on the New Pipeline Definition button. if necessary.µ ATG Commerce Programming Guide Creating a New Pipeline Definition Follow these steps to create a new pipeline definition. 5. 4. You will see an empty definition with a single empty chain named PipelineChain1. 3. 2. Right-click on the line between the new pipeline chain title and termination point and select Create Pipeline Link. Enter a new pipeline link name and change the Transaction Mode and Processor Mode. 428 13 . 1. Right-click on the Pipeline Chain title icon and select Edit Details. if necessary.

Save diffs: Saves only the difference between the latest changes and the xml combined version of the definition file up to the previous layer. 8. 7. all chains and their processors) is completely written out to XML and all chains are marked as “xmlcombine=replace”. select Edit->Insert Pipeline Chain or right click on any execution line and select Insert Pipeline Chain.xml. This is because you can only open definitions associated with pipeline managers. (JNDI Processor Mode only )Enter a processor for the link or click on Choose Processor to select one from the available processors. The first pipeline chain node is automatically inserted for the user. category. This ensures that this definition gets accepted when xml combination happens. Click on the check mark to close the pipeline link window. you must associate the new XML file with an existing pipeline manager. To register a new pipeline manager or processor. This ensures that information is not saved to the current layer that is already included in other layers. The Pipeline Registry component is located at /atg/registry/PipelineRegistry and its associated XML file is pipelineRegistry.Processor Chains and the Pipeline Manager .ATG Commerce Programming Guide µ 6. you won’t be able to see and select them in the editor. These new properties will be used in the processor picker dialog (edit a link node and for its Processor property hit “Choose Processor”). you need to specify its Nucleus path in the XML file. Save the pipeline definition by selecting one of the following from the File menu. If you don’t register new components. description.e. The following example registers a new manager called MyPipelineManager and a new processor called MyProcessor: <pipeline-registry-configuration> <pipeline-manager-registry xml-combine="append-without-matching"> <pipeline-manager> <nucleus-path>/atg/commerce/MyPipelineManager</nucleus-path> </pipeline-manager> </pipeline-manager-registry> 429 13 . Save all: The complete definition (i. including a display name. Processors are shown with their icon and the description is displayed in a tool tip. Note: If you create a new definition and later want to reopen it. Adding New Pipeline Managers and Processors to the ACC The Pipeline Registry is used to register pipeline manager and pipeline processor components with the Pipeline Editor. The pipeline editor will automatically display the appropriate number of transitions for the selected processor. You can optionally specify additional properties for processors. You can create a new pipeline manager and set its definition file to point to your new definition. To create new chain nodes. Repeat the steps for creating pipeline chains and links for the rest of the pipeline definition. The picker lists processors by category. and icon. 9.

You can edit the properties of this node to set the chain’s name and transaction mode. the set of possible integer outcomes (as defined by the interface atg. You can perform the following editing functionality on editor nodes. Once you have specified the processor. 430 13 . processor mode. • • • copy and paste drag and drop processor elements undo and redo actions Overview of Pipeline Editor Interface This section describes the icons in the pipeline editor.service.Processor Chains and the Pipeline Manager . The icon above represents an individual link in a pipeline chain. The icon above represents the name of the pipeline chain. and processor name.pipeline.PipelineProcessor) are automatically represented as part of the node with separate execution paths. transaction mode. You can edit the properties of this node to set the link’s name.µ ATG Commerce Programming Guide <processor-registry xml-combine="append-without-matching"> <processor> <nucleus-path>/atg/commerce/payment/MyProcessor</nucleus-path> <display-name>My Processor</display-name> <category>Payment</category> <description>A Custom Payment Processor</description> </processor> </processor-registry> </pipeline-registry-configuration> Editing Existing Pipeline Definitions Pipelines in the ACC are edited in a way similar to the way scenarios are edited.

The icon above represents a stop in the execution of this path.processor.ProcExecuteChain. The icon above represents a jump back to a prior link in the chain. Printing a Pipeline Definition Follow these steps to print the pipeline chains in the open pipeline definition. These are defined in atg. The same information is available by double clicking on 431 13 . The information appears in popup window.commerce.ATG Commerce Programming Guide µ The icon above represents a link whose processor returns a special value. The icon above represents a special link whose processor is an instance of atg. There are 2 predefined return codes with a special meaning: 0 (stop chain execution and commit) and –1 (stop chain execution and rollback).pipeline.Processor Chains and the Pipeline Manager . Click on the Print icon.service. 1. This processor executes a subchain and returns. Activating Verbose Mode Verbose mode allows you to view detailed information for pipeline nodes by moving your cursor over the node. You can print any definition in the editor window.order. 2. Select one of the following and click on OK: Scale to Page: Prints entire pipeline definition on one page No Scaling: Prints pipeline definition at full size on multiple pages (if necessary). You can edit the node to change the destination.PipelineProcessor.

432 13 . Select File… Edit pipeline manager component.Processor Chains and the Pipeline Manager . When verbose mode is active. Pipeline Debugging You can access the component editors for pipeline manager and pipeline processor components to turn debugging on/off. 3. A link’s destination is the next link to be executed if the current processor returns a certain value. Follow these steps to debug an individual processor. You can activate verbose mode by selecting File…Set Verbose Mode On. 1. verbose mode is turned off. 2. Select Edit selected pipeline processor component. and the possible destinations for a pipeline link. the verbose tool tip lists the headlink for pipeline chains. you can turn it off by selecting File…Set Verbose Mode Off. Select a pipeline manager. set loggingDebugOnProcessors to true to turn debugging on for all processors in the definition. In the component editor. By default. Follow these steps to debug a definition. 2.µ ATG Commerce Programming Guide a node or right clicking and choosing Edit Details In addition. Right-click on a pipeline link node. 1.

This is determined by what is defined in the PipelineChain object. make a call to the runProcess() method in the PipelineManager. This section describes what happens when a processor chain is executed. Select Tools > Preferences.Processor Chains and the Pipeline Manager . If you make changes to a pipeline definition and you want the changes to take affect in the session you are currently running. an exception is thrown. 2. PipelineManager calls runProcess() on it and passes it the user data. 2. 4. Click on the Fonts tab in the dialog box. In the component editor. Changing the Display Font of the Pipeline Editor You can change the font that the pipeline editor uses to display the pipeline definitions in the ACC as follows: 1. If is not enabled. If the requested chain is enabled. Select a new font for the Scenario Editor. The runProcess() method in the PipelineChain managers execution of the processors. The Pipeline Editor uses the same font settings. set loggingDebug to true. Open an existing pipeline definition Modify the definition.ATG Commerce Programming Guide µ 3. the pipeline manager is automatically reinitialized. 3. delete a link in a chain or change a link to execute a different processor. you must reinitialize the pipeline manager. The PipelineLink is responsible for three actions: • • • handling the transaction (if required) executing the processor. and returning the return code to the PipelineChain. Click on Save your changes. The runProcess() method is called on the head PipelineLink object of the processor chain. A PipelineResult object or subclass of it is constructed. 1. Reinitializing the Pipeline Manager When you deploy an application that includes ATG Commerce. Follow these steps to reinitialize the pipeline manager. Running a Processor Chain To execute a processor chain in the PipelineManager. The PipelineManager first finds the requested chain. 433 13 . For example. Click on the Reinitialize button to load the new definition into the pipeline manager. 3.

µ • • • • preChainTransaction() postChainTransaction() preLinkTransaction() postLinkTransaction() ATG Commerce Programming Guide To handle the transaction. The following sections describe how to create a processor pipeline: • Configuring a Pipeline Manager 434 13 . If a value other than STOP_CHAIN_EXECUTION is returned. and deletion of processor chains and processors. Any other return value from runProcess() indicates the next processor to execute. The API is provided for dynamic creation.Processor Chains and the Pipeline Manager . see the Creating and Editing Processor Chains Programmatically section. STOP_CHAIN_EXECUTION can be returned from any PipelineProcessor.STOP_CHAIN_EXECUTION. For more information. the transactions are handled and the PipelineResult object is returned. If a PipelineLink is returned. editing. the transaction is rolled back if needed. Any non-globally scoped Pipeline Managers need to be created using the API. which can be organized into processor chains. and this method exits throwing the appropriate exception object. This provides you with a simple way to construct and manage the global PipelineManager without writing code. which is mapped to the static variable PipelineProcessor. the PipelineChain calls getNextLink() on the PipelineLink just executed and passes it the return value it received. through an XML file or through the atg. You can create and delete pipelines in two ways. tells the PipelineManager that execution for this chain should stop normally. The runProcess() method is called between these methods and the return value of the call is returned to the PipelineChain. If null is returned. then an exception is thrown. You can initialize a Pipeline Manager with a set of processor chains at application deployment using an XML configuration file called a pipeline definition file.service. Creating a Processor Pipeline A processor pipeline consists of a Pipeline Manager and a set of processors. These methods are called in the following order: These calls make the appropriate calls and construct any required objects for the execution of the processor in the context of the transaction mode. regardless of whether it has next links or not. This call returns another PipelineLink to execute or null. These calls are described in the Pipelines and Transactions section. For more information. The return value of 0. When STOP_CHAIN_EXECUTION is returned. four methods are called before and after the call to runProcess() in the PipelineProcessor.pipeline API. It only can be used for initializing the globally scoped PipelineManager that is created during deployment. see the Pipeline Definition Files section. then the above process repeats.

or can be configured by an XML definition file.xml The value of this property is a file pathname. 435 13 . The default setting is: chainLockWaitTimeout=15000 Creating Processors Any Java class can act as a processor in a pipeline by implementing the atg.pipeline. Pipeline Definition Files The contents of the processor chains controlled by a Pipeline Manager can be determined programmatically. relative to your CONFIGPATH.Processor Chains and the Pipeline Manager . For example: definitionFile=/atg/userprofiling/registrationPipeline. The Pipeline Definition Files section describes how to create the XML file that defines the processor chains controlled by a Pipeline Manager. as specified by the Pipeline Manager’s definitionFile property. PipelineResult pResult) The runProcess() method returns an integer status code that the Pipeline Manager uses to determine the next processor to run. This XML file can be anywhere in the CONFIGPATH. The PipelineProcessor interface has a single method: int runProcess(Object pParam. as described in the next section. The value of this property is in milliseconds.PipelineProcessor interface. The Pipeline Manager has two properties you may want to configure: definitionFile and chainLockWaitTimeout. a Pipeline Manager instance is located at /atg/commerce/PipelineManager.ATG Commerce Programming Guide µ • • • • Creating Processors Pipeline Definition Files Creating and Editing Processor Chains Programmatically Extending the PipelineChain and PipelineResult Classes Configuring a Pipeline Manager Each processor chain is controlled by a Pipeline Manager component. If you are using ATG Commerce. chainLockWaitTimeout Property The chainLockWaitTimeout property determines the amount of time the request handling thread should wait for a processor chain to execute its processing of the request. definitionFile Property The definitionFile property points to the XML file that defines the processor chains that can be run by the Pipeline Manager. Creating and Editing Processor Chains Programmatically.service. This section describes how to create an XML definition file for a Pipeline Manager.

Tag defining a given processor chain in the Pipeline Manager.the full name of a Java class which is to be instantiated and used as the PipelineChain object.service. The default is atg. The value must be this class or a subclass of it. each defined by a <pipelinechain> Attributes none pipelinechain name .(required) the name of the processor chain (for example: AddToCart). tag. Must be unique. The valid modes are TX_REQUIRED TX_REQUIRES_NEW TX_SUPPORTS TX_NOT_SUPPORTED TX_MANDATORY 436 13 .the full name of a Java class which is to be instantiated and used as the PipelineResult object. transaction .the default transactional mode of all the processors in this chain. The default is atg. This configuration file must be written in XML. Must be unique. resultclassname . A pipeline definition file can use the following tags: Description The top level tag that encloses a definition of a Pipeline Manager.PipelineChain. This corresponds to the id in the PipelineChain object.(required) a name for this processor (for example: CheckInventory).PipelineResult.a transactional mode that overrides the default mode of the chain. headlink . The value must implement PipelineResult. pipelinelink Defines a processor within the chain and names it.Processor Chains and the Pipeline Manager .(required) the first processor in the chain to be executed. A Pipeline Manager can include any number of processor chains. name .pipeline.pipeline.µ Tag PipelineManager ATG Commerce Programming Guide Configuring processor chains with a pipeline definition file is useful for creating chains that are not edited or creating generic chains that will later be edited dynamically using the API based on some other criteria.service. The valid modes are: TX_REQUIRED TX_REQUIRES_NEW TX_SUPPORTS TX_NOT_SUPPORTED TX_MANDATORY classname . transaction .

jndi .. link .. "TX_REQUIRED" classname CDATA "atg. processor The name of the PipelineProcessor object. then the object is resolved through JNDI and its reference is used as the pipeline element. The object is resolved through JNDI and its reference is used as the processor. transition A reference to the next link to be executed mapped by a return value. "TX_REQUIRED"> <!ELEMENT processor EMPTY> <!ATTLIST processor class CDATA #IMPLIED jndi CDATA #IMPLIED> <!ELEMENT transition EMPTY <!ATTLIST transition 437 13 .service.pipeline.the processor class to be referenced to. If it is of the form jndi://.service.(required) an integer string that is used to define the next pipeline element. If the attribute is of the form packagename.PipelineChain" resultclassname CDATA "atg.classname then a new object is to be created.Processor Chains and the Pipeline Manager ..the processor class to be instantiated or referenced to.. Document Type Definition for Pipeline Definition Files Pipeline definition files use the following XML document type definition: <!ENTITY %transactionmodes "(TX_REQUIRED|TX_REQUIRES_NEW|TX_SUPPORTS|TX_NOT_SUPPORTED|TX_MANDATORY)"> <!ELEMENT PipelineManager (pipelinechain*)> <!ELEMENT pipelinechain (pipelinelink*)> <!ATTLIST pipelinechain name ID #REQUIRED headlink IDREF #REQUIRED transaction %transactionmodes. returnvalue ./.(required) the name of a pipelineprocessor that will be executed if the return value of the current pipelineprocessor matches the returnvalue of this link.PipelineResultImpl"> <!ELEMENT pipelinelink (processor..ATG Commerce Programming Guide µ class .transition*)> <!ATTLIST pipelinelink name ID #REQUIRED transaction %transactionmodes.pipeline.

xml.µ returnvalue CDATA #REQUIRED link IDREF #REQUIRED> ATG Commerce Programming Guide Pipeline Definition File Example The following file.addB"/> <transition returnvalue="1" link="proc4"/> <transition returnvalue="2" link="proc5"/> </pipelinelink> <pipelinelink name="proc3"> <processor class="atg. is an example of a pipeline definition file that might be used for initializing a pipeline.addD"/> </pipelinelink> <pipelinelink name="proc6" transaction="TX_NOT_SUPPORTED"> <processor class="atg.pipeline.addE"/> <transition returnvalue="1" link="proc6"/> <transition returnvalue="2" link="proc7"/> <transition returnvalue="3" link="proc2"/> </pipelinelink> <pipelinelink name="proc4"> <processor class="atg.commerce.commerce.Processor Chains and the Pipeline Manager .commerce.addA"/> <transition returnvalue="1" link="proc2"/> <transition returnvalue="2" link="proc3"/> </pipelinelink> <pipelinelink name="proc2" transaction="TX_REQUIRES_NEW"> <processor class="atg.dtd"> <PipelineManager> <pipelinechain name="AddToCart" transaction="TX_REQUIRED" headlink="proc1"> <pipelinelink name="proc1"> <processor class="atg.removeA"/> </pipelinelink> 438 13 .0"?> <!DOCTYPE PipelineManager SYSTEM "PipelineManager.commerce.PipelineMonoChain"> <pipelinelink name="proc99"> <processor class="atg.commerce.addC"/> </pipelinelink> <pipelinelink name="proc5" transaction="TX_REQUIRES_NEW"> <processor class="atg.commerce.addF"/> </pipelinelink> <pipelinelink name="proc7" transaction="TX_SUPPORTS"> <processor jndi="/dynamo/atg/commerce/addG"/> </pipelinelink> </pipelinechain> <pipelinechain name="RemoveFromCart" transaction="TX_REQUIRED" headlink="proc99" classname="atg.service. <?xml version="1. PipelineManager.commerce.

commerce.ATG Commerce Programming Guide µ </pipelinechain> </PipelineManager> Each section of the PipelineManager. The PipelineManager initialization routine will construct the object atg.commerce. one with return value 1 which links to proc2 and one with return value 2 which links to proc3. It is like the previous except that proc2 has defined an overriding transactional mode. <PipelineManager> The following line begins the definition for a chain named AddToCart. This PipelineLink has two transitions coming out of it. The head link is proc1.addB"/> <transition returnvalue="1" link="proc4"/> <transition returnvalue="2" link="proc5"/> </pipelinelink> <pipelinelink name="proc3"> 439 13 . <pipelinelink name="proc1"> <processor class="atg. Both proc2 and proc3 are defined later in the file. The default transactional mode of the PipelineLinks is TX_REQUIRED.addA and set the PipelineLink’s processor reference to this object. <pipelinechain name="AddToCart" transaction="TX_REQUIRED" headlink="proc1"> The next section is the definition of a PipelineLink with name proc1 and PipelineProcessor class name atg.commerce.addA.0"?> The following line says that this is a XML file and that its DTD (document type definition) is in the file PipelineManager.addA"/> <transition returnvalue="1" link="proc2"/> <transition returnvalue="2" link="proc3"/> </pipelinelink> The next section defines two additional PipelineLinks. The first line says that this file compiles with the XML version 1.0 specification. <!DOCTYPE PipelineManager SYSTEM "PipelineManager. A <PipelineManager> tag encloses all of the processor chain definitions. <?xml version="1. <pipelinelink name="proc2" transaction="TX_REQUIRES_NEW"> <processor class="atg.dtd.Processor Chains and the Pipeline Manager . which specifies the name of a PipelineProcessor defined later in the file.commerce.dtd"> This following line is the start of the PipelineManager definition.xml file is described below. TX_REQUIRES_NEW.

pipeline.service. The interesting part of this section is the processor definition for proc7. headlink proc99.commerce.commerce. This JNDI reference will be resolved at initialization time and used as the processor for this link.addC"/> </pipelinelink> <pipelinelink name="proc5" transaction="TX_REQUIRES_NEW"> <processor class="atg. Instead of using a Java class name definition. start the Pipeline Manager component to construct the PipelineManager and its chains automatically. Creating and Editing Processor Chains Programmatically The following section describes various ways to construct or edit a processor chain using the API. some with overriding transactional modes. this processor is defined with a JNDI reference as jndi="/dynamo/atg/commerce/addG".Processor Chains and the Pipeline Manager .µ ATG Commerce Programming Guide <processor class="atg. <pipelinechain name="RemoveFromCart" transaction="TX_REQUIRED" headlink="proc99" classname="atg. The last line is the closing tag that closes off the PipelineManager definition.addE"/> <transition returnvalue="1" link="proc6"/> <transition returnvalue="2" link="proc7"/> <transition returnvalue="3" link="proc2"/> </pipelinelink> This section defines four more PipelineLink objects.commerce. 440 13 . It specifies that the classname to be used for the construction of the PipelineChain is called PipelineMonoChain.commerce.commerce.addF"/> </pipelinelink> <pipelinelink name="proc7" transaction="TX_SUPPORTS"> <processor jndi="/dynamo/atg/commerce/addG"/> </pipelinelink> </pipelinechain> The last section defines another PipelineChain called RemoveFromCart with default transaction mode TX_REQUIRED. The final line is the closing </pipelinechain> tag for the processor chain. <pipelinelink name="proc4"> <processor class="atg.addD"/> </pipelinelink> <pipelinelink name="proc6" transaction="TX_NOT_SUPPORTED"> <processor class="atg.PipelineMonoChain"> <pipelinelink name="proc99"> <processor class="atg.removeA"/> </pipelinelink> </pipelinechain> </PipelineManager> After the XML file is defined.

If the lock reference is the same as the requesting thread. setHeadLink() is called to set the first link object into the chain. as described in the preceding Creating a New Processor Chain from Scratch section. and removeTransition() to edit the chain. When the reference count reaches 0. To prevent starvation of the lockChain() call. createLink(). Otherwise. For all other cases an exception is thrown. Call the PipelineManager’s method createChain(). setHeadLink(). 1.ATG Commerce Programming Guide µ Locking and Synchronization for Editing Processor Chains When you edit a processor chain.Processor Chains and the Pipeline Manager . Call lockChain(). createLink() is called to create all the PipelineLink objects that will be used in this chain and to link them together. Call setHeadLink(). Edit the chain by making calls to the createLink(). Portions of the lockChain() and unlockChain() methods need to be synchronized. Creating a New Processor Chain from Scratch To create a new processor chain using the API: 1. addTransition() is called to create any additional transitions between links. once that method is called. 2. This call will block until there are no threads executing the chain and a lock can be obtained.When you lock a chain. addTransition(). If the lock reference of the chain is null. then the call to lockChain() blocks until the reference count is 0. the PipelineManager gets a reference to the calling thread and stores it within the requested chain. It implicitly locks and disables the chain and then adds it to the Pipeline Manager. The chain keeps a reference count for all the threads executing within it. 441 13 . all the threads sleeping on the runProcess() call will be notified. using the lockChain() method of the PipelineManager. other threads attempting to call runProcess() will sleep until unlockChain() is called. which means that the chain is already locked by another thread. then the lock is granted. Editing an Existing Processor Chain Follow these steps to edit an existing processor chain. particularly those with sections that check the lock reference and set it. you must first obtain a lock on the chain. Once this happens. The lock cannot be granted if there are threads executing in the requested chain. The createChain() method constructs the appropriate PipelineChain object and sets the proper return type into it. Call enableChain() to allow execution on it and unlockChain() to allow other threads to edit the chain. 2. These last two calls must be made in this order. then the chain is already locked by the caller and execution falls through. 3. then the blocked call is notified and the lockChain() method continues. and addTransition() methods of the PipelineManager. If this count is greater than 0. an exception will be thrown because enableChain() requires the caller to have a lock on the chain.

ATG Commerce Programming Guide Call unlockChain() to release the lock and allow execution of the chain to resume. createLink(). This returns a copy of the chain with a new name. 2. This will replace the chain that has the same name as the new chain. Edit the new chain if required. which will be replaced as the argument. Call enableChain() to allow execution on it and unlockChain() to allow other threads to edit the chain. Create a copy of the chain you want to replace by calling duplicateChain() and passing the chainId. newChainName). Adding and Removing Transitions to and from a Processor Chain Adding and removing transitions to and from a processor chain requires the use of the addTransition() and removeTransition() methods. 3. The new chain is locked and disabled. using the setHeadLink(). These last two calls must be made in this order or an exception will be thrown. 442 13 . because enableChain() requires the caller to have a lock. as described in the Editing an Existing Processor Chain section. addTransition(). Replacing an Existing Processor Chain Follow these steps to remove a chain and replace it with a new version of the same chain. 3. Edit the new chain. as described in the Editing an Existing Processor Chain section. Call lockChain() on the chain that is to be replaced. 1. Call replaceChain() with the new chain as the argument. The following before and after diagram demonstrates adding and removing transitions. 4. Creating a New Processor Chain from an Existing Chain Follow these steps to create a chain based on an existing chain in the PipelineManager. This call will return a duplicate disabled copy of that chain. and removeTransition() methods. Call copyChain(oldChainName.µ 3. Pipeline Link 1 is the head of the chain. 5. in that order. Call enableChain() and unlockChain() on the new chain. 2. Pipeline Link 1a is inserted after Pipeline Link 1 and before Pipeline Link 2 and Pipeline Link 3. The transition from Pipeline Link 3 to Pipeline Link 4 is removed. 1.Processor Chains and the Pipeline Manager .

a PipelineProcessor object. Call createLink() in the PipelineChain to create Pipeline Link 1a.pipeline. 3. Extending the PipelineChain and PipelineResult Classes The examples in the preceding section. 5. 4. Call unlockChain() on the chain.service. atg.Processor Chains and the Pipeline Manager . and 1.ATG Commerce Programming Guide µ Pipeline 1 Link 2 Pipeline Link 4 Pipeline 1 Link 2 Pipeline Link 1 1 Pipeline Link 4 Pipeline Link 3 1 Pipeline Link 1 1 2 Pipeline Link 1a 1 2 Pipeline Link 3 1. 2. This creates the transition from Pipeline Link 1 to Pipeline Link 1a Call addTransition() twice to add the two transitions to Pipeline Link 2 and Pipeline Link 3. Call removeTransition() twice to remove the two transitions that come from Pipeline Link 1.PipelineResult will be the object used for that chain’s PipelineResult object. showed how to create processor chains using the default version of the createChain() method. Call lockChain() in the PipelineManager with the chainId. a reference to the link whose ID is Pipeline Link 1. This version of createChain() takes one argument and constructs and returns an object of type atg. 6. This 443 13 . you can create a processor chain with your subclass in the same way you create a chain using the default PipelineChain and PipelineResult objects. Call removeTransition() with arguments Pipeline Link 3 and 1. If you subclass PipelineChain and PipelineResult. The only difference is that you need to use another version of the createChain() method.pipeline.service. Remove the two transitions from Pipeline Link 1 by doing the following: Get references to Pipeline Link 2 and Pipeline Link 3. This insures that no thread executes in the chain and no other thread edits this chain.PipelineChain (the default). Creating and Editing Processor Chains Programmatically. The arguments to createLink() will be as follows: Pipeline Link 1a. This removes the transition from Pipeline Link 3 to Pipeline Link 4.

PipelineProcessor aProc. PipelineLink aFromLink. the first step is to subclass PipelineChain. except that it accepts two String arguments. Your subclass should include a new version of addTransition() with the following signature: void addTransition(PipelineMonoLink aFromLink.pipeline.Processor Chains and the Pipeline Manager . This example uses a specialized version of PipelineChain called PipelineMonoChain. and the two removeTransition() methods. The subclass’s createLink() method returns PipelineMonoLink. so each PipelineLink object transitions only to a single PipelineLink. For PipelineMonoChain to instantiate a PipelineMonoLink. addTransition(). This PipelineChain subclass represents a singly linked list. The PipelineMonoChain class overrides the following methods in PipelineChain: createLink(). PipelineMonoLink aToLink) throws TransitionException 444 13 .PipelineLink. Otherwise. the instantiatePipelineLink method must be overridden to return a new instance of a PipelineLink subclass. These String arguments identify the classes to be used for the PipelineChain and PipelineResult objects. then a TransitionException is thrown. then the transition is followed. In PipelineLink. The code would look like this: protected PipelineLink instantiatePipelineLink(String pLinkId) { return new PipelineMonoLink(pLinkId). } The addTransition() method checks to see if there is a transition coming out of aFromLink. Otherwise execution on the chain ends and the PipelineResult is returned to the caller.service. The declaration of createLink() looks like this: public PipelineMonoLink createLink(String aLinkId. The aRetCode value has a slightly different meaning in PipelineMonoLink.µ Example ATG Commerce Programming Guide createChain() method does the same thing. which is a special type of PipelineLink object that only allows a single transition out of it. If there is. then a TransitionException would be thrown. the link is mapped. TransitionException This creates a PipelineMonoLink object instead of a PipelineLink object and returns it to the caller. The main difference is that if aFromLink already has a transition coming out of it. To create the PipelineMonoChain class. int aRetCode. It extends atg. the TransitionException is thrown if the aRetCode was already mapped in aFromLink. int aRetCode) throws CreateLinkException. If its value is returned from the PipelineProcessor for that link.

The removeTransition() method checks to see if a transition is coming out of aFromLink. This method would only be called if a PipelineLink (or subclass) that is not a PipelineMonoLink were passed as one of the arguments. The type in the method above is PipelineMonoLink. as in PipelineChain. If none exists then a TransitionException is thrown. insert it into an array and return it. new versions of removeTransition() should be added with the following signatures: void removeTransition(PipelineMonoLink aFromLink. It overrides PipelineChain and PipelineLink to force the objects to allow each link to have only one transition.Processor Chains and the Pipeline Manager . The reason PipelineChain is overridden is to create PipelineMonoLink objects rather than PipelineLink objects. which provide for PipelineMonoLink objects to be passed as parameters rather than PipelineLink objects. The addTransition() method in PipelineLink however still exists and has not been overridden. int aRetCode) throws TransitionException void removeTransition(PipelineMonoLink aFromLink. The PipelineMonoLink would contain the following methods: public public public public public public PipelineMonoLink getNextLink() PipelineLink getNextLink(int aRetCode) PipelineMonoLink getNextLinks() PipelineLink[] getNextLinks(int[] aRetCodes) int getRetCode() int[] getRetCodes() Although it takes a return code parameter. The PipelineMonoLink enforces this. The inherited getNextLink(int aRetCode) method should just call the one with no arguments and return the PipelineMonoLink object that is cast to a PipelineLink. PipelineMonoLink aToLink) throws TransitionException These differ again by the arguments. a getNextLink() method should be defined that takes no arguments and returns a PipelineMonoLink. Again. If one does exist then the transition would be removed. The getNextLinks(int[] aRetCodes) method should also just call getNextLinks() and ignore the aRetCodes and put the PipelineMonoLink into a PipelineLink array. and getRetCodes(). 445 13 . The example in this section implements a singly linked chain. The PipelineMonoLink object needs to extend PipelineLink. getNextLinks(). For cleanliness. The removeTransition() methods that take PipelineLink objects should again be overridden explicitly and exceptions thrown. rather than PipelineLink. This should be explicitly overridden and the code should throw a TransitionException.ATG Commerce Programming Guide µ This differs from the addTransition() in PipelineLink by the first and third arguments. getNextLink(int aRetCode) should just return the PipelineMonoLink object that is mapped to the link that called the method. New methods that are specific to this implementation need to be defined and the following methods need to be overridden: getNextLink(). The int[] getRetCodes() method should again just call getRetCode() and take the return value.

A processor may handle transactions in one of five modes: TX_REQUIRED TX_REQUIRES_NEW TX_NOT_SUPPORTED TX_SUPPORTS TX_MANDATORY Processor Transaction Management Transaction management refers to the action of executing PipelineProcessors in the context of their defined transaction modes. but without a transaction. This table describes each transaction mode and what the Pipeline Manager does for each of those modes. TX_REQUIRES_NEW TX_NOT_SUPPORTED TX_SUPPORTS TX_MANDATORY 446 13 . The processor then executes its code. The current transaction is suspended.µ Pipelines and Transactions ATG Commerce Programming Guide The Pipeline Manager is transactionally aware. then it is committed when the chain has finished executing. If none of the processors mark the transaction. It will execute in the context of a transaction is one is available. see the Transaction Management chapter in the ATG Programming Guide. The processor can be executed in a transaction. The pipeline processor requires its own transaction for execution. each processor has the ability to mark the chain execution to be rolled back. If one is not available it will still execute. This means that as it executes the processors in its processor chains. the processor executes. For more information about JTA transactions in the ATG platform. TX_REQUIRED The pipeline processor requires that a transaction be present for execution. and then the transaction is resumed. otherwise an error occurs. If the PipelineManager created the transaction then it will be committed after the processor completes. At completion. then the manager will create one and use it for execution of the pipeline. The Pipeline Manager relies on the Java Transaction API (JTA) for its transactional needs. If a transaction is present. the transaction is either committed or rolled back. The transaction is not automatically committed after the request.Processor Chains and the Pipeline Manager . then it is suspended. The processor is not to be executed in a transaction. otherwise it will not be. The original transaction is then resumed. If there is no transaction available when the pipeline manager is called. A new transaction is created before the execution. This means that a transaction must already be in place.

pipeline. 447 13 .service. PipelineChain An object that contains a PipelineLink to the first PipelineProcessor for a given chain. This object is used internally in the PipelineManager.pipeline API for customized behavior.pipeline package: PipelineManager A global GenericService that controls the management of the pipelines and the execution of requests in the pipelines. An example of this was given in the Extending the PipelineChain and PipelineResult Classes topic of the Creating a Processor Pipeline section.service. This new chain should have all its processors marked as either TX_REQUIRES or TX_MANDATORY.Processor Chains and the Pipeline Manager . The following table summarizes the classes in the atg. The processor of the calling chain should have its mode set to TX_REQUIRES_NEW.ATG Commerce Programming Guide µ Spanning Transactions over a Chain Subset Transactions cannot span a subset of the chain.service.pipeline API contains two interfaces that allow the objects in the system to be customized: atg. Its main method is runProcess(). An object that contains data about a PipelineChain and a reference to PipelineChainConfiguration the chain itself.service. The atg.pipeline. Extending the Processor Pipeline Classes You can extend the atg. A more flexible way to span transactions over subsets of a chain is to break the subset into a new chain and then execute that chain within a processor of another chain. If a transaction must only support a subset of a chain.PipelineResult: an interface that provides access to the pipeline execution error data. It also manages the execution and editing of the PipelineLinks. It must either span an entire chain or one element of a chain.PipelineProcessor: an interface that is implemented by the processor components that the Pipeline Manager executes. atg. you can code the logic for the subset of the chain to be in one processor and then set the transaction mode for that processor to TX_REQUIRES_NEW.service.

PipelineManagerException The base exception object extended by all exceptions thrown from methods in the atg. An object that implements the PipelineResult interface. The other way is to use XML combination. <pipelinechain name="processOrder" transaction="TX_REQUIRED" headlink="executeValidateForCheckoutChain"> <pipelinelink name="executeValidateForCheckoutChain" transaction="TX_MANDATORY"> <processor jndi="/atg/commerce/order/processor/ExecuteValidateForCheckoutChain"/> <transition returnvalue="1" link="checkForExpiredPromotions"/> </pipelinelink> <pipelinelink name="checkForExpiredPromotions" transaction="TX_MANDATORY"> <processor jndi="/atg/commerce/order/processor/CheckForExpiredPromotions"/> <transition returnvalue="1" link="removeEmptyShippingGroups"/> </pipelinelink> 448 13 .Processor Chains and the Pipeline Manager . It is used by the PipelineChain to call the runProcess() method on the component and then get the reference to the next processor based on the return value. Using XML combination is the preferred approach. The XML below is a section of the processOrder pipeline chain as it appears out of the box.service. Adding a Commerce Processor Using XML Combination There are two ways to extend a pipeline defined for a PipelineManager. The example below demonstrates of how to use XML combination to modify a pipeline chain.pipeline package.µ PipelineLink ATG Commerce Programming Guide An object that contains a reference to a PipelineProcessor and a mapping of return values to next processors. This is the default PipelineResult object created by the PipelineManager PipelineResult when a chain is executed if no other PipelineResult object is specified. One is to copy the entire XML file into your CONFIG layer and make the necessary changes.

The important sections of this code are the additions of the xml-combine attributes in the pipelinechain and pipelinelink tags. Executing Processor Chains from Processors within Other Chains A processor uses another processor called ProcExecuteChain to execute a subchain. The property file of the ProcExecuteChain is configured with a PipelineManager and a chain name to execute. <pipelinemanager> <pipelinechain name="processOrder" transaction="TX_REQUIRED" headlink="executeValidateForCheckoutChain" xml-combine="append"> <pipelinelink name="executeValidateForCheckoutChain" transaction="TX_MANDATORY" xml-combine="replace"> <processor jndi="/atg/commerce/order/processor/ExecuteValidateForCheckoutChain"/> <transition returnvalue="1" link="purgeExcessOrderData"/> </pipelinelink> <pipelinelink name="purgeExcessOrderData" transaction="TX_MANDATORY"> <processor jndi="/atg/commerce/order/processor/PurgeExcessOrderData"/> <transition returnvalue="1" link="checkForExpiredPromotions"/> </pipelinelink> </pipelinechain> </pipelinemanager> The purgeExcessOrderData processor’s transition is what the executeValidateForCheckoutChain's transition is in the base file within the commerce platform. The key to the ProcExecuteChain execution is its return value.Processor Chains and the Pipeline Manager . This series of processors is called a pipeline. If it did contain an error. otherwise it will return SUCCESS (SUCCESS is mapped to the value 1 by default). The pipelinechain tag indicates what is being appended to its contents. Commerce Processor Chains Some commerce processes are executed using the PipelineManager. The value it returns is not that of the last processor in the chain that it executed. but rather whether or not the result object contains errors. ProcExecuteChain will return STOP_CHAIN_EXECUTION_AND_ROLLBACK. 449 13 . each of which accomplish a task. These return values are configurable in the properties file. The execution of a pipeline chain is usually wrapped in a method call that eliminates the need for interacting directly with the PipelineManager. The pipelinelink tag for executeValidateForCheckoutChain indicates what is replacing its contents. The following XML code should be added to your config layer.ATG Commerce Programming Guide µ The following example demonstrates how to add a new processor called purgeExcessOrderData between the executeValidateForCheckoutChain and checkForExpiredPromotions processors in the processOrder pipeline chain. The PipelineManager is a component that executes a series of processors.

the related XML configuration file is defined in <ATG9dir>/B2CCommerce/config/atg/commerce/commercepipeline. The following pipeline chains are defined in commercepipeline. In ATG Business Commerce. recalcPaymentGroupAmounts Pipeline Chain: Regenerates the amount that must be assigned to each PaymentGroup in the order. validatePostApproval Pipeline Chain: Revalidates an order after approval.Processor Chains and the Pipeline Manager . which is supplied to the executing chain. The updateOrder() method adds the given Order and the OrderManager to its parameter list.µ ATG Commerce Programming Guide For information editing pipeline chains. The updateOrder pipeline chain is executed by the updateOrder() method in the OrderManager. see the Using the Pipeline Editor section and the Adding a Commerce Processor Using XML Combination section in this chapter. The PipelineManager Nucleus component for ATG Commerce is located at /atg/commerce/PipelineManager. validateNoApproval Pipeline Chain: Validates an order that does not require approval. validateForCheckout Pipeline Chain: Verifies that the order is ready for checkout. Each of these chains is described in detail in this chapter: • • • • • • • • • • • • • • updateOrder Pipeline Chain: Saves the order supplied to it.xml. see the Adding a Commerce Processor Using XML Combination section in this chapter. processOrder Pipeline Chain: Submits the given order for checkout. In ATG Consumer Commerce. The following list describes each processor in the pipeline chain: 450 13 . loadOrder Pipeline Chain: Loads the order from the repository whose ID is supplied as a parameter. repriceOrder Pipeline Chain: Prices the order moveToConfirmation Pipeline Chain: Prices the order and validates it. The pipeline chain’s transaction mode is TX_REQUIRED.xml. For information on how to extend a pipeline defined for a PipelineManager. sendScenarioEvent Pipeline Chain: Sends a message to the Dynamo Message System.xml. updateOrder Pipeline Chain The updateOrder pipeline saves the Order supplied to it. validateShippingInfo Pipeline Chain: Validates the shipping groups in the order. the related XML configuration file is defined in <ATG9dir/B2BCommerce/config/atg/commerce/commercepipeline. validatePaymentGroupsPostApproval Pipeline Chain: Validates each payment group in an order after the order has been approved. moveToPurchaseInfo Pipeline Chain: Validates the order. refreshOrder Pipeline Chain: Reloads an order after an error and causes the unloaded portion of an Order to be loaded when accessed.

ProcSavePaymentGroupObjects Transitions: return value of 1 will execute updatePaymentStatusObjects next 6.commerce. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SaveCommerceItemObjects PipelineProcessor object: atg.order.order.commerce.processor.order.ProcSaveOrderObject Transitions: return value of 1 will execute updateCommerceItemObjects next 2.processor. PipelineLink Name: updatePaymentGroupObjects This processor saves the properties in the PaymentGroup objects in the Order. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SaveOrderObject PipelineProcessor object: atg. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SavePaymentGroupObjects PipelineProcessor object: atg. PipelineLink Name: updateShippingGroupObjects This processor saves the properties in the ShippingGroup objects in the Order.ATG Commerce Programming Guide µ 1.order. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SaveHandlingInstructionObjects PipelineProcessor object: atg.processor. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SaveShippingGroupObjects PipelineProcessor object: atg.commerce.commerce.order. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SavePaymentStatusObjects PipelineProcessor object: 451 13 .ProcSaveCommerceItemObjects Transitions: return value of 1 will execute updateShippingGroupObjects next 3.commerce. PipelineLink Name: updateOrderObject This processor saves the properties in the Order object.Processor Chains and the Pipeline Manager . PipelineLink Name: updatePaymentStatusObjects This processor saves the properties in the PaymentStatus objects in all the PaymentGroups in the Order.ProcSaveShippingGroupObjects Transitions: return value of 1 will execute updateHandlingInstructionObjects next 4. PipelineLink Name: updateHandlingInstructionObjects This processor saves the properties in the HandlingInstruction objects in all the ShippingGroups in the Order.processor. PipelineLink Name: updateCommerceItemObjects This processor saves the properties in the CommerceItem objects in the Order.ProcSaveHandlingInstructionObjects Transitions: return value of 1 will execute updatePaymentGroupObjects next 5.processor.

order.commerce.commerce. PipelineProcessor object: ATG Commerce Programming Guide atg. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SetLastModifiedTime PipelineProcessor object: atg. and the customer removes items. Transactional Mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SaveManualAdjustments Transitions: return value of 1 will execute setLastModifiedTime next 10.commerce.ProcSaveRelationshipObjects Transitions: return value of 1 will execute updatePriceInfoObjects next 8.Processor Chains and the Pipeline Manager . changes at checkout time do not affect the adjustment. Manual adjustments are applied unconditionally by the OrderAdjustmentCalculator (see the ATG Commerce Service Center User Guide for information on this class). If you are not using CSC. this step does not apply.µ 7. PipelineLink Name: setLastModifiedTime This processor sets the lastModifiedTime property of an Order to the current time if any changes were made to an Order. this behavior is configurable. By default.processor. See Warning below.order.order. the processor is configured not to save manual adjustments for incomplete orders.ProcSavePriceInfoObjects Transitions: return value of 1 will execute saveManualAdjustments next 9. PipelineLink Name: updatePriceInfoObjects This processor saves the properties in the OrderPriceInfo and TaxPriceInfo objects in the Order.order. if a $20 credit is manually applied to an incomplete order.ProcSavePaymentStatusObjects Transitions: return value of 1 will execute updateRelationshipObjects next PipelineLink Name: updateRelationshipObjects This processor saves the properties in the Relationship objects in the Order. the order could end up with a $0 total. PipelineLink Name: saveManualAdjustments This processor updates the order for any manual adjustments made by agents in the Commerce Service Center application. If you want to apply manual adjustments to incomplete orders. this is the last link in the chain and causes the PipelineManager to return to the caller. the ShippingPriceInfo object in the ShippingGroups. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SavePriceInfoObjects PipelineProcessor object: atg.processor.processor. it affects the order’s price regardless of the order’s contents. and the ItemPriceInfo object in the CommerceItems. for example. If an adjustment is applied to an incomplete order. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SaveRelationshipObjects atg. Once an adjustment has been added.processor. in which case the adjustment is discarded if the agent does not check out the order. set the saveIncompleteOrderAdjustments property to true in the 452 13 . Warning: Manual adjustments are changes to an order made by an agent using the ATG Commerce Service Center.ProcSetLastModifiedTime Transitions: None. However.commerce.

commerce.ATG Commerce Programming Guide µ /atg/commerce/order/processor/SaveManualAdjustments component. The loadOrder() method adds the given OrderId. PipelineLink Name: loadOrderObject This processor constructs a new Order object and loads the properties from the repository into it. incompleteStates^=/atg/commerce/order/OrderLookupService. # The processor will save the manual adjustments to the repository for orders # in these states. The following list describes each processor in the pipeline chain: 1.ProcLoadOrderObject Transitions: return value of 1 will execute loadPriceInfoObjectsForOrder next 2.incompleteStates # The processor will save the manual adjustments to the repository for orders # in the configured incomplete states if this property is true. To save manual adjustments for orders in additional states. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/LoadPriceInfoObjects PipelineProcessor object: atg. CatalogTools Nucleus component. adjust the configuration of the incompleteStates property. saveIncompleteOrderAdjustments=false loadOrder Pipeline Chain The loadOrder pipeline chain loads the Order from the repository whose ID is supplied as a parameter. depending on the value of saveIncompleteOrderAdjustments. PipelineLink Name: loadPriceInfoObjectsForOrder This processor constructs a new OrderPriceInfo and TaxPriceInfo object for the Order it loads and loads the properties from the repository into it.processor.processor.order. the # manual adjustments are not saved for incomplete orders. this is the last link in the chain and will cause the PipelineManager to return to the caller. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/LoadOrderObject PipelineProcessor object: atg. It then sets the PriceInfo to the corresponding object in the Order. which is supplied to the executing chain.Processor Chains and the Pipeline Manager . 453 13 . OrderRepository.ProcLoadPriceInfoObjects Transitions: None. The pipeline chain’s transaction mode is TX_REQUIRED.commerce.order. The loadOrder pipeline chain is executed by the loadOrder() method in the OrderManager. Otherwise. and the OrderManager to its parameter list.

The pipeline chain’s transaction mode is TX_REQUIRED. PipelineLink Name: loadShippingGroupObjects This processor constructs a new ShippingGroup object for each item it loads and loads the properties from the repository into it. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/LoadCommerceItemObjects PipelineProcessor object: atg. PipelineLink Name: loadCommerceItemObjects This processor constructs a new CommerceItem object for each item it loads and loads the properties from the repository into it. The following list describes each processor in the pipeline chain: PipelineLink Name: loadOrderObjectForRefresh This processor takes an existing Order object and reloads the properties from the repository into it.commerce.commerce.commerce. It then adds the object to the Order. It then adds the object to the ShippingGroup to which it belongs.Processor Chains and the Pipeline Manager .ProcLoadShippingGroupObjects Transitions: return value of 1 will execute loadHandlingInstructionsObjects next 4.processor. PipelineLink Name: loadPaymentGroupObjects This processor constructs a new PaymentGroup object for each item it loads and loads 454 13 .order. etc.processor.commerce. PipelineLink Name: loadHandlingInstructionsObjects This processor constructs a new HandlingInstruction object for each ShippingGroup that was loaded in the previous processor and loads the properties from the repository into it.ProcLoadCommerceItemObjects Transitions: return value of 1 will execute loadShippingGroupObjects next 3. such as CommerceItem. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/LoadShippingGroupObjects PipelineProcessor object: atg. ShippingGroup. The refreshOrder pipeline chain is not executed explicitly.order. but rather by the Commerce components. It then adds the object to the Order.processor.ProcLoadOrderObject Transitions: return value of 1 will execute loadCommerceItemObjects next 2. ATG Commerce Programming Guide The refreshOrder pipeline chain reloads an Order from the repository. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/LoadOrderObject PipelineProcessor object: atg. It also loads all the supporting objects. The Order object is supplied as a parameter.µ refreshOrder Pipeline Chain 1. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/LoadHandlingInstructionObjects PipelineProcessor object: atg.order.ProcLoadHandlingInstructionObjects Transitions: return value of 1 will execute loadPaymentGroupObjects next 5.order.processor.

It then adds the object to the Order.commerce.processor.ProcLoadPriceInfoObjects Transitions: return value of 1 will execute setCatalogRefs next 9. if SetCatalogRefs.commerce. ShippingPriceInfo.order.order.substituteDeletedSkuId. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SetCatalogRefs PipelineProcessor object: 455 13 . It does this by loading the RepositoryItem object using the catalogRefId in the auxiliaryData object.Processor Chains and the Pipeline Manager .processor. PipelineLink Name: loadPriceInfoObjects This processor constructs a new OrderPriceInfo.ProcLoadPaymentGroupObjects Transitions: return value of 1 will execute loadPaymentStatusObjects next 6. PipelineLink Name: loadRelationshipObjects This processor constructs a new Relationship object for each item it loads and loads the properties from the repository into it. see Refreshing Orders in the Configuring Purchase Process Services chapter. or ItemPriceInfo object for each item it loads and loads the properties from the repository into it. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/LoadPriceInfoObjects PipelineProcessor object: atg. It then adds the object to the Order.ATG Commerce Programming Guide µ the properties from the repository into it. It then adds the object to the PaymentGroup to which it belongs. PipelineLink Name: setCatalogRefs This processor sets the catalogRef property in the auxiliaryData object in the CommerceItem. PipelineLink Name: loadPaymentStatusObjects This processor constructs a new PaymentStatus object for each PaymentGroup that was loaded in the previous processor and loads the properties from the repository into it. For more information. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/LoadRelationshipObjects PipelineProcessor object: atg. TaxPriceInfo.order.order.commerce. this processor replaces all deleted SKUs in the Order with the “dummy” SKU defined by SetCatalogRefs.commerce. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/LoadPaymentStatusObjects PipelineProcessor object: atg. Additionally.processor. It then sets the PriceInfo to the corresponding object in the Order.substituteRemovedSku is true. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/LoadPaymentGroupObjects PipelineProcessor object: atg.processor.ProcLoadPaymentStatusObjects Transitions: return value of 1 will execute loadRelationshipObjects next 7.ProcLoadRelationshipObjects Transitions: return value of 1 will execute loadPriceInfoObjects next 8.

processor. if SetProductRefs. The following list describes each processor in the pipeline chain: 1.substituteRemovedProduct is true. For more information. PipelineLink Name: setProductRefs This processor sets the productRef property in the auxiliaryData object in the CommerceItem. and OrderManager to its parameter list. Profile.ProcRemoveExpiredCommerceItems Transitions: None.processor.commerce.processor. A “dummy” SKU is automatically removed.order. it causes the PipelineManager to return to the caller.order. this processor removes from the Order any CommerceItem that contains a “dummy” SKU or product that was substituted by SetCatalogRefs or SetProductRefs. this processor replaces all deleted products in the Order with the “dummy” product defined by SetProductRefs. The processOrder() method adds the given Order. processOrder Pipeline Chain The processOrder pipeline chain submits the given Order for checkout. PipelineLink Name: removeExpiredCommerceItems Used in conjunction with SetCatalogRefs and SetProductRefs. the default is true. 10.Processor Chains and the Pipeline Manager . Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/ExecuteValidateForCheckoutChain PipelineProcessor object: atg. see Refreshing Orders in the Configuring Purchase Process Services chapter.commerce. Request.removeItemsWithDeletedProducts is set to true.commerce.processor.openOrderStates. If the state of the Order is one that is defined in RemoveExpiredCommerceItems. Additionally.ProcSetCatalogRefs Transitions: Return value of 1 executes setProductRefs next. this is the last link in the chain. If the execution of this chain causes any errors.order. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SetProductRefs PipelineProcessor object: atg.substituteDeletedProductId.commerce. return value of 1 executes 456 13 .ProcSetProductRefs Transitions: Return value of 1 executes removeExpiredCommerceItems next. For more information. PipelineLink Name: executeValidateForCheckoutChain This processor causes the validateForCheckout chain to be executed. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/RemoveExpiredCommerceItems PipelineProcessor object: atg. The pipeline chain’s transaction mode is TX_REQUIRED.order. Locale. The processOrder pipeline chain is executed by the processOrder() method in the OrderManager. see Refreshing Orders in the Configuring Purchase Process Services chapter.ProcExecuteChain Transitions: In ATG Consumer Commerce. then execution will be returned to the caller. A “dummy” product is removed only if RemoveExpiredCommerceItems. It does this by loading the RepositoryItem object using the productId in the auxiliaryData object. 11. which is supplied to the executing chain.µ ATG Commerce Programming Guide atg.

commerce.processor.ProcExecuteChain Transitions: Return value of 1 executes checkForExpiredPromotions next.order.ProcCheckOrderState Transitions: Return value of 1 executes executeValidatePostApprovalChain next. return value of 1 executes executeApproveOrderChain next. If it is.processor. (ATG Business Commerce only) Pipeline Link Name: executeValidateNoApprovalChain If the order does not require approval. Specifically.commerce. 6. 5. Return value of 2 executes executeValidateNoApprovalChain. (ATG Business Commerce only) Pipeline Link Name: executeValidatePostApprovalChain If the order requires approval and has been approved. 457 13 .processor.commerce.order.processor.order.ProcExecuteChain Transitions: Return value of 1 executes stopChainIfOrderRequiresApproval next. the order moves to the next processor in processOrder. 2.order. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/approval/processor/StopChainIfOrderRequiresApproval PipelineProcessor object: atg. execution of the processOrder chain stops.ATG Commerce Programming Guide µ checkForExpiredPromotions next. Transactional mode: TX_MANDATORY Nucleus component: atg/commerce/order/processor/ExecuteValidateNoApprovalChain PipelineProcessor object: atg.commerce. it checks whether the state of the order is PENDING_APPROVAL.ProcExecuteChain Transitions: Return value of 1 executes checkForExpiredPromotions. In ATG Business Commerce. 3. If it isn’t. this means that an error occurred. 4. this processor revalidates order information in case the approver changed anything. PipelineLink Name: checkForExpiredPromotions This processor walks through all the promotions that are being applied to the Order and verifies that none of them have expired. (ATG Business Commerce only) PipelineLink Name: executeApproveOrderChain This processor executes the approveOrder pipeline chain. Transactional mode: TX_MANDATORY Nucleus component: atg/commerce/order/processor/ExecuteValidatePostApprovalChain PipelineProcessor object: atg.Processor Chains and the Pipeline Manager . Return value of -1 (STOP_CHAIN_EXECUTION_AND_ROLLBACK) stops the execution of the processOrder chain. finish validation. (ATG Business Commerce only) PipelineLink Name: stopChainIfOrderRequiresApproval This processor checks whether the order has been determined to require approval. which begins the order approval process. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/approval/processor/ExecuteApproveOrderChain PipelineProcessor object: atg.

order.µ Transactional mode: TX_MANDATORY Nucleus component: PipelineProcessor object: 7. ATG Commerce Programming Guide /atg/commerce/order/processor/CheckForExpiredPromotions atg. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/SetPaymentGroupAmount PipelineProcessor object: 458 13 . If either one of these or both have no Relationships. If so then it will remove them.ProcCheckForExpiredPromotions Transitions: return value of 1 will execute removeEmptyShippingGroups next PipelineLink Name: removeEmptyShippingGroups This processor checks to see if there are any empty ShippingGroups in the Order.commerce. PipelineLink Name: createImplicitRelationships This processor adds Relationships to the Order if there is only one ShippingGroup or one PaymentGroup. a Relationship will be created between itself and the Order with type OrderAmountRemaining.ProcRemoveEmptyPaymentGroups Transitions: return value of 1 will execute createImplicitRelationships next 9.order. For the PaymentGroup.order.ProcRemoveEmptyShippingGroups Transitions: return value of 1 will execute removeEmptyPaymentGroups next 8.processor.commerce.processor.processor. Relationships will be created between it and each CommerceItem. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/CreateImplicitRelationships PipelineProcessor object: atg. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/RemoveEmptyShippingGroups PipelineProcessor object: atg.commerce. If the Order contains only one PaymentGroup then it will not be removed if it is empty. This amount is the amount that will ultimately be debited by the PaymentManager. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/RemoveEmptyPaymentGroups PipelineProcessor object: atg.order.Processor Chains and the Pipeline Manager . PipelineLink Name: setPaymentGroupAmount This processor sets the amount property of each PaymentGroup in the Order based on the Relationships in each PaymentGroup. It removes any empty groups it finds.processor. If the Order contains only one ShippingGroup then it will not be removed if it is empty. PipelineLink Name: removeEmptyPaymentGroups This processor checks to see if there are any empty PaymentGroups in the Order. An empty PaymentGroup contains no Relationships.commerce. then relationships will automatically be created. For the ShippingGroup. An empty ShippingGroup contains no Relationships.ProcCreateImplicitRelationships Transitions: return value of 1 will execute setPaymentGroupAmount next 10.

processor.commerce.ProcSetPaymentGroupAmount Transitions: return value of 1 will execute moveUsedPromotions next 11.order. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/UpdateGiftRepository PipelineProcessor object: atg. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/order/processor/AddOrderToRepository PipelineProcessor object: atg. Transactional mode: TX_MANDATORY Nucleus component: /atg/commerce/o