Oracle® Retail POS Suite Implementation Guide, Volume 2 – Extension Solutions Release 14.1 E54476-02 |
|
Previous |
Next |
This chapter contains an overview of the Oracle Retail business objects, including steps to create, extend, and use them. The Retail Domain is the set of classes that represent the business objects used by Point-of-Service. Typical domain classes are Customer, Transaction, and Tender.
The Retail Domain is a set of business logic components that implement retail-oriented business functionality in Point-of-Service. The Retail Domain provides a common vocabulary that enables the expression of retail functionality as processes that can be executed by the Oracle Retail Platform engine.
The Retail Domain is a set of retail-oriented objects that have a set of attributes. They do not implement work flow or a user interface. The Tour scripts executed by Oracle Retail Platform provide the work flow, and the UI subsystem provides the user interface. The Retail Domain objects simply define the attributes and logic for application data.
A significant advantage of Retail Domain objects is that they can be easily used as-is or can be extended to include attributes and logic that are specific to a retailer's business requirements. The Domain objects could be used as a basis for many different types of retail applications. The objects serve as containers for the transient data used by the applications. Domain objects do not persist themselves, but they are persisted via the Oracle Retail Store Data Manager interface.
Retail Domain is packaged as domain360.jar and domainconfig.jar, which are installed with the Point-of-Service application. The Data Transactions and Data Operations are also packaged within the Retail Domain jars.
All Retail Domain classes extend EYSDomainIfc. This interface ensures the following interfaces are implemented:
This communicates Java's ability to flatten an object to a data stream and, conversely, reconstruct the object from a data stream, when using RMI.
This communicates that it is legal to make a field-for-field copy of instances of this class.
The EYSDomainIfc interface also requires that the following methods be implemented:
This method accepts an object as a parameter. If the object passed has data attributes equal to this object, the method returns true, otherwise it returns false.
This method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object.
This method returns a String version of the object contents for debugging and logging purposes.
When an existing Retail Domain object contains attributes and methods that are a subset of those required, a new Retail Domain object can extend the existing object. For example, if a new Domain object is necessary for the Tender service, the AbstractTenderLineItem class can be extended. This class implements TenderLineItemIfc, which extends the generic EYSDomainIfc interface. If no similar Domain object exists in the application, create a new Domain object. The usual coding standards apply; reference the Development Standards document.
Create a new interface extending EYSDomainIfc. All Retail Domain objects extend EYSDomainIfc, but existing Services have an interface available for Domain objects related to that Service. For example, TenderLineItemIfc, which extends EYSDomainIfc, is the interface implemented by each Retail Domain object interface in the Tender service. The following code sample shows the header of TenderPurchaseOrderIfc, found in <source_directory>
\modules\domain\src\oracle\retail\stores\domain\tender\TenderPurchaseOrderIfc.java
.
Create a new Java class that implements the interface created in the previous step. The class of a brand new object that does not fit an existing pattern should extend AbstractRoutable, which defines a luggage tag for EYS domain classes; otherwise, the class should extend the existing class that represents a similar type of object.
The following code sample shows the header for the TenderPurchaseOrder Domain object from <source_directory>
\modules\domain\src\oracle\retail\stores\domain\tender\TenderPurchaseOrder.java
.
Example 15-2 TenderPurchaseOrder.java: Class Header
public class TenderPurchaseOrder extends AbstractTenderLineItem implements TenderPurchaseOrderIfc { }
In the implementation of the class, make sure to do the following:
Define attributes for the class.
Check the superclass to see if an attribute has already been defined. For example, the AbstractTenderLineItem class defines the amountTender attribute, so amountTender should not be redefined in a new Tender Domain object.
If the new domain object has numerous constants, you might consider defining ObjectNameConstantsIfc.java
Define get and set methods for the attributes as necessary.
Implement methods required by EYSDomainIfc: equals(), clone(), toString(). Reference the superclass as appropriate. toString() should indicate the class name and revision number.
To return a new instance of the Domain object, add a method to <source_directory>
\modules\domain\src\oracle\retail\stores\domain\factory\DomainObjectFactoryIfc.java
called getObjectNameInstance().
Domain objects should always be instantiated by the factory. The following code sample shows the method interface to return an instance of the TenderPurchaseOrder object.
To return a new instance of the Domain object, implement the method <source_directory>
\modules\domain\src\oracle\retail\stores\domain\factory\DomainObjectFactory.java
called getObjectNameInstance().
The following code sample shows the method definition to return an instance of the TenderPurchaseOrder object.
Once a Retail Domain class is identified for use, the Java code needs to be written to instantiate the object and call the object's methods. This code is typically located in site, road and aisle classes of application tours. There are two very important things to keep in mind when using Domain objects in Tour code:
Retail Domain objects cannot be instantiated directly. They must be generated by the factory.
All interaction with Domain objects take place through the object's interface, even interaction between objects.
Do the following to use the object:
Get an instance of the DomainObjectFactory and request the instance of the object from the factory.
The factory class is instantiated once for the application and returns instances of Retail Domain objects. Since different implementations use different classes to implement the objects, the factory keeps track of which class implements the requested object.
The following line of code from <source_directory>
\applications\pos\src\oracle\retail\stores\pos\ado\tender\TenderCheckADO.java
gets an instance of a Check object.
Call methods on the object.
Now that an instance of the object exists, methods of the class can be called. The following lines of code from TenderCheckADO.java sets attributes on the Check object.
The Domain Objects discussed below include a description of the purpose of the object, classes and interfaces involved in its construction, a class diagram, and examples in Tour code.
To implement Point-of-Service metadata such as reasons for return, shipping methods, and departments, the CodeList objects are used. This data is referred to as reason codes from the UI. Codes are read in from the database.
The reason codes are managed in multiple languages/locales simultaneously by loading the ReasonCodes (CodeList) or ReasonCode(CodeEntry) on demand. The reason codes are externalized in the database: table ID_LU_CD_I8. The CodeListManager is used as the single point of access to retrieve the code lists from the database. For performance reasons, code list manager retrieves code lists from local derby database.
The sites and aisles call the following function to retrieve a code list. The code list contains localized text of all supported locales. The function in turn calls getCodeList API in CodeListManagerIfc:
CodeListIfc UtilityManager.getReasonCodes(String storeId, String codeListType);
Table 15-1 lists files are involved in the formation of CodeLists.
Table 15-1 CodeListMap Object Classes and Interfaces
Class or Interface | Description | Important Methods |
---|---|---|
CodeEntry |
This class handles the functions associated with an entry in a list of codes. |
void setText(String) void setCode(int) void setEnabled(boolean) LocalizedTextIfc getLocalizedText(); String getText(Locale lcl); void setLocalizedText (LocalizedTextIfc localizedText); void setText(Locale lcl, String value); |
CodeList |
This class is used for handling lists of codes which map to strings, such as reason codes. |
Vector<String> getTextEntries(Locale lcl) String[] getTextStrings(Locale lcl); CodeEntryIfc[] getEntries(); CodeEntryIfc findListEntry(String str, boolean useDefault,Locale lcl); addEntry(CodeEntryIfc value); addEntry(LocalizedTextIfc text, String code, int index, boolean enable, String ref); |
CodeConstantsIfc |
This class defines constants used for the implementation of CodeList and CodeEntry. It includes the constants for the lists currently defined, such as TimekeepingManagerEditReasonCodes and TillPayOutReasonCodes. |
This class does not contain methods. |
LocalizedCode |
This class contains the localized code/text. All the Domain Objects, which contain a reason code, will use this class. |
void setCode (String code); String getCode (); void putText (Locale lcl, String text); String getText (Locale lcl); LocalizedTextIfc getText (); setText (LocalizedTextIfc text); |
Figure 15-1 illustrates loading CodeList / CodeText on Demand.
To get the CodeListIfc, the Utility Manager provides two methods:
CodeListIfc getReasonCodes(String storeId, String codeListType)
String getReasonCodeText(CodeListIfc list, int reasonCode)
Tour code that requires a code entry would retrieve it as in the following code from <source_directory>
\applications\pos\src\oracle\retail\stores\pos\services\returns\returnitem\ItemInfoEnteredAisle.java.
Example 15-7 ItemInfoEnteredAisle.java: CodeListIfc in Tour Code
UtilityManagerIfc utility = (UtilityManagerIfc) bus.getManager(UtilityManagerIfc.TYPE); Locale locale = LocaleMap.getLocale(LocaleConstantsIfc.USER_INTERFACE); if (model.getDepartmentName()!=null) { item.setDepartmentID (((utility.getReasonCodes(cargo.getStoreID(), CodeConstantsIfc.CODE_LIST_DEPARTMENT)). findListEntry(model.getDepartmentName(), false, locale)).getCode()); }
All currency representation and behavior is abstracted, so any currency can be implemented. Currency is a Domain Object that handles the behaviors and attributes of money used as a medium of exchange. It is important to use Currency objects and methods to compare and manipulate numbers instead of primitive types.
Table 15-2 lists Currency Object Classes and Interfaces.
Table 15-2 Currency Object Classes and Interfaces
Class or Interface | Description | Important Methods |
---|---|---|
CurrencyIfc |
This interface defines a common interface for currency objects. |
CurrencyIfc add(CurrencyIfc) CurrencyIfc negate() String getCountryCode() |
AbstractCurrency |
This abstract class contains the behaviors and attributes common to all currency. |
BigDecimal getBaseConversionRate() void setNationality(String) String getNationality() |
CurrencyDecimal |
This class contains the behaviors and attributes common to all decimal-based currency. |
CurrencyIfc add(CurrencyIfc) CurrencyIfc negate() String getCountryCode() |
Example 15-8 is an example of the Currency object used in <source_directory>
\applications\pos\src\oracle\retail\stores\pos\services\modifytransaction\discount\AmountEnteredAisle.java.
Example 15-8 AmountEnteredAisle.java: CurrencyIfc in Tour Code
POSUIManagerIfc uiManager = (POSUIManagerIfc)bus.getManager(UIManagerIfc.TYPE); DecimalWithReasonBeanModel beanModel = (DecimalWithReasonBeanModel)uiManager .getModel(POSUIManagerIfc.TRANS_DISC_AMT); BigDecimal discountAmount = beanModel.getValue(); CurrencyIfc amount = DomainGateway.getBaseCurrencyInstance(String.valueOf(discountAmount));
A Transaction is a record of business activity that involves a financial and/or merchandise unit exchange or the granting of access to conduct business with an external device. There are various types of Transactions found in <source_directory>
\modules\domain\src\oracle\retail\stores\domain\transaction
such as LayawayTransaction, StoreOpenCloseTransaction, and BankDepositTransaction. SaleReturnTransaction is a commonly used Domain Object that extends AbstractTenderableTransaction. The classes involved in the implementation of a SaleReturnTransaction and its behaviors are described in the following table.
Table 15-3 lists classes involved in the implementation of a SaleReturnTransaction and its behaviors.
Table 15-3 Transaction Object Classes
Class or Interface | Description | Important Methods |
---|---|---|
SaleReturnTransaction |
This class is a sale or return transaction. |
void SaleReturnLineItemIfc addPLUItem(PLUItemIfc pItem, BigDecimal qty); void addLineItem(AbstractTransactionLineItemIfc lineItem) void linkCustomer(CustomerIfc value) TransactionTotalsIfc getTenderTransactionTotals() void addLineItem(SaleReturnLineItemIfc); addLineItem(AbstractTransactionLineIt emIfc) |
AbstractTenderableTransaction |
This class contains the behavior associated with a transaction that involves the tendering of money. |
void addTenderLineItem(TenderLineItemIfc item); CustomerIfc getCustomer(); CustomerIfc getCustomer() void addTender(TenderLineItemIfc item); |
Transaction |
This class represents a record of business activity that involves a financial and/or merchandise unit exchange or the granting of access to conduct business at a specific device, at a specific point in time for a specific employee. |
CustomerInfoIfc getCustomerInfo() String getTillID() void setCashier(EmployeeIfc) |
Example 15-9 is a code sample from <source_directory>
\modules\domain\src\oracle\retail\stores\domain\arts\JdbcSaveTenderLineItems.java
that shows how SaleReturnTransaction is used in Tour code.
Example 15-9 JdbcSaveTenderLineItems.java: SaleReturnTransactionIfc in Tour Code
public void saveTenderLineItems(JdbcDataConnection dataConnection,TenderableTransactionIfc transaction) throws DataException
{
if (transaction instanceof SaleReturnTransactionIfc)
{
SaleReturnTransactionIfc srt = (SaleReturnTransactionIfc) transaction;
int numDiscounts = 0;
if (srt.getTransactionDiscounts() != null)
{
numDiscounts = srt.getTransactionDiscounts().length;
}
lineItemSequenceNumber = srt.getLineItems().length + 1 + numDiscounts;
}
...code to handle different transaction types...
}