Table of Contents
List of Figures
Figure 1: Sample data – 2 products, 2 price levels, 5 base prices 10
Figure 2: Wizard New Product 11
Figure 3: Class Diagram product1.AbstractProduct 12
Figure 4: Class Diagram product1.Products 13
Figure 5: UOMs of the Root Segment 14
Figure 6: Class Diagram uom1.Main 14
Figure 7: Class Diagram product1.Prices – ProductBasePrice 15
Figure 8: Widget A with 3 different Base Prices 16
Figure 9: Class Diagram product1.PriceLevel 17
Figure 10: Sample data – 2 products, 2 price levels, 5 base prices 17
Figure 11: Class Diagram product1.Prices – PriceLevel 18
Figure 12: Product Widget A and its prices 19
Figure 13: Class Diagrams product1.ProductFilter / PriceLevelProductFilter 22
Figure 14: Class Diagrams product1.PriceLevelAccountFilter 23
Figure 15: Class Diagram account1.AccountFilter 23
Figure 16: Class Diagrams product1.PriceList 24
Figure 17: Price Level Sales with Price List 25
Figure 18: Pricing Rule Lowest Price 26
Figure 19: Calculation Rule Default 28
List of Listings
This book is designed to help you understand some basic concepts of the openCRX package product1, which allows you to design, configure, and manage complex products and their prices.
The intended audiences are openCRX administrators and openCRX users.
A basic understanding of how to read UML diagrams.
If you intend to reproduce the examples given in this guide, you might want to make sure you have a access to a working instance of openCRX. For detailed information on how to setup/install an openCRX instance, see http://www.opencrx.org/server.htm for more information.
Enter the sample data as explained below.
With the following steps you can enter the test data used in this guide:
The following figure shows an overview of the sample data created by the above steps:
Figure 1: Sample data – 2 products, 2 price levels, 5 base prices
openCRX products are objects that typically fall into one of the following categories: goods, services, ideas, etc. While the default customizing of openCRX enables many attributes useful for goods (like for example weight and dimension information) it is easily possible to tailor the list of available and/or visible attributes to your specific requirements with customizing.
openCRX provides a wizard that helps you create new products interactively and populate the various attributes including price information. The wizard New Product is available from the product segment in the File menu:
Figure 2: Wizard New Product
AbstractProduct is one of the core classes (all the relevant class diagrams are all located in the package org.opencrx.kernel.product1), but it contains only the most basic attributes. On the other hand, AbstractProduct inherits a lot of attributes from other classes, including CrxObject (and hence, it is very easy to add/enable additional attributes by customizing).
Figure 3: Class Diagram product1.AbstractProduct
For information on how to “attach” prices to products, see chapter 5 Basic Pricing.
openCRX Product inherits from AbstractProduct and introduces additional concepts like
Figure 4: Class Diagram product1.Products
openCRX UOMs are what you would expect them to be: any division of quantity accepted as a standard of measurement or exchange. openCRX includes a variety of typical UOMs in the Root segment (but it is straight-forward to define your own UOMs):
Figure 5: UOMs of the Root Segment
Figure 6: Class Diagram uom1.Main
In this chapter we will present a high-level overview of how product pricing works in openCRX. The relevant class diagrams are all located in the package org.opencrx.kernel.product1 (AbstractProduct, PriceLevel, PriceList, and PricingRule).
The following class diagram excerpt shows the classes and associations that are relevant for “attaching” prices to products:
Figure 7: Class Diagram product1.Prices – ProductBasePrice
There are a few things to note:
The following figure shows an example Product Widget A with 3 different Base Prices:
Figure 8: Widget A with 3 different Base Prices
The price of EUR 100.– is valid for any quantity and linked to the PriceLevel Standard, while the price of EUR 90.– is valid for quantities up to 9 pieces (linked to the PriceLevel Sales) and the price of EUR 80.– is valid for quantities of 10 and more pieces (and also linked to the PriceLevel Sales).
PriceLevels are very useful constructs to combine products and their prices and to define the period of validity for prices (think of price lists). With PriceLevels you can also establish relationships between accounts and prices, e.g. define which accounts are eligible for which prices. In addition to these basic “features”, price levels also offer a variety of operations to highly automate the management of product prices and price lists in even the most complex environments.
Figure 9: Class Diagram product1.PriceLevel
Next, we will discuss how products, prices and accounts can be “linked” to price levels, based on this sample data (see chapter 2.1 Sample data):
Figure 10: Sample data – 2 products, 2 price levels, 5 base prices
The following class diagram excerpt shows the classes and associations that are relevant for “assigning” prices to PriceLevels:
Figure 11: Class Diagram product1.Prices – PriceLevel
There are a few things to note:
While you can assign prices to price levels manually, such assignments (or even the calculation of prices to be assigned) is typically done in an automated manner, e.g. by means of executing operations like Create Initial Prices.
Let us have a look at the product Widget A:
Figure 12: Product Widget A and its prices
This product has 3 Base Prices, 1 linked to the Price Level Standard and 2 linked to the Price Level Sales. Not that the sales price depends on the quantity, i.e. up to 9 pieces the price is EUR 90.--, for 10 pieces and more the price is EUR 80.--. Let us now add another sales price that applies to quantities of 100 or more pieces:
On the one hand products are assigned to price levels implicitly by manually assigning product prices to price levels. More interestingly, however, is the use of product filters to automatically “assign” products to price levels:
Figure 13: Class Diagrams product1.ProductFilter / PriceLevelProductFilter
The shared association filteredProduct yields all products that are assigned to a particular price level based on the defined product filters (or all products in case no filters are defined). This construct (combined with various price level operations) enables you to create price lists based on product criteria in a highly automated fashion.
If you create a new Price Level, there is (by default) no product filter defined. In the absence of a product filter, the grid [Products (Filtered)] of a Price Level includes all products.
You can manually assign accounts to price levels with AccountAssignments. Such account assignments also allow you to define discounts that apply to a particular account only:
Figure 14: Class Diagrams product1.PriceLevelAccountFilter
Account filters allow you to automatically “assign” accounts to price levels:
Figure 15: Class Diagram account1.AccountFilter
The shared association filteredAccount yields all accounts that are assigned to a particular price level based on the defined account filters (or all accounts in case no filters are defined). This construct (combined with various price level operations) enables you to create account-specific price lists highly automated.
If you create a new Price Level, there is (by default) no account filter defined. In the absence of an account filter, the grid [Accounts (Filtered)] of a Price Level includes all accounts.
In addition to the “global price list” (the price list containing all product prices in any currency) openCRX provides a Price List for each Price Level. Such a price list contains all product prices that are assigned to the particular price level.
Figure 16: Class Diagrams product1.PriceList
Please note that price lists are derived information, i.e. you do not explicitly define price lists, but rather you assign product prices (or products with prices) and accounts to price levels (see sections Assigning Products to Price Levels and Assigning Accounts to Price Levels for details).
The following figure shows the Price Level Sales with the respective (derived) Price List:
Figure 17: Price Level Sales with Price List
Pricing rules are used to automatically determine an appropriate price level for a contract position based on any algorithm you like (e.g. “select the price level with the lowest price a particular account is eligible for” - see section Pricing Rule LowestPrice for details). Pricing rules are basically "scripts" that are programmed in Java and have access to the complete API of openCRX (and anything else that is available, including third-party systems like billing systems, etc.); the scripts are compiled on the fly at runtime (we use Janino - http://www.janino.net/ - an embedded Java compiler) for maximum flexibility, i.e. scripts can be added/modified/deleted at runtime!
openCRX provides a sample pricing rule called Lowest Price:
Figure 18: Pricing Rule Lowest Price
In a nutshell, here is how this pricing rule determines the price level with the lowest product price given a contract (e.g. a quote or a sales order, which also defines the customer [= account] and a contract currency), a product (on each contract position), and optionally a quantity (useful for quantity-based pricing), a pricing date (useful for look-back or forward pricing) and a unit of measurement for the price:
Pricing Rules can be defined both at the Contract level and at the ContractPosition level. The following rules apply:
Automated pricing of a ContractPosition requires that a PricingRule is assigned to the respective Contract Position (either automatically or then manually). Contract Positions without assigned Pricing Rules cannot be (re)priced automatically and their pricing status remains “dirty”.
Automated pricing of a Contract requires that all of its Contract Positions can be priced automatically. If at least 1 Contract Position cannot be priced automatically (i.e. its pricing status remains “dirty”) then the Contract cannot be priced automatically and its own pricing status is set to “dirty” as well.
Calculation rules are used to control the way prices are calculated in terms of rounding, number of significant decimals, etc. Calculation rules are basically "scripts" that are programmed in Java and have access to the complete API of openCRX (and anything else that is available, including third-party systems like billing systems, etc.); the scripts are compiled on the fly at runtime (we use Janino - http://www.janino.net/ - an embedded Java compiler) for maximum flexibility, i.e. scripts can be added/modified/deleted at runtime!
Calculation Rules can be defined both at the Contract level and at the Contract Position level.
openCRX provides a sample calculation rule called Default:
Figure 19: Calculation Rule Default
In this chapter we create some samle contracts and contract positions based on the sample data (see chapter 2.1 Sample data) and the additional sales price of EUR 75.-- for Widget B (created at the end of chapter 5.2.1 Assigning Prices to Price Levels) to show how this all fits together.
Let us create a sales order with 2 positions as follows:
Let us continue with the sales order created in the previous chapter 6.1 and see what happens if we change the Pricing date:
Let us now continue with this sales order and see what happens if we change the Active/Valid from date:
The sales price of Widget A is prepared for volume discounts, that is in quantities up to (and including 9) the price is EUR 90.00, in quantities from 10 to 99 the price is EUR 80.00, and in quantities of 100 or more the price drops to EUR 75.00:
Let us now change the quantity of the position with Widget A from 25 to 150:
Finally, let us clear the Pricing date and see how that effects the prices:
You might want to have a look at some of the wizards included in the standard distribution of openCRX if you want to learn about how to program against the openCRX API and make use of the built-in business logic:
You might want to have a look at some of the additional documentation published at http://www.opencrx.org/documents.htm.