292
GK/Retail SAP Promotion Calculation Engine SDK Promotion Calculation Engine Version: 3.7 Date: 01.12.2020 Promotion Calculation Engine 3 Document Version: 3.7 PUBLIC SDK Promotion Calculation Engine

GK/Retail SAP Promotion Calculation Engine SDK Promotion

  • Upload
    others

  • View
    13

  • Download
    0

Embed Size (px)

Citation preview

Page 1: GK/Retail SAP Promotion Calculation Engine SDK Promotion

GK/Retail SAP Promotion Calculation

Engine

SDK Promotion Calculation Engine Version: 3.7

Date: 01.12.2020

Promotion Calculation Engine 3

Document Version: 3.7

PUBLIC

SDK Promotion Calculation Engine

Page 2: GK/Retail SAP Promotion Calculation Engine SDK Promotion

2

Contents

1 Document History ........................................................................................................ 5

2 Preface ........................................................................................................................ 11

2.1 Introduction .................................................................................................................................. 11

2.2 Definitions ..................................................................................................................................... 11

3 Getting Started ........................................................................................................... 13

4 Technologies ............................................................................................................... 15

4.1 Spring Framework ........................................................................................................................ 15

4.2 ARTS standard .............................................................................................................................. 15

4.3 Libraries ......................................................................................................................................... 15

5 How the PCE works .................................................................................................... 19

5.1 PCE Request .................................................................................................................................. 19

5.2 PCE Response ............................................................................................................................... 19

5.3 Calculation modes........................................................................................................................ 21

5.3.1 Basket mode ........................................................................................................................... 22

5.3.2 LineItem mode ........................................................................................................................ 22

5.4 PCE Processing ............................................................................................................................. 23

5.5 Request processing ...................................................................................................................... 23

5.6 Eligibility loading ........................................................................................................................... 27

5.7 Promotion calculation ................................................................................................................. 29

5.8 Update transaction ...................................................................................................................... 35

5.9 Create response ........................................................................................................................... 36

5.9.1 Response Header Mappings: ................................................................................................. 38

5.9.2 Response Body Mappings: ..................................................................................................... 38

5.10 Normalized Item Calculation .................................................................................................. 39

5.10.1 Calculation Overview .......................................................................................................... 39

5.10.2 Discount Calculation and Rounding .................................................................................. 41

6 PCE Modules ............................................................................................................... 44

6.1 Overview ........................................................................................................................................ 44

6.2 Spring Context .............................................................................................................................. 45

6.3 Pricing Engine Model ................................................................................................................... 45

6.3.1 Overview.................................................................................................................................. 45

6.3.2 Data Model ............................................................................................................................. 46

6.4 Pricing Engine API......................................................................................................................... 55

6.4.1 Overview.................................................................................................................................. 55

6.4.2 API Overview ........................................................................................................................... 55

Page 3: GK/Retail SAP Promotion Calculation Engine SDK Promotion

3

6.5 Pricing Engine Common .............................................................................................................. 79

6.6 Pricing Engine Core Implementation ........................................................................................ 83

6.6.1 Overview.................................................................................................................................. 83

6.6.2 Spring Context ........................................................................................................................ 83

6.7 Pricing Engine Promotion Service Implementation .............................................................. 102

6.8 The data access layer (DAL) ...................................................................................................... 104

6.8.1 Spring configuration............................................................................................................. 104

6.8.2 Promotion data loading ....................................................................................................... 105

6.8.3 Data mapping ....................................................................................................................... 108

6.9 Omnichannel Point-of-Sale Integration .................................................................................. 109

6.9.1 Overview................................................................................................................................ 109

6.9.2 PCE Model implementation ................................................................................................. 110

6.9.3 Public GK API......................................................................................................................... 111

6.9.4 Data Access Layer ................................................................................................................. 115

6.9.5 POS Integration Extensions .................................................................................................. 115

7 PCE Extensions .......................................................................................................... 117

7.1 Extension Patterns ..................................................................................................................... 117

7.1.1 Overview................................................................................................................................ 117

7.1.2 Plugins ................................................................................................................................... 118

7.1.3 Bean Overrides ..................................................................................................................... 125

7.1.4 Extending PCE standard implementations ......................................................................... 126

7.2 Extension Points ......................................................................................................................... 126

7.2.1 Context .................................................................................................................................. 126

7.2.2 Eligibilities ............................................................................................................................. 131

7.2.3 Promotion data loading ....................................................................................................... 141

7.2.4 Condition Calculation........................................................................................................... 144

7.2.5 Validate the calculation result ............................................................................................. 164

7.2.6 Update the transaction ........................................................................................................ 168

7.2.7 Custom field mapping .......................................................................................................... 171

7.3 Custom Extension Samples ...................................................................................................... 173

7.3.1 Plugin implementation of the PCE part............................................................................... 173

7.3.2 Concurrence Control Vector Extension Sample .................................................................. 178

7.3.3 Item Discount Control Vector Extension Sample ................................................................ 181

7.4 PCE Annotations for categorizing API interfaces ................................................................... 182

8 Troubleshooting ....................................................................................................... 183

8.1 Business Error Codes................................................................................................................. 183

8.1.1 Error message format .......................................................................................................... 185

8.1.2 Business Error Codes ............................................................................................................ 185

8.2 Debugging ................................................................................................................................... 187

Page 4: GK/Retail SAP Promotion Calculation Engine SDK Promotion

4

8.2.1 Request/Response mapping ................................................................................................ 187

8.2.2 PCE Configuration ................................................................................................................ 190

8.2.3 Calculate Transaction .......................................................................................................... 192

8.2.4 PCE Processing ...................................................................................................................... 192

8.3 Performance Logging ................................................................................................................ 194

8.3.1 Overview................................................................................................................................ 194

8.3.2 Usage ..................................................................................................................................... 194

8.3.3 Development ......................................................................................................................... 205

9 Configuration............................................................................................................ 207

10 Glossary.................................................................................................................. 208

11 Appendix ............................................................................................................... 210

11.1 Appendix A: Request and Response Mapping ................................................................... 210

11.1.1 Mapping of PCE internal model to/from the interface ................................................... 210

11.1.2 Request Mapper ................................................................................................................ 242

11.1.3 Response Mapper ............................................................................................................. 243

11.2 Appendix B: Extension Sample code ................................................................................... 244

11.2.1 Custom Bean context ....................................................................................................... 244

11.2.2 External Coupon Context ................................................................................................. 245

11.2.3 Extension Context ............................................................................................................. 246

11.2.4 Custom Coupons Handling .............................................................................................. 248

11.2.5 Custom Exclusive Check Handler ..................................................................................... 254

11.2.6 Custom Rebate-able Item Filter ....................................................................................... 259

11.2.7 Custom Mix&Match Proration Customizer for Scale Discounts..................................... 261

11.2.8 Mapping of Custom Fields................................................................................................ 267

11.2.9 Custom PriceModificationMethod RT transaction-related handling ............................. 275

11.3 Appendix C: Diagrams ........................................................................................................... 282

11.3.1 Pricing Engine Processing Flow ........................................................................................ 283

11.3.2 Price Calculation Logic (Buckets) Diagram ...................................................................... 283

11.3.3 Pricing Engine Request Processing .................................................................................. 284

11.3.4 Pricing Engine Calculation Process .................................................................................. 285

11.3.5 Eligibility Loading Process ................................................................................................ 288

11.3.6 Condition Loading Process............................................................................................... 289

11.3.7 Condition Calculation Process ......................................................................................... 290

11.3.8 Promotion Calculation Process ....................................................................................... 291

11.3.9 Update Transaction Process ............................................................................................ 292

Page 5: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

5

1 Document History

Version Change Date

1.0 Chapter Configuration added. 2016-07-07

1.0 Chapter Configuration: Deletion of unused parameters. 2016-07-12

1.0 Chapter Configuration: New parameter conditionLimit 2016-07-26

1.0 Chapter Glossary added. 2016-08-26

2.9 Chapter Custom Extension Samples added. 2017-03-19

2.9 Chapter Preface added. 2017-04-13

2.9 Chapter How the PCE works added. 2017-04-13

2.9 Chapter Business Error Codes added 2017-04-13

2.9 Chapter Configuration: Complete rework 2017-04-13

2.9 Chapter Getting Started: Splitting of documentation into GK and SAP content

2017-05-11

2.9 Chapter Pricing Engine Model added. 2017-05-11

2.9 Chapter Debugging added 2017-05-11

2.9 Chapter Performance Logging added. 2017-05-11

2.9 Chapter Pricing Engine API: Extended with parameters for fully priced items 2017-05-15

2.9 Chapter Libraries added. 2017-05-22

Page 6: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

6

Version Change Date

2.9 Chapter Extension Patterns added. 2017-09-18

2.9 Chapter Pricing Engine API added. 2017-09-25

2.9 Chapter Pricing Engine Core Implementation: Initial version 2017-09-25

2.9 Chapter Preface: Definitions section added. 2017-10-19

2.9 Chapter Pricing Engine API: Added chapters Context API, Eligibility API, Result API, Rules API 2017-10-19

2.9 Chapter Extension Points added. 2017-10-22

2.9 Chapter Appendix C: Diagrams added. 2017-10-23

2.9 Chapter Pricing Engine Core Implementation: List of plugins added, list of bean definitions extended. Changed existing bean lists according to implementation changes.

2017-10-24

2.9 Chapter Create Response added. 2017-10-27

2.9 Chapter The data access layer (DAL) added. 2017-10-27

2.9 Added chapter Create Response 2017-10-27

2.9 Chapter GK/Retail OmniPOS Integration added. 2017-10-30

2.9 Chapter GK/Retail OmniPOS Integration: Added model, local cache, POS transaction sections. 2017-10-30

2.9 Chapter Extension Points: Added chapter 'Filter valid normalized items for condition before processing'

2017-10-30

2.9 Modified chapter Extension Patterns. 2017-11-01

2.9 Chapter Appendix C: Diagrams: Disclaimer added. 2017-11-22

2.9 Chapter Concurrence Control Vector Extension Sample added. 2017-11-23

Page 7: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

7

Version Change Date

3.0 Modified chapter Omnichannel Point-of-Sale Integration:

• Description: for OmniPos the call is not made via the client API

• Description: any-fields are not available in OmniPOS

• Description: how to access the xxCustom-fields

2017-11-23

3.0 Modified chapter Debugging: Added description for

• Request/Response mapping

• PCE Configuration

• Calculate Transaction

• PCE rocessing

2017-11-23

3.0 Chapter Item Discount Control Vector Extension Sample added. 2017-11-23

3.0 Chapter Pricing Engine API: Added information regarding new features in 3.0 2018-03-08

3.0 Chapter Pricing Engine Common: Added ad hoc eligibility related information 2018-03-08

3.0 Chapter Pricing Engine Core Implementation: Added ad hoc promotion handling related information 2018-03-08

3.0 Chapter GK/Retail OmniPOS Integration: Ad hoc promotion related information 2018-03-08

3.0 Chapter Extension Patterns: Included plugins introduced in this version 2018-03-08

3.0 Chapter Extension Points: Included plugins introduced in version 3.0 2018-03-08

3.0 Chapter Extension Patterns: Added chapter about subclassing 2018-03-14

3.0 Chapter Extension Points: Included custom field mapping related chapter 2018-03-21

3.0 Chapter Extension Points: Include Mapping to any fields in Data Access Layer (DAL) level 2018-05-15

3.0 Chapter Extension Points: Include sorting of normalized line items for eligibilities and matching items 2018-05-17

3.0 Chapter Marking API Interfaces PCE Annotations for categorizing API interfacec added 2018-05-17

3.2 Chapter Pricing Engine API: Added information regarding API changes for new features in 3.1 2018-06-14

3.2 Chapter Extension Points: Documented new extension points and plugins in version 3.1 2018-06-15

Page 8: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

8

Version Change Date

3.2 Chapter Pricing Engine Core Implementation: Listed new beans and plugins introduced in 3.1 2018-06-18

3.2 Chapter Pricing Engine Model: Extended with model objects introduced for the Manufacturer Coupon feature

2018-09-04

3.2 Chapter Pricing Engine API: Extended with changes implemented for the Manufacturer Coupon feature

2018-09-04

3.2 Chapter Pricing Engine Common: Updated with manufacturer coupon related changes 2018-09-05

3.2 Chapter Pricing Engine Core Implementation: Listed new beans introduced for the Manufacturer coupon feature

2018-09-05

3.2 Chapter Extension Points: Sorting criteria for the greedy conflict handler are updated 2018-09-26

3.2 Chapter Avoid negative prices added. 2018-09-28

3.2 Chapter Extension Points: Customer Specific Prices and additional improvement related changes 2018-11-27

3.2 Chapter Extension Points: Sales vs Returns refactoring related changes 2019-01-07

3.2 Chapter Promotion Calculation: Sales vs Returns refactoring related changes 2019-01-07

3.2 Chapter Eligibility Loading: Sales vs Returns refactoring related changes 2019-01-07

3.2 Chapter Pricing Engine Model: Sales vs Returns refactoring related changes 2019-01-07

3.2 Chapter Pricing Engine API: Sales vs Returns refactoring related changes 2019-01-07

3.2 Chapter Brute Force Tweak added. 2019-01-07

3.2 Chapter Scale Discounts added. 2019-05-03

3.2 Chapter Extension Points: Documented new LineItemChangeValidator extension point, additional minor changes

2019-05-17

3.5 Chapter Extension Points: Transaction Discount After Subtotal feature implementation related changes documented

2019-08-06

3.5 Chapter Pricing Engine Model extended with model objects introduced with the new feature package prices

2019-08-15

Page 9: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

9

Version Change Date

3.5 Chapter Libraries updated. 2019-08-30

3.6 Chapter Extension Points: Documented new extension point Discountable Item Validator 2019-09-10

3.6 Chapter Extension Points adjusted with new subchapters:

• Trigger conflict handler preprocessor

2019-11-04

3.6 Chapter Pricing Engine Model: Extended with model objects introduced with the Customer Specific Prices feature

2019-11-23

3.6 Chapter Extension Points adjusted with new subchapter describing the feature package measured items:

• Add a new validator for discountability of a triggering item

2019-12-12

3.7 Documented PCE implementation changes related to the new feature subsequent discount.

Updated the following chapters:

• Pricing Engine Model

• Pricing Engine API

• Pricing Engine Common

• Pricing Engine Core Implementation

• Extension Points

2020-03-12

3.7 Corrected product names ("Omnichannel Point-of-Sale" instead of "GK/Retail OmniPOS") in the following chapters:

• Pricing Engine Model

• Omnichannel Point-of-Sale Integration

• Customer Specific Prices for Pricing Service

• US Manufacturer Coupons for Pricing Service

2020-04-21

3.7 Updated Pricing Engine Common: new interfaces listed 2020-06-09

3.7 Updated Pricing Engine Core Implementation: missing beans listed 2020-06-09

3.7 Updated Extension Points: missing extension point documented, removed plugins deleted from documentation

2020-06-09

3.7 Updated Getting Started: corrected high-level PCE process diagram, small adjustments in wording 2020-07-13

3.7 Updated Libraries: updated list of external libs used by PCE 3.7 2020-07-13

3.7 Updated: Pricing Engine Model: added missing model interfaces 2020-07-13

3.7 Updated Pricing Engine API: added missing API methods 2020-07-13

Page 10: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

10

Version Change Date

3.7 Updated Pricing Engine Core Implementation: updated bean list 2020-07-13

3.7 Updated Extension Points: updated available extension point and plugin list 2020-07-13

3.7 Updated Custom Extension Samples with the plug-in description for custom PriceModificationMethod RT transaction-related handling

2020-08-26

Page 11: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

11

2 Preface

2.1 Introduction

The Promotion Calculation Engine (PCE) is the calculation core of the Promotion Pricing Service

(PPS). In an integrated Omnichannel concept, the PCE ensures homogeneous pricing, the consistent

application of promotions, and loyalty activities as well as the accurate calculation of refunds across

all channels.

The highly configurable solution is designed to handle a large number of price calculations

simultaneously across multiple channels and in real time.

The subsequent chapters provide you with an in-depth look into how the PCE operates. You will get

to know the algorithm and the technology behind the PCE and learn how to extend it according to

your needs.

Note that this documentation occasionally uses the term "Pricing Engine". This term denotes

the core components of the Promotion Calculation Engine. As the Pricing Engine comprises a

part of the PCE, it must not be confused with the PCE itself.

2.2 Definitions

The table below lists and explains the PCE terminology used throughout the document. For the

complete set of PCE-related terminology, refer to chapter Glossary.

PCE terminology

OPP/PPS Terminology

Description

Calculation Rule Price Rule Describes the benefit to be granted to the customer in case that the condition is applied.

Condition Promotion Price Derivation Rule

A condition can be understood as a single action granting a benefit to the customer. It consists of a set of triggers (eligibilities), time validity, and a rule describing the benefit. Multiple conditions can belong to a promotion.

PCE Context Holds the complete state for transaction processing and promotion calculation.

Eligibility Price Derivation Rule Eligibility

Precondition which has to be fulfilled in order to apply the condition. An eligibility triggers a condition.

Line Item Item An element of a transaction that contains information on goods or services delivered.

Page 12: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

12

PCE terminology

OPP/PPS Terminology

Description

Normalized Item Representation of a product, an article, a good, or a service that is bought or returned by a customer. An item is the smallest unit or customer pack that can be ordered independently and that cannot be split further into any smaller units.

Pricing Engine The core of the Promotion Calculation Engine. The Pricing Engine passes the request from the application, performs the price determination, and returns the result.

Promotion OPP Promotion Functional mapping of a campaign granting a benefit to the customer. A promotion consists of one or more conditions.

Request Message that contains common information pieces which are needed in order to process the message: A shopping basket with multiple line items and other information being relevant for the calculation of the benefits for the shopping basket.

The request is provided via the client API.

Response Responding message regarding to the request sent in. This can be the updated shopping basket including calculated discounts and bonus points as well as information about used promotion master data and applied coupons, or an error information in case that the request could not be processed.

Transaction The shopping basket with line item data and other information relevant for price calculation.

Page 13: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

13

3 Getting Started

The Promotion Calculation Engine (PCE) is a software component designed to calculate promotions

over items presented in a transaction. The PCE - besides calculating promotions related to the line

items - also processes other parts of the transaction, for example coupons or assigned customer

groups among others.

Technically, the PCE receives requests via a client exposed interface API. These requests are

expressed in Java objects which store the transaction with all calculation relevant information

provided by the client, such as line items that belong to the sales order. The objects contain all

information regarding the item necessary for the calculation. An incoming request is analyzed and

mapped to internal PCE model objects. The PCE extracts and analyzes information from the

transaction. Afterwards, if applicable, monetary discounts and bonus points are calculated, based on

the analyzed data from the transaction and on promotion data.

The result of the PCE calculation is mapped back to an exposed Client API object and is returned to

the requesting process, which can be another Java application or an HTTP client.

The following figure demonstrates the PCE process in a larger context:

To process promotions and to apply them to line items, the PCE evaluates promotion definitions. A

promotion definition is composed of promotion price derivation rules (for example, "promotion only

applies if you buy for more than a 100 € sum amount") including a price derivation rule and so-

called eligibilities. An eligibility is a trigger for a promotion.

Page 14: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

14

For further details on the functionality and features of the PCE, refer to the document

Functional Guide for the Promotion Calculation Engine.

The API communication within a PPS deployment is stateless and without any GUI. The responsibility

for storing information received from the PCE is delegated to the called process.

The transmitted content is based on the ARTS Pricing Service Interface schema.

Page 15: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

15

4 Technologies

Besides Java experience, an extension developer should have some knowledge of the following

technologies:

4.1 Spring Framework

Spring is used as a framework for dependency injection and enables the usage of wired components

in different combinations.

The PCE uses XML bean context definitions and Spring features to allow extensibility. See the

Extensibility chapter for more details.

4.2 ARTS standard

The PCE applies the standard provided by The Association for Retail Technology

Standards (ARTS) when defining data exchange message schemes.

The internal data model is based on ARTS standard as well with extensions required for price

calculation.

Especially the following ARTS specifications are of interest:

• ARTS Pricing Service Interface Technical Specification v 1.0

• ARTS Pricing Service Domain Model v 1.0.1

• ARTS Retail Transaction Interface Specification v 1.0

• ARTS Retail Transaction Interface Domain Model v 4.0

4.3 Libraries

The following external open source libraries are dependencies of the Promotion Calculation Engine.

All are available via Maven central.

The defined versions of the libraries are the ones that the Promotion Calculation Engine is built

and tested against.

A newer version of a library may work if the third party provider did not change their API in an

incompatible way.

Furthermore, the listed versions may differ from the dependency versions used in the PPS

environment and are specific for the Promotion Calculation Engine.

Page 16: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

16

Group ID Artifact Id Version Scope Description

org.springframework spring-beans 5.2.4.RELEASE compile & runtime

Spring framework

org.springframework spring-core 5.2.4.RELEASE compile & runtime

Spring framework

org.springframework spring-expression 5.2.4.RELEASE compile & runtime

Spring framework

org.springframework spring-context 5.2.4.RELEASE compile & runtime

Spring framework

org.springframework spring-aop 5.2.4.RELEASE compile & runtime

Spring framework

org.springframework spring-webmvc 5.2.4.RELEASE compile & runtime

Spring framework

org.slf4j slf4j-api 1.7.30 compile & runtime

Logging API

org.springframework.plugin spring-plugin-core 2.0.0.RELEASE compile & runtime

Spring framework

org.springframework.plugin spring-plugin-metadata

2.0.0.RELEASE compile & runtime

Spring framework

com.fasterxml.jackson.core jackson-annotations

2.10.0 compile & runtime

XML & JSON Parsing

com.fasterxml.jackson.core jackson-databind 2.10.0 compile & runtime

XML & JSON Parsing

com.fasterxml.jackson.core jackson-core 2.10.0 compile & runtime

XML & JSON Parsing

com.fasterxml.jackson.jaxrs jackson-jaxrs-json-provider

2.10.0 compile & runtime

XML & JSON Parsing

com.fasterxml.jackson.module jackson-module-jaxb-annotations

2.10.0 compile & runtime

XML & JSON Parsing

Page 17: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

17

Group ID Artifact Id Version Scope Description

com.fasterxml.jackson.dataformat jackson-dataformat-xml

2.7.9 compile & runtime

XML & JSON Parsing

joda-time joda-time 2.6 compile & runtime

Datetime utilities

com.google.guava guava 27.0.1-jre compile & runtime

Guava is a set of core libraries that includes new collection types (such as multimap and multiset), immutable collections, a graph library, functional types, an in-memory cache, and APIs/utilities for concurrency, I/O, hashing, primitives, reflection, string processing, and much more!

net.jperf jperf 1.0.3 compile & runtime

Performance Monitoring and Statistics for Java Code

commons-collections commons-collections

3.2.2 compile & runtime

Apache commons collection helper utilities.

Extends or augments the Java Collections Framework.

commons-lang commons-lang 2.6 compile & runtime

Apache commons utilities.

Provides extra functionality for classes in java.lang.

commons-logging commons-logging 1.2 compile & runtime

The Logging package is an ultra-thin bridge between different logging implementations. A library that uses the commons-logging API can be used with any logging implementation at runtime. Commons-logging comes with support for a number of popular logging implementations, and writing adapters for others is a reasonably simple task.

org.codehaus.woodstox stax2-api 4.1 compile & runtime

Extension to standard Stax API ("STandard Api for Xml procesing"), pull-parser API of JDK.

com.google.code.findbugs annotations 3.0.1 compile Findbugs static code check annotation. Compile time only dependency.

org.quartz-scheduler quartz 2.3.2 compile & runtime

Scheaduler, used for cron parsing.

javax.xml.bind jaxb-api 2.3.0 compile & runtime

XML Marshaling - Included for Java 11 support

Page 18: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

18

Group ID Artifact Id Version Scope Description

com.sun.xml.bind jaxb-core 2.3.0 compile & runtime

XML Marshaling - Included for Java 11 support

com.sun.xml.bind jaxb-impl 2.3.0 compile & runtime

XML Marshaling - Included for Java 11 support

javax.activation activation 1.1.1 compile & runtime

JavaBeans activation framework - Included for Java 11 support

javax.annotation javax.annotation-api

1.3.2 compile & runtime

Java Annotatins - Included for Java 11 support

Page 19: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

19

5 How the PCE works

5.1 PCE Request

The Promotion Calculation Engine is called via the Pricing Service API. The requester has to send a

PriceCalculate representation. The PriceCalculate object's ARTSHeader element contains request-specific

header information, while the PriceCalculateBody contains all required information to perform the price

calculation. Only one PriceCalculateBody and one ShoppingBasket is allowed per request.

The representation of a PriceCalculate request in XML format can be seen in the following sample:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<PriceCalculate xmlns="http://www.sap.com/IXRetail/namespace/" InternalMajorVersion="1"

InternalMinorVersion="0">

<ARTSHeader ActionCode="Calculate" MessageType="Request">

<MessageID>9a89f2edfd1e413ea147e334b9c2ed4b</MessageID>

<DateTime>2250-01-13T04:48:30.427-05:00</DateTime>

<BusinessUnit TypeCode="RetailStore">FC01</BusinessUnit>

</ARTSHeader>

<PriceCalculateBody TransactionType="SaleTransaction" NetPriceFlag="true">

<TransactionID>9a89f2edfd1e413ea147e334b9c2ed4b</TransactionID>

<DateTime>2250-01-13T04:48:30.427-05:00</DateTime>

<ShoppingBasket>

<LineItem>

<SequenceNumber>0</SequenceNumber>

<MerchandiseHierarchy ID="1">CHA2111</MerchandiseHierarchy>

<Sale ItemType="Stock" NonDiscountableFlag="false" FixedPriceFlag="false">

<TaxIncludedInPriceFlag>false</TaxIncludedInPriceFlag>

<NonPieceGoodFlag>false</NonPieceGoodFlag>

<FrequentShopperPointsEligibilityFlag>true</FrequentShopperPointsEligibilityFlag>

<NotConsideredByPriceEngineFlag>false</NotConsideredByPriceEngineFlag>

<ItemID>CHA2111001</ItemID>

<Quantity Units="1" UnitOfMeasureCode="PCE">2</Quantity>

</Sale>

</LineItem>

</ShoppingBasket>

</PriceCalculateBody>

</PriceCalculate>

Codeblock 1 Sample 1: Simple request in XML format

5.2 PCE Response

After a successful call, the PCE returns the response in a PriceCalculateResponse object (see

com.sap.ppengine.client.dto.PriceCalculateResponse) and informs the client about status using a

ResponseCode.

Page 20: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

20

Below you can see the XML representation of the response received for the request presented in

sample 1.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<PriceCalculateResponse xmlns="http://www.sap.com/IXRetail/namespace/" InternalMajorVersion="1"

InternalMinorVersion="0">

<ARTSHeader ActionCode="Calculate" MessageType="Response">

<MessageID>471b53ba-958e-4f8b-804c-d690e1c3f6d7</MessageID>

<DateTime>2017-04-10T09:29:27.862+02:00</DateTime>

<Response ResponseCode="OK">

<RequestID>9a89f2edfd1e413ea147e334b9c2ed4b</RequestID>

<ResponseTimestamp>2250-01-13T04:48:30.427-05:00</ResponseTimestamp>

</Response>

<BusinessUnit TypeCode="RetailStore">FC01</BusinessUnit>

</ARTSHeader>

<PriceCalculateBody TransactionType="SaleTransaction" NetPriceFlag="true">

<TransactionID>9a89f2edfd1e413ea147e334b9c2ed4b</TransactionID>

<DateTime>2250-01-13T04:48:30.427-05:00</DateTime>

<ShoppingBasket>

<LineItem>

<Sale ItemType="Stock" NonDiscountableFlag="false" FixedPriceFlag="false">

<ItemID>CHA2111001</ItemID>

<ExtendedAmount>0.0</ExtendedAmount>

<ExtendedDiscountAmount>0.0</ExtendedDiscountAmount>

<Quantity Units="1.0" UnitOfMeasureCode="PCE">2</Quantity>

<TaxIncludedInPriceFlag>false</TaxIncludedInPriceFlag>

<NonPieceGoodFlag>false</NonPieceGoodFlag>

<FrequentShopperPointsEligibilityFlag>true</FrequentShopperPointsEligibilityFlag>

<PriceTypeCode>00</PriceTypeCode>

<NotConsideredByPriceEngineFlag>false</NotConsideredByPriceEngineFlag>

</Sale>

<SequenceNumber>0</SequenceNumber>

<MerchandiseHierarchy ID="1">CHA2111</MerchandiseHierarchy>

</LineItem>

</ShoppingBasket>

</PriceCalculateBody>

</PriceCalculateResponse>

Codeblock 2 Sample 2: Response to request in code sample 1

If a valid request is sent, but with unexpected values or structure, the PCE will inform the

client through a Business Error Code in the response header section. You can find detailed

descriptions of the Business Error Codes for the concrete error cases in chapter Business Error

Codes . The Business Error Code is returned as part of the ARTSHeader element in the response

message.

See the following example for details:

Page 21: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

21

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<PriceCalculateResponse xmlns="http://www.sap.com/IXRetail/namespace/" InternalMajorVersion="1"

InternalMinorVersion="0">

<ARTSHeader ActionCode="Calculate" MessageType="Response">

<MessageID>0b15d202-5536-4b1c-bd1e-06f8beee72ba</MessageID>

<DateTime>2017-04-10T09:38:09.894+02:00</DateTime>

<Response ResponseCode="Rejected">

<RequestID>9a89f2edfd1e413ea147e334b9c2ed4b</RequestID>

<ResponseTimestamp>2017-04-10T09:38:09.893+02:00</ResponseTimestamp>

<BusinessError Severity="Error">

<ErrorID>GKR-100500</ErrorID>

<Description>Value not supported. Element LineItem.SequenceNumber. Sent: -10.

Expected: 0.</Description>

</BusinessError>

</Response>

<BusinessUnit TypeCode="RetailStore">FC01</BusinessUnit>

</ARTSHeader>

<PriceCalculateBody TransactionType="SaleTransaction" NetPriceFlag="true">

<TransactionID>9a89f2edfd1e413ea147e334b9c2ed4b</TransactionID>

<DateTime>2250-01-13T04:48:30.427-05:00</DateTime>

<ShoppingBasket>

<LineItem>

<Sale ItemType="Stock" NonDiscountableFlag="false" FixedPriceFlag="false">

<ItemID>CHA2111001</ItemID>

<Quantity Units="1" UnitOfMeasureCode="PCE">2</Quantity>

<TaxIncludedInPriceFlag>false</TaxIncludedInPriceFlag>

<NonPieceGoodFlag>false</NonPieceGoodFlag>

<FrequentShopperPointsEligibilityFlag>true</FrequentShopperPointsEligibilityFlag>

<NotConsideredByPriceEngineFlag>false</NotConsideredByPriceEngineFlag>

</Sale>

<SequenceNumber>-10</SequenceNumber>

<MerchandiseHierarchy ID="1">CHA2111</MerchandiseHierarchy>

</LineItem>

</ShoppingBasket>

</PriceCalculateBody>

</PriceCalculateResponse>

Codeblock 3 Business Error Code GKR-100500 (unexpected value)

5.3 Calculation modes

The PCE currently supports two calculation modes: Basket and LineItem . The calculation mode

controls how the PCE interprets and processes the incoming request, which causes different

expected results as well. Calculation modes are supported since interface version 2 (that is,

InternalMajorVersion="2"). Some promotions can only be applied in Basket mode, as they might

require multiple retail transaction line items present in the transaction to even be eligible.

Furthermore, coupons are prohibited in LineItem mode, a Business Error is returned if one is present

in the request. However, if a promotion is allowed and eligible, it will be handled, analyzed, and

applied either for Basket or LineItem mode.

Page 22: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

22

5.3.1 Basket mode

The calculation mode Basket is the default way to analyze and calculate transactions. All line items

are considered and processed at the same time.

• Example 1: If a transaction contains 10 line items with quantity 1, each costs 1€, a transaction

coupon of 3€ rebate will be applied and prorated to all items, producing a total price of 7€.

• Example 2: We have a transaction containing 3 line items of "item A" with quantity 1 and

price 10€ each. A 10% promotion with an item eligibility (threshold type "QUT" and 3 as

threshold quantity) can be applied on all three items.

Basket mode can be explicitly defined in the attribute CalculationMode of the request

message's PriceCalculateBody element.

See example below:

<PriceCalculateBody TransactionType="SaleTransaction" NetPriceFlag="true" CalculationMode="Basket">

Codeblock 4 CalculationMode "Basket"

5.3.2 LineItem mode

In Line Item mode, all line items in the transaction are handled and processed separately. This

means that all line items in the request will be split and processed by the PCE independently and the

individual results will be summarized in the end. Note that the Client API only supports one

PriceCalculateBody and one ShoppingBasket elements in the request message.

• Example 1: If a transaction contains 10 line items with quantity 1, each costs 1€ and a

transaction coupon for 3€ discount, a Business Error will be returned, as coupons are

prohibited in LineItem mode.

• Example 2: We have a transaction containing 3 line items of "item A" with quantity 1 and

price 10€ each. A 10% promotion with an item eligibility (threshold type "QUT" and 3 as

threshold quantity) cannot be applied, as the request is split three ways and processed

separately. None of the three reaches the defined threshold quantity individually.

Line Item mode can be explicitly defined/requested using the attribute CalculationMode of the request

message's PriceCalculateBody element.

See example below:

<PriceCalculateBody TransactionType="SaleTransaction" NetPriceFlag="true"

CalculationMode="LineItem">

Codeblock 5 CalculationMode "LineItem"

Page 23: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

23

5.4 PCE Processing

In order to achieve the expected results, the PCE executes a series of well-defined steps. The

following figure demonstrates these execution steps:

You find a detailed explanation of these steps in the following sections. More diagrams can also be

found in Appendix C.

5.5 Request processing

The process starts when the system receives a request of type PriceCalculate. In the phase of Parse

request, the request is validated and mapped to internal Java models with the help of a data

mapper object. Afterwards, an instance of Pricing Engine is created. Pricing Engine is called passing

through a Pricing Engine request containing configuration data and the mapped request.

HOW IT WORKS

Page 24: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

24

Parse request: The request of type PriceCalculate is parsed, validated, and mapped to internal object

models to be processed. Validations are done in this step, for example, check data format integrity,

check correlative sequence numbers, check constraints regarding max permitted values, etc. If

something is wrong according to specification, a business error is produced and the execution is

interrupted.

Map Any fields: The Any fields included in the PriceCalculate object are also processed and mapped

to the internal model during the parsing of the request. The Any fields are reserved for custom

extensions of the PriceCalculate object to support any possible customer requirements. These custom

fields must be mapped to the PCE's internal transaction model to be accessible throughout the

entire calculation process and to be available for mapping back to the response PriceCalculateResponse

object if necessary. For this reason, each model object of the internal transaction model extends the

TxModelDto interface (com.gk_software.pricing_engine.model.transaction.TxModelDto), which defines the

List<Object> getAny() method for accessing the extension data provided in the request.

Create Pricing Engine instance: An instance of PricingEngine Interface (PricingEngineImpl) is created

with the help of a PricingEngineFactory class.

Call Pricing Engine: Call Pricing Engine main method process passing through a Pricing Engine

request that contains configuration data and mapped request. At this step, the called calculation

mode is checked. If line item mode is requested, the line item will be split into separate transactions

to be processed independently. Otherwise, the default basket mode is used and the transaction

with all line items from the request is processed as a whole.

Initialize PCE context: All information during the analysis and calculation is stored into a PCE

context. The PCE context is available during the whole calculation process and updated as needed.

This step ensures that all initially available information is stored.

Clean promotion data from transaction: Useful for line item mode where the line items are

processed independently. Cleans the PCE context and makes sure that no information of a finished

process interferes with the process of the next line item.

Analyze transaction: Phase of analysis where every line item is analyzed and classified. The

analyzers are split by functionalities and can be easily extended by implementing the

interface TransactionAnalyzer. Every analyzer has to store information in the PCE context.

Currently implemented analyzers are:

• Coupon transaction analyzer: Responsible for processing and storing coupons from the

request.

• Customer group transaction analyzer: Responsible for looking for customer group-related

items.

• External promotion transaction analyzer: Responsible for looking for external promotions like

external price modifiers, external line items, loyalty reward, or price derivation rules.

Page 25: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

25

• Item transaction analyzer: Responsible for extracting line item basket values, transaction total

basket values, finding and processing of related merchandise hierarchy groups, manufacturer

information and additional prices.

• Manufacturer coupon transaction analyzer: Responsible for processing and storing

manufacturer coupons from the request.

• Promotion manual trigger analyzer: Responsible of looking for manual triggers related to line

item position as well as transaction level rebates.

Normalize transaction: Line items are normalized according to their quantity. For instance, if a

transaction contains a line item with quantity 10, the result of normalized process will be a

transaction with 10 line items with quantity 1. This ensures uniform results of the price calculation,

regardless of the structure of the transaction (1 line item with quantity 10 must give exactly the

same results as 10 line items with quantity 1). A detailed description of this process and its purpose

can be found in chapter Normalized Item Calculation.

Load ad hoc promotions: Ad hoc promotions provided by external systems are loaded in this step

in case of available AdhocPromotionLoader plugins. The ad hoc promotion are validated and processed

seamlessly with other promotion data retrieved from the data access layer, so it is crucial that they

are loaded before eligibility or condition loading and processing. The loading of these promotions

and their registration to the PCE context is performed by the AdhocEligibilityHandlerImpl, the core

implementation of the AdhocEligibilityHandler interface.

The following diagram shows the sequence of involved classes of the first steps of the request

processing: parsing the PriceCalculate request to the internal PCE model. As various elements of the

PriceCalculate object contain any fields, the mapping of these is performed as part of the request

mapping steps.

Page 26: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

26

The following diagram shows in detail the call sequence of involved classes of the request

processing, after the PriceCalculate mapping to the internal PCE model was completed.

Page 27: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

27

5.6 Eligibility loading

Eligibilities are the triggers for applying a promotion. Eligibilities contain all necessary information

that enables the PCE to determine whether a promotion is applicable on a certain line item. A

promotion must contain at least one eligibility. The eligibilities are loaded from the data access

layer, or in case of ad hoc promotions are provided in the promotion tree.

HOW IT WORKS

Similar to the transaction analyzer, the eligibility data loader is split into well-defined modules, called

fragments and item loaders. Each fragment is responsible for loading a specific type of eligibility

from the data access layer and for activating and registering it into the PCE context, while item

loaders are responsible for finding the eligible normalized items of the eligibility and storing them in

the corresponding working bucket. The fragment and item loader plugins are managed by the

DefaultEligibilityLoader

The PCE implements the following fragments:

• Coupon eligibility loader

• Customer group eligibility loader

• Item eligibility loader

• Market basket amount eligibility loader

• Merchandise group eligibility loader

• Merchandise set eligibility loader

Page 28: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

28

• Additional price type eligibility loader

• Manufacturer coupon eligibility loader

• Ad hoc eligibility loader

And the following eligibility item loaders:

• Item eligibility item loader

• Merchandise group item loader

• Merchandise set eligibility item loader

In addition to the DefaultEligibilityLoader , there is a special loader for manual eligibilities: the

ManualTriggerEligibilityLoader . This is because in case of ManualEligibilities some advanced context-specific

checks and handling must be performed in addition.

Besides loading the eligibility type specific promotion master data, the eligibility loading process is

responsible for several other steps regarding the preparation of the loaded eligibilities for

calculation. Some of these steps are explained below:

• Load eligibilities: Eligibilities are loaded from the persistence layer.

• Fill item buckets: Based on the analyzed data, the item bucket is saved into the PCE context.

Bucket is a special data abstraction for items that are handled by the same eligibility. More

about buckets can be found in chapter Normalized Item Calculation . The eligibility item

buckets are only relevant for item related eligibilities and are maintained separately for sold

and returned items.

• Check loaded eligibilities and activate eligibility: Checks whether eligibility is valid (active,

not expired, amount threshold was achieved,...) and whether items apply to eligibility. If true,

the eligibility is activated. The eligibility activation must be performed separately for sales,

returns and sales minus returns, and all activation statuses are stored.

• Check and activate parent eligibility: If an eligibility has a parent eligibility, it will also be

checked and activated if the item conditions are fulfilled.

Ad hoc eligibilities may be of any eligibility types supported by the rest of the eligibility loader

fragments. Because the eligibility is provided in the ad hoc promotion's tree structure it must not be

loaded from the DAL. The ad hoc eligibility loader implements the loading of promotions from the

PCE context, instead of the DAL. The eligibility activation and item bucket filling however is done by

the eligibility type specific eligibility loader fragments, which are registered to the ad hoc eligibility

loader as delegate fragments.

The following diagram explains the eligibility loading process in detail.

Page 29: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

29

5.7 Promotion calculation

This phase is responsible for calculating the promotions for the normalized items. The calculation

and distribution of rebates and bonus points is performed for position- and transaction-related

promotions as well. The calculation is based on the analyzed transaction data and on promotion-

related master data (promotion conditions, promotion condition rules, etc.) loaded form the data

access layer for the activated eligibilities.

HOW IT WORKS

The promotion calculation is responsible for the loading of promotion data related to the activated

eligibilities and for calculating the overall benefit.

Similar to the eligibility loader, the promotion data loader is split into well-defined modules, called

condition loader fragments . Each fragment is responsible for loading the promotion data from a

specific source and for validating the loaded promotions . The fragments are managed by

the ConditionLoaderImpl. The PCE implements the following condition loader fragments:

• DefaultConditionLoaderFragment: Loads the promotion data for activated eligibilities from the DAL

• AdhocConditionLoaderFragment: Loads the promotion data for activated ad hoc promotion

eligibilities from the PCE context

The steps of the promotion data loading process are explained below.

Page 30: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

30

• Load conditions for activated eligibilities: Promotion conditions and related promotion

condition rules are loaded from the data access layer (or other sources defined by the

registered condition loader fragments) for all of the activated root eligibilities.

• Load related promotions: Promotion information is loaded from data access layer and

other sources defined by the registered condition loader fragments.

• Check promotion validity: Checks whether the loaded promotions and conditions are valid

- effective, not expired, and so on. Promotion eligibilities are already validated.

• Register valid conditions to the PCE Context: All successfully loaded and validated

condition must be registered to the Context. Depending on the condition's parameters and

the different activation statuses of the eligibility a condition may be registered one or two

times, or not at all. This is necessary to ensure that the calculation is performed on sold and

returned line items separately, as it is configured in the promotion condition.

The following diagram illustrates the condition loading process.

Page 31: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

31

The determination of how many times and for which item types a promotion condition is to be

registered and calculated is summarized in the following table.

Rule control type

Calculation Base

Sale return type code

Condition registration

PO any value SALES If the root eligibility was activated for sales,

• then the condition is registered once to the PCE Context,

• and the condition calculation will be performed on sold items only.

Whether the eligibility was activated for returns or sales-minus-returns is not relevant in this case, does not influence the registration.

As a result the condition may be registered at most once .

Page 32: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

32

Rule control type

Calculation Base

Sale return type code

Condition registration

RETURNS If the root eligibility was activated for returns,

• then the condition is registered once to the PCE Context,

• and the condition calculation will be performed on returned items only.

Whether the eligibility was activated for sales or sales-minus-returns is not relevant in this case, does not influence the registration.

As a result the condition may be registered at most once .

SALES_RETURNS If the root eligibility was activated for sales ,

• then the condition is registered once to the PCE Context,

• and the condition calculation will be performed on sold items only .

If the root eligibility was activated for returns ,

• then the condition is registered once to the PCE Context,

• and the condition calculation will be performed on returned items only .

Whether the eligibility was activated for sales-minus-returns is not relevant in this case, does not influence the registration.

As a result the condition may be registered at most twice.

SU null or 00 SALES If the root eligibility was activated for sales, and the current transaction is a general transaction,

• then the condition is registered once to the PCE Context,

• and the condition calculation will be performed on sold items only.

Whether the eligibility was activated for returns or sales-minus-returns is not relevant in this case, does not influence the registration.

As a result the condition may be registered at most once .

RETURNS If the root eligibility was activated for returns and the current transaction is a return transaction,

• then the condition is registered once to the PCE Context,

• and the condition calculation will be performed on returned items only.

Whether the eligibility was activated for sales or sales-minus-returns is not relevant in this case, does not influence the registration.

As a result the condition may be registered at most once .

Page 33: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

33

Rule control type

Calculation Base

Sale return type code

Condition registration

SALES _RETURNS If the root eligibility was activated for sales , and the current transaction is a general transaction,

• then the condition is registered once to the PCE Context,

• and the condition calculation will be performed on sold items only .

If the root eligibility was activated for returns and the current transaction is a return transaction,

• then the condition is registered once to the PCE Context,

• and the condition calculation will be performed on returned items only.

Whether the eligibility was activated for sales-minus-returns is not relevant in this case, does not influence the registration.

As a result the condition may be registered at most once .

01 SALES If the root eligibility was activated for sales, and the current transaction is a general transaction,

• then the condition is registered once to the PCE Context,

• and the condition calculation will be performed on sold items only.

Whether the eligibility was activated for returns or sales-minus-returns is not relevant in this case, does not influence the registration.

As a result the condition may be registered at most once .

RETURNS If the root eligibility was activated for returns and the current transaction is a return transaction,

• then the condition is registered once to the PCE Context,

• and the condition calculation will be performed on returned items only.

Whether the eligibility was activated for sales or sales-minus-returns is not relevant in this case, does not influence the registration.

As a result the condition may be registered at most once .

SALES _RETURNS If the current transaction is a general transaction and the root eligibility was activated for sales-minus- returns,

• then the condition is registered once to the PCE Context,

• and the condition calculation will be performed on sold minus returned items. This is the only scenario where it is allowed to charge sold and returned items against each other.

If the current transaction is a return transaction and the root eligibility was activated for returns ,

• then the condition is registered once to the PCE Context,

• and the condition calculation will be performed on returned items only .

Whether the eligibility was activated for sales is not relevant in this case, does not influence the registration.

As a result the condition may be registered at most once .

After the promotion data has been successfully loaded and validated, the calculation is performed.

The steps of the calculation process are explained below.

Page 34: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

34

• Order conditions by sequence: Position and transaction related conditions are stored in

separate collections and are ordered by sequence number and resolution for processing.

Conditions which have the same sequence and resolution are sorted by their condition map

key, which is constructed as follows: <eligibility_ID> + "_" + <rule_ID> + (IF exists

manualTriggerAddend THEN ("_" + <addend>)) + (IF condition registered for second time

THEN ("_2")). As a result the order of conditions is always predictable. When the same

condition is to be calculated multiple times for sales and returns, the calculation is always

done first on sold items.

• Calculate position conditions: First position-related conditions are calculated. The

calculation is done on normalized items for consistent results regardless of the transaction's

structure.

• Apply to position summary results: After the calculation is performed, the resulting

information is saved into the position summary result.

• Calculate transaction conditions: Calculate conditions related to transaction.

• Apply transaction summary result: After the calculation on transaction level is finished, the

resulting information is saved into the transaction summary result.

The following diagram illustrates the calculation process of conditions.

Abbildung 1 PCE Condition Calculation

Page 35: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

35

5.8 Update transaction

After performing all calculations, the transaction must be updated with the result. The update

transaction phase is responsible for creating transaction model objects for the response with the

calculated promotions both on item and transaction level and for updating other related

information, such as details on used coupons.

The related steps are explained below:

• Summarize price and point modifiers: Retail price modifiers and frequent shopper point

modifiers are summarized first. As the calculation is performed on normalized items for

consistent results, the modifiers are also created for each individual normalized item.

However, the response's structure provided by the PCE to the caller must match the request

transaction. For this reason, the modifiers of all normalized items related to the same

transaction line item are merged. The line items are then updated with these summarized

modifiers.

• Update transaction: Transaction model objects reflecting the calculation result for positions

and transaction (for example, sale return line item modifier coupons, sale return line item

modifier references, retail transaction manufacturer coupon summaries or discount line

items) are created and the transaction is updated with them.

The following diagram illustrates the process of updating the transaction with the calculated

promotions.

Page 36: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

36

5.9 Create response

After the transaction was updated with the calculated results, it is mapped to the

PriceCalculateResponse object, which is then sent back to the calling process.

Page 37: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

37

HOW IT WORKS

DataResponseMapper object is used to create PriceCalculateResponse object.

Prepare response mapping context: DataMappingResponseContext is created using

DataMappingDefaultObjectFactory class. It is then filled with updated Transaction object, original

PriceCalculate request object and Configuration object.

Map response header: ARTSCommonHeaderType object is created. It is filled with newly created

random response. The header's messageID element is filled with a pseudo randomly generated

UUID, while the DateTime if filled with the current date and time. The response object also contains

original request ID and request timestamp. Both are mapped from the request object. The response

code is set to OK, if there was no problem during the calculation, or to REJECTED and corresponding

error code.

Map response body: PriceCalculateBase object is created. Response body fields are then mapped

from the original request, where it is necessary, or from the PCE model (mapped from request and

updated during request processing). The shopping basket is mapped completely from the PCE

model, using internal mappers:

• DataResponseLineItemMapperService - mapping for line items.

• DataResponseCouponMapperService - mappings for coupons.

• DataResponsePromotionManualTriggerTypeMapperService - mappings for manual triggers.

• DataResponseExternalTriggerMapperService - mappings for external triggers.

Create ARTS response: PriceCalculateResponse object is created. ARTSCommonHeaderType (header) and

PriceCalculateBase (body) are linked and InternalMajorVersion and InternalMinorVersion are filled from the

request.

Map ANY fields: PCE model objects contains also a list of plain Java objects of any type

(java.lang.Object) called ANY fields. This is part of the extension concept. They are originally copied

from the request but can be changed during the PCE calculation process. During the response

mapping step, they are copied back into the response. Example:

...

<PriceCalculateBody TransactionType="SaleTransaction" NetPriceFlag="true" CalculationMode="Basket">

<any>

<Street>Neue Bahnhofstrasse 21</Street>

<City>Sankt Ingbert</City>

<PostalCode>66386</PostalCode>

<Country>Deutschland</Country>

</any>

...

Page 38: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

38

5.9.1 Response Header Mappings:

Response Field Mapped From Value

PriceCalculateResponse InternalMajorVersion Request

PriceCalculateResponse InternalMinorVersion Request

Response Header Field Mapped From Value

ARTSHeader ActionCode Request Header

ARTSHeader MessageType Response

ARTSHeader.MessageID Generated (random)

ARTSHeader.DateTime Current timestamp

ARTSHeader.BusinessUnit PCE Model Transaction.BusinessUnitID

ARTSHeader.Response ResponseCode OK, REJECTED

ARTSHeader.Response.ResponseTimestamp Request Header Request timestamp

ARTSHeader.Requestor Request Header

ARTSHeader.WorkstationID Request Header

ARTSHeader.RequestedLanguage Request Header

ARTSHeader.RequestedMultiLanguage Request Header

5.9.2 Response Body Mappings:

Response Body Field Mapped From

Value

PriceCalculateBody TransactionType Request Body

PriceCalculateBody NetPriceFlag Request Body

PriceCalculateBody CalculationMode Request Body

Default: Basket

PriceCalculateBody.TransactionID PCE Model Transaction.Key.TransactionID

PriceCalculateBody.DateTime Request Body

Page 39: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

39

Response Body Field Mapped From

Value

PriceCalculateBody.ShoppingBasket PCE Model

PriceCalculateBody.RegularSalesUnitPriceRoundingRule RoundingMethod Request Body

PriceCalculateBody.RegularSalesUnitPriceRoundingRule Multiple Request Body

5.10 Normalized Item Calculation

5.10.1 Calculation Overview

The item prices and promotions are calculated from the item data received in a transaction. The

transaction is composed of line items (positions), each referring to a specific item from the article

master data with different quantities set. The structure of the transaction should have no influence

on the result of the calculation.

Thus, a position with a quantity of two is semantically the same as two positions of the same item

each with a quantity of one. As a real quantity is a combination of unit and quantity, the

normalizations lead to items with unit=1 and quantity=1. Any fractional units will lead to an additional

NormalizedItem with units<1 (the remaining) and quantity=1.

To reflect this, the PCE uses a normalized item calculation for calculating the promotions. This means

each position with quantity not one will be converted to multiple positions with quantity of one for

the calculation, a so-called NormalizedItem. When the calculation is finished, the results are then

aggregated to the real position structure inside the transaction.

During calculation, these NormalizedItems will be stored in special collections called buckets. A bucket

is a collection that allows set operations and includes sorting, filtering, and sum calculation

functions. Buckets are used as the standard collection of NormalizedItems throughout the PCE

calculation process. The bucket is created for every activated eligibility containing the eligible

NormalizedItems, or as another example the NormalizedItems of the same merchandise hierarchy group

or with the same item ID are also stored in buckets in the PCE Context. For more information about

buckets please refer to chapter Bucket API.

The following image illustrates the bucket calculation algorithm.

Page 40: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

40

On the left side, there is a sketch of a transaction with five positions (line items) inside. To

easily differentiate the items visually, each item (item ID) is represented with a different color

(position 1 and 3 contain the same item - in the example represented by red color).

• Position 1 is a red item with a quantity of 1.

• Position 2 is a blue item with a quantity of 2.

• Position 3 is again a red item with a quantity of 4.

• Position 4 is a yellow item with a quantity of 3.

• Position 5 is a green item with a quantity of 1.

During the analysis of the transaction, the positions are normalized to the NormalizedItems (each

represented by a bubble). Then they are put into item buckets based on their item type (color).

In addition, items are also grouped (put to the bucket) based on transaction merchandise

hierarchy groups. In the example we assume that there are two merchandise hierarchy groups

defined. One for red and blue items and one for green and yellow items. For each

merchandise hierarchy group, an MHG bucket is created which contains all related items.

As each bucket holds only references to the items, the red item 1 in the red item bucket is the

same as the red item 1 in the MHG bucket. This allows more complex combinations to use set

operations like unions or intersections to define the working set for a calculation.

Each eligibility has a reference to an original bucket which contains all related NormalizedItems

and a working bucket that is used during calculation loops and form which elements are

removed if the promotion was applied. This is required, for example, for interval calculations.

During eligibility loading step, the buckets are created also for all activated eligibilities. They

may be the same as buckets created during transaction analysis (like item or MHG eligibilities),

or different (like combination or merchandise set eligibilities). In the example, you see an

ItemEligibility for red items, a Merchandise Hierarchy Group Eligibility for red/blue MHG, and

an Item Or CombinationEligibility containing blue and yellow items.

During calculation of the promotion, temporary PriceModifiers A-D are created for the red items.

Each modifier is related to some specific NormalizedItem. This example assumes a promotion

with an interval of two, so the promotion can be applied twice and uses four items.

Page 41: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

41

One item is left in the working bucket as the interval is not fulfilled anymore.

During update of the transaction with the results, the temporary PriceModifiers are aggregated

to the final PriceModifiers on the positions. The result is that position 1 has one PriceModifier with

an applied quantity of 1 and position 3 has a PriceModifier with an applied quantity of 3 (of 4

item quantities available).

Due to the possibility of performance decrease as a result of the normalization of large

number of items the minimumQuantityForSingleNormalizedItemCreation configuration

parameter was introduced. The integer value defines the minimum number of line items which

must be present in the transaction for disabling the standard item normalization. In case this

item count is exceeded a single normalized item will be created for each different item in the

transaction with quantity >= 1. For more information regarding the PCE configuration please

refer to the Functional Guide.

5.10.2 Discount Calculation and Rounding

Due to the normalized calculation, the discount amounts are rounded on NormalizedItem level as well.

This can lead to different values for rounding than it may be expected for a position.

The rounding element consists of a value and a direction.

The rounding value is the absolute difference between the calculated discount before rounding and

after rounding. The rounding direction reflects the direction of rounding (UP or DOWN).

Rounding always is done on the discount amount and not on the new prices.

The following chapters show through examples the calculation on NormalizedItem level and the

resulting rounding amounts.

5.10.2.1 Position Discount rounding

A position that has a regular sales unit price of 15.95 and a quantity of 10 should get a 10%

rebate each.

We assume the rounding decimal places is set to 2 and rounding destination value to 0.01

(round to the nearest cent denomination) and rounding direction should be half up.

The PCE normalizes this to 10 NormalizedItems with a quantity of 1 each.

So a 10% Rebate will calculate a discount amount of 15.95 * 0.1 = 1.595.

Page 42: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

42

This will round to 1.60. The rounding value is 0.005 (1.60-1.595) and the rounding direction is

UP for a single NormalizedItem.

In the result, these discounts are summed up for the position (10 times). This leads to a

discount of 1.60*10 and a new price of 143.50. The rounding value for the position would then

be 0.05.

Note the difference if the engine would calculate on position level completely. Then we could

assume a rebate of 15.95*10*0.1=15.95 with a rounding value of 0! But this would lead to

different discounts depending on the structure of the transaction. Having 1 position with

quantity 10 would have different result than 10 positions with quantity of 1.

Therefore, to ensure consistent rebate calculation the PCE uses the normalized approach.

5.10.2.2 Transaction Rebate Distribution

Now we assume the same transaction with one position that has a regular sales unit price of

15.95 and a quantity of 10.

But this time we have a transaction rebate of 10%.

We assume the rounding decimal places is set to 2 and rounding destination value to 0.01

(round to the nearest cent denomination) and rounding direction should be half up.

The PCE normalizes this to 10 NormalizedItems with a quantity of 1 each.

So a 10% Transaction rebate will calculate a discount amount based on the overall basket

amount of 15.95 *10 = 159.50. Getting 10% rebate on this will lead to a discount of 159.50 *

0.1 = 15.95.

This overall discount is then distributed to the single NormalizedItems.

For each item, the related part of the discount will be calculated like 15.95*0.1 = 1.595.

This will again round to 1.60. So the rounding value is 0.005 (1.60-1.595) and the rounding

direction is UP for a single Normalized Item.

This is true for the first 9 items. The last item then gets the remaining discount. That means we

used up of the overall discount of 15.95 for the first 9 items each a discount of 1.60. So the

remaining discount is 15.95-9*1.6=1.55.

As the last item simply gets what is left, no rounding is done as 1.55 already fits to 2 decimal

places with destination value of 0.01.

In the result, the discounts are summed up for the position. This leads to a discount of

1.60*9+1.55=15.95 and a new price of 143.55. The rounding value for the position would then

be 9*0.005=0.045.

Page 43: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

43

Due to the different ways of calculating position rebates and transaction rebates we may see

slightly different results for what seems the same rebate (10%). Keep this in mind when

designing your promotions. Always consider the normalized calculation approach will behave

as if a transaction contains only positions with quantity 1.

Page 44: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

44

6 PCE Modules

6.1 Overview

The PCE is composed of several modules. Each module provides a jar file for runtime deployment.

The modules are grouped in three main modules that define responsibility of the contained

modules.

The three main modules are:

• Pricing Engine: Contains submodules for the concrete promotion calculation. Most of the

business logic can be found here.

• Pricing Service: Provides the integration to the service layer via the Client API. Mainly the

mapping of the Client API to the internal data model.

• SAP Integration: Contains a single submodule responsible for accessing the master data via

the data access layer. It provides mapping of the data access API data model to the internal

PCE data model.

Other modules:

• Model: Defines the internal data model of PCE core.

• Model Default: Standard implementation of internal PCE model.

• API: Defines the public API of the PCE core.

• Common: Contains the internal PCE API which is not part of public API.

• Impl: Base implementations for public and internal API, most of the business logic

functionality is implemented here.

• Core: Pricing engine service client API and base implementation.

• PSI SAP: Pricing engine service SAP integration.

• Data Access SAP: Mapping of SAP data model into internal PCE model, interface for

accessing data layer.

Page 45: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

45

6.2 Spring Context

The PCE core is configured and initialized via Spring XML contexts.

It is assumed that a developer who writes an extension for the PCE knows Spring and its basic

concepts.

There are three main XML files needed to set up the complete PCE core context:

• META-INF/com.gk-software.pricing-engine/psi-sap/common.xml: The core engine beans. Defined in

pricing-engine-impl module.

• META-INF/com.gk-software.pricing-engine/psi-sap/beans.xml: Service-related beans like

request/response mapper. Defined in pricing-engine-psi-sap module.

• META-INF/com.gk-software.pricing-engine/dataaccess-sap/beans.xml: Definitions of data access for SAP

data layer. Defined in pricing-engine-dataaccess-sap module.

The following Spring contexts are imported into application context to be able to initialize the

complete PCE core:

<import resource="classpath:/META-INF/com.gk-software.pricing-engine/psi-sap/common.xml" />

<import resource="classpath:/META-INF/com.gk-software.pricing-engine/psi-sap/beans.xml" />

<import resource="classpath:/META-INF/com.gk-software.pricing-engine/dataaccess-sap/beans.xml"

/>

6.3 Pricing Engine Model

6.3.1 Overview

The pricing-engine-model module defines the internal data model of the PCE core. The model is defined

mostly by interfaces. These interfaces are part of the public API and are kept release-stable for

usage. That means extensions based on these APIs should still run on newer version of the PCE core

without any migration needed.

Page 46: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

46

For a more detailed description of the defined stability levels, refer to chapter PCE Extensions

.

The standard implementation of this model API is provided in the pricing-engine-model-default module.

The classes in that module are not public API. For the Omnichannel Point-of-Sale integration, a

specific implementation of the model API is provided for internal POS usage.

The model has three important parts:

• Typecodes

• Promotion Masterdata model

• Transaction model

In addition, there is a small Omnichannel Point-of-Sale-specific part for rounding rule definitions

and merchandise hierarchy group handling.

6.3.1.1 DataModel Factories

The data model defines factory interfaces for creating concrete model object instance. The

implementation used of these interfaces is injected via the Spring application context. By using the

Spring bean replacement approach, it is possible to use different implementations in the existing

application context.

Factory Interface Default Bean Bean Alias Description

IPromotionFactory defaultPromotionSOFactory promotionSOFactory Factory for promotion master data objects.

ITransactionFactory defaultTransactionFactory transactionFactory Factory for transaction model objects.

6.3.2 Data Model

This chapter provides a high-level overview on all Pricing Engine model interfaces with a brief

description.

For details on the model, refer to the Javadoc of the pricing-engine-model project, or the PCE Functional

Guide's Configuration chapter.

6.3.2.1 Typecodes

All typecodes are designed as interfaces with two implementations: One enum implementation for

the standard codes and one String-Code implementation for custom or unknown values.

The typecodes all extend the ValueTypeEnum interface that defines specific comparison methods for

checking equality against a String or another typecode. Always use these defined "is" methods for

comparing ValueTypeEnums and not the equals method of Java.

Page 47: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

47

Note that while the enum implementations are part of the API, they are just release-stable

regarding existing values. The values can be extended without notice to support additional use

cases and functionalities.

Consider that additional values may be added in the future, especially when referencing these

enums in loops or switch statements. Therefore, it is advised to implement a reasonable

default handling in case you must use these enums in loops or switch statements.

6.3.2.1.1 General Typecodes

In the package com.gk_software.pricing_engine.model.typecodes, you find general typecodes that are used

inside the calculation logic or defined via configuration.

Specifically, these are:

Interface Description

AdditionalPriceTypeCode Additional price type code representation.

BucketClassifier Classifies buckets based on their intended purpose during the calculation.

BucketItemTypeCode Defines the type of item which can be added to the bucket.

CalculationScheme Calculation scheme controlling promotion filtering based on the promotion price derivation rules' transaction control break code.

DiscountVectorMethodCode Defines which positions are checked against the discount vector.

RebateShareCalculationMethodCode Defines the method for proportionally distributing the receipt discount among the different receipt line items (for receipt related monetary discounts, not used for points): Defined by Pricing Engine Configuration.

RoundingMethod Rounding methods defined in Configuration.

RoundingPercentualPointsMethodCode Defines the method which is used to calculate percentual points condition values.

TimeValidationMethodCode Method to determine the validity level of a condition defined in Configuration.

TransactionAnalyzerType Transaction analyzer type useful for plugin delimiter identification.

TransactionRebateCalculationMethodCode Specifies how to determine the calculation base of the receipt related discount.

6.3.2.1.2 Promotion Master Data Codes

The package com.gk_software.pricing_engine.model.typecodes.promotion contains typecodes referenced in

the promotion master data model. Besides the interfaces, you find here the enums with the default

values. The String-based generic implementations are defined in

com.gk_software.pricing_engine.model.typecodes.promotion_default.

Page 48: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

48

Interface Description

AdjustmentMethodCode A mnemonic code denoting what kind of adjustment is being made to the retail price of the item.

AmendmentTypeCode Determines whether the condition can be used only for sales, only for amendments, or for both: - 00/null: for sales as well as for amendments - 01: only for sales - 02: only for amendments.

CalculationBaseType The parameter CalculationBase is only influencing the calculation base for transaction-related conditions.

ChooseItemMethod Defines the order in which items are used in promotion calculation, for example, lowest priced first or highest priced first.

CombinationCode Code denoting the style of combination that is to be applied across the child eligibilities, for example, logical AND, logical OR.

CouponConsumptionCode Enum for consumption code for coupons.

CouponPrintoutRule The type code of the printout rule SEPARATE_RECEIPT as "00" PRINT_AT_END as "01".

DiscountMethodCode The type code of the printout rule.

EligibilityStatusCode Enum for eligibility status codes values for PromotionConditionEligibilitySO.getStatusCode().

EligibilityType Eligibility type interface.

EligibilityUnitOfMeasureCode Defines special eligibility unit of measure type codes like _ALL.

MerchandiseSetCombination The merchandise set element combination code indication whether the defined items are included or excluded in the merchandise set.

MerchandiseSetTypeCode Defines type of Merchandise set element MRHRC - Merchandise hierarchy group ITM - Item OPR - Set operation.

MixAndMatchCombinationType Determines how the matching items belonging to the rule can be combined.

PositionType Type safe, extensible enumeration for RetailTransactionLineItemTypeCodes in a PositionTypePromotionConditionEligibilitySO.

PriceModificationMethod A code denoting the method of modifying the price that is being applied to the transaction.

PrivilegeType For mapping privilege type values for manual trigger.

ReductionMethodMixAndMatch A code denoting the method of modifying the price that is being applied in case of MixAndMatch promotions.

RoundingMethodCode Determines how the calculated reduction amount is to be rounded.

RuleControlType Mapping for PriceDerivationRuleBase-> TransactionControlBreakCode. Determines whether the price derivation rule is to be applied during the registration of the transaction.

Page 49: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

49

Interface Description

RuleType Defines the type of price derivation rule.

SaleReturnTypeCode Determines whether the condition can be used only for sales, only for returns, or for both: - 00/null: for sales as well as for returns - 01: only for sales - 02: only for returns.

ThresholdType A code for the type of threshold which applies to a price derivation rule eligibility.

TriggerValueTypeCode The type of the TriggerValue for ExternalTriggerValuePromotionConditionEligibilitySO.

6.3.2.1.3 Transaction Model Codes

The package com.gk_software.pricing_engine.model.typecodes.transaction contains typecodes referenced in

the transaction data model. Besides the interfaces, you find here the enums with the default values.

The String-based generic implementations are defined in

com.gk_software.pricing_engine.model.typecodes.transaction_default.

Interface Description

CalculationMethodCode A mnemonic code denoting how the price modification calculation was performed.

PriceModificationMethodTx PriceModification codes for transaction data mapping. Combination of RuleTypeEnum and PriceModificationMethodEnum mapped in RetailTransactionPromotionPriceDerivationRule.getPriceModificationMethodCode().

QuantityInputMethod Sale return line items quantity input method values.

RetailTransactionLineItemTypeCode Type safe, extensible enumeration for RetailTransactionLineItemTypeCodes.

SaleReturnLineItemActionCode Type safe, extensible enumeration for SaleReturnLineItemActionCodes.

SalesOrderDeliveryTypeCode Type safe, extensible enum for mapping the delivery type code of the related sales order SaleReturnLineItemSalesOrder.getSalesOrderDeliveryTypeCode().

UnitOfMeasureCode Deprecated due to incorrect naming, use QuantityInputMethod instead. Represents the sale return line items quantity input method values.

6.3.2.2 Promotion Master Data

The promotion master data model is used for loading promotion data from the data access layer. It

contains the rules and configurations for calculation of promotions and prices.

Package: com.gk_software.pricing_engine.model.md.promotion

Factory Interface: com.gk_software.pricing_engine.model.md.promotion.IPromotionSOFactory

Interface Description

AdditionalPriceTypePromotionConditionEligibilitySO

Additional price type condition eligibility.

Page 50: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

50

Interface Description

AdditionalPriceTypePromotionConditionRuleSO

Additional Price Type Rule.

CombinationPromotionConditionEligibilitySO

Combination of eligibilities.

CouponPromotionConditionEligibilitySO Eligibility for coupon. If the Promotion.Condition.Eligibility.Coupon.IDList contains more coupon IDs, one eligibility is created for each ID and the eligibilities are connected via a combination eligibility of the type OR.

CustomerGroupPromotionConditionEligibilitySO

Eligibility for customer group.

CustomerPromotionConditionEligibilitySO Eligibility for customers.

ExternalActionParameterSO Contains information about parameters for the action to be performed by the client which invoked the Pricing Engine in case that the price derivation rule applies.

ExternalActionPromotionConditionRuleSO An action is to be performed by the client which invoked the Pricing Engine in case that the price derivation rule applies.

ExternalActionTextSO Contains information about texts for the action to be performed by the client which invoked the Pricing Engine in case that the price derivation rule applies.

ExternalTriggerValuePromotionConditionEligibilitySO

Eligibility for external trigger.

Get3Pay2PromotionConditionRuleSO Rule: Get 3 Pay 2. It is not supported with default calculation but may be still used by custom extensions with existing model definition.

ItemPromotionConditionEligibilitySO Item eligibility.

ManualPromotionConditionEligibilitySO Manual eligibility promotion condition.

ManufacturerCouponPromotionConditionEligibilitySO

Manufacturer coupon eligibility.

Implementation only available in the PCE internal model.

ManufacturerCouponQualifyingPurchaseSO Manufacturer coupon purchase requirement.

Implementation only available in the PCE internal model.

ManufacturerCouponSO Manufacturer coupon mapped from the coupon bar code provided in the transaction in GS1 format.

Implementation only available in the PCE internal model.

MarketBasketAmountEligibilitySO Eligibility for market basket amount.

Page 51: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

51

Interface Description

MatchingItemRelationSO Promotional items.

MatchingItemSO Matching item.

MatchingManufacturerCouponRelationSO Promotional manufacturer coupon.

Only available in the PCE internal model.

MatchingMhgRelationSO Promotional merchandise groups.

MerchandiseSetPromotionConditionEligibilitySO

Defines a merchandise set resulting from the application of set operations to merchandise hierarchy groups and/or items and the further conditions regarding quantities and amounts which govern the application of the associate rule to an item falling under the resulting merchandise set at the time an instance of the item is recorded as a line item in a sale/return.

MerchandiseSetRelationSO An association between two merchandise sets that establishes one as the higher and one as the lower level

MerchandiseSetSO A merchandise set (that is, the reference to the root element of the merchandise set)

MHGPromotionConditionEligibilitySO Merchandise hierarchy group eligibility.

Eligibilities from Promotion.Condition.Eligibility.MerchandiseHierarchyGroupList|MerchandiseHierarchyGroup. Eligibilities from Promotion.Condition.Eligibility.ItemList|Item in case the eligibility contains more than one item.

Additionally, if the Promotion.Condition.Eligibility.MerchandiseHierarchyGroup element contains IntersectionList, one MHG eligibility is created for each IntersectionList.ID and the MHG eligibilities are connected via a CombinationEligibility of the type Intersection.

MixAndMatchPromotionConditionRuleSO Mix and Match.

PositionTypePromotionConditionEligibilitySO

Eligibility for position type.

PromotionConditionEligibilitySO Promotion condition eligibility.

PromotionConditionRuleSO Promotion condition rule.

PromotionConditionSO Condition of the promotion.

PromotionConditionTimeGroupSO Time restriction.

PromotionMhgFilterSO This domain object contains the promotion data relevant for the PCE.

PromotionSO This domain object contains the promotion data relevant for the PCE.

Page 52: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

52

Interface Description

PromotionTextSO Language-dependent texts to a promotion.

RebatePromotionConditionRuleSO Simple discount.

ThresholdPromotionConditionEligibility Threshold promotion condition data for eligibility.

TimeRestrictionSO Time restriction for the promotion.

WorkerDiscountGroupPromotionConditionEligibilitySO

Eligibility for workers.

6.3.2.3 Transaction

The transaction data model is the data model for the client data. It is mapped from the incoming

request and the results are mapped back.

Each interface defined in the transaction model extends the TxModelDto interface

(com.gk_software.pricing_engine.model.transaction.TxModelDto), which provides access to the any fields

mapped from the request message. This way the custom any fields are available throughout the

calculation.

Type Method Description

List<Object> getAny Extension data provided by request (any objects).

Package: com.gk_software.pricing_engine.model.transaction

Factory Interface: com.gk_software.pricing_engine.model.transaction.ITransactionFactory

Interface Description

FrequentShopperPointsModifier A line item modifier that reflects a modification of the frequent shopper points.

LoyaltyRewardLineItem A RetailTransactionLineItem sub-type that records the crediting of a CustomerLoyaltyAccount with points, or the gifting of an Item or gift certificate to that account because of some Promotion. In the PCE context, at the moment points are used only.

ManualPromotionTrigger Common interface for manual promotion triggers.

PriceModificationLineItem A line item component of a RetailTransaction that records the granting of a reduction or increase of price on all Items in the Transaction

Page 53: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

53

Interface Description

RetailPriceModifier A line item modifier that reflects a modification of the retail selling price. It is provided by PLU through the application of a predefined price derivation rule that depends on parameters provided during the sale transaction. This entity is intended to support pricing schemes which vary depending on the rule applied, Mix and Match etc. The price change reflected in this modifier may be treated as a markdown, a discount, a promotional expense, etc. This entity is also intended to support tiered pricing that is determined by a shopper/customer affiliation with some group like AARP etc. that receives special price breaks.

RetailTransaction A type of Transaction that records the business conducted between the retail enterprise and another party involving the exchange in ownership and/or accountability for merchandise and/or tender or involving the exchange of tender for services.

RetailTransactionCouponSummary Information about coupons which were applied for that sales transaction.

RetailTransactionCustomer Information about the customer the transaction was created for.

RetailTransactionCustomerGroupAssignment The customer groups which are assigned to the transaction (indirectly by the assigned customers).

RetailTransactionExternalTrigger Contains the external values which were requested via web services in order to check whether the transaction is eligible for promotions containing eligibilities of type "external trigger value".

RetailTransactionLineItem A detail line item of a RetailTransaction that records the business conducted between the retail store and another party involving the exchange in ownership and/or accountability for merchandise and/or tender or involving the exchange of tender for services.

RetailTransactionLineItemAssociation Associative entity recording relationships between line items within the same RetailTransaction.

Examples of usage of this entity include:

• Associating an original sales line item to a return line item

• Associating an original sales line item to an exchange line item

• Associating a sales line item to a fee line item

RetailTransactionManufacturerCouponSummary Information about manufacturer coupons in the transaction.

RetailTransactionManufacturerCouponValidation The manufacturer coupon validation element containing information about the sale return line item which received the manufacturer coupon related promotion.

RetailTransactionModifierCoupon Information about coupons which were applied for that line item.

RetailTransactionPromotionExternalActionParameter Contains information about the parameters of the action to be performed by the client which invoked the Pricing Engine in case that the price derivation rule applies.

Page 54: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

54

Interface Description

RetailTransactionPromotionExternalActionText Contains information about the texts of the action to be performed by the client which invoked the Pricing Engine in case that the price derivation rule applies.

RetailTransactionPromotionPriceDerivationRule Contains relevant data regarding the price derivation rules which apply to the transaction, respectively, its line items.

RetailTransactionPromotionTrigger Manual triggers which are created by POS function and used as eligibilities for conditions.

RetailTransactionTotal A monetary or unit count total for the RetailTransaction. Usually TotalTaxableAmount, TotalTaxCollected, TotalAmountPaid, TotalItemCount, etc.

ReturnLineItem A sub-type of SaleReturnLineItem recording the reason and disposal of an Item being returned by a customer. If the return is to be recorded against the original retail transaction line item, this should be recorded as a RetailTransactionLineItemAssociation with RetailTransactionLineItemAssociation.AssocationTypeCode of "return".

SaleReturnLineItem A line item component of a RetailTransaction that records the exchange in ownership of a merchandise item (that is, a sale or return) or the sale or refund related to a service. The sale or refund related to a service captures an item and action taken that reflects an event of interest to the retail business but DOES NOT RESULT in the exchange in ownership of a merchandise item.

SaleReturnLineItemAdditionalPrice Represent the sale return line item additional prices.

SaleReturnLineItemMerchandiseHierarchyGroup All merchandise hierarchy groups which are directly assigned to the item.

SaleReturnLineItemModifierCoupon Information about coupons which were applied for that line item.

SaleReturnLineItemModifierReference Contains all line items of the current transaction which together caused that a price derivation rule was applied (if the price derivation rule was applied more than one time summarization takes place); is filled only in case that several positions together caused it, is needed for calculating the average rebate in case of item return.

SaleReturnLineItemPromotionTrigger Manual triggers which are created by POS function and used as eligibilities for conditions.

SaleReturnLineItemSalesOrder Information about the SAP customer order related to this line item.

SaleReturnLineItemSplitPackage Contains methods for accessing/updating package price information for normalized items of a line item.

Transaction 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.

Page 55: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

55

Interface Description

TransactionCategory Describes which categories transactions fall into.

6.4 Pricing Engine API

6.4.1 Overview

The pricing-engine-api module defines the public API of the PCE core. The API defined in this module is

release-stable from PCE 2.9.4 onward. That means extensions based on these APIs should still run on

newer version of the PCE core without any migration needed. The PCE defines two levels of API

stability: Consumer stability and Extension stability.

For more detailed description of the defined stability levels, refer to chapter PCE Extensions .

6.4.2 API Overview

This chapter gives an overview on the common API use cases for caller type APIs. Details on the

extension points API can be found in the chapter PCE Extensions .

6.4.2.1 General API

6.4.2.1.1 How to create API object instances

Several API objects are instantiated at runtime during processing of a calculation request. As the API

is defined as interfaces, there is a factory pattern implemented to create concrete instances of these

objects.

HOW IT WORKS

The factory to create API object instances is defined via the Interface

com.gk_software.pricing_engine.api.PricingEngineAPIFactory.

An implementation of this factory is initialized via the Spring context. The bean is available to be

injected in extension implementations via the following Spring coordinates.

You should use the bean alias to access factory via Spring.

Bean Alias Default bean name Implemented interfaces

pricingEngineObjectFactory

defaultPricingEngineObjectFactory

com.gk_software.pricing_engine.api.PricingEngineAPIFactory

com.gk_software.pricing_engine.PricingEngineObjectFactory

The factory allows to create the following object instances:

Page 56: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

56

Object to create Method Description

CacheContext createCacheContext Creates a new cache context.

CalculationResultContext createCalculationResultContext Creates a new calculation result context.

CollisionHandlingContext createCollisionHandlingContext Creates a new collision handling context

CollisionHandlingResult createCollisionHandlingResult Creates a new collision handling result

Configuration createConfiguration Creates a new configuration object.

Context createContext Creates a new context object.

Comparator<EligibilityWrapper<T>> createEligibilityIDComparator Creates a new eligibility ID comparator.

EligibilityLoaderContext createEligibilityLoaderContext Creates new eligibility loader context object.

EligibilityWrapper<T> createEligibilityWrapper Creates new eligibility wrapper object from a PromotionConditionEligibilitySO.

BucketFilter<LineItemSummaryResult> createFullyPricedLineItemSummaryResultFilter Creates new fully priced filter for LineItemSummaryResult buckets.

BucketFilter<NormalizedItem> createFullyPricedNormalizedItemFilter Creates new fully priced filter for NormalizedItem buckets.

LineItemSummariesSequenceNumberComparator

createLineItemSummariesSequenceNumberComparator

Creates a new line item summary sequence number comparator.

Comparator<LineItemSummaryResult> createLineItemSummariesTriggerAmountAscendingComparator

Creates a new line item summary trigger amount ascending comparator.

Comparator<LineItemSummaryResult> createLineItemSummariesTriggerAmountDescendingComparator

Creates a new line item summary trigger amount descending comparator.

Comparator<LineItemSummaryResult> createLineItemSummaryResultPositionAscendingComparator

Creates a new ascending position comparator for LineItemSummaryResults

Page 57: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

57

Object to create Method Description

Comparator<LineItemSummaryResult> createLineItemSummaryResultPositionDescendingComparator

Creates a new descending position comparator for LineItemSummaryResults

LineItemSummaryResult createLineItemSummaryResult Creates new line item summary result object.

Bucket<LineItemSummaryResult> createLineItemSummaryResultBucket Creates new line item summary result bucket.

BucketFilter<LineItemSummaryResult> createManualTriggerFilter Creates new manual trigger filter.

Comparator<ManufacturerCouponPromotionKey>

createManufacturerCouponPromotionKeyComparator

Create new descending comparator for comparing the manufacturer coupon ad hoc promotion cache keys

MarketBasketAnalyzerResult createMarketBasketAnalyzerResult Creates a new market basket analyzer result

Comparator<MatchingItemSO> createMatchingItemIDComparator Creates a new matching item ID comparator

MixAndMatchResult createMixAndMatchResult Creates a new MixAndMatchResult, mix and match rule calculation result

NormalizedItem createNormalizedItem Creates new normalized item.

Bucket<NormalizedItem> createNormalizedItemBucket Creates new normalized item bucket.

Comparator<NormalizedItem> createNormalizedItemQuantityComparator Creates a new normalized item quantity comparator.

PartialResultCollisionValues createPartialResultCollisionValues Creates a new partial result collision values object

PluginRegistryContext createPluginRegistryContext Creates a new plugin registry context.

Comparator<NormalizedItem> createPositionAscendingComparator Creates a new position ascending comparator.

Comparator<NormalizedItem> createPositionDescendingComparator Creates a new position descending comparator.

Page 58: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

58

Object to create Method Description

PositionPartialResult createPositionPartialResult Creates a new position partial result.

PositionPartialResultBase createPositionPartialResultBase Creates a new position partial result base.

PositionSummaryResult createPositionSummaryResult Creates a new position summary result.

PriceCalculationContext createPriceCalculationContext Creates new price calculation context.

PriceCalculationResult createPriceCalculationResult Creates new price calculation result object.

PricingEngineRequest createPricingEngineRequest Creates a new pricing engine request object.

PricingEngineResponse createPricingEngineResponse Creates a new pricing engine response object.

PromotionConditionContext createPromotionConditionContext Creates a new promotion condition context.

PromotionConditionWrapper createPromotionConditionWrapper Creates new promotion condition wrapper object.

BucketFilter<LineItemSummaryResult> createRebatableLineItemSummaryResultBucketFilter

Creates a new rebatable line item summary result bucket filter.

RebateShareResult createRebateShareResult Creates new rebate share result.

RuleCalculationContext createRuleCalculationContext Creates new rule calculation context.

Comparator<LineItemSummaryResult> createSequenceNumberComparator Creates a new sequence number comparator.

TransactionAnalyzerContext createTransactionAnalyzerContext Creates a new transaction analyzer context.

TransactionPartialResult createTransactionPartialResult Creates a new transaction partial result.

TransactionPartialResultBase createTransactionPartialResultBase Creates a new transaction partial result base.

TransactionSummaryResult createTransactionSummaryResult Creates a new transaction summary result.

Page 59: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

59

Object to create Method Description

Comparator<LineItemSummaryResult> createTriggerAmountComparator Creates a new line item summary result trigger amount comparator.

6.4.2.2 Bucket API

6.4.2.2.1 What are normalized items

A transaction can contain multiple line items. But a line item does not have to represent a single

item in the basket. Each line item has a quantity and unit attribute that together define the actual

quantity represented. This means a single line item in the transaction or request with multiple

quantities is equivalent to a request with multiple items with single quantities. For example, let us

assume the following LineItem from a request with a quantity of 3:

<LineItem>

<Sale ItemType="Stock" NonDiscountableFlag="false" FixedPriceFlag="false">

<ItemID>000000000000000885</ItemID>

<RegularSalesUnitPrice>1.6</RegularSalesUnitPrice>

<Quantity Units="1.0" UnitOfMeasureCode="PCE">3</Quantity>

<TaxIncludedInPriceFlag>false</TaxIncludedInPriceFlag>

<NonPieceGoodFlag>false</NonPieceGoodFlag>

<FrequentShopperPointsEligibilityFlag>true</FrequentShopperPointsEligibilityFlag>

<PriceTypeCode>00</PriceTypeCode>

<NotConsideredByPriceEngineFlag>false</NotConsideredByPriceEngineFlag>

</Sale>

<SequenceNumber>0</SequenceNumber>

</LineItem>

This is logically the same as a request with three single line items with a quantity of 1 each:

Page 60: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

60

<LineItem>

<Sale ItemType="Stock" NonDiscountableFlag="false" FixedPriceFlag="false">

<ItemID>000000000000000885</ItemID>

<RegularSalesUnitPrice>1.6</RegularSalesUnitPrice>

<Quantity Units="1.0" UnitOfMeasureCode="PCE">1</Quantity>

<TaxIncludedInPriceFlag>true</TaxIncludedInPriceFlag>

<NonPieceGoodFlag>false</NonPieceGoodFlag>

<FrequentShopperPointsEligibilityFlag>true</FrequentShopperPointsEligibilityFlag>

<PriceTypeCode>00</PriceTypeCode>

<NotConsideredByPriceEngineFlag>false</NotConsideredByPriceEngineFlag>

</Sale>

<SequenceNumber>0</SequenceNumber>

</LineItem>

<LineItem>

<Sale ItemType="Stock" NonDiscountableFlag="false" FixedPriceFlag="false">

<ItemID>000000000000000885</ItemID>

<RegularSalesUnitPrice>1.6</RegularSalesUnitPrice>

<Quantity Units="1.0" UnitOfMeasureCode="PCE">1</Quantity>

<TaxIncludedInPriceFlag>true</TaxIncludedInPriceFlag>

<NonPieceGoodFlag>false</NonPieceGoodFlag>

<FrequentShopperPointsEligibilityFlag>true</FrequentShopperPointsEligibilityFlag>

<PriceTypeCode>00</PriceTypeCode>

<NotConsideredByPriceEngineFlag>false</NotConsideredByPriceEngineFlag>

</Sale>

<SequenceNumber>1</SequenceNumber>

</LineItem>

<LineItem>

<Sale ItemType="Stock" NonDiscountableFlag="false" FixedPriceFlag="false">

<ItemID>000000000000000885</ItemID>

<RegularSalesUnitPrice>1.6</RegularSalesUnitPrice>

<Quantity Units="1.0" UnitOfMeasureCode="PCE">1</Quantity>

<TaxIncludedInPriceFlag>true</TaxIncludedInPriceFlag>

<NonPieceGoodFlag>false</NonPieceGoodFlag>

<FrequentShopperPointsEligibilityFlag>true</FrequentShopperPointsEligibilityFlag>

<PriceTypeCode>00</PriceTypeCode>

<NotConsideredByPriceEngineFlag>false</NotConsideredByPriceEngineFlag>

</Sale>

<SequenceNumber>3</SequenceNumber>

</LineItem>

To make sure the promotion calculation behaves the same, independent of how the items are

structured in the transaction, the PCE maps LineItems from the request to an internal item type called

NormalizedItem. A NormalizedItem extends the SaleReturnLineItem from the transaction data model. Each

NormalizedItem is used to represent a single quantity of an item. So in the examples above, both

transaction items would be represented as three NormalizedItem objects for the calculation of the

promotions.

HOW IT WORKS

Page 61: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

61

When the items of a transaction are analyzed by the PCE core implementation of the

ItemTransactionAnalyzer, during analysis the SaleReturnLineItems in the transaction are transformed to

NormalizedItems. These are then stored in the TransactionAnalyzerContext attributes

positionPromotionRelevantItems and transactionPromotionRelevantItems. During normalization process, the

actual quantities (units times quantity) of the LineItems are analyzed and normalized to one or a

fraction of one if the actual quantity is not an integer value.

The NormalizedItem contains calculation-relevant data and a reference via the key to the original

LineItem.

THERE IS MORE

The normalization process of a LineItem to NormalizedItems is handled by the internal utility

method normalizeLineItem in com.gk_software.pricing_engine.common.utils.BucketUtils.

The NormalizedItems are internally stored in buckets.

6.4.2.2.2 What is a bucket

A Bucket is a PCE-specific implementation of Java Collection Queue API. It supports all common Java

Collection and Queue operations and in addition adds additional functionality:

• Buckets can only contain unique elements similar to a Set. This check assumes all elements

follow the Java standard equals and hashCode contract.

• Buckets are sortable by adding a comparator.

• Buckets allow applying a Filter.

• Support collection operations for union, difference, and intersection.

• Additional sum calculation on contained elements is possible.

HOW IT WORKS

The Bucket API is defined by com.gk_software.pricing_engine.api.bucket.Bucket Interface.

Type Method Description

boolean addAll(Collection<? extends T> c, boolean sort) Adds all items from the given collection to the bucket with optional sorting.

boolean addBucket(Bucket<T> otherBucket) Adds another bucket to this bucket, overtaking calculated values.

Bucket<T> addFluent(T item) Same as add but for use in fluent call.

void addItemValues(T item) Adds item values to totalized values.

void applyComparator(Comparator<T> comparator) Adds new comparator to the bucket.

Bucket<T> applyFilter(BucketFilter<T> filter) Applies a filter to the bucket.

Page 62: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

62

Type Method Description

Bucket<T> applyFilters(List<BucketFilter<T>> filters) Applies a list of filters to the bucket.

List<T> asList() Gets bucket items as list.

Comparator<T> comparator() Gets the current comparator.

T getItemByLineItemKey(SaleReturnLineItem.Key lineItemKey)

Returns the item from the bucket identified by the saleReturnLineItem key passed.

BigDecimal getTriggerAmount() Gets the sum of all actual amounts inside this bucket.

BigDecimal getTriggerQuantity() Gets the sum of all actual quantities inside this bucket.

BigDecimal getUsedTriggerAmt() Gets the sum of trigger amounts used in a rebate calculation or ZERO if not applicable.

BigDecimal getUsedTriggerQut() Gets the sum of trigger quantities used in a rebate calculation or ZERO if not applicable.

boolean offer(T o, boolean sort) Adds the given item to bucket. Allows to control is bucket is immediately resorted.

void recalculate() Recalculates all summed up values.

boolean remove(Object o, boolean sort) Removes the given item from bucket. Allows to control is bucket is immediately resorted.

void setComparator(Comparator<T> comparator) Sets the current comparator.

void sort() Sorts the bucket.

void subtractItemValues(T item) Subtracts values for this item from the summed up values.

In addition, a Bucket supports the standard Java API Queue and Collection methods.

Modifier and Type Method

boolean add(T e)

boolean addAll(Collection<? extends T> c)

void clear()

boolean contains(Object o)

boolean containsAll(Collection<?> c)

T element()

Page 63: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

63

Modifier and Type Method

boolean isEmpty()

Iterator<T> iterator()

boolean offer(T e)

T peek()

T poll()

T remove()

boolean remove(Object o)

boolean removeAll(Collection<?> c)

boolean retainAll(Collection<?> c)

int size()

Object[] toArray()

<T> T[] toArray(T[] a)

THERE IS MORE

The PCE relies on two different implementations of Buckets: One implementation is based on

NormalizedItems as Bucket elements (com.gk_software.pricing_engine.common.impl.bucket.NormalizedItemBucket).

This is mainly used for the normalization process, in the Context and for eligibility loading and

evaluation.

Another implementation is based on LineItemSummaryResults as elements. These LineItemSummaryResults

are containers for calculation-specific values (see section Result API for details). The

LineItemSummaryResultBucket is used in the actual promotion calculation.

You can create both types of Buckets via the PricingEngineAPIFactory.

6.4.2.3 Context API

The PCE context is responsible for storing and exposing all data extracted and analyzed in the

phases of a PCE process. The PCE Context helps to carry out this information between processes and

the process that uses it to read and update content. The PCE Context is defined in the interface PCE

Context (com.gk_software.pricing_engine.api.context.Context). The context is passed as a parameter on all

phases of the PCE process.

More specifically, the context stores the following information:

• PCE Context composed of several elements,

Page 64: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

64

• Configuration,

• Transaction and retail transaction line items,

• Position and transaction relevant line items,

• Business unit group,

• Position and transaction summary results,

• Partial results,

• Manual promotions triggers.

HOW IT WORKS

The context is composed by several elements, each responsible for storing a well-defined set of

data.

Interface Description

CacheContext Local master data cache.

CalculationResultContext Calculation result context.

CollisionHandlingContext The collision handling context. Stores information regarding the PCE's collision handling and resolution results.

Context The PCE Context stores all needed data for the processing of the Pricing Engine.

ContextPostProcessor Any functionality to be processed before the price calculation is executed can be added as ContextPostProcessor plugin implementation.

EligibilityLoaderContext Stores information for loaded eligibilities.

ExternalModifiersProcessingResult Interface representing the results of processing external modifiers in a PCE request, which will be used during validation of the promotion conditions.

MarketBasketAnalyzerResult Stores all total market basket amount related values.

PromotionConditionContext Context data on loaded promotions and conditions.

RequestContext<R> Used to store information regarding the original request message received by the Pricing Engine and the calculation scheme of the current request processing.

TransactionAnalyzerContext Analyzed data from transaction preprocessing.

PluginRegistryContext Contains all registered plugins.

6.4.2.3.1 Reading configuration settings

It is possible to pass a configuration map containing key/value pairs with the request message to the

PCE. The configuration parameters are mapped to an internal Configuration object which is then stored

in the context making it accessible in all phases of the PCE processing. The PCE Configuration is

defined in the interface Configuration (com.gk_software.pricing_engine.api.configuration.Configuration).

HOW IT WORKS

Page 65: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

65

The configured values passed with the PCE request are parsed by the ConfigurationInitializer to the

internal Configuration instance (com.gk_software.pricing_engine.core.configuration.ConfigurationInitializer). In case

a key value pair was not provided with the request for a given configuration parameter, the default

value defined in the ConfigurationImpl, the PCE core implementation of the Configuration, will be used in

the calculation (com.gk_software.pricing_engine.common.impl.configuration.ConfigurationImpl).

For a list of the configuration parameters supported by the Pricing Engine, refer to chapter

Configuration .

6.4.2.3.2 Getting transaction information

The TransactionAnalyzerContext stores all data available from analyzing and preprocessing the

transaction.

The PCE TransactionAnalyzerContext is defined in the interface TransactionAnalyzerContext

(com.gk_software.pricing_engine.api.context.TransactionAnalyzerContext).

HOW IT WORKS

The analysis is carried out by the PCE core plugin implementations of the TransactionAnalyzer interface

(com.gk_software.pricing_engine.api.analyzer.TransactionAnalyzer). All analyzer plugin implementations are

responsible for extracting and processing a standard transaction part, such as coupons, external

promotions or triggers, and are executed in sequence.

The TransactionAnalyzerContext stores the following data:

Data extracted from transaction PCE core implementation used for analysis (in com.gk_software.pricing_engine.core.analyzer)

Item information for all items - item ID, unit of measure code, manufacturer related information, additional prices if available

ItemTransactionAnalyzer

The associated merchandise hierarchy group IDs for each merchandise hierarchy group present in the transaction

ItemTransactionAnalyzer

Coupon numbers of coupons present in the transaction CouponTransactionAnalyzer

Customer group IDs present in the transaction and customer ID CustomerGroupTransactionAnalyzer

Transaction elements resulting from an external promotion such as price and points modifiers, price derivation rules, price modification, and loyalty reward line items

ExternalPromotionsTransactionAnalyzer

Normalized item buckets filled according to different filtering criteria such as item IDs, merchandise hierarchy groups, position or transaction promotion relevant items, manufacturer related information

ItemTransactionAnalyzer

Manual triggers PromotionManualTriggerTransactionAnalyzer

Page 66: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

66

Data extracted from transaction PCE core implementation used for analysis (in com.gk_software.pricing_engine.core.analyzer)

General transaction related information

• Does it include sale and return line items

• Transaction basket amount

• Discountable items on position and transaction level

ItemTransactionAnalyzer

Manufacturer coupons present in the transaction ManufacturerCouponTransactionAnalyzer

6.4.2.3.3 Getting specific item buckets from context

The item buckets stored in the TransactionAnalyzerContext are used throughout the PCE process to

access the normalized items eligible for the specific calculation use case. The following buckets are

available from the context:

• Item buckets stored in a map by item key information and by their sale return type.

• Merchandise hierarchy group (mhg) buckets stored in a map by mhg information and by

their sale return type.

• Manufacturer buckets stored in a map by manufacturer item key specific to the given

collection. The manufacturer item key is constructed from the item's company code, family

code and unit of measure code.

• Merchandise set buckets stored in a map by merchandise set information and by their sale

return type .

• Item buckets stored by the additional price type code when such a price is available for the

item.

• Position-related promotion-relevant item bucket.

• Transaction-related promotion-relevant item bucket.

HOW IT WORKS

The buckets are filled separately for each line item present in the transaction when the transaction

analysis is performed by the PCE core implementation ItemTransactionAnalyzer after the item

normalization was completed.

The transaction-related promotion-relevant item bucket is filled with all normalized items available

from the transaction. Any transaction-related promotion calculation process will use this set of items

as base for the calculation. The position-related promotion-relevant bucket is filled with all

normalized items which meet the criteria set by the internal utility method isPositionPromotionRelevant

in com.gk_software.pricing_engine.common.utils.LineItemUtils. This bucket contains all normalized items which

can be used in position-related promotion calculation. Any further analysis is done for position

discount-related normalized items only.

Page 67: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

67

The analysis continues with processing all items available from the normalization. An ItemInfo

(com.gk_software.pricing_engine.common.impl.dto.ItemInfo) object is created and saved to the

TransactionAnalyzerContext, as well as the item key and the normalized item to the item bucket map

As the next step, the merchandise hierarchy groups present in the request are processed. For each

merchandise hierarchy group, a findAssociatedMhgByChildId call is made to the data access layer

retrieving the associated parent merchandise hierarchy groups. The mhg ID and all active, non-

expired parent mhg IDs are then saved to the context. The normalized items are added to the mhg

buckets under each mhg key.

In case the transaction contains any manufacturer coupons, then the items' manufacturer related

information is also analyzed, the manufacturer buckets are filled in the TransactionAnalyzerContext.

THERE IS MORE

One normalized item might belong to several buckets. For example, the line item in the request

fragment below would belong to the item bucket in the item bucket map stored under the key

"000000000000000885__PCE" as well as the merchandise hierarchy group bucket stored in the mhg

bucket map under the key "031901__MAIN". In case that "031901__MAIN" had parent merchandise

hierarchy groups in the master data structure, the normalized item would be included in the buckets

for all the parent mhgs as well.

<LineItem>

<Sale ItemType="Stock" NonDiscountableFlag="false" FixedPriceFlag="false">

<ItemID>000000000000000885</ItemID>

<RegularSalesUnitPrice>1.6</RegularSalesUnitPrice>

<Quantity Units="1.0" UnitOfMeasureCode="PCE">1</Quantity>

<TaxIncludedInPriceFlag>true</TaxIncludedInPriceFlag>

<NonPieceGoodFlag>false</NonPieceGoodFlag>

<FrequentShopperPointsEligibilityFlag>true</FrequentShopperPointsEligibilityFlag>

<PriceTypeCode>00</PriceTypeCode>

<NotConsideredByPriceEngineFlag>false</NotConsideredByPriceEngineFlag>

</Sale>

<MerchandiseHierarchy ID="MAIN">031901</MerchandiseHierarchy>

<SequenceNumber>0</SequenceNumber>

</LineItem>

Thus, the buckets all contain references to the same normalized items, making sure that any

modifications to them during the PCE processes are considered in subsequent calculation steps as

well.

6.4.2.3.4 Check loaded and activated eligibilities

The EligibilityLoaderContext stores all data available from loading eligibilities from the data access layer.

The PCE EligibilityLoaderContext is defined in the interface EligibilityLoaderContext

(com.gk_software.pricing_engine.api.context.EligibilityLoaderContext).

Page 68: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

68

The EligibilityLoaderContext stores eligibility collections for all supported PromotionConditionEligibilitySO

implementations that are filled with the data retrieved by the eligibility loaders. The collections

contain wrapper objects which include the eligibility and further information regarding the loaded

eligibility. All eligibilities received from the data access layer are stored, regardless of their status.

HOW IT WORKS

The eligibility loading and storing in the EligibilityLoaderContext is carried out by the PCE core

implementations of the EligibilityLoader interface (com.gk_software.pricing_engine.api.eligibility .

EligibilityLoader). All eligibility loader plugin implementations are executed in sequence.

The eligibilities are stored in the EligibilityLoaderContext in the following collections and can be accessed

through the getter methods provided by the interface.

Type of collection Name of collection Description

Map<Long, EligibilityWrapper<AdditionalPriceTypePromotionConditionEligibilitySO>>

additionalPriceTypeEligibilityMapByEligibilityID

Map of loaded additional price type eligibilities stored by the eligibility ID.

List<EligibilityWrapper<CouponPromotionConditionEligibilitySO>> couponEligibilityList List of loaded coupon eligibilities.

List<EligibilityWrapper<CustomerGroupPromotionConditionEligibilitySO>>

customerGroupEligibilityList List of loaded customer group eligibilities.

Map<Long, EligibilityWrapper<ItemPromotionConditionEligibilitySO>>

itemEligibilityMapByItemEligibilityID Map of loaded item eligibilities stored by eligibility ID.

List<EligibilityWrapper<ManualPromotionConditionEligibilitySO>> manualPromotionEligibilityListForPositions

List of loaded position related manual trigger eligibilities.

Page 69: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

69

Type of collection Name of collection Description

List<EligibilityWrapper<ManualPromotionConditionEligibilitySO>> manualPromotionEligibilityListForTransaction

List of loaded transaction related manual trigger eligibilities.

Map<Long, ManufacturerCouponPromotionConditionEligibilitySO>

manufacturerCouponEligibilityMapByEligibilityID

Map of mapped manufacturer coupon promotion condition eligibilities stored by eligibility ID.

List<EligibilityWrapper<MarketBasketAmountEligibilitySO>> marketBasketAmountEligibilityList List of loaded market basket amount eligibilities.

Map<String, List<EligibilityWrapper<MerchandiseSetPromotionConditionEligibilitySO>>>

merchandiseSetEligibilitiesByID Map of loaded merchandise set eligibilities stored by merchandise set ID.

Map<Long, EligibilityWrapper<MHGPromotionConditionEligibilitySO>>

mhgEligibilityMapByMhgEligibilityID Map of loaded merchandise hierarchy group eligibilities stored by eligibility ID.

How to find activated conditions

The PromotionConditionContext stores all data available from loading promotion conditions, rules, and

promotions from the data access layer based on the activated root eligibilities. Besides that, some

further information regarding the loaded promotion data is also available from the

PromotionConditionContext throughout the promotion calculation.

The PCE PromotionConditionContext is defined in the interface PromotionConditionContext

(com.gk_software.pricing_engine.api.context.PromotionConditionContext).

Page 70: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

70

HOW IT WORKS

The following information regarding the loaded promotion data is stored in the

PromotionConditionContext in collections and can be accessed through the methods provided by the

interface.

Type of collection Name of collection Description

Set<Long> activatedRootEligibilities List of activated root eligibilities. Further promotion master data is loaded based on this.

Map<Long, PromotionSO> adhocPromotionsByPromotionID Loaded ad hoc promotions stored by promotion ID.

Map<Long, ManualPromotionTrigger> appliedManualPromotionForRule Applied manual promotion triggers provided in the transaction stored by rule ID.

SortedMap<Long, SortedMap<Long, Map<String, PromotionConditionWrapper>>>

lineItemConditionAtSubtotalMap Position-related promotion condition at subtotal maps stored by sequence and resolution.

SortedMap<Long, SortedMap<Long, Map<String, PromotionConditionWrapper>>>

lineItemConditionMap Position-related promotion condition maps stored by sequence and resolution.

Map<Long, List<ManualPromotionTrigger>>

manualPromotionTriggerMapByEligibilityID Manual promotion triggers provided in the transaction stored by eligibility ID.

Map<Long, ManufacturerCouponSO> manufacturerCouponByAdhocPromotionID Manufacturer coupons by the related ad hoc promotion's ID

Map<Long, List<String>> matchingItemIDMapByMerchandiseSetID Mix and match matching items IDs stored by merchandise set IDs.

Map<Long, EligibilityWrapper<?>> promotionConditionEligibilityMapByID Eligibilities stored by internal eligibility ID.

Map<Long, List<EligibilityWrapper<?>>> promotionConditionEligibilityMapByParentID Eligibilities stored by their parent eligibility ID.

Map<Long, PromotionConditionWrapper> promotionConditionMapByEligibilityID Loaded promotion conditions stored by eligibility ID.

Map<Long, PromotionConditionRuleSO> promotionConditionRuleMapByID Loaded promotion condition rules stored by internal rule ID.

Map<ManualPromotionTrigger, PromotionConditionRuleSO>

promotionConditionRuleMapByManualTrigger Rules stored by the manual trigger which triggered them.

Page 71: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

71

Type of collection Name of collection Description

Map<Long, PromotionSO> promotionMapByPromotionID Loaded Promotions stored by promotion ID.

Map<Long, Map<Long, Map<String, PromotionConditionWrapper>>>

transactionConditionAtSubtotalMap Transaction-related promotion condition at subtotal maps stored by sequence and resolution.

SortedMap<Long, SortedMap<Long, Map<String, PromotionConditionWrapper>>>

transactionConditionMap Transaction-related promotion condition maps stored by sequence and resolution.

List<PromotionConditionWrapper> transactionPromotionConditions Stores all transaction promotions

List<PromotionConditionWrapper> transactionPromotionConditionsAtSubTotalList Stores all transaction promotions at sub total

Map<Long, PromotionConditionRuleSO> virtualDiscounts Rules providing virtual discounts stored by their internal rule ID.

6.4.2.4 Eligibility API

6.4.2.4.1 Getting calculation specific eligibility information

The eligibilities are loaded from the data access layer for the transaction and are processed by the

PCE core plugin implementations of the EligibilityLoader interface

(com.gk_software.pricing_engine.api.eligibility.EligibilityLoader ). Besides retrieving the master data, the

EligibilityLoader is responsible for creating an eligibility-specific bucket to work on during calculation

filled with all normalized items affected by the eligibility, for registering the eligibility in the context,

for checking and loading of parent eligibilities, and for validating and activating eligibilities. All

information resulting from the eligibility processing is stored in a wrapper object which is stored by

the EligibilityLoaderContext as well, making it available throughout the entire PCE process.

The eligibility wrapper is defined in the generic interface EligibilityWrapper

(com.gk_software.pricing_engine.api.eligibility.EligibilityWrapper<T extends PromotionConditionEligibilitySO>).

HOW IT WORKS

After the eligibilities have been loaded from the data access layer, the next step of the eligibility

loading process is to create a new EligibilityWrapper object for each loaded eligibility. In all further

steps of the eligibility loading and the calculation, the wrapper object is used exposing all

information available from the eligibility loading process.

The EligibilityWrapper<T extends PromotionConditionEligibilitySO> stores the following information:

Page 72: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

72

Name Type Description

Eligibility T extends PromotionConditionEligibilitySO

The eligibility loaded from the data access layer.

Eligibility status

EligibilityStatus The status of the eligibility. The status is determined by the eligibility loader process on eligibility activation. The status is set to active if the eligibility was activated for at least one of the following activation types: sales, returns or sales minus returns.

Eligibility status map

Map<EligibilityActivationType, EligibilityStatus>

The status map of the eligibility, which stores the activation status for all defined activation types. The eligibilities are always activated for the following activation types separately:

• Sales: Active if the sold items in the transaction are eligible on their own.

• Returns: Active if the returned items in the transaction are eligible on their own.

• Sales-Minus-Returns: Active if the sold minus the returned items in the transaction are eligible together.

Child count int The total count of child eligibilities of a combination eligibility. Relevant in case of combination eligibilities.

Active child count

int The count of already activated child eligibilities of a combination eligibility. Relevant in case of combination eligibilities.

Combination code

CombinationCode The combination code of the eligibility. Relevant in case of combination eligibilities.

Current coupon count

int The number of used coupons.

Associated retail transaction line item keys

Set<RetailTransactionLineItem.Key> Set of retail transaction line item keys of items related to this eligibility.

Item bucket map

Map<BucketKey, NormalizedItemBucket>

Holds all normalized item buckets related to the eligibility:

• Original item bucket for sold items: Bucket containing all sold normalized items related to the eligibility.

• Original item bucket for returned items: Bucket containing all returned normalized items related to the eligibility.

• Working item bucket for sold items: Bucket used during PCE calculation. This working bucket is initialized with the complete set of sold normalized items related to the eligibility. During calculation for sales, all filtering is done on this bucket, so the original set of normalized items are still available in the original item bucket.

• Working item bucket for returned items: Bucket used during PCE calculation. This working bucket is initialized with the complete set of returned normalized items related to the eligibility. During calculation for sales, all filtering is done on this bucket, so the original set of normalized items are still available in the original item bucket.

Page 73: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

73

Name Type Description

Is manual trigger transaction level

boolean True if the eligibility is a ManualPromotionConditionEligibilitySO and the manual trigger is transaction-related, false otherwise.

Is ad hoc eligibility

boolean True if the eligibility was loaded as part of an ad hoc promotion, false otherwise.

6.4.2.5 Result API

6.4.2.5.1 Checking overall calculation result

The overall calculation result is maintained throughout the PCE calculation in the so-called

SummaryResult. It contains the total achieved benefit from all applied conditions. The SummaryResult

holds the LineItemSummaryResult (com.gk_software.pricing_engine.api.result.LineItemSummaryResult) for each

normalized item in a bucket with the individual calculation result values and other related

information such as used coupons in the calculation. The SummaryResult also stores similar buckets

with the calculation result for each applied sequence, as these may be required as a base of the

calculation in some use cases.

The SummaryResult is defined in the interface SummaryResult (com.gk_software.pricing_engine.api.result

.SummaryResult).

HOW IT WORKS

The SummaryResult stores the following information regarding the overall calculation result:

Name Type Description

Condition applied list Map<String, Integer> The number of how many times the given condition was applied stored by promotion condition ID.

LineItemSummaryResult bucket

Bucket<LineItemSummaryResult> The LineItemSummaryResult bucket holding the overall calculation result.

Sequence line item summaries

Map<Long, Bucket<LineItemSummaryResult>>

The LineItemSummaryResult buckets holding the calculation result for each applied condition sequence stored by sequence.

Customer group factor BigDecimal The customer group factor, which is a multiplier for earned points based on the customer group.

The PCE API contains two additional interfaces extending the SummaryResult interface:

PositionSummaryResult and TransactionSummaryResult. These API objects are instantiated and initialized as

the first step of the PCE condition calculation process, and saved to the Context. Note that the

corresponding SummaryResults are only created and saved to the context if position or transaction

calculation is deemed required based on the loaded eligibilities. In case of multiple calculated

sequences, the summary result must be updated with the result of the single calculation and the

updated SummaryResult's LineItemSummaryResultBucket must be saved to the sequence map.

Page 74: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

74

The PositionSummaryResult is defined in the interface

PositionSummaryResult (com.gk_software.pricing_engine.api.result .PositionSummaryResult). It extends the

Summary result with the following additional information:

• The calculation PartialResults from the current sequence processing. The list is cleared on

starting the next sequence calculation.

The TransactionSummaryResult is defined in the interface TransactionSummaryResult

(com.gk_software.pricing_engine.api.result .TransactionSummaryResult). It extends the Summary result with the

following additional information:

• The sum amount of awarded frequent shopper points.

• The transaction basket amount.

• The actual basket amount to be considered in the calculation.

• The sum awarded rebate amount.

• The updated coupon info to be included in the response.

• Loyalty reward line items created for the transaction.

• Price modification line items created for the transaction.

• The calculation base amount to be used by further conditions stored by the promotion

sequence

Working with the result of a single calculation

The result for each condition applied by the PCE is calculated separately from one another. For each

individual calculation, a PartialResult is created which then holds the calculation result. After all

condition results were calculated for the given promotion sequence and resolution, the

SummaryResult is updated with the PartialResults.

The PartialResult is defined in the generic interface PartialResult (com.gk_software.pricing_engine.api.result

.PartialResult<S extends SummaryResult>).

HOW IT WORKS

The PartialResult is created and initialized for each condition as a first step of the calculation for both

transaction- and position-related promotions. The PartialResult takes over the LineItemSummaryResult

bucket from the SummaryResult as the base normalized item bucket to perform the calculation and

filters it if necessary. In case of position-related conditions, it is possible that the calculation base is

required to be different from the latest overall result, such as the original price for each item, or the

result after applying a given promotion sequence. In that case, the LineItemSummaryResultBucket is

retrieved from the SummaryResult's sequence line item summaries map.

Throughout the processing of the given condition, the calculation result and any additional

information regarding it is stored in the PartialResult. Finally, the SummaryResult is updated with the

calculated valid PartialResults. In case there are multiple conditions with the same sequence and

Page 75: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

75

resolution and the calculation results in multiple valid PartialResults, the best price calculation is

performed before updating the SummaryResult, ensuring that the highest benefit is applied.

The PartialResult interface provides the following information:

• The SummaryResult used as base for the calculation

• The ConditionWrapper of the condition to be applied

• The promotion condition rule

• The ChooseItemMethod to be used in the calculation

• The LineItemSummaryResult bucket to perform the calculation on

• Calculation related flags:

o isResultValid indicating whether the PartialResult is valid and can be applied

o isBonusPointsCondition indicating if the condition is bonus points related or not

o isCashMonetaryDiscountFlag indicating if the calculation result is cache monetary discount or

not

• Counters for applying the condition

o Number of eligibilities applied

o Number of completed intervals

o Number of coupons available

• Lists of eligibilities related to the condition

o Map of all threshold eligibilities related to the condition stored by eligibility type and

separated into simple and interval eligibilities

o Coupon eligibilities

o Market basket amount eligibilities

• Rounding methods, rounding denomination, and rounding scale for the following

calculations: rebate calculation, rebate share calculation, points amount calculation, awarded

points calculation

• Error reason in case of invalid partial result

Understand single item result

While the SummaryResult represents the overall calculation result and the PartialResult holds the

calculated result for a single condition, the LineItemSummaryResult stores the calculation result for a

single NormalizedItem. Just like NormalizedItems, the LineItemSummaryResults are stored in bucket

throughout the calculation.

Page 76: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

76

The LineItemSummaryResult is defined in the interface LineItemSummaryResult

(com.gk_software.pricing_engine.api.result .LineItemSummaryResult).

HOW IT WORKS

The LineItemSummaryResult is created on initialization of the SummaryResult. A LineItemSummaryResult is

instantiated for every NormalizedItem stored in the TransactionAnalyzerContext's position promotion-

relevant items bucket in case of position-related calculation, while in case of transaction-related

calculation the transaction promotion relevant items bucket is used.

The LineItemSummaryResult stores the following information regarding the normalized item it

represents:

• The NormalizedItem itself

• The RetailTransactionLineItem key for the item

• Flag indication if the position is valid for receiving bonus points or not

• Flags indicating

o if the position is a valid trigger position

o if discounts can be applied on it or not

o if the line item has been already used for calculation in best price calculation

• The trigger amount and trigger quantity that are available for applying further promotions

The LineItemSummaryResult furthermore stores the following information on the applied condition and

trigger amounts and quantities available for it.

Name Type Description

New price BigDecimal The new price defined in the promotion mater data if there is one

Deprecated

Deprecated since 3.7.0 not reliable to store new price

on the line item summary result, since the subsequent

new price may differ from the regular. Should not be

used, as it will not contain the expected value.

Used count int Number of times the item was used in the calculation

Applied count int The number of conditions applied on the item

Required count int Number of times the item is required to be used in the calculation. Relevant in case of Mix and Match promotion rules.

Page 77: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

77

Name Type Description

External promotion count

int The number of external promotions applied on this item.

Deprecated

Deprecated since 3.5.1 never used by the PCE for the

calculation.

Awarded points sum

BigDecimal The total value of awarded points for this item

Trigger quantity TriggerValues The quantities of this item available for the calculation. In the TriggerValues class, this value is maintained for rebates and points calculation separately, as well as values considering all previously applied discounts and values not affected by those.

Trigger amount TriggerValues The amounts of this item available for the calculation. In the TriggerValues class, this value is maintained for rebates and points calculation separately, as well as values considering all previously applied discounts and values not affected by those.

Lost trigger quantity

TriggerValues The quantities lost for this calculation that may not be used. In the TriggerValues class, this value is maintained for rebates and points calculation separately, as well as values considering all previously applied discounts and values not affected by those.

Lost trigger amount

TriggerValues The amounts lost for this calculation that may not be used. In the TriggerValues class, this value is maintained for rebates and points calculation separately, as well as values considering all previously applied discounts and values not affected by those.

Condition values LineItemSummaryValues Stores calculation results for the single line item calculation for the overall calculation.

Subsequent discount values

LineItemSummaryValues Returns subsequent discount values containing the used/actual trigger amount/quantity values and subsequent discount amount for the line item summary result.

Interval values LineItemSummaryValues Stores calculation results for the single line item calculation for interval calculation.

Sequence values

SequenceValues Calculation values related to the given sequence and resolution

MixAndMatch Result

MixAndMatchResult Stores Mix&Match rule specific calculation results.

• The matching items used for applying the condition on this item.

• The partial calculation results for each matching item used for applying the condition on this item. This information is used to create individual retail price modifiers in the response for each matching item used.

• The partial calculation results for each matching item used for applying the condition on this item in the currently calculated interval.

Page 78: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

78

Name Type Description

Custom result value

<C extends CustomResultValues> C

Custom calculation result values may be added as extension

Calculation Base Amount

BigDecimal The item's calculation base amount for the current calculation

THERE IS MORE

The LineItemSummaryResult also stores all price and points modifiers as well as updated coupons

created or updated as a result of the applied promotions.

6.4.2.6 Rules API

6.4.2.6.1 Getting calculation-specific condition information

The promotion conditions and the related promotion condition rules are loaded from the data

access layer based on the activated root eligibilities and processed by the PCE core plugin

implementation of the ConditionLoader interface (com.gk_software.pricing_engine.api.engine .ConditionLoader).

Besides retrieving the master data, the ConditionLoader is responsible for the preprocessing of the

loaded promotion data for the PCE calculation process, such as validation whether all required

promotion data was available for the given condition, validation of the condition, or saving the

loaded data to the context. All results of the condition loading and processing are stored in the

context and a designated wrapper object, similar to the EligibilityWrapper.

The wrapper class for the condition is defined in the interface PromotionConditionWrapper

(com.gk_software.pricing_engine.api.rules.PromotionConditionWrapper) and it stores the loaded condition and

additional information.

HOW IT WORKS

The ConditionLoader loads the related promotion conditions and rules for each activated root eligibility

found in the context. A PromotionConditionWrapper is instantiated for each and it is initialized with the

promotion data loaded. The PromotionConditionWrappers are stored in the PromotionConditionContext.

The PromotionConditionWrapper stores the following information:

Name Type Description

Promotion condition

PromotionConditionSO The promotion condition.

Sequence Long Calculated sequence value to be used in the calculation. It adds up of the condition's sequence and the related manual triggers sequence added, if there is one.

Condition status

int The status of the condition determined on condition loading.

Page 79: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

79

Name Type Description

Is overridden flag

boolean Indicates whether - in case of a manual rule - the values should be taken from the request transaction or not.

Manual trigger addend

Long The manual trigger sequence added or null if the condition does not relate to a manual eligibility.

Calculation rule processor

CalculationRuleProcessor The processor responsible for executing rule-specific calculations.

Rebate distribution processor

RebateDistributionProcessor The rule-specific processor responsible for rebate distribution between a set of items.

Manual eligibility

ManualPromotionConditionEligibilitySO Gets the manual eligibility for the condition, if there is one.

Eligibility activation type

EligibilityActivationType Determines which items may be used for the calculation of the current promotion condition wrapper.

• Sales - only sold items may be used as trigger or matching items

• Returns - only returned items may be used as trigger or matching items

• SalesMinusReturns - sold minus returned items may be used as trigger or matching items

6.5 Pricing Engine Common

The pricing-engine-common module contains the internal PCE API. This is not part of the public API,

therefore it is not guaranteed to be release-stable and classes and interfaces may change without

notice.

That being said, it is not expected to often change and will be kept stable as much as possible. The

use of this API is possible for extensions, but you should expect some migration effort on new

versions of the PCE.

The module contains the common implementation for some API interfaces and basic test framework

and utility classes.

Important internal API interfaces and classes are:

• Bucket and NormalizedItem core implementations.

• Common implementations for context and configuration related interfaces.

• PricingEngine and PricingEngineRequest for internal embedding.

• PricingEngineObjectFactory for PCE calculation related object creation.

• DataAccessService, the internal data access interface.

• PromotionCalculator, the main entry point to promotion calculation.

• CalculatorService interface for calculating, distributing, and validating promotions.

• ConflictHandler interface for resolving possible conflicts between promotion conditions.

Page 80: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

80

• TransactionUpdateHandler interface for updating transaction with calculated data.

• Classes for business error handling.

• Comparator and utility classes used by the calculation.

• Ad hoc promotion and manufacturer coupon mapper interfaces.

• CalculationBaseService - calculation base amount calculator service.

• ManufacturerCouponService - manufacturer coupon processing service.

• RebateValidatorService - rebate validator service interface.

• CouponConsumptionService - coupon consumption handling service interface.

HOW IT WORKS

There are several internal APIs provided by the common module.

Package: com.gk_software.pricing_engine

Interface Description

PricingEngine Main entry point to promotion calculation.

PricingEngineFactory Factory for creating and initializing PricingEngine instances and PricingEngineRequest and response objects.

PricingEngineObjectFactory This object contains factory methods for calculation-related PricingEngine objects.

PricingEngineRequest Internal Pricing Engine request object.

PricingEngineResponse Internal Pricing engine response object.

ResolutionComparator Resolution comparator for collision handling.

Package: com.gk_software.pricing_engine.common.engine

Interface Description

PromotionCalculator Promotion calculator.

Package: com.gk_software.pri cing_engine.common.data_access

Interface Description

DataAccessService Data access service interface for integration of master data loading.

Package: com.gk_software.pricing_engine.common.calculator_service

Interface Description

CalculatorService<S extends SummaryResult> Service for calculating, distributing, and validating promotions.

TransactionCalculationService Service to perform transaction related calculations.

Page 81: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

81

Package: com.gk_software.pricing_engine.common.eligibility

Interface Description

AdhocEligibilityProcessor Processes eligibilities loaded with ad hoc promotions.

EligibilityService Eligibility related operations service, responsible for providing additional eligibility specific information for promotion calculation of a single partial result.

ThresholdEligibilityProcessor Process to handle all registered ThresholdActivationCheck instances.

Package: com.gk_software.pricing_engine.common.exceptions

Interface Description

BusinessErrorCode Interface to define business errors by specific codes

Package: com.gk_software.pricing_engine.common.result

Interface Description

NormalizedItemModifierCreator<T extends TxModelDto> extends PCEPlugin<PartialResult<? extends SummaryResult>>

Internal plugin interface responsible for creating modifiers (e.g. retail price modifiers or frequent shopper points modifiers) for normalized items after successful promotion calculation, to store the results in the transaction. The created normalized modifiers will later be summarized for each line item: these are intermediate, normalized results.

PartialResultCalculator Partial result calculation related service.

ResultCustomizerService Helper service to handle ResultDtoCustomizer plugins.

SummaryResultHandler<S extends SummaryResult>

Supports updating summary results with single calculation partial results.

Package: com.gk_software.pricing_engine.common.transaction

Interface Description

PromotionRelevantItemFilter Filters items which are not promotion relevant.

TransactionDomainObjectService Service for creating and handling transaction DO entities.

TransactionMapper Map internal calculation results to transaction data objects...

TransactionUpdateHandler Transaction update handler, responsible for creating transaction model objects based on the calculation result and updating the transaction for the response.

Package: com.gk_software.pricing_engine.common.price_modification

Interface Description

PriceModificationEngine Price or points discount value calculation service.

Package: com.gk_software.pricing_engine.common.rules.calculation

Page 82: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

82

Interface Description

MixAndMatchRuleCalculator Responsible for Mix&Match rule related calculation

Package: com.gk_software.pricing_engine.common.adhoc.mapper

Interface Description

AdhocPromotionMapperService Ad hoc promotion mapper service.

ManufacturerCouponAdhocPromotionMapper Maps a given part of the ad hoc promotion from the provided manufacturer coupon.

ManufacturerCouponValidator Validates the manufacturer coupon.

Package: com.gk_software.pricing_engine.common.context

Interface Description

ContextProvider Interface for accessing the Context In preparation of multi-threading & POS Mode.

ContextProviderFactory Context provider factory.

Package: com.gk_software.pricing_engine.common.services

Interface Description

CalculationBaseService Service to encapsulate logic regarding to calculation base.

ConditionCalculationCachingService Performs caching of intermediate line item summary results during condition calculation.

CouponConsumptionService Coupon consumption service, responsible for consuming the available coupons during calculation based on the condition's coupon eligibilities' coupon consumption type.

ManufacturerCouponService Manufacturer coupon service, encapsulated manufacturer coupon processing specific logic.

RebateValidatorService Rebate validation service calling position- and transaction-based rebate validator plugins.

Package: com.gk_software.pricing_engine.common.manufacturercoupon.parser

Interface Description

GS1FieldParser Parses a field of a GS1 formatted coupon barcode and stores the parsed values in the internal {@link ManufacturerCoupon manufacturer coupon} object.

ManufacturerCouponParserService Parses manufacturer coupons into PCE internal model object.

Package: com.gk_software.pricing_engine.common.transaction.normalization

Page 83: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

83

Interface Description

LineItemNormalizer An interface used when defining line item normalization strategies.

Package: com.gk_software.pricing_engine.common.comparator

Interface Description

NormalizedItemComparator Plugin interface for normalized item comparison based on different item choosing criteria

6.6 Pricing Engine Core Implementation

6.6.1 Overview

The pricing-engine-impl module contains the bulk of the implemented logic of the PCE core. The

module contains all classes below the package com.gk_software.pricing_engine.core and the main Spring

context definitions.

6.6.2 Spring Context

This module contains the majority of the Spring bean definitions of the PCE core.

There is one main XML that provides access to the defined beans: META-INF/com.gk-software.pricing-

engine/psi-sap/common.xml

Internally, the bean definitions are structured in several smaller context definition files under META-

INF/com.gk-software.pricing-engine/core:

/default-beans.xml All standard beans are defined in this context definition file

/beans.xml Helper context definition file to integrate default beans and import default plugins

/comparators/default-plugin-pce.xml All comparison logic related plugins are defined in this context definition file

/conditions/default-plugin-pce.xml All condition loading-related default plugins are defined in this context definition file

/context/default-plugin-pce.xml All context processing related plugins are defined in this context definition file

/eligibilities/default-plugin-pce.xml All eligibility processing-related default plugins are defined in this context definition file

/filters/default-plugin-pce.xml All default item filter plugins are defined in this context definition file

/mappers/default-plugin-pce.xml All default mapper plugins are defined in this context definition file

/parsers/default-plugin-pce.xml All default parser plugins are defined in this context definition file

/price_modifications/default-plugin-pce.xml All price modification related default plugins are defined in this context definition file

Page 84: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

84

/promotions/default-plugin-pce.xml All default promotion handling related plugins are defined in this context definition file

/result/default-plugin-pce.xml All default calculation result handling related plugins are defined in this context definition file

/rules/default-plugin-pce.xml All rule processing related default plugins are defined in this context definition file

/transaction/default-plugin-pce.xml All default transaction modifier plugins are defined in this context definition file

/transaction_analyzers/default-plugin-pce.xml

All default request transaction analyzer plugins are defined in this context definition file

/validators/default-plugin-pce.xml All validation related default plugins are defined in this context definition file

6.6.2.1 Default beans

Inside the bean context, the standard beans providing the processing framework of the PCE core are

defined.

Bean Name Alias Bean Class Description

defaultPriceModificationLookup

priceModificationLookup

com.gk_software.pricing_engine.core.price_modification.PriceModificationLookupImpl

Handler for lookup of the priceModification related to a PromotionConditionRuleSO checking for PriceModificationMethod or getting the PriceModification for a given ReductionMethodMixAndMatch.

defaultPriceModificationEngine

priceModificationEngine

com.gk_software.pricing_engine.core.price_modification.PriceModificationEngineImpl

Manages calculation logic regarding specific price modification during rule processing.

defaultPricingEngineObjectFactory

pricingEngineObjectFactory

com.gk_software.pricing_engine.common.impl.PricingEngineDefaultObjectFactory

Default implementation of the PricingEngineAPIFactory and PricingEngineObjectFactory interfaces.

Page 85: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

85

Bean Name Alias Bean Class Description

defaultRebateValidatorService

rebateValidatorService

com.gk_software.pricing_engine.common.impl.services.RebateValidatorServiceImpl

Default rebate validator service which can execute all position- and transaction-related rebate validators, when requested.

defaultResultCustomizerService

resultCustomizerService

com.gk_software.pricing_engine.common.impl.result.ResultCustomizerServiceImp

Helper service to handle ResultDtoCustomizer plugins.

defaultPromotionSOFactory

promotionSOFactory com.gk_software.pricing_engine.model_default.PromotionSODefaultFactory

The default model factory for promotion master data DOs (data objects).

defaultTransactionFactory transactionFactory com.gk_software.pricing_engine.model_default.TransactionDefaultFactory

The default model factory for promotion transaction DOs (data objects).

defaultPricingEngineFactory

pricingEngineFactory com.gk_software.pricing_engine.core.engine.PricingEngineDefaultFactory

Factory for creation of PricingEngine and PricingEngineRequest instances.

defaultContextProviderFactory

contextProviderFactory

com.gk_software.pricing_engine.core.engine.SimpleContextProviderFactory

The ContextProvider manages the context in a PricingEngine instance. This factory is called during initialization of a PricingEngine instance to get the corresponding ContextProvider.

defaultConfigurationInitializer

configurationInitializer com.gk_software.pricing_engine.core.configuration.ConfigurationInitializer

Parser for converting a configuration property map to the internal Configuration instance.

Page 86: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

86

Bean Name Alias Bean Class Description

defaultTransactionUpdateHandler

transactionUpdateHandler

com.gk_software.pricing_engine.core.transaction.TransactionUpdateHandlerImpl

Central entry point for manipulating the transaction DO. Handles update of transaction with calculated data and cleaning data from request.

defaultTransactionMapper

transactionMapper com.gk_software.pricing_engine.core.transaction.TransactionMapperImpl

Responsible for mapping internal data objects to the transaction DO objects.

defaultTransactionSplitter transactionSplitter com.gk_software.pricing_engine.common.utils.TransactionSplitter

Utility component for Pricing Engine Calculation Mode to split a request in many request with one line item each.

defaultAdhocEligibilityProcessor

adhocEligibilityProcessor

com.gk_software.pricing_engine.core.eligibility.AdhocEligibilityProcessorImpl

Processes eligibilities loaded with ad hoc promotions.

defaultConditionLoader conditionLoader com.gk_software.pricing_engine.core.engine.ConditionLoaderImpl

Loading and validation of Conditions and Promotions.

defaultAdhocPromotionHandler

adhocPromotionHandler

com.gk_software.pricing_engine.core.engine.AdhocPromotionHandlerImpl

Loads and processes ad hoc promotions and stores the result in the context.

defaultResolutionComparator

resolutionComparator com.gk_software.pricing_engine.common.impl.comparator.ResolutionComparatorImpl

Resolution comparator.

defaultPromotionCalculator

promotionCalculator com.gk_software.pricing_engine.core.engine.PromotionCalculatorImpl

Central entry point to promotion calculation of loaded Conditions.

defaultTransactionCalculator

transactionCalculator com.gk_software.pricing_engine.common.impl.result.calculator.TransactionCalculator

Utility for different calculation steps during condition processing.

defaultMixAndMatchRuleCalculator

mixAndMatchRuleCalculator

com.gk_software.pricing_engine.core.rules.calculation.MixAndMatchRuleCalculatorImpl

Responsible for Mix&Match rule related calculation.

Page 87: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

87

Bean Name Alias Bean Class Description

defaultCalculatedAmountComparator

calculatedAmountComparator

com.gk_software.pricing_engine.common.impl.comparator.CalculatedAmountComparator

Compares calculated amounts for given PartialResult.

defaultBestPriceGreedyCalculatedAmountComparator

bestPriceGreedyCalculatedAmountComparator

com.gk_software.pricing_engine.common.impl.comparator.BestPriceGreedyCalculatedAmountComparator

Compares calculated discount amounts and benefits for a given pair of PartialResult objects to be used during greedy best price calculation

defaultDefaultEligibilityMatchingItemBucketSorter

defaultEligibilityMatchingItemBucketSorter

com.gk_software.pricing_engine.core.eligibility.DefaultEligibilityMatchingItemBucketSorter

Sorts the working item bucket of eligibilities and matching items in order to provide for triggering of maximum of them by the current transaction.

defaultPartialResultCalculator

partialResultCalculator com.gk_software.pricing_engine.core.engine.PartialResultCalculatorImpl

Calculates the result of a single condition.

defaultConditionCalculationCachingService

conditionCalculationCachingService

com.gk_software.pricing_engine.common.impl.services.ConditionCalculationCachingServiceImpl

Caching service implementation for line item summary results processed during condition calculation.

defaultCalculationBaseService

calculationBaseService

com.gk_software.pricing_engine.common.impl.services.CalculationBaseServiceImpl

Service to encapsulate logic regarding to calculation base.

defaultCouponConsumptionService

couponConsumptionService

com.gk_software.pricing_engine.common.impl.services.CouponConsumptionServiceImpl

Service to encapsulate the coupon consumption handling.

defaultManufacturerCouponService

manufacturerCouponService

com.gk_software.pricing_engine.common.impl.services.ManufacturerCouponServiceImpl

Service to encapsulate logic regarding to manufacturer coupon.

Page 88: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

88

Bean Name Alias Bean Class Description

defaultPositionSummaryResultHandler

positionSummaryResultHandler

com.gk_software.pricing_engine.core.result.PositionSummaryResultHandler

Applies a single position-related partial result to the overall position summary result.

defaultTransactionSummaryResultHandler

transactionSummaryResultHandler

com.gk_software.pricing_engine.core.result.TransactionSummaryResultHandler

Applies a single transaction-related partial result to the overall transaction summary result.

defaultCalculatorPositionPartialService

calculatorPositionPartialService

com.gk_software.pricing_engine.core.calculator_service.CalculatorPositionPartialService

Calculates the result of a single position-related condition. Used by PartialResultCalculator.

defaultCalculatorTransactionPartialService

calculatorTransactionPartialService

com.gk_software.pricing_engine.core.calculator_service.CalculatorTransactionPartialService

Calculates the result of a single transaction-related condition. Used by PartialResultCalculator.

transactionCalculationServiceLE

transactionCalculationService

com.gk_software.pricing_engine.core.calculator_service.TransactionCalculationServiceImpl

Service to perform additional transaction related calculations like subtotal calculation.

defaultEligibilityService eligibilityService com.gk_software.pricing_engine.core.eligibility.EligibilityServiceImpl

Eligibility related operations service implementation.

defaultEligibilityActivator eligibilityActivator com.gk_software.pricing_engine.core.eligibility.EligibilityActivatorImpl

The EligibilityActivator handles the activation of a valid eligibility. It checks the parent eligibilities and tries to activate them accordingly. It sets the EligibiltiyWrapper status to ACTIVE and updates the context There is one EligibilityActivator in the application context.

Page 89: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

89

Bean Name Alias Bean Class Description

defaultEligibilityRegistry eligibilityRegistry com.gk_software.pricing_engine.core.eligibility.EligibilityRegistryImpl

The eligibility registry is responsible to validate and register the eligibilities to the context. It will not do additional activation checks.

defaultThresholdTypeEligibilityProcessor

thresholdTypeEligibilityProcessor

com.gk_software.pricing_engine.core.eligibility.ThresholdEligibilityProcessorImpl

Process to handle all registered ThresholdActivationCheck instances. It receives the right instance for a given ThresholdType and checks ThresholdPromotionConditionEligibility for activation.

defaultGS1CouponParserService

gs1CouponParserService

com.gk_software.pricing_engine.core.manufacturercoupon.parser.GS1CouponParserServiceImpl

Parses manufacturer coupons into PCE internal model object.

defaultAdhocPromotionMapperService

adhocPromotionMapperService

com.gk_software.pricing_engine.core.adhoc.mapper.AdhocPromotionMapperServiceImpl

Ad hoc promotion mapper service.

6.6.2.2 Plugin Lists

Besides standard Spring beans, the Spring context defines the lists of collected plugins. These are

provided via Spring context as beans of Java List type. The content of the list is automatically

collected from all beans in the application context that implement the corresponding plugin

interface.

Bean Name Alias Plugin Interface

allPCEPlugins - com.gk_software.pricing_engine.api.PCEPlugin

pluginContextProviders - com.gk_software.pricing_engine.api.context.plugin.PluginContextProvider

defaultEligibilityLoaderList eligibilityLoaderList com.gk_software.pricing_engine.api.eligibility.EligibilityLoader

defaultEligibilityLoaderFragments

eligibilityLoaderFragments com.gk_software.pricing_engine.api.eligibility.EligibilityLoaderFragment

defaultEligibilityRuleHandlerFragments

eligibilityRuleHandlerFragments

com.gk_software.pricing_engine.api.rules.EligibilityRuleHandlerFragment

Page 90: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

90

Bean Name Alias Plugin Interface

defaultEligibilityValidators eligibilityValidators com.gk_software.pricing_engine.api.eligibility.EligibilityValidator

defaultThresholdTypeActivators thresholdTypeActivators com.gk_software.pricing_engine.api.eligibility.ThresholdActivationCheck

defaultEligibilityParsers eligibilityParsers com.gk_software.pricing_engine.api.eligibility.EligibilityResultParser

defaultRebatableItemFilterPlugins

rebatableItemFilterPlugins com.gk_software.pricing_engine.api.filter.plugin.RebatableItemFilterPlugin

defaultPriceModifications priceModifications com.gk_software.pricing_engine.api.price_modification.PriceModification

defaultRuleLoaderList ruleLoaderList com.gk_software.pricing_engine.api.rules.RuleLoader

defaultEligibilityMatchingItemBucketSorterList

eligibilityMatchingItemBucketSorters

com.gk_software.pricing_engine.api.eligibility.EligibilityMatchingItemBucketSorter

defaultEligibilityRuleHandlerList eligibilityRuleHandlers com.gk_software.pricing_engine.api.rules.EligibilityRuleHandler

defaultTransactionAnalyzerList transactionAnalyzerList com.gk_software.pricing_engine.api.analyzer.TransactionAnalyzer

defaultContextPostProcessorList contextPostProcessorList com.gk_software.pricing_engine.api.context.ContextPostProcessor

defaultRebateDistributionProcessors

rebateDistributionProcessors com.gk_software.pricing_engine.api.rules.RebateDistributionProcessor

defaultConditionValidatorList conditionValidatorList com.gk_software.pricing_engine.api.calculation.ConditionValidator

defaultMixAndMatchProrationCustomizers

mixAndMatchProrationCustomizers

com.gk_software.pricing_engine.api.rules.MixAndMatchProrationCustomizer

defaultResultValidatorList resultValidatorList com.gk_software.pricing_engine.api.result.ResultValidator

defaultIntervalResultValidatorList intervalResultValidatorList com.gk_software.pricing_engine.api.result.IntervalResultValidator

defaultCalculationRuleProcessors

calculationRuleProcessors com.gk_software.pricing_engine.api.rules.CalculationRuleProcessor

defaultExclusiveCheckHandler exclusiveCheckHandler com.gk_software.pricing_engine.api.calculation.ExclusiveCheckHandler

defaultRebateValidatorList rebateValidatorList com.gk_software.pricing_engine.api.result.RebateValidator

Page 91: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

91

Bean Name Alias Plugin Interface

defaultLineItemRebateValidatorList

lineItemRebateValidatorList com.gk_software.pricing_engine.api.result.LineItemRebateValidator

defaultConditionRebateValidatorList

conditionRebateValidatorList com.gk_software.pricing_engine.api.result.ConditionRebateValidator

defaultCalculationLimiters calculationLimiters com.gk_software.pricing_engine.api.calculation.CalculationLimiter

defaultBestPriceCalculators bestPriceCalculators com.gk_software.pricing_engine.api.calculation.BestPriceCalculator

defaultPromotionRelevantItemFilters

promotionRelevantItemFilters

com.gk_software.pricing_engine.common.transaction.PromotionRelevantItemFilter

defaultConflictHandlerPreprocessors

conflictHandlerPreprocessors

com.gk_software.pricing_engine.api.calculation.ConflictHandlerPreprocessor

defaultConflictHandlers conflictHandlers com.gk_software.pricing_engine.api.calculation.ConflictHandler

defaultRetailPriceModifierCustomizer

retailPriceModifierCustomizer

com.gk_software.pricing_engine.api.result.customizer.RetailPriceModifierCustomizer

defaultFrequentShopperPointsModifierCustomizer

frequentShopperPointsModifierCustomizer

com.gk_software.pricing_engine.api.result.customizer.FrequentShopperPointsModifierCustomizer

defaultLoyaltyRewardLineItemCustomizer

loyaltyRewardLineItemCustomizer

com.gk_software.pricing_engine.api.result.customizer.LoyaltyRewardLineItemCustomizer

defaultPriceModificationLineItemCustomizer

priceModificationLineItemCustomizer

com.gk_software.pricing_engine.api.result.customizer.PriceModificationLineItemCustomizer

defaultRetailTransactionPromotionPriceDerivationRuleCustomizer

retailTransactionPromotionPriceDerivationRuleCustomizer

com.gk_software.pricing_engine.api.result.customizer.RetailTransactionPromotionPriceDerivationRuleCustomizer

defaultAdhocPromotionLoaders adhocPromotionLoaders com.gk_software.pricing_engine.api.engine.AdhocPromotionLoader

defaultConditionLoaderFragments

conditionLoaderFragments com.gk_software.pricing_engine.api.engine.ConditionLoaderFragment

defaultMixAndMatchCombinationTypeProcessor

mixAndMatchCombinationTypeProcessors

com.gk_software.pricing_engine.api.rules.MixAndMatchCombinationTypeProcessor

defaultManufacturerCouponValidators

manufacturerCouponValidators

com.gk_software.pricing_engine.common.adhoc.mapper.ManufacturerCouponValidator

defaultGS1FieldParsers gs1FieldParsers com.gk_software.pricing_engine.common.manufacturercoupon.parser.GS1FieldParser

defaultManufacturerCouponAdhocPromotionMappers

manufacturerCouponAdhocPromotionMappers

com.gk_software.pricing_engine.common.adhoc.mapper.ManufacturerCouponAdhocPromotionMapper

Page 92: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

92

Bean Name Alias Plugin Interface

defaultUomCodeMappers uomCodeMappers com.gk_software.pricing_engine.api.mapper.UomCodeMapper

defaultTransactionUpdaters transactionUpdaters com.gk_software.pricing_engine.api.transaction.TransactionUpdater

defaultTransactionCleaners transactionCleaners com.gk_software.pricing_engine.api.transaction.TransactionCleaner

defaultLineItemCleaners lineItemCleaners com.gk_software.pricing_engine.api.transaction.LineItemCleaner

defaultConditionRegistryList conditionRegistryList com.gk_software.pricing_engine.api.engine.ConditionRegistry

defaultCombinationEligibilityActivators

combinationEligibilityActivators

com.gk_software.pricing_engine.api.eligibility.CombinationEligibilityActivator

defaultEligibilityRuleValidators eligibilityRuleValidators com.gk_software.pricing_engine.api.rules.EligibilityRuleValidator

defaultEligibilityItemLoaders eligibilityItemLoaders com.gk_software.pricing_engine.api.eligibility.EligibilityItemLoader

defaultNormalizedItemComparators

normalizedItemComparators com.gk_software.pricing_engine.common.comparator.NormalizedItemComparator

defaultDiscountableValidatorServiceList

discountableValidatorServiceList

com.gk_software.pricing_engine.api.discount_item.validator.DiscountableItemValidator

defaultNormalizedItemModifierCreators

normalizedItemModifierCreators

com.gk_software.pricing_engine.common.result.NormalizedItemModifierCreator

defaultTransactionMatchingItemLoaders

transactionMatchingItemLoaders

com.gk_software.pricing_engine.api.rules.TransactionMatchingItemLoader

6.6.2.3 Core Plugins

The following core plugin implementations are registered to the application context and available

through the plugins listed above.

Bean Name Alias Plugin List Alias Bean Class

defaultConditionLoaderFragment

conditionLoaderFragment

conditionLoaderFragments

com.gk_software.pricing_engine.core.engine.DefaultConditionLoaderFragment

defaultAdhocConditionLoaderFragment

adhocConditionLoaderFragment

com.gk_software.pricing_engine.core.engine.AdhocConditionLoaderFragment

defaultBruteForceConflictHandler

bruteForceConflictHandler

conflictHandlers com.gk_software.pricing_engine.core.calculation.best_price.BruteForceConflictHandler

Page 93: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

93

Bean Name Alias Plugin List Alias Bean Class

defaultGreedyConflictHandler

defaultConflictHandler com.gk_software.pricing_engine.core.calculation.best_price.GreedyConflictHandler

defaultContextItemInitializer

contextItemInitializer contextPostProcessorList

com.gk_software.pricing_engine.core.engine.ContextItemInitializer

defaultEligibilityLoader defaultEligibilityLoader eligibilityLoaderList com.gk_software.pricing_engine.core.eligibility.DefaultEligibilityLoader

defaultManualTriggerEligibilityLoader

manualTriggerEligibilityLoader

com.gk_software.pricing_engine.core.eligibility.ManualTriggerEligibilityLoader

defaultCouponEligibilityLoader

couponEligibilityLoader eligibilityLoaderFragments

com.gk_software.pricing_engine.core.eligibility.fragments.CouponEligibilityLoader

defaultItemEligibilityLoader

itemEligibilityLoader com.gk_software.pricing_engine.core.eligibility.fragments.ItemEligibilityLoader

defaultMerchandiseGroupEligibilityLoader

merchandiseGroupEligibilityLoader

com.gk_software.pricing_engine.core.eligibility.fragments.MerchandiseGroupEligibilityLoader

defaultMerchandiseSetEligibilityLoader

merchandiseSetEligibilityLoader

com.gk_software.pricing_engine.core.eligibility.fragments.MerchandiseSetEligibilityLoader

defaultMarketBasketAmountEligibilityLoader

marketBasketAmountEligibilityLoader

com.gk_software.pricing_engine.core.eligibility.fragments.MarketBasketAmountEligibilityLoader

defaultCustomerGroupEligibilityLoader

customerGroupEligibilityLoader

com.gk_software.pricing_engine.core.eligibility.fragments.CustomerGroupEligibilityLoader

defaultAdhocEligibilityLoaderFragment

adhocEligibilityLoaderFragment

com.gk_software.pricing_engine.core.eligibility.fragments.AdhocEligibilityLoader

defaultManufacturerCouponEligibilityLoaderFragment

manufacturerCouponEligibilityLoaderFragment

com.gk_software.pricing_engine.core.eligibility.fragments.ManufacturerCouponEligibilityLoader

defaultAdditionalPriceTypeEligibilityLoaderFragment

additionalPriceTypeEligibilityLoaderFragment

com.gk_software.pricing_engine.core.eligibility.fragments.AdditionalPriceTypeEligibilityLoader

defaultItemEligibilityItemLoader

itemEligibilityItemLoader

eligibilityItemLoaders

com.gk_software.pricing_engine.core.eligibility.fragments.ItemEligibilityItemLoader

defaultMerchandiseGroupEligibilityItemLoader

merchandiseGroupEligibilityItemLoader

com.gk_software.pricing_engine.core.eligibility.fragments.MerchandiseGroupEligibilityItemLoader

defaultMerchandiseSetEligibilityItemLoader

merchandiseSetEligibilityItemLoader

com.gk_software.pricing_engine.core.eligibility.fragments.MerchandiseSetEligibilityItemLoader

defaultThresholdActivatorAMQU

thresholdActivatorAMQU

thresholdTypeActivators

com.gk_software.pricing_engine.core.eligibility.threshold.ThresholdActivatonCheckAMQU

defaultThresholdActivatorAMT

thresholdActivatorAMT com.gk_software.pricing_engine.core.eligibility.threshold.ThresholdActivatonCheckAMT

Page 94: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

94

Bean Name Alias Plugin List Alias Bean Class

defaultThresholdActivatorQUT

thresholdActivatorQUT com.gk_software.pricing_engine.core.eligibility.threshold.ThresholdActivationCheckQUT

defaultThresholdActivatorCOMB

thresholdActivatorCOMB

com.gk_software.pricing_engine.core.eligibility.threshold.ThresholdActivationCheckCOMB

defaultCouponEligibilityParser

couponEligibilityParser eligibilityParsers com.gk_software.pricing_engine.core.eligibility.parser.CouponEligibilityParser

defaultTotalEligibilityParser

totalEligibilityParser com.gk_software.pricing_engine.core.eligibility.parser.TotalEligibilityParser

defaultItemEligibilityParser itemEligibilityParser com.gk_software.pricing_engine.core.eligibility.parser.ItemEligibilityParser

defaultMhgEligibilityParser mhgEligibilityParser com.gk_software.pricing_engine.core.eligibility.parser.MhgEligibilityParser

defaultCombinationEligibilityParser

combinationEligibilityParser

com.gk_software.pricing_engine.core.eligibility.parser.CombinationEligibilityParser

defaultMerchandiseSetEligibilityParser

merchandiseSetEligibilityParser

com.gk_software.pricing_engine.core.eligibility.parser.MerchandiseSetEligibilityParser

defaultManufacturerCouponEligibilityParser

manufacturerCouponEligibilityParser

com.gk_software.pricing_engine.core.eligibility.parser.ManufacturerCouponEligibilityParser

defaultItemEligibilityRuleHandlerFragment

itemEligibilityRuleHandlerFragment

eligibilityRuleHandlerFragments

com.gk_software.pricing_engine.core.rules.handler.fragments.ItemEligibilityRuleHandlerFragment

defaultMerchandiseSetEligibilityRuleHandlerFragment

merchandiseSetEligibilityRuleHandlerFragment

com.gk_software.pricing_engine.core.rules.handler.fragments.MerchandiseSetEligibilityRuleHandlerFragment

defaultMhgEligibilityRuleHandlerFragment

mhgEligibilityRuleHandlerFragment

com.gk_software.pricing_engine.core.rules.handler.fragments.MhgEligibilityRuleHandlerFragment

defaultCombinationEligibilityRuleHandlerFragment

combinationEligibilityRuleHandlerFragment

com.gk_software.pricing_engine.core.rules.handler.fragments.CombinationEligibilityRuleHandlerFragment

defaultManufacturerCouponEligibilityRuleHandlerFragment

manufacturerCouponEligibilityRuleHandlerFragment

com.gk_software.pricing_engine.core.rules.handler.fragments.ManufacturerCouponEligibilityRuleHandlerFragment

defaultCombinationOrEligibilityActivator

combinationOrEligibilityActivator

combinationEligibilityActivators

com.gk_software.pricing_engine.core.eligibility.activator.CombinationOrEligibilityActivator

defaultCombinationAndEligibilityActivator

combinationAndEligibilityActivator

com.gk_software.pricing_engine.core.eligibility.activator.CombinationAndEligibilityActivator

Page 95: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

95

Bean Name Alias Plugin List Alias Bean Class

defaultSaleReturnTypeItemFilter

defaultSaleReturnTypeItemFilter

rebatableItemFilterPlugins

com.gk_software.pricing_engine.common.impl.bucket.filter.SaleReturnTypeItemFilter

defaultCustomerSpecificPricedItemFilter

customerSpecificPricedItemFilter

com.gk_software.pricing_engine.common.impl.bucket.filter.CustomerSpecificPricedItemFilter

defaultPackageMeasuredEligibleItemFilter

packageMeasuredEligibleItemFilter

com.gk_software.pricing_engine.common.impl.bucket.filter.PackageMeasuredEligibleItemFilter

defaultUomCodeMapper uomCodeMapper uomCodeMappers com.gk_software.pricing_engine.common.impl.mapper.UomCodeMapperImpl

defaultManufacturerCouponPromotionSOMapper

manufacturerCouponPromotionSOMapper

manufacturerCouponAdhocPromotionMappers

com.gk_software.pricing_engine.core.adhoc.mapper.ManufacturerCouponPromotionSOMapper

defaultManufacturerCouponConditionMapper

manufacturerCouponConditionMapper

com.gk_software.pricing_engine.core.adhoc.mapper.ManufacturerCouponConditionMapper

defaultManufacturerCouponEligibilityMapper

manufacturerCouponEligibilityMapper

com.gk_software.pricing_engine.core.adhoc.mapper.ManufacturerCouponEligibilityMapper

defaultManufacturerCouponSimpleRebateRuleMapper

manufacturerCouponSimpleRebateRuleMapper

com.gk_software.pricing_engine.core.adhoc.mapper.ManufacturerCouponSimpleRebateRuleMapper

defaultManufacturerCouponMixAndMatchRuleMapper

manufacturerCouponMixAndMatchRuleMapper

com.gk_software.pricing_engine.core.adhoc.mapper.ManufacturerCouponMixAndMatchRuleMapper

defaultManufacturerCouponMatchingItemMapper

manufacturerCouponMatchingItemMapper

com.gk_software.pricing_engine.core.adhoc.mapper.ManufacturerCouponMatchingItemMapper

defaultNormalizedItemTriggerAmountComparator

normalizedItemTriggerAmountComparator

normalizedItemComparators

com.gk_software.pricing_engine.common.impl.comparator.NormalizedItemTriggerAmountComparator

defaultLineItemUnitsComparator

lineItemUnitsComparator

com.gk_software.pricing_engine.common.impl.comparator.LineItemUnitsComparator

defaultItemIdComparator itemIdComparator com.gk_software.pricing_engine.common.impl.comparator.ItemIdComparator

defaultLineItemSequenceComparator

lineItemSequenceComparator

com.gk_software.pricing_engine.common.impl.comparator.LineItemSequenceComparator

defaultPrimaryCompanyCodeParser

primaryCompanyCodeParser

gs1FieldParsers com.gk_software.pricing_engine.core.manufacturercoupon.parser.PrimaryCompanyCodeParser

defaultOfferCodeParser offerCodeParser com.gk_software.pricing_engine.core.manufacturercoupon.parser.OfferCodeParser

defaultSaveValueParser saveValueParser com.gk_software.pricing_engine.core.manufacturercoupon.parser.SaveValueParser

Page 96: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

96

Bean Name Alias Plugin List Alias Bean Class

defaultPrimaryQualifyingPurchaseParser

primaryQualifyingPurchaseParser

com.gk_software.pricing_engine.core.manufacturercoupon.parser.PrimaryQualifyingPurchaseParser

defaultDataField1Parser dataField1Parser com.gk_software.pricing_engine.core.manufacturercoupon.parser.DataField1Parser

defaultDataField2Parser dataField2Parser com.gk_software.pricing_engine.core.manufacturercoupon.parser.DataField2Parser

defaultDataField3Parser dataField3Parser com.gk_software.pricing_engine.core.manufacturercoupon.parser.DataField3Parser

defaultDataField4Parser dataField4Parser com.gk_software.pricing_engine.core.manufacturercoupon.parser.DataField4Parser

defaultDataField5Parser dataField5Parser com.gk_software.pricing_engine.core.manufacturercoupon.parser.DataField5Parser

defaultDataField6Parser dataField6Parser com.gk_software.pricing_engine.core.manufacturercoupon.parser.DataField6Parser

defaultDataField9Parser dataField9Parser com.gk_software.pricing_engine.core.manufacturercoupon.parser.DataField9Parser

absoluteDiscountPriceModification

- priceModifications com.gk_software.pricing_engine.core.price_modification.AbsoluteDiscountPriceModification

newPricePriceModification - com.gk_software.pricing_engine.core.price_modification.NewPricePriceModification

newTotalPricePriceModification

- com.gk_software.pricing_engine.core.price_modification.NewTotalPricePriceModification

newSetPricePriceModification

- com.gk_software.pricing_engine.core.price_modification.NewSetPricePriceModification

totalAbsoluteDiscountPriceModification

- com.gk_software.pricing_engine.core.price_modification.TotalAbsoluteDiscountPriceModification

totalPercentageDiscountPriceModification

- com.gk_software.pricing_engine.core.price_modification.TotalPercentageDiscountPriceModification

totalPercentageDiscountRoundedTwicePriceModification

- com.gk_software.pricing_engine.core.price_modification.TotalPercentageDiscountRoundedTwicePriceModification

percentageDiscountPriceModification

- com.gk_software.pricing_engine.core.price_modification.PercentageDiscountPriceModification

defaultManufacturerCouponAdhocPromotionLoader

manufacturerCouponAdhocPromotionLoader

adhocPromotionLoaders

com.gk_software.pricing_engine.core.adhoc.mapper.ManufacturerCouponAdhocPromotionLoader

Page 97: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

97

Bean Name Alias Plugin List Alias Bean Class

defaultEligibilityRuleHandler

defaultEligibilityRuleHandler

eligibilityRuleHandlers

com.gk_software.pricing_engine.core.rules.handler.DefaultEligibilityRuleHandler

defaultStandardRuleLoader

standardRuleLoader ruleLoaderList com.gk_software.pricing_engine.core.rules.loader.StandardPriceRuleLoader

defaultExternalActionRuleLoader

externalActionRuleLoader

com.gk_software.pricing_engine.core.rules.loader.ExternalActionRuleLoader

defaultMixAndMatchRuleLoader

mixAndMatchRuleLoader

com.gk_software.pricing_engine.core.rules.loader.MixAndMatchRuleLoader

defaultRebateRuleLoader rebateRuleLoader com.gk_software.pricing_engine.core.rules.loader.RebateRuleLoader

defaultAdditionalPriceTypeRuleLoader

additionalPriceTypeRuleLoader

com.gk_software.pricing_engine.core.rules.loader.AdditionalPriceTypeRuleLoader

defaultExternalActionCalculationRule

externalActionCalculationRule

calculationRuleProcessors

com.gk_software.pricing_engine.core.rules.ExternalActionCalculationRule

defaultManualPriceCalculationRule

manualPriceCalculationRule

com.gk_software.pricing_engine.core.rules.ManualPriceCalculationRule

defaultMixAndMatchCalculationRule

mixAndMatchCalculationRule

com.gk_software.pricing_engine.core.rules.MixAndMatchCalculationRule

defaultNoDiscountCalculationRule

noDiscountCalculationRule

com.gk_software.pricing_engine.core.rules.NoDiscountCalculationRule

defaultSimpleDiscountCalculationRule

simpleDiscountCalculationRule

com.gk_software.pricing_engine.core.rules.SimpleDiscountCalculationRule

defaultAdditionalPriceTypeCalculationRule

additionalPriceTypeCalculationRule

com.gk_software.pricing_engine.core.rules.AdditionalPriceTypeCalculationRule

defaultExternalActionRebateDistributionService

externalActionRebateDistributionService

rebateDistributionProcessors

com.gk_software.pricing_engine.core.rules.proration.ExternalActionRebateDistributionService

defaultManualPriceRebateDistributionService

manualPriceRebateDistributionService

com.gk_software.pricing_engine.core.rules.proration.ManualPriceRebateDistributionService

defaultMixAndMatchRebateDistributionService

mixAndMatchRebateDistributionService

com.gk_software.pricing_engine.core.rules.proration.MixAndMatchRebateDistributionService

defaultNoDiscountRebateDistributionService

noDiscountRebateDistributionService

com.gk_software.pricing_engine.core.rules.proration.NoDiscountRebateDistributionService

defaultSimpleDiscountRebateDistributionService

simpleDiscountRebateDistributionService

com.gk_software.pricing_engine.core.rules.proration.SimpleDiscountRebateDistributionService

defaultAdditionalPriceTypeRebateDistributionService

additionalPriceTypeRebateDistributionService

com.gk_software.pricing_engine.core.rules.proration.AdditionalPriceTypeRebateDistributionService

Page 98: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

98

Bean Name Alias Plugin List Alias Bean Class

defaultBestPriceCalculator bestPriceCalculator bestPriceCalculators

com.gk_software.pricing_engine.core.calculation.DefaultBestPriceCalculator

defaultMixAndMatchCombinationAndProcessor

mixAndMatchCombinationAndProcessor

mixAndMatchCombinationTypeProcessors

com.gk_software.pricing_engine.core.rules.calculation.MixAndMatchCombinationAndProcessor

defaultMixAndMatchCombinationOrProcessor

mixAndMatchCombinationOrProcessor

com.gk_software.pricing_engine.core.rules.calculation.MixAndMatchCombinationOrProcessor

defaultMixAndMatchCombinationOrQuantityProcessor

mixAndMatchCombinationOrQuantityProcessor

com.gk_software.pricing_engine.core.rules.calculation.MixAndMatchCombinationOrQuantityProcessor

defaultMixAndMatchCombinationExclusiveOrProcessor

mixAndMatchCombinationExclusiveOrProcessor

com.gk_software.pricing_engine.core.rules.calculation.MixAndMatchCombinationExclusiveOrProcessor

defaultManufacturerCouponProrationCustomizer

manufacturerCouponProrationCustomizer

mixAndMatchProrationCustomizers

com.gk_software.pricing_engine.core.rules.proration.ManufacturerCouponProrationCustomizer

defaultItemTransactionMatchingItemLoader

itemTransactionMatchingItemLoader

transactionMatchingItemLoaders

com.gk_software.pricing_engine.core.rules.calculation.ItemTransactionMatchingItemLoader

defaultMhgTransactionMatchingItemLoader

mhgTransactionMatchingItemLoader

com.gk_software.pricing_engine.core.rules.calculation.MhgTransactionMatchingItemLoader

defaultMerchandiseSetTransactionMatchingItemLoader

merchandiseSetTransactionMatchingItemLoader

com.gk_software.pricing_engine.core.rules.calculation.MerchandiseSetTransactionMatchingItemLoader

defaultManufacturerCouponTransactionMatchingItemLoader

manufacturerCouponTransactionMatchingItemLoader

com.gk_software.pricing_engine.core.rules.calculation.ManufacturerCouponTransactionMatchingItemLoader

defaultRetailTransactionLineItemCleaner

retailTransactionLineItemCleaner

transactionCleaners

com.gk_software.pricing_engine.core.transaction.cleaner.RetailTransactionLineItemCleaner

defaultPriceModificationAndLoyaltyRewardLineItemCleaner

priceModificationAndLoyaltyRewardLineItemCleaner

com.gk_software.pricing_engine.core.transaction.cleaner.PriceModificationAndLoyaltyRewardLineItemCleaner

defaultPriceDerivationRuleCleaner

priceDerivationRuleCleaner

com.gk_software.pricing_engine.core.transaction.cleaner.PriceDerivationRuleCleaner

defaultRetailTransactionModifierCouponCleaner

retailTransactionModifierCouponCleaner

com.gk_software.pricing_engine.core.transaction.cleaner.RetailTransactionModifierCouponCleaner

defaultRetailTransactionCouponSummaryTransactionCleaner

retailTransactionCouponSummaryTransactionCleaner

com.gk_software.pricing_engine.core.transaction.cleaner.RetailTransactionCouponSummaryTransactionCleaner

defaultRetailPriceModifierCleaner

retailPriceModifierCleaner

lineItemCleaners com.gk_software.pricing_engine.core.transaction.cleaner.RetailPriceModifierCleaner

Page 99: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

99

Bean Name Alias Plugin List Alias Bean Class

defaultFrequentShopperPointsModifierCleaner

frequentShopperPointsModifierCleaner

com.gk_software.pricing_engine.core.transaction.cleaner.FrequentShopperPointsModifierCleaner

defaultSaleReturnLineItemModifierReferenceCleaner

saleReturnLineItemModifierReferenceCleaner

com.gk_software.pricing_engine.core.transaction.cleaner.SaleReturnLineItemModifierReferenceCleaner

defaultSaleReturnLineItemModifierCouponCleaner

saleReturnLineItemModifierCouponCleaner

com.gk_software.pricing_engine.core.transaction.cleaner.SaleReturnLineItemModifierCouponCleaner

defaultPriceDerivationRulesTransactionUpdaterForTransaction

priceDerivationRulesTransactionUpdaterForTransaction

transactionUpdaters

com.gk_software.pricing_engine.core.transaction.updater.PriceDerivationRulesTransactionUpdaterForTransaction

defaultPriceDerivationRulesTransactionUpdaterForPosition

priceDerivationRulesTransactionUpdaterForPosition

com.gk_software.pricing_engine.core.transaction.updater.PriceDerivationRulesTransactionUpdaterForPosition

defaultPriceModificationLineItemsTransactionUpdater

priceModificationLineItemsTransactionUpdater

com.gk_software.pricing_engine.core.transaction.updater.PriceModificationLineItemsTransactionUpdater

defaultLoyaltyRewardLineItemsTransactionUpdater

loyaltyRewardLineItemsTransactionUpdater

com.gk_software.pricing_engine.core.transaction.updater.LoyaltyRewardLineItemsTransactionUpdater

defaultRetailTransactionCouponSummaryTransactionUpdater

retailTransactionCouponSummaryTransactionUpdater

com.gk_software.pricing_engine.core.transaction.updater.RetailTransactionCouponSummaryTransactionUpdater

defaultManufacturerCouponTransactionAnalyzer

manufacturerCouponTransactionAnalyzer

transactionAnalyzerList

com.gk_software.pricing_engine.core.analyzer.ManufacturerCouponTransactionAnalyzer

defaultItemTransactionAnalyzer

itemTransactionAnalyzer

com.gk_software.pricing_engine.core.analyzer.ItemTransactionAnalyzer

defaultExternalPromotionsTransactionAnalyzer

externalPromotionsTransactionAnalyzer

com.gk_software.pricing_engine.core.analyzer.ExternalPromotionsTransactionAnalyzer

defaultCouponTransactionAnalyzer

couponTransactionAnalyzer

com.gk_software.pricing_engine.core.analyzer.CouponTransactionAnalyzer

defaultCustomerGroupTransactionAnalyzer

customerGroupTransactionAnalyzer

com.gk_software.pricing_engine.core.analyzer.CustomerGroupTransactionAnalyzer

defaultPromotionManualTriggerAnalyzer

promotionManualTriggerAnalyzer

com.gk_software.pricing_engine.core.analyzer.PromotionManualTriggerTransactionAnalyzer

defaultVoidedLineItemFilter

voidedLineItemFilter promotionRelevantItemFilters

com.gk_software.pricing_engine.core.transaction.VoidedLineItemFilter

defaultSaleReturnLineItemFilter

saleReturnLineItemFilter

com.gk_software.pricing_engine.core.transaction.SaleReturnLineItemFilter

Page 100: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

100

Bean Name Alias Plugin List Alias Bean Class

defaultLineItemPriceTypeCodeFilter

lineItemPriceTypeCodeFilter

com.gk_software.pricing_engine.core.transaction.LineItemPriceTypeCodeFilter

defaultTransactionResultActualPurchaseBaseValidator

transactionResultActualPurchaseBaseValidator

resultValidatorList com.gk_software.pricing_engine.core.result.validator.TransactionResultActualPurchaseBaseValidator

defaultPositionResultActualPurchaseBaseValidator

positionResultActualPurchaseBaseValidator

com.gk_software.pricing_engine.core.result.validator.PositionResultActualPurchaseBaseValidator

defaultPositionResultInfluencedPositionValidator

positionResultInfluencedPositionValidator

com.gk_software.pricing_engine.core.result.validator.PositionResultInfluencedPositionValidator

defaultTransactionResultInfluencedPositionValidator

transactionResultInfluencedPositionValidator

com.gk_software.pricing_engine.core.result.validator.TransactionResultInfluencedPositionValidator

defaultPositionResultConditionAmountValidator

positionResultConditionAmountValidator

com.gk_software.pricing_engine.core.result.validator.PositionResultConditionAmountValidator

defaultTransactionResultConditionAmountValidator

transactionResultConditionAmountValidator

com.gk_software.pricing_engine.core.result.validator.TransactionResultConditionAmountValidator

defaultCombinationOrIntervalResultValidator

combinationOrIntervalResultValidator

intervalResultValidatorList

com.gk_software.pricing_engine.core.result.validator.CombinationOrIntervalResultValidator

defaultExternalActionRebateValidator

externalActionRebateValidator

lineItemRebateValidatorList

com.gk_software.pricing_engine.core.result.validator.ExternalActionRebateValidator

defaultSimpleLineItemRebateValidator

simpleLineItemRebateValidator

com.gk_software.pricing_engine.core.result.validator.SimpleLineItemRebateValidator

defaultPriceIncreaseRebateValidator

priceIncreaseRebateValidator

com.gk_software.pricing_engine.core.result.validator.PriceIncreaseRebateValidator

defaultSimpleConditionRebateValidator

simpleConditionRebateValidator

conditionRebateValidatorList

com.gk_software.pricing_engine.core.result.validator.SimpleConditionRebateValidator

defaultConditionSequenceAllowedValidator

conditionSequenceAllowedValidator

conditionValidatorList

com.gk_software.pricing_engine.core.calculation.validator.ConditionSequenceAllowedValidator

defaultExclusivePromotionCombinationValidator

exclusivePromotionCombinationValidator

com.gk_software.pricing_engine.common.validator.ExclusivePromotionCombinationValidator

defaultConditionTimeRestrictionValidator

conditionTimeRestrictionValidator

com.gk_software.pricing_engine.core.calculation.validator.ConditionTimeRestrictionValidator

defaultMixAndMatchConditionAllowedValidator

mixAndMatchConditionAllowedValidator

com.gk_software.pricing_engine.core.calculation.validator.MixAndMatchConditionAllowedValidator

Page 101: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

101

Bean Name Alias Plugin List Alias Bean Class

defaultAdditionalPriceTypeConditionAllowedValidator

additionalPriceTypeConditionAllowedValidator

com.gk_software.pricing_engine.core.calculation.validator.AdditionalPriceTypeConditionAllowedValidator

defaultSimpleDiscountRuleConditionValidator

simpleDiscountRuleConditionValidator

com.gk_software.pricing_engine.core.calculation.validator.SimpleDiscountRuleConditionValidator

defaultCalculationSchemeConditionValidator

calculationSchemeConditionValidator

com.gk_software.pricing_engine.core.calculation.validator.CalculationSchemeConditionValidator

defaultPackageLimitQuantityConditionValidator

packageLimitQuantityConditionValidator

com.gk_software.pricing_engine.core.calculation.validator.PackageLimitQuantityConditionValidator

defaultEligibilityExpirationValidator

eligibilityExpirationValidator

eligibilityValidators com.gk_software.pricing_engine.core.eligibility.validator.EligibilityExpirationValidator

defaultEligibilityStatusValidator

eligibilityStatusValidator

com.gk_software.pricing_engine.core.eligibility.validator.EligibilityStatusValidator

defaultMarketBasketAmountEligibilityValidator

marketBasketAmountEligibilityValidator

com.gk_software.pricing_engine.core.eligibility.validator.MarketBasketAmountEligibilityValidator

defaultThresholdEligibilityValidator

thresholdEligibilityValidator

com.gk_software.pricing_engine.core.eligibility.validator.ThresholdEligibilityValidator

defaultAdhocEligibilityFulfillmentValidator

adhocEligibilityFulfillmentValidator

com.gk_software.pricing_engine.core.eligibility.validator.AdhocEligibilityFulfillmentValidator

defaultAdditionalPriceTypeEligibilityFulfillmentValidator

additionalPriceTypeEligibilityFulfillmentValidator

com.gk_software.pricing_engine.core.eligibility.validator.AdditionalPriceTypeEligibilityFulfillmentValidator

defaultCouponEligibilityValidator

couponEligibilityValidator

com.gk_software.pricing_engine.core.eligibility.validator.CouponEligibilityValidator

defaultDefaultEligibilityRuleValidator

defaultEligibilityRuleValidator

eligibilityRuleValidators

com.gk_software.pricing_engine.core.rules.validator.DefaultEligibilityRuleValidator

defaultCombinationOrEligibilityRuleValidator

combinationOrEligibilityRuleValidator

com.gk_software.pricing_engine.core.rules.validator.CombinationOrEligibilityRuleValidator

defaultCombinationXoEligibilityRuleValidator

combinationXoEligibilityRuleValidator

com.gk_software.pricing_engine.core.rules.validator.CombinationXoEligibilityRuleValidator

defaultExclusiveCheckHandlerValidator

exclusiveCheckHandlerValidator

exclusiveCheckHandler

com.gk_software.pricing_engine.common.validator.DefaultExclusiveCheckHandler

defaultCalculationTimeLimiter

calculationTimeLimiter calculationLimiters com.gk_software.pricing_engine.core.calculation.best_price.CalculationTimeLimiter

defaultManufacturerCouponValidityPeriodValidator

manufacturerCouponValidityPeriodValidator

manufacturerCouponValidators

com.gk_software.pricing_engine.core.adhoc.mapper.ManufacturerCouponValidityPeriodValidator

Page 102: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

102

Bean Name Alias Plugin List Alias Bean Class

defaultConditionRegistry conditionRegistry conditionRegistryList

com.gk_software.pricing_engine.core.engine.SalesVsReturnsConditionRegistry

defaultPackageMeasuredDiscountableItemValidator

packageMeasuredDiscountableItemValidator

discountableValidatorServiceList

com.gk_software.pricing_engine.common.impl.validator.PackageMeasuredDiscountableItemValidator

defaultDefaultRetailPriceModifierCreator

defaultRetailPriceModifierCreator

normalizedItemModifierCreators

com.gk_software.pricing_engine.core.result.DefaultRetailPriceModifierCreator

defaultMixAndMatchRuleRetailPriceModifierCreator

mixAndMatchRuleRetailPriceModifierCreator

com.gk_software.pricing_engine.core.result.MixAndMatchRuleRetailPriceModifierCreator

defaultSubsequentDiscountRetailPriceModifierCreator

subsequentDiscountRetailPriceModifierCreator

com.gk_software.pricing_engine.core.result.SubsequentDiscountRetailPriceModifierCreator

defaultDefaultFrequentShopperPointsModifierCreator

defaultFrequentShopperPointsModifierCreator

com.gk_software.pricing_engine.core.result.DefaultFrequentShopperPointsModifierCreator

6.7 Pricing Engine Promotion Service Implementation

The modules provide the Implementation of PromotionPricingService interface of the Client API. It

provides the main integration point in the PPS environment.

The module handles all mapping from Client API to PCE transaction model. During this mapping, the

Client API compatibility checks and validations are done. In the psi-sap module, the Spring bean

context for the service integration is defined.

The module provides three important parts:

• The class PromotionPricingServiceImpl is the implementation of

com.sap.ppengine.client.service.PromotionPricingService and the main entry point for SAP integration.

• DataMappingRequestMapper: The classes in package

com.gk_software.pricing_engine.psi.sapmapping.request are responsible for mapping and validating

the client API request to the PCE model.

• DataMappingResponseMapper: The classes in package

com.gk_software.pricing_engine.psi.sapmapping.response are responsible for mapping PCE model to

client API response.

HOW IT WORKS

The general call sequence for Client API request processing follows these steps:

1. The PromotionPricingServiceImpl.calculate method is called with request and configuration map

information.

2. The configuration is parsed by the ConfigurationInitializer.

Page 103: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

103

3. The DataMappingRequestMapper is called to map the Client API request to the PCE transaction

model.

During this mapping, the API compatibility and validity is checked.

4. The DataMappingRequestMapper delegates the calls to several child classes that are responsible

for mapping specific elements of the request.

5. The parsed transaction is passed to the internal PricingService that creates a PricingEngine

instance and processes the calculation request.

6. The returned transaction is then mapped by the DataResponseMapper back to a Client API

response.

7. Again, the DataResponseMapper delegates the mapping to child classes for specific elements.

8. The mapped response is returned from the calculate method.

Abbildung 2 PromotionPricingService call sequence

Page 104: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

104

6.8 The data access layer (DAL)

The Promotion Calculation Engine's Data Access Layer (DAL) module is responsible for the loading

of the promotion master data used in the calculation and for the mapping of the environment-

specific loaded data to the internal data model.

The Data Access Layer is accessible through the DataAccessService interface

(com.gk_software.pricing_engine.common.data_access.DataAccessService) defined in the internal API. All

vendor specific DAL implementations must implement this interface.

6.8.1 Spring configuration

The DAL implementation used by the PCE is configured via Spring beans. A delegate pattern is

implemented to support seamless changes between different implementations of the DAL. For

enabling a custom implementation of the DAL, the dataAccessService bean of

type com.gk_software.pricing_engine.core.data_access.DataAccessServiceDelegate must be replaced as the

Page 105: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

105

code sample below demonstrates. The delegate property must reference the DataAccessService

implementation intended to be used for accessing the persistence layer.

<bean id="dataAccessService"

class="com.gk_software.pricing_engine.core.data_access.DataAccessServiceDelegate">

<property name="delegate" ref="dataAccessServiceVendorSpecific" />

</bean>

Codeblock 6 DataAccessServiceDelegate bean

6.8.2 Promotion data loading

The DAL is accessible for the PCE through the DataAccessService interface. To make the integration of

the DAL seamless for the PCE, only internal data model objects are used by the DataAccessService. The

mapping between master data provider-specific data objects and the internal model is the

responsibility of the DAL. The following methods are supported by the DataAccessService interface:

As the DataAccessService is not part of the public API, it is not guaranteed to be release-stable

and may change without notice.

Type Method Description

List<AssociatedMhgSO> findAssociatedMhgByChildId( Context context, long businessUnitGroupID, String childMhgId, String merchandiseGroupIDQualifier, boolean recursive)

Finds all associations for the specified child merchandise hierarchy group. If the recursive parameter is set to true, the complete sequence of parents will be returned ordered from the closest to the root.

RoundingRuleDO findRoundingRuleByKey( Context context, long businessUnitGroupID, Long roundingRuleID)

Finds the rounding rule by its external rule ID.

int getChildEligibilitiesCount( Context context, long eligibilityID)

Returns the count of child eligibilities of parent eligibility specified by the eligibility ID parameter.

Page 106: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

106

Type Method Description

List<PromotionConditionEligibilitySO> getChildEligibilitiesForParentEligibility( Context context, long businessUnitGroupID, long parentInternalEligibilityID)

Loads all child eligibilities of the given parent eligibility.

CombinationPromotionConditionEligibilitySO getCombinationEligibility( Context context, long eligibilityID)

Returns the combination eligibility specified by the given eligibility ID.

List<CouponPromotionConditionEligibilitySO> getCouponEligibilities( Context context, long businessUnitGroupID, String couponNumber, List<SaleReturnTypeCode>saleReturnTypeENUMS)

Returns a list of coupon eligibilities that match the registered coupon.

List<CustomerGroupPromotionConditionEligibilitySO>

getCustomerGroupEligibilities( Context context, long businessUnitGroupID, String customerGroupID, List<SaleReturnTypeCode>saleReturnTypeENUMS)

Returns a list of customer group eligibilities that match the registered customer group.

PromotionConditionEligibilitySO getEligibility( Context context, long eligibilityID)

Returns one concrete eligibility specified by the given eligibility ID.

ExternalActionPromotionConditionRuleSO getExternalActionRule( Context context, long ruleID)

Returns the external action rule specified by the given rule ID.

Get3Pay2PromotionConditionRuleSO getGet3Pay2Rule( Context context, long ruleID)

Returns the get 3 pay 2 promotion condition rule specified by the given rule ID.

Get3Pa

y2 rules

are not

support

ed by

the

PCE.

Page 107: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

107

Type Method Description

List<ItemPromotionConditionEligibilitySO> getItemEligibilitiesByFilter( Context context, long businessUnitGroupID, Set<ItemInformation> itemsInfoSet)

Returns a list of item eligibilities matching the parameters.

RebatePromotionConditionRuleSO getItemRule( Context context, long ruleID)

Returns the item price derivation rule specified by the given rule ID.

List<ManualPromotionConditionEligibilitySO> getManualPromotionEligibilities( Context context, long businessUnitGroupID, String triggerType, String triggerValue, List<SaleReturnTypeCode>saleReturnTypeENUMS)

Returns a list of all manual trigger eligibilities matching the given trigger type and trigger value.

List<MarketBasketAmountEligibilitySO> getMarketBasketAmountEligibilities( Context context, long businessUnitGroupID, List<SaleReturnTypeCode>saleReturnTypeENUMS)

Returns a list of all market basket amount eligibilities matching the parameters.

List<MHGPromotionConditionEligibilitySO> getMerchandiseGroupEligibilitiesByFilter( Context context, long businessUnitGroupID, Set<ItemInformation> itemsInfoSet)

Batch query for merchandise hierarchy group eligibilities.

List<MerchandiseSetPromotionConditionEligibilitySO>

getMerchandiseSetEligibilities( Context context, long businessUnitGroupID, String itemNumber, String uomCode, Set<PromotionMhgFilterSO>promotionMhgFilterSet, List<SaleReturnTypeCode>saleReturnTypeENUMS)

Returns a list of all merchandise set eligibilities related to the given item or merchandise hierarchy group.

List<Long> getMerchandiseSetIdsForItem( Context context, String itemID, String uomCode, Set<PromotionMhgFilterSO>promotionMhgFilterSet, List<SaleReturnTypeCode>saleReturnTypeCodes)

Gets the IDs of all Merchandise Sets the specified item is included in.

List<MatchingItemSO> getMixAndMatchItems( Context context, long ruleID)

Returns the mix and match price derivation item list of the rule specified with the given rule ID.

Page 108: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

108

Type Method Description

MixAndMatchPromotionConditionRuleSO getMixAndMatchRule( Context context, long ruleID)

Returns the mix and match price derivation rule specified by the given rule ID.

PromotionSO getPromotion( Context context, long businessUnitGroupID, long promotionID)

Returns the promotion specified by the given business unit group ID and promotion ID.

List<PromotionConditionSO> getPromotionConditions( Context context, long eligibilityID)

Returns a promotion condition list specified by the given eligibility ID. If the eligibility ID is the root eligibility ID, only one promotion condition will be returned. If the eligibility ID is not the root eligibility ID, no promotion conditions will be returned.

PromotionConditionRuleSO getRule( Context context, long ruleID)

Returns the promotion condition rule specified by the given ruleID.

List<AdditionalPriceTypePromotionConditionEligibilitySO>

getAdditionalPriceTypeEligibilities( Context context, long businessUnitGroupID, Collection<AdditionalPriceTypeCode>additionalPriceTypeCodes, Set<SaleReturnTypeCode> saleReturnTypeCodes)

Returns list of eligibilities corresponding to the given additional price type codes.

6.8.3 Data mapping

The DAL implementation is responsible for the mapping between the data provider-specific model

and the PCE internal data model. The implementation may also perform validation on the retrieved

data to make sure it is compatible with the internal model.

The PCE internal data model supports extension fields for the promotion master data retrieved from

the DAL. Each internal data object extends the ModelDto interface

(com.gk_software.pricing_engine.model.ModelDto), which provides methods for saving the loaded extension

fields and for accessing them at any point in the calculation. The DataAccessService implementation

Page 109: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

109

must take care of the mapping of these custom fields as well. The following methods are provided in

the ModelDto interface for saving and retrieving the extension fields.

Type Method Description

T get(String name) Supports accessing the extension fields of the entity by name. Each field stored in the extension map is identified by its name. The name of the extension field is the name defined in the data access model's entity and does not necessarily match the name of the DB table column. T is the type of the extension field.

Map<String, ?>

getExtensions() Accesses the extension data loaded from the Data Access Layer.

void setExtensions(Map<String, ?> extensions)

Sets the extension data provided by Data Access Layer.

6.9 Omnichannel Point-of-Sale Integration

6.9.1 Overview

The Promotion Calculation Engine also supports direct integration with Omnichannel Point-of-Sale.

In this case, the PCE is integrated as a module (jar files) to the POS and the Pricing Engine Promotion

Service.

A significant difference between the POS and the SAP Promotion Pricing Service use case is that the

POS may call the PCE several times within the same transaction, whereas in the SAP use case each

transaction is completed with one call to the Pricing Engine Promotion Service. Because the PCE

Context is kept within a session and is returned to the PCE with previous calculation results included,

it is possible to cache data to improve performance in the GK context. During request processing,

the Clean promotion data from Transaction step is also performed to remove calculated results

from previous PCE calls so that those will not influence the calculation.

Similar to the SAP Integration module, there is also a GK Integration main module, which contains

the following sub-modules:

• Pricing Engine GK Data Access: GK data access integration.

• Pricing Engine GK Model: GK-specific implementation of the PCE model, contains the

wrappers for POS data model to be used directly by the PCE.

• POS Pricing Service API: API for POS integration.

• POS Pricing Engine Component: Base implementation for POS API.

• POS Pricing Connector: Connector for the POS Service. Includes implementation of all

functionality that require calling the POS Service.

HOW IT WORKS

The POS creates a PriceCalculationRequest object, which contains a PosSession and a Transaction object.

Then from this the PCE PricingEngineRequest model object

Page 110: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

110

(com.gk_software.pricing_engine.PricingEngineRequest) is created using the AbstractRequestProcessor from POS

Pricing Engine Component module and filled with the Transaction. The POS Transaction is wrapped

with PCE Transaction object, so it can be used directly by the PCE. The Configuration is also mapped

from the POS request. Then the PricingEngine is called with this PCE request.

When the calculation is done, a

standard PriceCalculationResponse (com.gk_software.pricing_engine.pos.calculation.responses.CompleteResultRespo

nse) object is returned, which contains POS Transaction object updated with the calculated result and

which can be used by the POS.

6.9.2 PCE Model implementation

The Pricing Engine GK Model module contains a GK use case-specific implementation for the PCE

Model API. The GK implementation of the model interfaces each extend the AdaptedDto<T> abstract

implementation of the ModelDto (com.gk_software.pricing_engine.model.ModelDto), where T is the transaction

or promotion data object to be mapped to the internal model. The external model object is saved to

the AdaptedDto's T adaptedObject attribute. It is accessible through the methods of the internal model

interface implemented. Thus, no extended request mapping from GK-specific transaction and

promotion model to the internal PCE model is required, the GK internal model objects wrap the GK

model objects.

6.9.2.1 Custom data on Omnichannel Point-of-Sale

In the Omnichannel Point-of-Sale there is currently no support for the any fields of the client API or

the extension map on the SAP Promotion data model.

There is an alternative way to pass additional information dynamically to the PCE. This is done via

XXCustom parameters. They are stored in the database and are available for instance in

table CO_EL_PRDV as

XX_CUSTOM_0[1-5]_GK.

There are five available custom fields to put information.

Page 111: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

111

Name Null? Type

--------- -------- -----------------

TENANT_ID NOT NULL VARCHAR2(20 CHAR)

NAME NOT NULL VARCHAR2(80 CHAR)

STATE NOT NULL NUMBER(38)

SCHEMA_ID VARCHAR2(36 CHAR)

Usage: DESCRIBE [schema.]object[@db_link]

Name Null? Type

--------------------------- -------- ------------------

ID_BSNGP NOT NULL NUMBER(18)

ID_EL_PRDV NOT NULL NUMBER(18)

TY_EL_PRDV NOT NULL VARCHAR2(4 CHAR)

PARENT_PRICE_DRV_RULE_EL_ID NOT NULL NUMBER(18)

ROOT_PRICE_DRV_RULE_EL_ID NOT NULL NUMBER(18)

LEVEL_ID NOT NULL NUMBER(38)

EFFECTIVE_DATE_TIME NOT NULL DATE

EXPIRATION_DATE_TIME NOT NULL DATE

STATUS_CODE VARCHAR2(2 CHAR)

XX_CUSTOM_01_GK VARCHAR2(256 CHAR)

XX_CUSTOM_02_GK VARCHAR2(256 CHAR)

XX_CUSTOM_03_GK VARCHAR2(256 CHAR)

XX_CUSTOM_04_GK VARCHAR2(256 CHAR)

XX_CUSTOM_05_GK VARCHAR2(256 CHAR)

XID_GK NUMBER(18)

FL_NG_GK NOT NULL CHAR(1 CHAR)

To get access to this field just use the method "get" available in the PCE model entities:

PromotionConditionEligibilitySO eligibility = getEligibility();

String custom = eligibility.get("XXCustom02");

In the same way transaction information may be enriched by the Omnichannel Point-of-Sale and is

available via the XXCustom-fields in the transaction objects on PCE side.

It is also possible to implement the GKModelAdapter and GkModelExtractor to automate the

conversion from and to any fields for the transaction model specific for an extension. See chapter

Extension points for details.

6.9.3 Public GK API

The pricing-pos-api module defines the public, GK specific API of the PCE core. The API defined in this

module is release-stable from PCE 2.9.4 onward. That means extensions based on these APIs should

still run on newer version of the PCE core without any migration needed. Similarly to the common

public API module, there are two levels of API stability defined: Consumer stability and Extension

stability.

Page 112: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

112

For more detailed description of the defined stability levels, refer to chapter PCE Extensions.

This paragraph gives an overview on the common API use cases for caller type APIs. Details on the

extension points API can be found in the chapter PCE Extensions.

6.9.3.1 POS API

The POS API consists of interfaces and their default implementations required for receiving price

calculation requests from GK client applications and for providing the corresponding response. The

following interfaces are included:

Package: com.gk_software.pricing_engine.pos.calculation

Interface Description

LineItemChangeValidator Extension point for validating {@link RetailTransactionLineItem retail transaction line item} changes resulting from the PCE calculation compared to previous calculation results.

Further information and the list of available default PCE plugin implementations can be found in chapter Extension Points.

PriceCalculationRequest Interface defining generic requests expected by the PCE. Follows command pattern, each request type is processed by its specific handler. Contains besides the request transaction the PCE Context with results of previous calculation results and with cached masterdata, the configuration and the calculation scheme for the current processing.

PriceCalculationRequestFactory Factory interface for creating PriceCalculationRequest objects.

PriceCalculationResponse Interface defining generic requests responded by the PCE.

PriceCalculationResponseFactory Factory interface for creating PriceCalculationResponse objects.

PriceCalculationService Interface for triggering the PCE calculation with a specific request.

PriceCalculationSession Session to store context of Pricing Engine calculation and additional information required by the client.

PriceCalculationSessionFactory Factory interface for creating PriceCalculationSession objects.

The following default implementations exist for the POS API interfaces.

Note that even though the different implementation of request and response types exist, the PCE

calculation itself does not differentiate between the different request types, all transactions are

calculated the same way, recalculating everything. The PCE session is only used to store the PCE

Context, cached masterdata and the list of changed / added / removed items. Incremental

Page 113: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

113

calculation is not supported. The PCE default implementation always responds a

CompleteResultResponse in case of successful calculation.

Name Description Interface Class

CalculateFinalResult Request for finalising an existing PriceCalculationSession.

PriceCalculationRequest

com.gk_software.pricing_engine.pos.calculation.requests.CalculateFinalResult

CalculateSubtotal Request to trigger a Subtotal calculation for an existing PriceCalculationSession.

PriceCalculationRequest

com.gk_software.pricing_engine.pos.calculation.requests.CalculateSubtotal

CalculateTransaction Request to completely calculate the transaction.

PriceCalculationRequest

com.gk_software.pricing_engine.pos.calculation.requests.CalculateTransaction

ChangeCoupon Request to add/remove coupons to an existing PriceCalculationSession.

PriceCalculationRequest

com.gk_software.pricing_engine.pos.calculation.requests.ChangeCoupon

ChangeCustomer Request to change customer in an existing PriceCalculationSession.

PriceCalculationRequest

com.gk_software.pricing_engine.pos.calculation.requests.ChangeCustomer

ChangeLineItem Request to send added/changed and removed line items to the Pricing Engine.

PriceCalculationRequest

com.gk_software.pricing_engine.pos.calculation.requests.ChangeLineItem

ChangeLineItemPromotionTrigger

Request to add/remove LineItemPromotionTriggers in an existing PriceCalculationSession.

PriceCalculationRequest

com.gk_software.pricing_engine.pos.calculation.requests.ChangeLineItemPromotionTrigger

Page 114: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

114

Name Description Interface Class

ChangeTransactionPromotionTrigger

Request to add/remove TransactionPromotionTriggers in an existing PriceCalculationSession.

PriceCalculationRequest

com.gk_software.pricing_engine.pos.calculation.requests.ChangeTransactionPromotionTrigger

StartTransaction Request to start a new transaction calculation, reseting current state of PriceCalculationSession.

PriceCalculationRequest

com.gk_software.pricing_engine.pos.calculation.requests.StartTransaction

CompleteResultResponse

Response type for indicating a complete transaction recalculation. All items might have been possibly changed.

PriceCalculationResponse

com.gk_software.pricing_engine.pos.calculation.responses.CompleteResultResponse

ConditionChangeResultResponse

Response indicating calculation was done and changes need to be applied.

Not used

by default

PCE

implemen

tation.

PriceCalculationResponse

com.gk_software.pricing_engine.pos.calculation.responses.ConditionChangeResultResponse

ErrorResponse A response returned in case of an error occurred during price calculation. An error Response will not return session or transaction information.

PriceCalculationResponse

com.gk_software.pricing_engine.pos.calculation.responses.ErrorResponse

Page 115: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

115

Name Description Interface Class

FinalResultResponse Response indicating a final result calculation.

Not used

by default

PCE

implemen

tation.

PriceCalculationResponse

com.gk_software.pricing_engine.pos.calculation.responses.FinalResultResponse

PromotionInputResponse

Result indicating a request for a promotion Input.

Not used

by default

PCE

implemen

tation.

PriceCalculationResponse

com.gk_software.pricing_engine.pos.calculation.responses.PromotionInputResponse

6.9.4 Data Access Layer

A GK-specific implementation is also available for the DataAccessService

(com.gk_software.pricing_engine.common.data_access.DataAccessService) for retrieving promotion data from

the persistence layer. The promotion service for accessing the data used in the POS integration use

case is provided by GK. Data retrieved using this service is again also wrapped by the GK-specific

implementation for the PCE promotion data model objects, so it is easily usable by the standard

pricing engine business logic and no additional mapping is required.

6.9.4.1 Promotion data cache

In the POS integration use case, one transaction might consist of several PCE calls. In all cases, the

PCE calculation is executed the same way, no previous calculation results are taken from the request.

As a result, the same calls must be made to the DAL for each calculation, causing some performance

issues. To reduce performance overhead it is possible to use a local masterdata cache implemented

in the PCE Context's CacheContext (com.gk_software.pricing_engine.api.context.CacheContext), which stores all

loaded promotion masterdata for the given transaction. The local masterdata cache can be enabled

through the configuration parameter localMasterdataCacheEnabled, the maximum size of the cached

data for each promotion object can be set with the configuration parameter cacheSize.

6.9.5 POS Integration Extensions

The PCE supports extensions also for POS Integration. New plugin implementations may be included

in the POS Pricing Engine Component module by adding new plugin.xml files like the following

example shows:

Page 116: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

116

<!-- Load pos pce plugins -->

<import resource="classpath*:META-INF/**/*-pos-plugin-pce.xml"/>

For detailed information about extensions, see chapter PCE Extensions.

6.9.5.1 Available POS extension plugins

There are plugin implementations available in the standard delivery for POS that are GK specific and

therefor are not included in the core implementation of the PCE. The following table summarizes

these extensions.

Extension point Plugin Supports criteria

Plugin order

Description

AdhocPromotionLoader PosSessionPromotionLoaderImpl Supported in any context

10000 Responsible for loading ad hoc promotions from the yMCA external system. For accessing the available ad hoc promotion list the plugin calls the POS service and then returns the promotion data.

Bean definitionavailable in the pricing-pos-connector module: META-INF/com.gk-software.pricing-engine/gk-connector/promotion/ymca-pos-plugin-pce.xml

Page 117: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

117

7 PCE Extensions

While the PCE supports already common features and a rich set of rules and eligibilities, there might

be always special requirements that are specific to a customer environment. To allow

implementation of additional features for such situations, the PCE Core provides a well-defined API

and defined extension points. These extension points are designed for easily adding new

functionality for common use cases.

The API for implementing PCE extensions is defined in the libraries pricing-engine-model and pricing-

engine-api. The API defines two levels of stability to rely on for extension compatibility with future PCE

versions:

• Extension stability: Someone implementing or sub-classing the “stable” entity can be sure

that an upgrade does not lead to a syntax error.

• Consumer stability: Someone externally calling / referring to a “stable” entity can be sure

that an update does not lead to a syntax error.

Most interfaces and classes in the API modules are sticking to consumer stability, so referencing

them in custom code will work with future PCE versions. There are several interfaces defined as

extension points that provide extension stability as well. These interfaces are marked with the

annotation com.gk_software.pricing_engine.api.ExtensionPoint. An additional property ExtensionType on this

annotation defines the kind of extension pattern for this extension point (for details on extension

patterns, see chapter Extension Patterns). The following extension types are defined:

• Plugin: The extension point follows the plugin pattern and is integrated automatically via

Spring.

• Overriding: This extension point allows overriding the default implementation and is

configured via Spring bean replacement.

• Implement: Such an interface can be implemented by a custom extension depending on

functional needs. It is used in method parameters or return values, but not defined as Spring

bean.

Extensions implemented using PCE core extension points should work with no or minimal adoptions

to the code in the SAP Promotion Pricing Service as well as Omnichannel Point-of-Sale.

7.1 Extension Patterns

7.1.1 Overview

The extensions for the PCE follow some common patterns to extend the PCE functionality at

different places with minimal effort and simple configuration. These recurring patterns allow an

extension developer to extend the different places in a similar way.

Page 118: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

118

All extension patterns of the PCE are based on extension of the Spring application context of the

PCE.

7.1.2 Plugins

The general extension pattern for most extension points follows the plugin design pattern. A plugin

is essentially the implementation of a small interface which is dynamically found and injected in the

PCE processing flow via Spring. To support easy integration, the PCE plugin handling uses the Spring

plugin framework.

All PCE plugin interfaces share some basic principles:

• Small interfaces, easy to implement

• Automatically found by the PCE plugin handling

• Dynamic injection in the PCE application context

• Allow to define an order of processing

• PCE Default Plugins can be replaced via Spring bean replacement.

HOW IT WORKS

Plugin extension points are defined as simple Java interfaces. All PCE plugins extend the

org.springframework.plugin.core.Plugin interface. This interface provides a method boolean supports(S

delimiter) to allow the plugin framework to check whether a plugin should be used for a specific

context. This is done by the PCE core depending on the plugin pattern for a given extension point

(see below). Each plugin extension point interface in the PCE is annotated by the ExtensionType.plugin

and extends the Plugin interface:

@ExtensionPoint(ExtensionType.Plugin)

public interface EligibilityValidator extends Plugin<PromotionConditionEligibilitySO>

The available plugins of a given type are collected in the PCE Spring application context. This

application context is defined in the pricing-engine-impl module at the path: META-INF/com.gk-

software.pricing-engine/core/default-beans.xml.

The collection of the plugins is done automatically using the Spring XML plugin namespace, based

on the plugin interface:

<!-- List of eligibility validators -->

<alias name="defaultEligibilityValidators" alias="eligibilityValidators"/>

<plugin:list id="defaultEligibilityValidators"

class="com.gk_software.pricing_engine.api.eligibility.EligibilityValidator"/>

Page 119: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

119

The PCE provides a number of default plugins that define the core calculation logic. The default

plugins are defined in specific application context files named default-plugin-pce.xml in the pricing-engine-

impl module.

These application context files are organized in subfolders of META-INF/com.gk-software.pricing-

engine/core. They are grouped by responsibility:

Group Description

conditions Default plugins related to condition loading, handling.

context Context post processor plugins

eligibilities Default plugins related to eligibility handling like EligibilityLoaderFragment and EligibilityResultParser.

filters Default item filter plugins.

mappers Default plugins implementing mapping functionality

parsers Plugins for GS1 coupon parsing

price-modifications

Plugins for handling the calculation logic for standard price modification codes.

promotions Default promotion loader plugins

rules All plugins related to processing of standard rule, for example, CalculationRuleProcessor and RebateDistributionProcessor implementations.

transaction Default plugins for updating the contents of the transaction

transaction-analyzers

Default plugins for retrieving content from transaction and fill the Context object.

validators Validator plugins for standard validation of conditions, eligibilities, and results.

Details on the bean definitions can be found in chapter Pricing Engine Core Implementation.

THERE IS MORE

Besides the common features for plugins, all plugin extension points are grouped by different usage

patterns. These usage patterns for plugins define which plugin shall be used in which order and how

multiple plugins for the same extension point are handled. The patterns are based on well-known

software design patterns.

There are actually three different kinds of plugin patterns in use in the PCE:

• Strategy pattern

• Filter Chain pattern

• Chain of responsibility pattern

Page 120: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

120

7.1.2.1 Strategy pattern

The plugin strategy pattern is based on the strategy design pattern. Based on the context of use,

different implementations will be used.

An extension point based on the strategy pattern does not know which implementation will handle

what. All implementing classes for a plugin will be called and the ones that are designed to take

action will execute the corresponding logic. It is also possible that more than one called plugin will

execute its logic.

HOW IT WORKS

The plugin framework integrated in the PCE Spring application context will collect all plugins

implementing a specific plugin interface. The list may be further filtered by checking the supports

method of the plugin implementation. All plugins are then called in the defined order. Each plugin

decides on its own whether to perform some action or not. This pattern is used for plugins when

each plugin is responsible for a specific type handling and all types should be handled accordingly.

For example, when loading eligibilities, each EligibiltiyLoaderFragment plugin takes care of the loading of

a specific eligibility type. This means there is a CouponEligibilityLoader, an ItemEligibilityLoader, a

MerchandiseSetEligibilityLoader etc.

There are several plugin types that are based on this strategy:

Plugin Interface Supports context

Description

ContextPostProcessor Context • Process different parts of the context as the first step of processing.

TransactionCleaner and LineItemCleaner Context • Clear out previous calculation results from the transaction.

TransactionAnalyzer No check done • Parse different parts of the transaction.

• Store information to Context.

• Default analyzers for standard transaction parts like coupons, items, manual triggers.

AdhocPromotionLoader Context • Load ad hoc promotions from external systems.

EligibilityLoaderFragment No check done • Handle loading and initialization of eligibilities.

• Provides eligibility-specific logic.

• Called from DefaultEligibilityHandler.

• All configured fragments are called in order.

• Default implementations for all standard eligibility types expect manual eligibilities.

Page 121: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

121

Plugin Interface Supports context

Description

EligibilityLoader No check done • For complete customization of eligibility loading if fragment is not enough.

• Needs to handle creation of Wrapper, registration in context and activation.

• DefaultEligibilityLoader and ManualEligibilityLoader.

EligibilityResultParser EligibilityWrapper

• Preprocess eligibility for calculation.

• Parse eligibility and result data.

• Updates PartialResult.

• Default implementations for context specific eligibilities.

ConditionLoaderFragment Context • Loads promotion data for the activated eligibilities.

EligibilityRuleHandler PartialResult • Takes care of common rule handling and applying

• Processes intervals, transaction and position related rules

EligibilityRuleHandlerFragment PartialResult • Takes care of eligibility type specific rule handling

CalculationLimiter Context • Checks limiting conditions for the calculation, including the best price determination

FrequentShopperPointsModifierCustomizer PartialResult • Customizer for FrequentShopperPointsModifier result data.

LoyaltyRewardLineItemCustomizer PartialResult • Customizer for LoyaltyRewardLineItem result data.

RetailPriceModifierCustomizer PartialResult • Customizer for RetailPriceModifier result data.

PriceModificationLineItemCustomizer PartialResult • Customizer for PriceModificationLineItem result data.

RetailTransactionPromotionPriceDerivationRuleCustomizer

PartialResult • Customizer for RetailTransactionPromotionPriceDerivationRule result.

TransactionUpdater Context • Updates the transaction with the calculation results.

7.1.2.2 Filter Chain Pattern

The filter chain pattern follows the intercepting filter software design pattern. Filter Chain extension

points build up a list of multiple matching plugins and execute them in defined order on the target.

Page 122: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

122

The methods called on these plugin interfaces typically return a boolean value. All called filters must

return true for the processing to carry on.

This kind of pattern is typically used for validation of an object. Only if all validators prove the object

is valid, it is accepted for processing.

HOW IT WORKS

Like the strategy pattern, all plugins implementing a specific plugin interface for the filter chain

extension point are collected. For each of these filter chain plugins, the supports(...) method is checked

to determine whether the filter should be applied in a given context. All matching plugins are then

called in order and the filter method is checked. As soon as one method returns false, the chain is

stopped and the processing aborted.

A good example is the ConditionValidator extension point. Before a promotion condition is processed,

the validators are checked to determine whether it should be applied. One concrete implementation

is the ExclusiveConditionValidator that checks whether there are already exclusive flagged promotions

applied in the context that prevent additional promotions from being used.

The following extension points are implemented according to the Filter Chain pattern:

Plugin Interface Supports context Description

EligibilityValidator EligibilityWrapper • Check eligibility after loading and initialization whether it should be used in the further processing.

• Implementations for generic checks (= supports all eligibilities) and eligibility specific checks (i.e. MarketBasketAmountEligibilityValidator).

ConditionValidator PromotionConditionWrapper • Check condition can be applied before calculation.

ResultValidator PartialResult • Checks a result after calculation.

• If invalid result will be skipped and not applied to summary.

RebatableItemFilter PromotionConditionWrapper • Filter items for rebate calculation.

EligibilityRuleHandler PartialResult • Handle eligibility specific rule calculation.

• Process items and intervals.

• Default implementations for standard Threshold type eligibilities.

RebateValidator PartialResult • Check whether a rebate is valid and can be applied.

• Validation is performed in case of valid partial results before the SummaryResult is updated.

LineItemRebateValidator PartialResult • Check whether a rebate is valid and can be applied for each line item.

ConditionRebateValidator PartialResult • Check whether a rebate is valid and can be applied for the condition.

Page 123: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

123

Plugin Interface Supports context Description

RebatableItemFilterPlugin PromotionConditionWrapper • Checks whether an item meets the defined criteria and decides if it is rebatable or not.

7.1.2.3 Chain of Responsibility Pattern

This plugin pattern works like the well-known software design pattern of the same name. All plugins

found for an extension point are checked in order and the first one that supports the defined

context will be used to execute the logic.

For these plugins, the order of plugins is important to allow to handle the processing in a plugin.

This means more specific plugins should be ordered before generic plugins that may provide a

default implementation and support every possible context.

HOW IT WORKS

In the PCE core logic, the list of chain of responsibility plugins is collected and injected as for all

plugins via the Spring context. The plugin list is then iterated in the order provided in the list. For

each plugin implementation found, the supports(...) method is checked. When a plugin returns true,

this plugin is used in processing the current context. A good example is the PriceModification interface

that is looked up for the first implementation supporting the PriceModificationMethodCode of a

PromotionConditionRule.

The following extension points are implemented according to the Chain of Responsibility pattern:

Plugin Interface Supports context Description

ThresholdActivationCheck ThresholdType • Check eligibility activation based on threshold.

• Initial check using plain transaction information without promotions.

RuleLoader RuleType • Customization of CalculationRule loading.

• Overrule default rule loading.

• Default implementations for standard rule types.

CalculationRuleProcessor PromotionConditionRuleSO • Evaluate Rule.

• Fill PartialResult.

• Default implementations for standard rule types.

ExclusiveCheckHandler PromotionConditionSO • Handle exclusion check at different places.

• Extension Point for customizing exclusive checks.

Page 124: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

124

Plugin Interface Supports context Description

PriceModification PromotionConditionRuleSO • Calculate Price for different price modification method codes.

• Calculation varies depending on PriceCalculationContext.

• Default implementations for standard method codes.

RebateDistributionProcessor PromotionConditionRuleSO • Rule-specific rebate distribution.

• Default implementations for standard rule types.

MixAndMatchCombinationTypeProcessor MixAndMatchCombinationType • Applies the mix&match rule according to its combination code.

MixAndMatchProrationCustomizer PartialResult & MatchingItemSO

• Customize Mix and Match proration.

BestPriceCalculator List of PartialResult • Validate whether the conflicting PartialResult list provides the best price variant.

UomCodeMapper Context • Custom mapping for manufacturer coupon UOM codes.

7.1.2.4 Plugin Order

To have a reproducible behavior and allow control of used plugins for the different patterns, it is

crucial to call the plugins in a defined order. Luckily, the plugin handling supports the ordering via

Spring by adding the Order annotation.

HOW IT WORKS

The plugin:list namespace element collects all plugins implementing the defined interface that are

found in the application context. The list of plugins will be ordered by Spring checking the @Order

annotation found at a plugin implementation class. If no annotation is found, the respecting plugins

are ordered after any @Order marked plugin in the order found in the application context.

It is highly recommended marking all custom plugins with an @Order annotation to guarantee

a defined behavior.

The Order annotation has an integer as parameter to define the ordering criteria. Ordering is done

numerical by this integer from low to high.

@Order(999)

public class CustomCouponTransactionAnalyzer implements TransactionAnalyzer

Page 125: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

125

THERE IS MORE

To prevent a custom implementation from getting in conflict with default plugins and to be able to

control how a custom plugin is called in respect to the default plugins, there is a reserved number

range for the default plugins.

The default plugins for the PCE core have all defined an order in the range of 0 to 100000. Default

plugins only use full hundred values (i.e. 100, 200, 1000, 1100, 10000 etc.). All values that are smaller

than 0 or greater than 100000 or between the 100s can be used for custom implementations.

Note that values outside the range between -10000000 and 10000000 are not used by

SAP plugin implementations. Inside this range, SAP reserves the multiples of 100 as order for

custom plugin implementations. Any values within this range that are not reserved for the PCE

core plugins may be used.

Details on which order value is defined for the default plugins can be found in the description of the

Pricing Engine Module: Impl.

7.1.3 Bean Overrides

Replacing existing functionality that is not provided as plugin extension point is sometimes required

to adopt the behavior to customer needs.

To do so, you have to write your own implementation of the related class/interface and define it as a

bean in your custom bean context.

All beans that can be replaced are defined with an alias (see below) to easily replace the bean

without changing existing definitions.

HOW IT WORKS

For example, to replace the standard ConditionLoader with a custom one add the new, custom bean

with alias conditionLoader:

<!-- Custom Condition Loader, Overwrite standard one-->

<alias name="customConditionLoader" alias="conditionLoader"/>

<bean id="customConditionLoader" class="foo.bar.CustomConditionLoader"/>

THERE IS MORE

Due to the dynamic plugin collection via the plugin framework, it is not possible to replace default

plugin implementations via the bean alias. If you really need to completely replace a default plugin,

you have to reference the default bean id for this plugin bean.

Page 126: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

126

<!-- Extension of Transaction Analyzer overwrite standard one-->

<alias name="customCouponTransactionAnalyzer" alias="defaultCouponTransactionAnalyzer"/>

<bean id="customCouponTransactionAnalyzer" class="foo.bar.CustomCouponTransactionAnalyzer"/>

7.1.4 Extending PCE standard implementations

In special cases you may want to extend some existing functionality without completely rewriting

everything. While this is not covered as part of the stable API, subclassing PCE beans could offer a

very flexible way to extend the calculation logic. You must consider in this case that there is no

guaranteed compatibility between different PCE versions for classes and other artifacts outside the

defined api packages.

This means a method signature may change over time, making custom subclass syntactically

incorrect on a new PCE version. The probability that a PCE object will be changed in an incompatible

way increases from first to last entry in the following list:

• Spring bean ID/alias

• Public constants and Enums

• Java interface (methods may, however, be added)

• Signature of public method of a Java class

• Signature of protected method of a Java class

• Protected attributes of a Java class

7.2 Extension Points

ContextItemInitializer

7.2.1 Context

7.2.1.1 Add additional initialization logic to request processing

As a custom requirement, it might be necessary to execute some functionality before any processing

was done by the PCE.

The PCE provides the ContextPostProcessor extension point with Context as supports context for such

scenarios. As the internal PCE Context is available for the plugin execution, the plugin provides the

possibility of adding any additional initialization processing on the request or the request

transaction.

The ContextPostProcessor is defined in the interface ContextPostProcessor

(com.gk_software.pricing_engine.api.context.ContextPostProcessor).

GETTING READY

For adding custom functionality to be executed before the PCE calculation, the following steps must

be taken:

Page 127: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

127

• Add custom implementation of the ContextPostProcessor interface.

• Implement supports method in a way that the plugin is only used in the desired context (

Context ).

• Mark plugin with @Order annotation in case the order of execution is important. As the

execution is done using the Strategy extension pattern, all supported plugins will be

executed.

• Add bean to the Spring application context for the custom implementation of

the ContextPostProcessor.

HOW IT WORKS

All available implementations of the ContextPostProcessor are gathered by the Spring application

context. They are executed as the last step of initializing the internal context, so all information from

the request transaction is already available in it, but before any further execution steps would have

been made by the PCE calculation. The plugins are executed by the executeContextPostProcessors

method in the PricingEngineImpl (com.gk_software.pricing_engine.core.engine.PricingEngineImpl), the PCE core

implementation for the PricingEngine interface. Execution is done by using the Strategy

extension pattern.

THERE IS MORE

The following PCE core implementations are provided for the ContextPostProcessor plugin:

Plugin Supports criteria Plugin order

Description

ContextItemInitializer Supported for all transactions

1000 Checks and filters all promotion relevant line items in the transaction and stores them in the PCE context.

StoreLanguageContextInitializer Supported for all transactions

2000 Lookup and set the language of store to the PCE context.

The following plugin implementations for the extension point are only available in the standard

delivery for SAP, therefore are not included in the core implementation of the PCE.

Plugin Supports criteria Plugin order

Description

CalculationSchemeRequestProcessor Supported for all requests 400 Context post-processor for calculation scheme handling. Maps the calculation scheme of the request to the PCE's request context.

DataAccessInitializationProcessor The RequestContext is not null

AND

The context mode is set to ContextMode.STANDARD

500 The plugin takes the PCE request from the RequestContext and calls the initialize method provided by the SAP Promotion Service.

Page 128: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

128

7.2.1.2 Clean previous calculation results from the transaction

Before calculation the pricing engine must clear out from the transaction any calculation result from

previous calculations so it does not influence the current calculation. By adding plugin

implementations for the TransactionCleaner and the LineItemCleaner extension points it is possible

to clear out a concrete part of the transaction or the line items in the transaction.

The TransactionCleaner is defined in the interface TransactionCleaner

(com.gk_software.pricing_engine.api.transaction.TransactionCleaner) with supports context Context

(com.gk_software.pricing_engine.api.context.Context).

The LineItemCleaner extension point is defined in the interface LineItemCleaner

(com.gk_software.pricing_engine.api.transaction. LineItemCleaner) with supports context Context

(com.gk_software.pricing_engine.api.context.Context).

HOW IT WORKS

The transaction cleaner plugins injected by Spring are executed by

the clearPromotionDataFromTransaction(Context c)method in the TransactionUpdateHandlerImpl

(com.gk_software.pricing_engine.core.transaction .TransactionUpdateHandlerImpl). Execution is done by using the

Strategy extension pattern, which means all implementing classes for the plugin will be called and

the ones that are designed to take action will execute the corresponding logic. A designated

implementation of the TransactionCleaner plugin, the RetailTransactionLineItemCleaner is responsible for

clearing out all previous calculation results from the retail transaction line items by executing all

registered LineItemCleaner plugins. When an additional field is desired to be cleared out from the line

items besides what the core PCE implementation covers, a new LineItemCleaner plugin must be

implemented rather than a TransactionCleaner - which of course would also be sufficient from a

functional point of view. This way the line item list of the transaction will only be iterated over once

in the RetailTransactionLineItemCleaner resulting in better performance.

When implementing custom transaction cleaners the following must be considered: calculation

results related to externally applied promotions or which are a result of manual price update, or

which are included on line items with NotConsideredByLoyaltyEngineFlag = true must not be

cleared.

GETTING READY

For adding custom transaction or line item cleaners, the following steps must be taken:

• Add custom implementation of the TransactionCleaner or LineItemCleaner the interface

based on which part of the transaction we would like to clear.

• Implement supports method in a way that the plugin is only used in the desired context.

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom plugin.

THERE IS MORE

Page 129: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

129

The following PCE core implementations are provided for the TransactionCleaner plugin:

Plugin Supports criteria

Plugin order

Description

RetailTransactionLineItemCleaner Always supported

1000 Clears all previous calculation results from the line items.

PriceModificationAndLoyaltyRewardLineItemCleaner Always supported

2000 Clears previous calculation results from the transaction's price modification line items loyalty reward line items.

PriceDerivationRuleCleaner Always supported

3000 Clears previous calculation results from the transaction's price derivation rules.

RetailTransactionModifierCouponCleaner Always supported

4000 Clears out the retail transaction modifier coupon list of the transaction.

RetailTransactionCouponSummaryTransactionCleaner Always supported

5000 Clears previous calculation results from the transaction's retail transaction coupon summaries.

ManufacturerCouponSummaryTransactionCleaner Always supported

6000 Clears previous calculation results from the transaction's retail transaction manufacturer coupon summaries.

The following PCE core implementations are provided for the LineItemCleaner plugin:

Plugin Supports criteria

Plugin order

Description

RetailPriceModifierCleaner Always supported

1000 Clears previous calculation results from the line item's retail price modifiers.

FrequentShopperPointsModifierCleaner Always supported

2000 Clears previous calculation results from the line item's frequent shopper points modifiers.

SaleReturnLineItemModifierReferenceCleaner Always supported

3000 Clears previous calculation results from the line item's modifier references.

SaleReturnLineItemModifierCouponCleaner Always supported

4000 Clears previous calculation results from the line item's modifier coupons.

7.2.1.3 Parse additional information from the transaction

The PCE provides the TransactionAnalyzer extension point with TransactionAnalyzerType

(com.gk_software.pricing_engine.model.typecodes.TransactionAnalyzerType) as supports context for adding

custom logic for analyzing and processing a specific part of the transaction.

The TransactionAnalyzer is defined in the

interface TransactionAnalyzer (com.gk_software.pricing_engine.api.analyzer.TransactionAnalyzer).

GETTING READY

For adding custom transaction analyzers, the following steps must be taken:

Page 130: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

130

• Add custom implementation of the TransactionAnalyzer interface.

• Extend the TransactionAnalyzerType with the value supported by the custom analyzer.

• Implement supports method in a way that the plugin is only used in the desired context

(TransactionAnalyzerType).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the

TransactionAnalyzer .

HOW IT WORKS

All implementations for the TransactionAnalyzer registered in the Spring application context are

executed as a last step of the PCE request processing.

The plugins are executed by the executeTransactionAnalyzer method in the PricingEngineImpl

(com.gk_software.pricing_engine.core.engine.PricingEngineImpl). Execution is done by using the

Strategy extension pattern, which means all implementing classes for the plugin will be called and

the ones that are designed to take action will execute the corresponding logic.

THERE IS MORE

The following PCE core implementations are provided for the TransactionAnalyzer plugin:

Plugin Supports criteria Plugin order

Description

CouponTransactionAnalyzer Transaction analyzer type "COUPON" 1000 Analyzes coupon-related transaction segments.

ManufacturerCouponTransactionAnalyzer Transaction analyzer type "MANUFACTURER_COUPON"

1500 Analyzes manufacturer coupon related transaction segments.

ItemTransactionAnalyzer Transaction analyzer type "ITEM" 2000 Analyzes all retail transaction line items in the transaction and normalizes them for the calculation. The following line item segments are analyzed:

• Item IDs

• Merchandise hierarchy groups of the item and parent merchandise hierarchy groups

• Manufacturer related information

• Additional price types of the item

• Total market basket amounts

Page 131: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

131

Plugin Supports criteria Plugin order

Description

CustomerGroupTransactionAnalyzer Transaction analyzer type "CUSTOMER_GROUP"

3000 Analyzes customer group-related transaction segments.

ExternalPromotionsTransactionAnalyzer Transaction analyzer type "EXTERNAL_PROMOTIONS"

4000 Analyzes external promotion-related transaction segments.

PromotionManualTriggerTransactionAnalyzer Transaction analyzer type "PROMOTION_MANUAL_TRIGGER"

5000 Analyzes manual trigger-related transaction segments.

When you add custom TransactionAnalyzer plugins in an extension, it is recommended to add an

@Order annotation with higher value (>100000) than the default plugins to be able to access

already initialized context data like parsed items.

7.2.2 Eligibilities

The PCE defines several extension points regarding eligibility loading, validation, and processing

throughout the calculation. For extending the PCE with custom eligibility types, it is necessary as a

minimum to implement the plugins responsible for the loading of the eligibility from the data access

layer. Depending on the specified functionality, it might be also required to add implementation for

other eligibility-related extension points as well. The following section describes all extension points

related to the loading, activating, and processing of eligibilities used throughout the PCE calculation

process.

7.2.2.1 Loading a custom eligibility

The PCE defines two extension points responsible for the loading of eligibilities: The eligibility

loader is responsible for validating and activating the loaded eligibilities and their parent

eligibilities, for registering them and for filling the item bucket for each eligibility. The eligibility

loader extension point is defined in the interface EligibilityLoader

(com.gk_software.pricing_engine.api.eligibility.EligibilityLoader) with extension context EligibilityType

(com.gk_software.pricing_engine.model.typecodes.promotion.EligibilityType).

The second extension point available for eligibility loading related plugins is the eligibility loader

fragment, which is responsible for handling eligibility-specific steps such as loading of a specific

PromotionConditioneligibilitySO from the persistence layer, while the EligibilityLoader takes care about

general registration. The eligibility loader fragment is defined in the generic

interface EligibilityLoaderFragment (com.gk_software.pricing_engine.api.eligibility.EligibilityLoaderFragment <E extends

PromotionConditionEligibilitySO>) with extension context EligibilityType

(com.gk_software.pricing_engine.model.typecodes.promotion.EligibilityType).

GETTING READY

Page 132: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

132

For loading custom eligibilities, the following steps must be taken:

• Add custom implementation of the EligibilityLoader interface. This step is only necessary if the

registration process of the eligibility differs from the one implemented as the default

eligibility loader in the PCE core implementation.

• Add custom, eligibility-specific implementation of the EligibilityLoaderFragment interface.

• Implement supports method for both in a way that the plugin is only used in the desired

context (EligibilityType).

• Mark both plugins with @Order annotation in case the order of execution is important. As the

execution is done using the Strategy extension pattern, in both cases all supported plugins

will be executed.

• Add beans to the Spring application context for the custom implementations of the

EligibilityLoader and EligibilityLoaderFragment.

HOW IT WORKS

All implementations for the EligibilityLoader that are registered in the Spring application context are

executed after PCE request processing was done.

The plugins are executed by the executeEligibilityLoader method in the PricingEngineImpl

(com.gk_software.pricing_engine.core.engine.PricingEngineImpl). Execution is done by using the

Strategy extension pattern, which means all implementing classes for the plugin will be called and

the ones that are designed to take action will execute the corresponding logic.

The eligibility loader processes and registers eligibilities in the following way. The process is

executed for each supported eligibility type. New EligibilityLoader implementations may extend this

functionality.

• Loads eligibilities from the data access layer based on information saved to the Context on

transaction analysis. In case of the PCE default eligibility loader, the type-specific operation is

performed by the registered EligibilityLoaderFragment plugins.

• EligibilityWrapper object is created and initialized for each loaded eligibility.

• In case of item related eligibilities the item buckets related to the eligibility and the working

buckets for sales and returns are filled. In case of the PCE default eligibility loader, the type-

specific operation is performed by the registered EligibilityItemLoader plugins.

• The eligibility and the parent eligibilities (if there is any) are registered to the context. The

eligibility type-specific registration is handled by the EligibilityLoaderFragment plugins in case of

the PCE default eligibility loader.

• In case of threshold eligibilities, the default threshold type-specific validations are performed.

• The eligibility status is set. In case of Active status, the activation is performed on the

eligibility and the parent eligibilities, if there are any.

The eligibility loader fragments are responsible for loading a specific type of eligibility from the

persistence layer, registering it to the type-specific collections in the context. The eligibility item

Page 133: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

133

loaders are responsible for getting the items related to the eligibility when loading the

EligibilityWrapper buckets.

THERE IS MORE

The following PCE core implementations are provided for the EligibilityLoader plugin:

Plugin Supports criteria

Plugin order

Description

DefaultEligibilityLoader All eligibility type codes

1000 Default eligibility loader. Implementation for common eligibility registration process. As most eligibilities require the same registrations steps, it may not be necessary to add a custom implementation for the EligibilityLoader interface. The default loader may be used with a custom EligibilityLoaderFragment plugin.

ManualTriggerEligibilityLoader Eligibility type code "MANU"

2000 Manual trigger eligibility-specific eligibility loader, since the registration of manual trigger-related eligibilities differs from all other supported eligibilities.

The following PCE core implementations are provided for the EligibilityLoaderFragment plugin:

Plugin Supports criteria

Plugin order

Description

CouponEligibilityLoader Eligibility type code "COUP "

1000 It tries to find coupon eligibilities for coupon data collected from the transaction and implements type specific handling.

CustomerGroupEligibilityLoader Eligibility type code "CGRP "

2000 It tries to find customer group promotion condition eligibilities for customer group data collected from the transaction and implements type specific handling.

ItemEligibilityLoader Eligibility type code "ITEM "

3000 It tries to find item eligibilities for item data collected from the transaction and implements type specific handling.

MarketBasketAmountEligibilityLoader Eligibility type code "TOTL "

4000 It tries to find market basket amount eligibilities based on the information available in the transaction and implements type specific handling .

MerchandiseGroupEligibilityLoader Eligibility type code "MSTR "

5000 It tries to find mhg eligibilities for merchandise hierarch group data collected from the transaction and resulting from the analysis of the transaction and implements type specific handling.

MerchandiseSetEligibilityLoader Eligibility type code "MSET "

6000 It tries to find merchandise set eligibilities for item data collected from the transaction and implements type specific handling.

AdditionalPriceTypeEligibilityLoader Eligibility type code "APRT "

7000 Eligibility loader fragment for additional price type code eligibilities.

Page 134: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

134

Plugin Supports criteria

Plugin order

Description

ManufacturerCouponEligibilityLoader Eligibility type code "MACP"

8000 I mplements type specific handling for manufacturer coupon related eligibilities.

AdhocEligibilityLoader All eligibility types are supported

10000 It tries to find all eligibilities that are part of previously loaded ad hoc promotions. The AdhocEligibilityLoader has a list of eligibility type-specific delegate fragments registered that contain all available eligibility loader fragments. The delegates perform the actual type-specific handling of these ad hoc eligibilities, but the ad hoc eligibility-specific processing is implemented in this plugin.

The following PCE core implementations are provided for the EligibilityItemLoader plugin:

Plugin Supports criteria Plugin order

Description

ItemEligibilityItemLoader Eligibility type code "ITEM "

1000 Responsible for loading eligible items for item eligibilities.

MerchandiseGroupEligibilityItemLoader Eligibility type code "MSTR "

2000 Responsible for loading eligible items for mhg eligibilities.

MerchandiseSetEligibilityItemLoader Eligibility type code "MSET "

3000 Responsible for loading eligible items for merchandise set eligibilities.

7.2.2.2 Add validation checks on eligibilities

By adding plugin implementations for the extension point EligibilityValidator, it is possible to extend the

eligibility activation process with any custom requirements. The PCE EligibilityValidator extension

point has the EligibilityWrapper (com.gk_software.pricing_engine.api.eligibility.EligibilityWrapper) class as its

supports context, which makes eligibility type or any other eligibility attribute-specific validation

possible.

The EligibilityValidator is defined in the

interface EligibilityValidator (com.gk_software.pricing_engine.api.eligibility.EligibilityValidator).

GETTING READY

For adding custom eligibility validators, the following steps must be taken:

• Add custom implementation of the EligibilityValidator interface.

• Implement supports method in a way that the plugin is only used in the desired context

(EligibilityWrapper).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the

EligibilityValidator.

HOW IT WORKS

Page 135: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

135

The validation of loaded eligibilities is a step of the eligibility loading process implemented by the

EligibilityLoader plugins. The eligibility validators registered to the Spring application context are

executed using the Filter Chain extension pattern, which means only eligibilities that are deemed

valid by all registered plugins may be activated and registered to the context.

The validation is performed by the validateEligibility method of the core PCE implementation of

the EligibilityRegistry interface (com.gk_software.pricing_engine.api.eligibility.EligibilityRegistry).

THERE IS MORE

The following PCE core implementations are provided for the EligibilityValidator plugin:

Plugin Supports criteria

Plugin order

Description

EligibilityExpirationValidator Supports all eligibilities

1000 Validates whether the time validation method is set to eligibilities, and if yes then checks the validity of the eligibility.

EligibilityStatusValidator Supports all eligibilities

2000 Validates whether the eligibility's status is active.

MarketBasketAmountEligibilityValidator Supports market basket amount eligibilities

3000 Checks whether the total basket amount in the transaction reaches the threshold amount defined by the eligibility.

AdhocEligibilityFulfillmentValidator Supports ad hoc eligibilities only

4000 Validates that the loaded ad hoc promotion-related eligibility is fulfilled by the current transaction or not.

AdditionalPriceTypeEligibilityValidator Supports additional price type eligibilities only

5000 Validates if the additional price type eligibility matches the specified restriction of not being part of a combination eligibility.

ThresholdEligibilityValidator Supports all threshold related eligibilities

6000 Checks validation criteria for threshold eligibilities. Checks the interval quantity/amount of the given threshold eligibility against zero.

CouponEligibilityValidator Supports coupon eligibilities

7000 Validates whether loaded coupon eligibility's consumption type code is supported by the PCE or not. PCE does not support CouponConsumptionCodeEnum CONSUME_PER_DIFFERENT_ITEM.

7.2.2.3 Customize threshold check logic

The eligibility activation process checks each threshold type eligibility for a threshold type-specific

acceptance criteria before performing the activation. For example, in case of quantity-related

threshold types it is checked whether the threshold quantity defined in the master data has been

Page 136: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

136

reached and that the threshold quantity is not greater than the limit quantity. The status is set based

on the result.

The PCE ThresholdActivationCheck extension point has

the ThresholdType (com.gk_software.pricing_engine.model.typecodes.promotion.ThresholdType) class as

its supports context.

The ThresholdActivationCheck is defined in the

interface ThresholdActivationCheck (com.gk_software.pricing_engine.api.eligibility.ThresholdActivationCheck).

GETTING READY

For adding custom threshold activation check plugins, the following steps must be taken:

• Add custom implementation of the ThresholdActivationCheck interface.

• Implement supports method in a way that the plugin is only used in the desired context

(ThresholdType).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of

the ThresholdActivationCheck.

HOW IT WORKS

The threshold activation checks are performed on already registered eligibilities as part of the

eligibility loading process. The checks are performed by the ThresholdEligibilityProcessorImpl, the PCE

core implementation for the ThresholdEligibilityProcessor interface

(com.gk_software.pricing_engine.common.eligibility.ThresholdEligibilityProcessor). The threshold activation check

plugins registered to the Spring application context are executed using the Chain of

Responsibility extension pattern, which means that the first one that supports the defined context

will be used to execute the logic. Thus, it is of great importance to define the order of registered

plugins with the use of the @Order annotation.

THERE IS MORE

The following PCE core implementations are provided for the ThresholdActivationCheck plugin:

Plugin Supports criteria Plugin order

Description

ThresholdActivationCheckQUT Threshold types "QUT" and "QUTI"

1000 Threshold check for eligibilities with quantity-related threshold type.

ThresholdActivatonCheckAMT Threshold types "AMT" and "AMTI"

2000 Threshold check for eligibilities with amount-related threshold type.

ThresholdActivationCheckCOMB Threshold type "COMB" 3000 Threshold check for ItemOr eligibilities (Simple Product Group).

Page 137: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

137

Plugin Supports criteria Plugin order

Description

ThresholdActivatonCheckAMQU Threshold type "AMQU" 4000 Threshold check for eligibilities with quantity-amount related threshold type.

7.2.2.4 Add additional eligibility-specific information to promotion calculation

The PCE promotion calculation process requires some additional eligibility-related information

besides what is registered to the context. For each applied condition, the information about the

number of used eligibilities and type-specific lists of those must be available in the partial result. To

provide this data, the so-called eligibility result parsers are executed as part of the initialization of

each partial result.

The PCE EligibilityResultParser extension point has

the EligibilityWrapper (com.gk_software.pricing_engine.api.eligibility.EligibilityWrapper) class as its supports

context.

The eligibility result parser is defined in the

interface EligibilityResultParser (com.gk_software.pricing_engine.api.eligibility.EligibilityResultParser).

GETTING READY

For adding custom eligibility parsers, the following steps must be taken.

• Add custom implementation of the EligibilityResultParser interface.

• Implement supports method in a way that the plugin is only used in the desired context

(EligibilityWrapper).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of

the EligibilityResultParser.

HOW IT WORKS

The eligibility result parsers are registered through the Spring application context to

the EligibilityServiceImpl, the PCE core implementation for the EligibilityService interface

(com.gk_software.pricing_engine.common.eligibility.EligibilityService), by which they are executed. The eligibility

parsing is executed during the initialization of the partial result created for each condition

calculation. The Strategy extension pattern is used for the plugin execution. Thus, all registered

plugins that are supported in the given context will be executed.

THERE IS MORE

The following PCE core implementations are provided for the EligibilityResultParser plugin:

Page 138: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

138

Plugin Supports criteria Plugin order

Description

ItemEligibilityParser Eligibilities with type code "ITEM".

1000 Parser for item eligibilities.

MhgEligibilityParser Eligibilities with type code "MSTR".

2000 Parser for merchandise hierarchy group eligibilities.

CombinationEligibilityParser Eligibilities with type code "COMB".

3000 Parser for combination eligibilities.

CouponEligibilityParser Eligibilities with type code "COUP".

4000 Parser for coupon eligibilities.

TotalEligibilityParser Eligibilities with type code "TOTL".

5000 Parser for market basket amount eligibilities.

MerchandiseSetEligibilityParser Eligibilities with type code "MSET".

6000 Parser for merchandise set eligibilities.

ManufacturerCouponEligibilityParser Eligibilities with type code "MACP".

7000 Parser for manufacturer coupon eligibilities.

7.2.2.5 Sort normalized line items for eligibilities and matching items

By adding plugin implementations for the extension point EligibilityMatchingItemBucketSorter, it is

possible to extend the item selection process for triggering eligibilities and matching items. The

PCE EligibilityMatchingItemBucketSorter extension point has the PartialResultBase

(com.gk_software.pricing_engine.api.result.PartialResultBase) interface as its support context, which makes

validation possible based on any attribute of the objects extending the PartialResultBase interface.

The EligibilityMatchingItemBucketSorter is defined in the package com.gk_software.pricing_engine.api.eligibility

and the default implementation class for it is the

com.gk_software.pricing_engine.core.eligibility.DefaultEligibilityMatchingItemBucketSorter class. This default

implementation class has the responsibility of sorting the normalized line items just before the

decision of triggering of eligibilities in such a way that allows maximum number of eligibilities to be

triggered. It is also used in the same way in the decision of satisfaction of matching items in order to

satisfy as many matching items as possible.

GETTING READY

For adding custom eligibility matching item bucket sorters, the following steps must be taken:

• Add custom implementation of the EligibilityMatchingItemBucketSorter interface.

• Implement supports() method in a way that the plugin is only used in the desired context

(PartialResultBase).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the

EligibilityMatchingItemBucketSorter.

Page 139: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

139

HOW IT WORKS

The EligibilityMatchingItemBucketSorter interface has methods to facilitate the sorting of normalized line

items in a stateful manner. The registerItemBucket() method of the interface is used to add a bucket of

normalized line items to the list of items to be sorted and relate these items with an eligibility or

matching item id. The unregisterTriggeredEntity() method of the interface is used to remove the relation

of the given normalized line items with the given eligibility or matching item id (triggered entity in

this scope represents an eligibliity or matching item). The sortItemBucket() method of the interface is

used to sort the given normalized line items according to the number of relations of them with the

eligibilities or matching items. The addItemComparator() method of the interface is used to add

secondary comparators for sorting normalized line items. The clearBucketSorter() method of the

interface is used to clear the internal data structures.

THERE IS MORE

The following PCE core implementations are provided for the EligibilityMatchingItemBucketSorter plugin:

Plugin Supports criteria

Plugin order

Description

DefaultEligibilityMatchingItemBucketSorter Supports all partial result bases

1000 Sorts the working item bucket of eligibilities and matching items in order to provide for triggering of maximum of them by the current transaction.

7.2.2.6 Map the unit of measure code of items for manufacturer coupon eligibility and rule

processing

Manufacturer coupon related promotions can be defined on piece items with unit of measure code

"PCE" or weight items with unit of measure code "KG" or "LBS". The unit of measure code

maintained by the retailer for pieces, kilograms and pounds may differ from these values provided in

the promotion. To ensure that qualifying items are found in the transaction in that case as well and

that the discount defined by the manufacturer coupon is granted a UOM code mapper extension

point was introduced.

The PCE UOM code mapper extension point has

the Context (com.gk_software.pricing_engine.api.context.Context) class as its supports context. and it

is defined in the interface UomCodeMapper (com.gk_software.pricing_engine.api.mapper .UomCodeMapper).

GETTING READY

For adding custom unit of measure code mappers, the following steps must be taken:

• Add custom implementation of the UomCodeMapper interface.

• Implement supports() method in a way that the plugin is only used in the desired context.

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the

UomCodeMapper.

Page 140: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

140

HOW IT WORKS

The UOM code mapper plugins are registered through the Spring application context to

the ManufacturerCouponServiceImpl , the PCE core implementation for the ManufacturerCouponService

interface (com.gk_software.pricing_engine.common.services .ManufacturerCouponService), by which they are

executed. The uom code mapping is executed when items are retrieved for manufacturer coupon

related eligibilities and matching items, so the UOM codes in the promotions are mapped to the

internal format. The Chain of Responsibility extension pattern is used for the plugin execution. Thus

the first supported plugin will perform the UOM code mapping.

THERE IS MORE

The following PCE core implementations are provided for the UomCodeMapper extension point:

Plugin Supports criteria

Plugin order

Description

DefaultUomCodeMapper Supports all non null PCE contexts

1000 Default UOM code mapper. No conversion is implemented, the external uom code is returned as is. Therefor the following item unit of measure codes can receive the manufacturer coupon related promotion:

• Piece items with uomCode = "PCE"

• Weight items in kilogram with uomCode = "KG"

• Weight items in pounds with uomCode = "LBS"

7.2.2.7 Combination eligibility activator

By adding plugin implementations for CombinationEligibilityActivator,its possible to implement the

combiantion eligibility activation logic for a new combination eligibility type with custom

combinationType to fulfill the custom requirements.

The PCE CombinationEligibilityActivator extension point

has CombinationCode(com.gk_software.pricing_engine.model.typecodes.promotion.CombinationCode) class as its

supports context, which makes eligibility type validation possible.

The combination eligibility activator is defined in the CombinationEligibilityActivator

(com.gk_software.pricing_engine.api.eligibility.CombinationEligibilityActivator) extension point interface.

GETTING READY

For adding custom combination eligibility activator, the following steps must be taken:

• Add custom implementation of the CombinationEligibilityActivator interface.

• Implement supports() method in a way that the plugin is only used in the desired context

(CombinationCode).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of

the CombinationEligibilityActivator.

Page 141: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

141

HOW IT WORKS

The activation of combination eligibility is a step of the eligibility activation process implemented by

the EligibilityActivatorImpl. First there is loaded correct CombinationEligibilityActivator implementation based

on CombinationCode and @Order annotation of current eligibility. Then validateCombinationEligibility method

is called to check whether the eligibility is valid for activation and if

yes, canCombinationEligibilityBeActivated method is called which check conditions which needs to be

fulfilled to activate eligibility.

THERE IS MORE

The following PCE core implementations are provided for the CombinationEligibilityActivator plugin:

Plugin Supports criteria Plugin order

Description

CombinationAndEligibilityActivator Supports combination eligibility with combinationType = "AND"

1000 Activates combination eligibility in case that all childs are active

CombinationOrEligibilityActivator Supports combination eligibility with combinationType = "OR" and combinationType="XO"

2000 Activates combination eligibility in case that at least one child is active

7.2.3 Promotion data loading

7.2.3.1 Load conditions

The ConditionLoader component of the PCE is responsible for loading, validating and registering to

the context promotion, promotion condition, and promotion condition rule master data based on

the previously activated eligibilities. In the ConditionLoader the general processing is implemented,

but accessing the data from the appropriate sources is done in the ConditionLoaderFragment plugins

registered to the loader.

The ConditionLoaderFragment extension point with Context (com.gk_software.pricing_engine.api.context .Context)

as supports context is provided by the PCE for retrieving promotion condition data from the

designated source.

The conditionLoaderFragment is defined in the interface ConditionLoaderFragment

(com.gk_software.pricing_engine.api.engine.ConditionLoaderFragment).

GETTING READY

For adding custom rule loaders, the following steps must be taken:

• Add custom implementation of the ConditionLoaderFragment interface.

• Implement supports method in a way that the plugin is only executed in the desired context.

• Mark plugin with @Order annotation for predictable execution.

Page 142: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

142

• Add bean to the Spring application context for the custom implementation of the

ConditionLoaderFragment.

HOW IT WORKS

The plugins are registered to the ConditionLoaderImpl class' conditionLoaderFragments list via

Spring and are executed during the loading of conditions for active eligibilities . Execution is done

by using the Strategy extension pattern, which means all implementing classes for the plugin will be

called and the ones that are designed to take action will execute the corresponding logic.

THERE IS MORE

The following PCE core implementations are provided for the ConditionLoaderFragment plugin:

Plugin Supports criteria

Plugin order

Description

DefaultConditionLoaderFragment Supported in any context

1000 The default condition loader fragment is responsible for loading the required master data from the DAL.

AdhocConditionLoaderFragment Supported in any context

2000 The ad hoc condition loader fragment is responsible for loading promotion data of ad hoc promotions. As ad hoc promotions are stored in the PCE Context, it is retrieved from there.

7.2.3.2 Load additional rule information

As a custom requirement, it might be necessary to introduce a new rule type to the PCE. As a part of

this extension, the condition loader must be prepared for loading the newly

introduced PromotionConditionRuleSO from the persistence layer.

The RuleLoader extension point with RuleType

(com.gk_software.pricing_engine.model.typecodes.promotion.RuleType) as supports context is provided by the

PCE for retrieving type-specific promotion condition rules from the data access layer.

The RuleLoader is defined in the interface RuleLoader (com.gk_software.pricing_engine.api.rules.RuleLoader).

GETTING READY

For adding custom rule loaders, the following steps must be taken:

• Add custom implementation of the RuleLoader interface.

• Implement supports method in a way that the plugin supports just the RuleType of the newly

introduced rule and this way is used only in the desired context.

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the RuleLoader

.

HOW IT WORKS

Page 143: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

143

The type-specific promotion condition rules are loaded during the first step of the condition

calculation: load conditions for active eligibilities. The plugins are executed by

the loadConditionRule method in the ConditionLoaderImpl

(com.gk_software.pricing_engine.core.engine.ConditionLoaderImpl), the core implementation provided by the

PCE for the ConditionLoader interface. Execution is done by using the Chain of

Responsibility extension pattern, which means the first plugin implementation found supporting the

given RuleType will be used to load the promotion master data. Thus, it is crucial to define the order

of registered plugins to ensure the expected behavior.

THERE IS MORE

The following PCE core implementations are provided for the RuleLoader plugin:

Plugin Supports criteria

Plugin order

Description

RebateRuleLoader Rule type is "RB "

1000 Loads rebate promotion condition rules from the data access layer.

MixAndMatchRuleLoader Rule type is "MM "

2000 Loads mix and match rules from the data access layer.

ExternalActionRuleLoader Rule type is "EX "

3000 Loads external action rules from the data access layer.

AdditionalPriceTypeRuleLoader Rule type is "AP "

4000 Loads additional price type rules from the data access layer.

StandardPriceRuleLoader Rule type is null 9000 Loads standard promotion condition rules from the data access layer.

7.2.3.3 Load ad hoc promotions

As a custom requirement it may be necessary to load promotion master data from an external

system during calculation. To do so a custom implementation of the AdhocPromotionLoader

extension point must be added. The plugin's getPromotions method is expected to return the

available ad hoc promotions loaded from the external system and mapped to the PCE internal

model's PromotionSO. The loaded promotions must include the complete set of promotion data

objects in the tree structure. All calls to external systems and required data mapping to the PCE

internal model must be implemented in the plugin.

The AdhocPromotionLoader extension point with Context

(com.gk_software.pricing_engine.api.context.Context) as supports context is provided by the PCE for the

loading of ad hoc promotion data.

The AdhocPromotionLoader is defined in the

interface AdhocPromotionLoader (com.gk_software.pricing_engine.api.engine.AdhocPromotionLoader).

GETTING READY

Page 144: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

144

For adding custom ad hoc promotion loaders, the following steps must be taken:

• Add custom implementation of the AdhocPromotionLoader interface.

• Implement supports method in a way that the plugin is only used in the desired context.

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the

AdhocPromotionLoader.

HOW IT WORKS

Ad hoc promotions are loaded and saved to the PCE context before the eligibility and condition

loaders are executed. The loading of ad hoc is performed by the method loadAdhocPromotions in

class AdhocPromotionHandlerImpl (com.gk_software.pricing_engine.core.engine.AdhocPromotionHandlerImpl), which

is the PCE core implementation for the AdhocPromotionHandler interface

(com.gk_software.pricing_engine.api.engine.AdhocPromotionHandler). Execution is done by using the

Strategy extension pattern, which means all implementing classes for the plugin will be called and

the ones that are designed to take action will execute the corresponding logic.

THERE IS MORE

The following PCE core implementations are provided for the AdhocPromotionLoader plugin:

Plugin Supports criteria Plugin order

Description

ManufacturerCouponAdhocPromotionLoader Supported when manufacturer coupons are found in the transaction

1000 Loads the ad hoc promotions based on the manufacturer coupons found in the transaction. The loader is responsible to retrieve the available manufacturer coupons, parse them to the internal model object ManufacturerCouponSO and map the ad hoc promotions from them.

7.2.4 Condition Calculation

7.2.4.1 Register conditions for processing

All conditions successfully loaded from the data access layer, must be registered to the PCE Context

in order to be further processed and applied. Based on the promotion's configured attributes and

the current transaction it is possible that a successfully loaded promotion condition is not registered

at all, or that is is registered once or multiple times in the Context. The condition loading process is

further explained in the Promotion Calculation chapter.

The ConditionRegistry extension point with Context (com.gk_software.pricing_engine.core.engine. Context)

as supports context is provided by the PCE for condition registering.

The ConditionRegistry is defined in the interface ConditionRegistry

(com.gk_software.pricing_engine.api.engine.ConditionRegistry).

Page 145: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

145

GETTING READY

For adding custom condition registry, the following steps must be taken:

• Add custom implementation of the ConditionRegistry interface.

• Implement supports method in a way that the plugin is only used in the desired context

(Context).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the

ConditionRegistry.

HOW IT WORKS

The condition validation is performed by the class ConditionLoaderImpl

(com.gk_software.pricing_engine.core.engine.ConditionLoaderImpl), which is the PCE core implementation for

the ConditionLoader interface. The condition is after all parts of the promotion have been successfully

loaded. The ConditionRegistry plugins registered to the application context are executed using the

Chain of Responsibility extension pattern. This means that the first supported ConditionRegistry found

will execute its corresponding logic.

THERE IS MORE

The following PCE core implementations are provided for the ConditionRegistry plugin:

Plugin Supports criteria

Plugin order

Description

SalesVsReturnsConditionRegistry Supports all 1000 Registers conditions according to the parameters specific to the sales vs returns context.

7.2.4.2 Validate a condition before processing

Before processing any conditions loaded from the data access layer, it is necessary to validate the

retrieved promotion data before the PCE processing can be started. If a condition is found invalid,

the calculation of the condition is aborted and the corresponding partial result's status is set to

invalid.

The ConditionValidator extension point with PromotionConditionWrapper

(com.gk_software.pricing_engine.api.rules.PromotionConditionWrapper) as supports context is provided by the

PCE for performing such validations.

The ConditionValidator is defined in the

interface ConditionValidator (com.gk_software.pricing_engine.api.calculation.ConditionValidator).

GETTING READY

For adding custom condition validators, the following steps must be taken:

Page 146: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

146

• Add custom implementation of the ConditionValidator interface.

• Implement supports method in a way that the plugin is only used in the desired context

(PromotionConditionWrapper).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the

ConditionValidator.

HOW IT WORKS

The condition validation is performed by the method isConditionValid in class PartialResultCalculatorImpl

(com.gk_software.pricing_engine.core.engine.PartialResultCalculatorImpl), which is the PCE core implementation

for the PartialResultCalculator interface (com.gk_software.pricing_engine.common.result.PartialResultCalculator).

The condition is validated right after the partial result was initialized, prohibiting any further

calculation efforts in case of invalid conditions. The validation is performed in case of position- and

transaction-related conditions as well. The execution is based on the Filter Chain extension pattern,

which means all registered plugins that can be applied in the given context must deem the

condition valid.

THERE IS MORE

The following PCE core implementations are provided for the ConditionValidator plugin:

Plugin Supports criteria

Plugin order

Description

ConditionSequenceAllowedValidator Supports all conditions

1000 Verifies whether the given condition can be applied by checking the external promotions and the maximum applicable sequence.

ExclusivePromotionCombinationValidator Supports transaction-related conditions only

2000 Verifies whether the combination with any available exclusive promotion is valid.

SimpleDiscountRuleConditionValidator Supports all conditions with simple rules

3000 Validates whether a given condition with simple rule (rules with type code "RB ") can be applied or not.

ConditionTimeRestrictionValidator Supports all conditions

4000 Validates the given condition according to the defined time restrictions. The time restrictions are defined by a list of cron expressions. The validator is responsible for interpreting these expressions and checking if the current transaction timestamp satisfies them or not.

MixAndMatchConditionAllowedValidator Supports all conditions

5000 Validates whether the Mix&Match rule is allowed for the given promotion price derivation rule.

Page 147: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

147

Plugin Supports criteria

Plugin order

Description

AdditionalPriceTypeConditionAllowedValidator Supports all conditions

6000 Validates whether the Additional Price Type rule is allowed for the given promotion price derivation rule. If the rule type is not AP, then true is returned. Additional Price Type rules are only allowed for position-related promotions with conditions with discount method 00.

CalculationSchemeConditionValidator Supports all conditions

7000 Validates the loaded and activated promotion price derivation rules based on the calculation scheme specific to the currently processed request and the rule's transaction control break code.

PackageLimitQuantityConditionValidator Supports all conditions

8000 Validates a condition by checking the package limit quantity value of the corresponding promotion condition rule.

7.2.4.3 Filter valid normalized items for condition before processing

It might be necessary to filter out normalized items from the working bucket of the condition

calculation based on custom flags or any other requirements. The RebatableItemFilterPlugin extension

point provides an interface for such filter implementations. The RebatableItemFilterPlugin is defined in

the interface RebatableItemFilterPlugin (com.gk_software.pricing_engine.api.filter.plugin.RebatableItemFilterPlugin)

with the supports context PromotionConditionWrapper

(com.gk_software.pricing_engine.api.rules.PromotionConditionWrapper).

GETTING READY

For adding RebatableItemFilterPlugins, the following steps must be taken:

• Add custom implementation of the RebatableItemFilterPlugin interface.

• Implement supports method in a way that the plugin is only used in the desired context

(PromotionConditionWrapper).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the

RebatableItemFilterPlugin.

HOW IT WORKS

The working bucket of eligible normalized items is filtered for each condition as the PartialResult

created for the calculation is initialized. The filtering is performed for both position- and transaction-

related PartialResults and only RebatableItemFilterPlugins supported in the current context will be

executed. The plugin execution follows the Filter Chain extension pattern, which means all filter

plugins registered to the Spring application context which are supported must accept a given

normalized item to be considered in the calculation.

THERE IS MORE

Page 148: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

148

Plugin Supports criteria Plugin order

Description

SaleReturnTypeItemFilter Supports all promotion condition wrappers

1000 Determines if a given normalized item can be used for applying the condition, based on the conditionWrappers's eligibility activation type statuses.

CustomerSpecificPricedItemFilter Supports all promotion condition wrappers

2000 Determines if a given normalized item can be used for applying the condition. Customer specific prices may not overwrite manually entered, position related prices.

PackageMeasuredEligibleItemFilter Supports not Mix&Match type rules, which define a package limit quantity

3000 Filters eligible items based on whether they are piece item or measured item.

7.2.4.4 Validate exclusive condition check handling

It is possible to overwrite the default handling of exclusive conditions provided by the PCE core

implementation. An implementation of the ExclusiveCheckHandler extension point should perform all

related checks: whether a condition is defined as exclusive and whether an exclusive condition can

be applied in the given context for both position- and transaction-related calculation.

The ExclusiveCheckHandler extension point

with PromotionConditionSO (com.gk_software.pricing_engine.model.md.promotion.PromotionConditionSO) as

supports context is defined in the

interface ExclusiveCheckHandler (com.gk_software.pricing_engine.api.calculation.ExclusiveCheckHandler).

GETTING READY

For adding custom exclusive check handlers, the following steps must be taken:

• Add custom implementation of the ExclusiveCheckHandler interface.

• Implement supports method in a way that the plugin is only used in the desired context

(PromotionConditionSO).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of

the EligibilityRuleHandler.

HOW IT WORKS

The ExclusiveCheckHandler plugins registered to the application context are executed using the Chain

of Responsibility pattern, meaning that the first supported plugin found will be used for checking

exclusivity.

THERE IS MORE

The following PCE core implementations are provided for the ExclusiveCheckHandler plugin:

Page 149: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

149

Plugin Supports criteria Plugin order Description

DefaultExclusiveCheckHandler Supports all promotion conditions 1000 Default exclusive check handler.

7.2.4.5 Process intervals on custom threshold eligibilities

The EligibilityRuleHandler extension point provides an interface for plugins that handle the execution of

rules in regard of item-related threshold type eligibilities. It takes care of processing interval

calculation and handles the thresholds and limits defined in the promotion data. The

implementation for the plugin always relates to a specific promotion condition eligibility, as it uses

the eligibility type-specific information saved to the partial result during eligibility parsing. The

implementation of this extension point is required if the PCE is extended with a new threshold type

eligibility.

HOW IT WORKS

The EligibilityRuleHandler extension point with PartialResult

(com.gk_software.pricing_engine.api.result.PartialResult ) as supports context is defined in the

interface EligibilityRuleHandler (com.gk_software.pricing_engine.api.rules.EligibilityRuleHandler).

The EligibilityRuleHandler is implemented in the DefaultEligibilityRuleHandler. The

DefaultEligibilityRuleHandler is responsible for handling all common logic to be applied to a position or

transaction-related rules for simple and interval eligibilities. Eligibility type-specific logic is handled

by eligibility rule handler fragments (com.gk_software.pricing_engine.api.rules.EligibilityRuleHandlerFragment).

GETTING READY

For adding custom eligibility rule handlers and eligibility rule handler fragments, the following steps

must be taken:

• Add custom implementation of the EligibilityRuleHandler or the

EligibilityRuleHandlerFragment interface.

• Make sure that the getEligibilityType method returns the type of the supported eligibility.

• Implement supports method in a way that the plugin is only used in the desired context

(PartialResult).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context.

THERE IS MORE

The following PCE core implementations are provided for the EligibilityRuleHandler plugin:

Page 150: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

150

Fragment Supports criteria Order Description

DefaultEligibilityRuleHandler PartialResults that are supported by at least one of the registered eligibility rule handler fragments

1000 The eligibility rule handler fragment is responsible for handling general, non eligibility-specific rule handling

The following PCE core implementations are provided for the EligibilityRuleHandlerFragment plugin:

Fragment Supports criteria Order Description

ItemEligibilityRuleHandlerFragment PartialResults that used eligibility with type "ITEM" in the calculation

1000 The eligibility rule handler fragment is responsible to handler-specific logic related to item eligibilities.

MhgEligibilityRuleHandlerFragment PartialResults that used eligibility with type "MSTR" in the calculation

2000 The eligibility rule handler fragment is responsible to handler-specific logic related to MHG eligibilities.

MerchandiseSetEligibilityRuleHandlerFragment PartialResults that used eligibility with type "MSET" in the calculation

3000 The eligibility rule handler fragment is responsible to handler-specific logic related to merchandise set eligibilities.

CombinationEligibilityRuleHandlerFragment PartialResults that used eligibility with type "COMB" in the calculation

4000 The eligibility rule handler fragment is responsible to handler-specific logic related to combination eligibilities.

ManufacturerCouponEligibilityRuleHandlerFragment PartialResults that used eligibility with type "MACP" in the calculation

5000 The eligibility rule handler fragment is responsible to handler-specific logic related to manufacturer coupon eligibilities.

7.2.4.6 Calculate promotions for new rule types

The CalculationRuleProcessor extension point is available for implementing the rule type-specific

promotion condition rule application to grant discounts. The rule processor plugins must implement

the logic for applying position- and transaction-related rules as well provide further rule type-

specific information that can be used in the calculation.

The CalculationRuleProcessor extension point

with PromotionConditionRuleSO (com.gk_software.pricing_engine.model.md.promotion.PromotionConditionRuleSO) as

supports context is defined in the

interface CalculationRuleProcessor (com.gk_software.pricing_engine.api.rules.CalculationRuleProcessor).

GETTING READY

For adding a calculation rule processor plugin for a new custom rule type, the following steps must

be taken:

• Add custom implementation of the CalculationRuleProcessor interface.

• Implement supports method in a way that the plugin is only used in the desired context, so

that it only supports the new rule type.

Page 151: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

151

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of

the CalculationRuleProcessor interface.

HOW IT WORKS

The CalculationRuleProcessor registered to the application context is executed using the Chain of

Responsibility extension pattern and called from the EligibilityRuleHandler plugin implementation used

for the current calculation. This means that the first CalculationRuleProcessor found supporting the

processed rule will execute its corresponding logic.

THERE IS MORE

The following PCE core implementations are provided for the CalculationRuleProcessor plugin:

Plugin Supports criteria Plugin order

Description

SimpleDiscountCalculationRule Rules with type code "RB "

1000 Calculation rule class for simple discounts rule.

ManualPriceCalculationRule Rules with type code "MA "

2000 Calculation rule class for manual price discounts rule.

MixAndMatchCalculationRule Rules with type code "MM "

3000 Calculation rule class for mix and match discounts rule.

ExternalActionCalculationRule Rules with type code "EX "

4000 Calculation rule class for external discounts rule.

NoDiscountCalculationRule Rules with type code "NO "

5000 Calculation rule class for no discount rule.

AdditionalPriceTypeCalculationRule Rules with type code "AP "

6000 Calculation rule class for additional price type rule.

7.2.4.7 Prorate rebates for new rule types

Newly introduced rule types may require rebate distribution handling to be different from the PCE

default. The RebateDistributionProcessor extension point is available for implementing custom proration

logic.

The RebateDistributionProcessor extension point

with PromotionConditionRuleSO (com.gk_software.pricing_engine.model.md.promotion.PartialResult) as supports

context is defined in the

interface RebateDistributionProcessor (com.gk_software.pricing_engine.api.rules.RebateDistributionProcessor).

GETTING READY

For adding a rebate proration plugin for a new custom rule type, the following steps must be taken:

Page 152: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

152

• Add custom implementation of the RebateDistributionProcessor interface.

• Implement supports method in a way that the plugin is only used in the desired context, so

that it only supports the new rule type.

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of

the RebateDistributionProcessor interface.

HOW IT WORKS

If rebate proration is necessary for transaction-related results or total position-related conditions,

the RebateDistributionProcessors registered to the application context will be executed using the Chain

of Responsibility extension pattern. This means that the first RebateDistributionProcessor found

supporting the processed rule will execute its corresponding logic.

THERE IS MORE

The following PCE core implementations are provided for the RebateDistributionProcessor plugin:

Plugin Supports criteria Plugin order

Description

SimpleDiscountRebateDistributionService Rules with type code "RB"

1000 Distribution service for simple discount rules.

ManualPriceRebateDistributionService Rules with type code "MA"

2000 Distribution service for manual rules.

MixAndMatchRebateDistributionService Rules with type code "MM"

3000 Distribution service for mix and match rules.

ExternalActionRebateDistributionService Rules with type code "EX"

4000 Distribution service for external action rules.

NoDiscountRebateDistributionService Rules with type code "NO"

5000 Distribution service for no discount rebate rules.

AdditionalPriceTypeRebateDistributionService Rules with type code "AP"

6000 Distribution service for additional price rules.

7.2.4.8 Prorate MixAndMatch on a custom item set

The MixAndMatchProrationCustomizer extension point allows customization of the MixAndMatch

Rebate proration. The MixAndMatchProrationCustomizer extension point is defined in the

interface MixAndMatchProrationCustomizer

(com.gk_software.pricing_engine.api.rules.MixAndMatchProrationCustomizer).

GETTING READY

For adding a mix and match proration customizer, the following steps must be taken:

• Add custom implementation of the MixAndMatchProrationCustomizer interface.

Page 153: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

153

• Implement supports method in a way that the plugin is only used in the desired context.

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of

the MixAndMatchProrationCustomizer interface.

HOW IT WORKS

The Chain of Responsibility extension pattern is used to execute the MixAndMatchProrationCustomizer

plugins, which means that the first Customizer registered to the application context that returns true

on supports method will be used. Thus, all proration customizer plugin implementations should be

annotated with Spring @Order annotation to define order of appliance. If no supported customizer is

found, standard proration on the matching item is executed by the default

MixAndMatchProrationCustomizer provided by the PCE core.

THERE IS MORE

The following PCE core implementations are provided for the MixAndMatchProrationCustomizer plugin:

Plugin Supports criteria Plugin order

Description

ManufacturerCouponProrationCustomizer PartialResults with manufacturer coupon related promotion conditions and with matching items with ReductionMethodMixAndMatch = "RS"

1000 MixAndMatch proration customizer to handle total discount amounts for manufacturer coupons. The plugin is only supported for manufacturer coupon related promotions and for mix&match price modification method rebate single. The proration customizer must assign the exact calculated amount for each matching normalized items, except for the last one. The last item's discount amount must be adjusted, so the total awarded amount matches the manufacturer coupon's save value.

7.2.4.9 Apply MixAndMatch rule based on a custom combination type code

The application of MatchingItems of Mix&Match rules is controlled by the rule's combination type

code. The MixAndMatchCombinationTypeProcessor extension point allows implementation for the

handling of custom combination type codes. The MixAndMatchCombinationTypeProcessor

extension point with MixAndMatchCombinationType

(com.gk_software.pricing_engine.model.typecodes.promotion.MixAndMatchCombinationType) as supports context is

defined in the interface MixAndMatchCombinationTypeProcessor (com.gk_software.pricing_engine.api.rules

.MixAndMatchCombinationTypeProcessor).

GETTING READY

Page 154: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

154

For adding a custom MixAndMatch combination type code processor, the following steps must be

taken:

• Extend the MixAndMatchCombinationType interface with the new combination type code enum

value.

• Add custom implementation of the MixAndMatchCombinationTypeProcessor interface.

• Implement supports method in a way that the plugin is only used in the desired context, with

the custom combination type code.

• Mark plugin with @Order annotation for predictable execution, if necessary.

• Add bean to the Spring application context for the custom implementation of the

MixAndMatchCombinationTypeProcessor.

HOW IT WORKS

The MixAndMatch rule calculation is performed by the MixAndMatchRuleCalculatorImpl. The

registered MixAndMatchCombinationTypeProcessor plugins are called during the application of the

rule to perform the combination type code-specific handling. The plugins registered to the Spring

application context are executed using the Chain of Responsibility extension pattern, which means

the order defined for the plugins controls which plugin will be used to execute the corresponding

logic. The first plugin supporting the Mix&Match rule's combination type code will be used.

THERE IS MORE

The following PCE core implementations are provided for the MixAndMatchCombinationTypeProcessor

plugin:

Plugin Supports criteria Plugin order

Description

MixAndMatchCombinationAndProcessor MixAndMatchCombinationType.AND 1000 Responsible for the MixAndMatchCombinationType specific processing of Mix&Match rules for combination type AND.

MixAndMatchCombinationOrProcessor MixAndMatchCombinationType.OR 2000 Responsible for the MixAndMatchCombinationType specific processing of Mix&Match rules for combination type OR.

MixAndMatchCombinationOrQuantityProcessor

MixAndMatchCombinationType.OR_QUANTITY

3000 Responsible for the MixAndMatchCombinationType specific processing of Mix&Match rules for combination type OR_QUANTITY.

Page 155: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

155

Plugin Supports criteria Plugin order

Description

MixAndMatchCombinationExclusiveOrProcessor

MixAndMatchCombinationTypeEnum.XO 4000 Responsible for the MixAndMatchCombinationType specific processing of Mix&Match rules for combination type XO.

This

combination

code is only

allowed to be

used for

manufacturer

coupon related

promotions!

7.2.4.10 Define MixAndMatch discountable transaction matching items

The rule matching items of a Mix&Match rule control which items of the transaction can be

discounted. It might be necessary as a custom solution to define these transaction matching items

by different criteria than the default PCE implementation support. The TransactionMatchingItemLoader

extension point allows implementation for the handling of custom matching item definitions, not

only by item ID, merchandise hierarchy groups or merchandise sets. The Transaction Matching Item

Loader extension point with

MatchingItemSO(com.gk_software.pricing_engine.model.md.promotion.MatchingItemSO) as supports context is

defined in the interface TransactionMatchingItemLoader

(com.gk_software.pricing_engine.api.rules.TransactionMatchingItemLoader).

GETTING READY

For adding a custom Mix&Match transaction matching item loader, the following steps must be

taken:

• Add custom implementation of the TransactionMatchingItemLoader interface.

• Implement supports method in a way that the plugin is only used in the desired context.

• Mark plugin with @Order annotation for predictable execution, if necessary.

• Add bean to the Spring application context for the custom implementation of the

TransactionMatchingItemLoader.

HOW IT WORKS

The Mix&Match rule calculation is performed by the MixAndMatchRuleCalculatorImpl. The

registered TransactionMatchingItemLoader plugins are called during the application of the rule to perform

Page 156: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

156

the transaction matching item look up. The plugins registered to the Spring application context are

executed using the Chain of Responsibility extension pattern, which means the order defined for the

plugins controls which plugin will be used to execute the corresponding logic. The first plugin

supporting the Mix&Match rule's combination type code will be used.

THERE IS MORE

The following PCE core implementations are provided for the MixAndMatchCombinationTypeProcessor

plugin:

Plugin Supports criteria Plugin order

Description

ItemTransactionMatchingItemLoader The matching item defines an item list

1000 Transaction matching item loader for rule matching items which define a specific item.

MhgTransactionMatchingItemLoader The matching item defines a merchandise hierarchy group list

2000 Transaction matching item loader for rule matching items which define a specific merchandise hierarchy group.

MerchandiseSetTransactionMatchingItemLoader The matching item defines a merchandise set

3000 Transaction matching item loader for rule matching items which define a merchandise set.

ManufacturerCouponTransactionMatchingItemLoader The matching item defines a manufacturer related company code and family code

4000 Transaction matching item loader for rule matching items which define a manufacturer coupon.

This implementation is

only used for

manufacturer coupon

related promotions!

7.2.4.11 Introduce new PriceModification codes

As a custom requirement it might be necessary to introduce a new price calculation method for

promotion calculation rules and a new method code for it. Each price modification method

supported by the PCE is implemented as a PriceModification plugin.

The PriceModification extension point with

a PromotionConditionRuleSO (com.gk_software.pricing_engine.model.md.promotion.PromotionConditionRuleSO) as

supports context is defined in the

interface PriceModification (com.gk_software.pricing_engine.api.price_modification.PriceModification).

GETTING READY

For adding a custom price modification method code, the following steps must be taken:

Page 157: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

157

• Extend the PriceModificationMethod interface

(com.gk_software.pricing_engine.model.typecodes.promotion.PriceModificationMethod) with the new

method code enum value.

• Add custom implementation of the PriceModification interface. The

abstract AbstractPriceModification super class with common methods used between price

modification plugins is available in the core PCE implementation and can be utilized by new

plugins.

• Implement supports method in a way that the plugin is only used in the desired context, with

the desired price modification type code (PromotionConditionRuleSO).

• Mark plugin with @Order annotation for predictable execution, if necessary.

• Add bean to the Spring application context for the custom implementation of

the PriceModification.

HOW IT WORKS

The price modification plugin implementations perform the calculation of the actual rebate to be

granted for the applied condition. All price modification plugins must handle both position- and

transaction-related condition calculations as well as monetary rebate and frequent shopper point

calculation. Total rebate and rebate share value calculation should also be handled if supported. The

different price modification modes available for each price modification method code are listed in

the enums PositionPriceModificationMode and TransactionPriceModificationType (defined in

package com.gk_software.pricing_engine.api.price_modification). All of these must be handled by

the plugin implementations. If a price modification mode for position-related calculation or a

transaction price modification type for transaction-related calculation is not supported for the price

modification code, then an UnsupportedOperationException should be thrown.

The price modification plugins registered to the Spring application context are executed using the

Chain of Responsibility mode, which means the first found, supported plugin will execute the

corresponding logic. If multiple implementations are registered for the same price modification

method code, the use of the @Order annotation is crucial for consistent, predictable calculation

results.

THERE IS MORE

The following PCE core implementations are provided for the PriceModification plugin:

Plugin Supports criteria Plugin order

Description

PercentageDiscountPriceModification Rules with price modification method code discount percent ("RP ")

1000 Price modification methods for percentage discounts.

Page 158: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

158

Plugin Supports criteria Plugin order

Description

AbsoluteDiscountPriceModification Rules with price modification method code rebate single ("RS")

2000 Price modification methods for absolute discounts.

NewPricePriceModification Rules with price modification method code fixed price ("PS")

3000 New price modification methods.

NewTotalPricePriceModification Rules with price modification method code fixed price total ("PT ")

4000 Price modification methods for new total price discounts.

TotalAbsoluteDiscountPriceModification Rules with price modification method code discount total ("RT ")

5000 Price modification methods for total absolute discounts.

TotalPercentageDiscountPriceModification Rules with price modification method code discount percent total ("TP ")

6000 Price modification methods for total percentage discounts.

NewSetPricePriceModification Rules with price modification method code set total price ("ST")

7000 New set total modification calculation.

TotalPercentageDiscountRoundedTwicePriceModification Rules with price modification method code discount percent total 2 ("T2 ")

8000 Price modification methods for total percentage discounts.

7.2.4.12 Introduce new calculation limit checks

As a custom requirement it might be necessary to define limitations for the promotion calculation,

may that be a time constraint or a constraint on the number of applied promotions for example.

To implement such custom constraints for the calculation the CalculationLimiter extension point is

available. It is defined in the interface CalculationLimiter (com.gk_software.pricing_engine.api.calculation

.CalculationLimiter) with Context (com.gk_software.pricing_engine.api.context.Context) as supports context .

GETTING READY

For adding a custom calculation limiter, the following steps must be taken:

• Add custom implementation of the CalculationLimiter interface.

• Implement supports method in a way that the plugin is only used in the desired context.

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the

CalculationLimiter.

HOW IT WORKS

Page 159: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

159

The calculaltion limit checks implemented by the CalculationLimiter plugins are executed by the

ConflictHandler (com.gk_software.pricing_engine.api.calculation. ConflictHandler) implementations

to enforce the defined limits during the best price calculation. The plugins registered to the Spring

application context are executed using the Strategy pattern, meaning all which have a supports

method designed to take action will be performed.

THERE IS MORE

The following PCE core implementations are provided for the CalculationLimiter plugin:

Plugin Supports criteria Plugin order

Description

CalculationTimeLimiter Supported if the CalculationTimeLimit configuration parameter is greater than 0.

1000 Time limit-based PCE best price calculation limiter.

7.2.4.13 Trigger Conflict Handler Preprocessors

It might be necessary to preprocess the valid, colliding promotions, before executing the configured

conflict handling strategy. The preprocessing extension can also be used to modify the list of valid

conflicting promotions, for example to create further promotions from the existing colliding ones

and use them as valid promotions during conflict handling.

PCE provides the ConflictHandlerPreprocessor plugin for providing support for preprocessing colliding

partial results. The ConflictHandlerPreprocessor plugins are registered to the PromotionCalculatorImpl class

defined by the PCE.

GETTING READY

For adding a custom conflict handler preprocessor, the following steps must be taken:

• Add custom implementation of the ConflictHandlerPreprocessor interface.

• Implement supports() method in a way that the plugin is only used in the desired context

(Context).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of

the ConflictHandlerPreprocessor.

HOW IT WORKS

The ConflictHandlerPreprocessor plugins registered to the application context are called during the best

price calculation via the PromotionCalculatorImpl class. The supports() method of each conflict handler

preprocessor plugin is checked in order and if this method returns true for a conflict handler

preprocessor plugin, then the preprocessConflictingPartialResults() method of the plugin is called.

THERE IS MORE

Page 160: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

160

The PCE core implementation provides no implementation of the ConflictHandlerPreprocessor plugin

interface. However, all custom plugin implementations added to the Spring application context will

be processed and considered as explained above.

7.2.4.14 Customize best price determination

The best price calculation algorithm is used only in case that the calculation of two or more valid

conditions with the same sequence and resolution dependent on each other have resulted in valid

partial results. In this case, the order of the applied conditions may affect the final total benefit. The

goal of the best price calculation is to always provide the best possible price in case of collisions.

The best price calculator extension points make it possible to use a custom algorithm for finding the

best price.

The BestPriceCalculator extension point with a PartialResult

list (com.gk_software.pricing_engine.api.result.PartialResult) as supports context is defined in the

interface BestPriceCalculator (com.gk_software.pricing_engine.api.calculation.BestPriceCalculator). The plugin

implementations of this extension point determine whether a given PartialResult list provides the

best price or not.

The ConflictHandler extension point with Context (com.gk_software.pricing_engine.api.context.Context ) as

supports context is defined in the interface ConflictHandler (com.gk_software.pricing_engine.api.calculation

.ConflictHandler). The implementations of this extension point resolve possible conflicts between

promotion conditions in case multiple valid partial results are available after calculation.

GETTING READY

For adding a custom best price calculator, the following steps must be taken:

• Add custom implementation of the BestPriceCalculator or the ConflictHandler interface.

• Implement supports method in a way that the plugin is only used in the desired context.

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of

the BestPriceCalculator or the ConflictHandler .

HOW IT WORKS

The best price calculation is performed by the registered BestPriceCalculator plugin as part of the

conflict handling execution of the registered ConflictHandler plugin. The BestPriceCalculator and

ConflictHandler plugins registered to the Spring application context are both executed using the Chain

of Responsibility extension pattern, which means the order defined for the plugins controls which

plugin will be used to execute the corresponding logic.

BruteForceConflictHandler works by trying all possible permutations of the triggered conditions

(PartialResult objects) until the calculation time limit is exceeded, in order to find the permutation of

conditions which results in the best discount. The conditions in each tried permutation are

recalculated. The recalculation of a condition includes checking of the triggering status of its

Page 161: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

161

eligibilities from start according to the line items in the transaction. It is an expensive process. If the

recalculation of a condition is successful according to the rebate status of the line items in the

transaction, the remaining conditions in the currently tried permutation are recalculated one by one

in order. If the recalculations of all of the conditions of a permutation are successful, the

permutation can be a candidate for best price permutation of conditions.

GreedyConflictHandler, on the other hand, first sorts the triggered conditions in descending order

according to the total discount amounts provided by each of them per interval. If the total discount

amounts per interval are the same for any two conditions, then the GreedyConflictHandler prioritizes the

conditions according to whether they have monetary or virtual discounts or bonus points. If all the

factors are equal for both conditions, the conflict handler also checks the number of normalized

items discounted by both conditions per interval and it prioritizes the condition discounting the

higher number of normalized items. After sorting the conditions, the greedy conflict handler fetches

the condition at the head of the list and recalculates it. If the recalculation of the condition is

successful, it sorts the remaining conditions in the same way again (according to the updated rebate

status of the line items) and continues by fetching the condition at the head of the sorted list, until

all the conditions are tried or the calculation limit is exceeded. Therefore, each condition is

recalculated at most once.

BruteForceConflictHandler performs slower and can be easily stuck into the time limit (default time limit

value is 1000ms), even when the number of the triggered conditions and/or line items in the

transaction moderately increase. Since it tries the permutations of conditions without applying any

prioritization among the permutations, when it is stuck by the calculation time limiter, the best result

found and returned by it may be far from the real best (ideal) result. GreedyConflictHandler, on the

other hand, performs much faster than the BruteForceConflictHandler in many real-world scenarios, but

it may produce inaccurate results for some specific scenarios, even when the number of the

triggered conditions and line items in the transaction are small enough. This can be seen as a result

of the greedy sorting applied to the conditions and the lack of backtracking.

THERE IS MORE

The following PCE core implementations are provided for the BestPriceCalculator plugin:

Plugin Supports criteria

Plugin order

Description

DefaultBestPriceCalculator Supported in any context

1000 Default Best Price checking. Checks that the best price is used if the price of a partial calculation is lower than the current best price.

The following PCE core implementations are provided for the ConflictHandler plugin:

Page 162: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

162

Plugin Supports criteria Plugin order

Description

BruteForceConflictHandler ConflictHandlerStrategy is configured as BRUTE_FORCE

1000 Brute force conflict handler for competing partial results during best price calculation which tries all possible combinations of competing partial results.

GreedyConflictHandler ConflictHandlerStrategy is configured as GREEDY

2000 Greedy conflict handler for competing partial results during best price calculation, which applies a greedy approach based on sorting the partial results according to their discount amounts for normalized line items.

7.2.4.15 Add a new validator for discountability of a triggering item

In case it becomes necessary to restrict which triggered items can receive a discount, a new plugin

can be created by extending the interface DiscountableItemValidator and adding it to the context of

the application. More detailed information can be found in the following lines.

PCE provides the DiscountableItemValidator plugin which is responsible to validate whether an item

used for triggering the eligibility can also receive discounts / bonus points or not. Currently the

plugin is executed only for line item-related promotion price derivation rules.

For adding a new discountable item validator plugin, the following steps must be taken:

• Add a custom implementation of the DiscountableItemValidator interface with the desired

restriction.

• Implementation of the supports method in order to execute the plugin in the expected

context.

• Implementation of the isItemDiscountable method which is responsible to check if the item can

receive the discount or not. True as return means that the item can receive a discount.

• Add bean to the Spring application context for the custom implementation of the extension

point.

HOW IT WORKS

Execution is done by using the Strategy extension pattern, which means all implementing classes for

the plugin will be called and the ones that are designed to take action will execute the

corresponding logic.

THERE IS MORE

The PCE core implementation provides on implementation of DiscountableItemValidator, see table

below:

Page 163: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

163

Plugin Supports criteria Plugin order

Description

PackageMeasuredDiscountableItemValidator Supported only for line item-related promotion price derivation rule,

Package limit quantity different from null and greater than zero.

1000 The plugin is responsible to check when the package limit quantity is reached.

7.2.4.16 Threshold eligibility specific rule application

EligibilityRuleValidator validates whether the eligibility is needed for successful rule application. Whether

each eligibility of the condition should be applied successfully or even shouldn't be processed at all

for a successful rule application depends on the combination eligibilities of the condition.

The EligibilityRuleValidator (com.gk_software.pricing_engine.api.rules.EligibilityRuleValidator) extension

point supports EligibilityWrapper (com.gk_software.pricing_engine.api.eligibility.EligibilityWrapper)

GETTING READY

For adding custom eligibility activator, the following steps must be taken:

• Add custom implementation of the EligibilityRuleValidator interface.

• Implement supports() method in a way that the plugin is only used in the desired context

(EligibilityWrapper).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of

the EligibilityRuleValidator

HOW IT WORKS

The rule validation is a step of an rule application implemented by the DefaultEligibilityRuleHandler.

Whether the eligibility is required for a rule application or not is decided by

method isEligibilityRequiredForRuleApplication of an specific implementation of EligibilityRuleValidator in

order defined by @Order annotation. After each calculation the

method validateEligibilityRuleHandlingResult method of an EligibilityRuleValidator is called to check whether

the result of calculation is correct or the result needs to be invalidated.

THERE IS MORE

The following PCE core implementations are provided for the EligibilityRuleValidator plugin:

Plugin Supports criteria Plugin order

Description

DefaultEligibilityRuleValidator supported for AND combination and non parent eligibilities

1000 Supported for eligibilities with no parent eligibility and for eligibilities which have a combination AND parent eligibility.

Page 164: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

164

Plugin Supports criteria Plugin order

Description

CombinationOrEligibilityRuleValidator supported for OR combination eligibilities

2000 Supported for eligibilities which have a combination OR parent eligibility.

CombinationXoEligibilityRuleValidator supported for XO combination eligibilities

3000 Supported for eligibilities which have a combination XO parent eligibility.

7.2.5 Validate the calculation result

7.2.5.1 Validate the result of a calculation

After calculating the partial result for each condition, a validation of the partial result is performed.

The ResultValidator extension point provides a plugin interface for these validators. The partial result is

validated the same way for both position- and transaction-related conditions.

The ResultValidator extension point with a PartialResult (com.gk_software.pricing_engine.api.result.PartialResult)

as supports context is defined in the

interface ResultValidator (com.gk_software.pricing_engine.api.result.ResultValidator).

GETTING READY

For adding a custom result validator, the following steps must be taken:

• Add custom implementation of the ResultValidator interface.

• Implement supports method in a way that the plugin is only used in the desired context

(PartialResult).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of

the ResultValidator.

HOW IT WORKS

The partial result validation is performed by the validatePartialResult method of

the PartialResultCalculatorImpl class, the PCE core implementation of the PartialResultCalculator interface

(com.gk_software.pricing_engine.core.engine.PartialResultCalculatorImpl). The result of each successfully

calculated position- and transaction-related condition is validated. However, this step is not

performed if the partial result was already invalidated during calculation. The result validator plugins

registered to the Spring application context are executed using the Filter Chain extension pattern.

Therefore, the calculated result must be deemed valid by all supported plugins in order for the

condition to be applied.

THERE IS MORE

The following PCE core implementations are provided for the ResultValidator plugin:

Page 165: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

165

Plugin Supports criteria Plugin order

Description

TransactionResultActualPurchaseBaseValidator Only supports TransactionPartialResult

1000 Verifies whether actual purchase base is valid for applying transaction rebate. This method compares the actual purchase base with the market basket threshold amount from all market basket amount eligibilities active for this condition.

PositionResultInfluencedPositionValidator Only supports PositionPartialResult

3000 Verifies whether the position partial result calculation has influenced any of the positions.

TransactionResultInfluencedPositionValidator Only supports TransactionPartialResult

4000 Verifies whether the transaction partial result calculation has influenced any of the positions.

PositionResultConditionAmountValidator Only supports PositionPartialResult

5000 Verifies whether the position partial result's condition value is allowed. The amount of the rebate or the points is allowed if it is greater than zero or if the zero discount is allowed.

TransactionResultConditionAmountValidator Only supports TransactionPartialResult

6000 Verifies whether the transaction partial result's condition value is allowed. The amount of the rebate or the points is allowed if it is greater than zero or if the zero discount is allowed.

PositionResultActualPurchaseBaseValidator Only supports PositionPartialResult

7000 Validates if the current total (sum) of position calculation base amounts reaches the defined threshold amount of all the condition's market basket amount eligibilities, if there is any.

7.2.5.2 Validate applied rebates

It might be necessary to add additional validation for the applied rebate, based on its amount or any

other information available in the PartialResult after successful calculation. The rebate validation is

needed at several points of the calculation: each individual result calculated for a line item must be

validated for line item related promotions as well as the entire calculated rebate amount must be

validated for all conditions.

The RebateValidator, LineItemRebateValidator extension points allow such custom validations. The

extension points are represented by the following interfaces:

• RebateValidator<S extends SummaryResult> (com.gk_software.pricing_engine.api.result.RebateValidator)

• LineItemRebateValidator (com.gk_software.pricing_engine.api.result.LineItemRebateValidator)

• ConditionRebateValidator (com.gk_software.pricing_engine.api.result.ConditionRebateValidator)

Page 166: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

166

All three validator extension points are defined with PartialResult

(com.gk_software.pricing_engine.api.result.PartialResult) as supports context.

GETTING READY

For adding a custom rebate validator, the following steps must be taken:

• Add custom implementation of the RebateValidator, LineItemRebateValidator or the

ConditionRebateValidator interface.

• Implement supports method in a way that the plugin is only used in the desired context

(PartialResult).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom plugin implementation.

HOW IT WORKS

The RebateValidator plugins registered to the application context are called using the Filter Chain

extension pattern after each successful PartialResult calculation, but before the result would have been

saved to the SummaryResult. The calculated rebate can only be applied this way, if it was deemed valid

by all registered rebate validators.

For better extensible validation in PCE version 3.2.3 two new validation extension points were

introduced.

Implementations of the LineItemRebateValidator extension point are responsible for checking the rebate

amount during the calculation of a condition for each single line item. The line item rebate validator

plugins registered to the Spring context are executed by the RebateValidatorServiceImpl's

(com.gk_software.pricing_engine.common.impl.services.RebateValidatorServiceImpl) executeLineItemRebateValidators

method. The calculated amount validation for line items is performed at several points in the

calculation process: after rule calculation for different rule types, during rebate distribution or when

appending the calculated partial result to the summary result. The plugins are executed using the

Filter Chain extension pattern.

Implementations of the ConditionRebateValidator extension point are responsible for checking the total

rebate amount after the calculation of each condition, when the partial result calculation is

successfully completed. It is possible that even though the single line item results were calculated

successfully, the total discount amount can not be applied anyway. The condition rebate validator

plugins registered to the Spring context are executed by the RebateValidatorServiceImpl's

executeConditionRebateValidators method. The plugins are executed using the Filter Chain extension

pattern.

The RebateValidator plugins are executed by the RebateValidatorServiceImpl's executeRebateValidators

method. The validation is performed for each line item when the appending the calculated partial

result to the summary result, similarly to the LineItemRebateValidators. However in all other instances

Page 167: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

167

listed above only the LineItemRebateValidators are executed. While the custom RebateValidator plugins

will work same as before, it is recommended to implement the LineItemRebateValidator interface instead

for better targeted line item rebate validation, or the ConditionRebateValidator for the whole calculation

result.

THERE IS MORE

The PCE core implementation does not provide any RebateValidator plugins. However, all custom

plugin implementations added to the Spring application context will be processed and considered

as explained. It is recommended for custom implementations to utilize the LineItemRebateValidator or

the ConditionRebateValidator extension points instead as well.

The following PCE core implementations are provided for the LineItemRebateValidator plugin:

Plugin Supports criteria Plugin order

Description

ExternalActionRebateValidator PartialResults with external action rules

1000 A rebate Validator that is checking only External Action promotions This makes sure a RetailPriceModifier is added only to items really triggering the promotion.

PriceIncreaseRebateValidator Position related PartialResults

2000 Position-based rebate validator for allowing discounts, which result in price increase. It is used mainly for validating rebate amounts computed during customer-specific prices.

SimpleLineItemRebateValidator Position related PartialResults

3000 Validates whether the calculated discount amount for a given line item is valid or not, taking into consideration possible zero rebates.

The following PCE core implementations are provided for the ConditionRebateValidator plugin:

Plugin Supports criteria Plugin order

Description

SimpleConditionRebateValidator Supported for all PartialResults

1000 Validates whether the total calculated discount amount for a given condition is valid or not, taking into consideration possible zero rebates.

7.2.5.3 Validate the interval result calculation

By adding plugin implementations for IntervalResultValidator,its possible to validate the calculation

result after each completed interval.

The PCE IntervalResultValidator extension point

has PartialResult (com.gk_software.pricing_engine.api.result.PartialResult) class as its supports context, which

makes result validation possible.

The interval result validator is defined in

the IntervalResultValidator (com.gk_software.pricing_engine.api.result.IntervalResultValidator) interface.

GETTING READY

Page 168: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

168

For adding a custom interval result validator, the following steps must be taken:

• Add custom implementation of the IntervalResultValidator interface.

• Implement supports method in a way that the plugin is only used in the desired context

(PartialResult).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom plugin implementation.

HOW IT WORKS

The interval result validation is done after each interval calculations implemented

in CalculatorTransactionPartialService and CalculatorPositionPartialService. For each partialResult the

method isPartialResultValid of implementation of IntervalResultValidator is called in order defined

by @Orderannotation. If validation fails, the result of calculation is invalidated.

THERE IS MORE

Plugin Supports criteria Plugin order

Description

CombinationOrIntervalResultValidator supported for all interval calculations

1000 Validator responsible for validation that all "OR" and "XO" combination eligibilities of promotion price derivation rule have been fulfilled for interval.

7.2.6 Update the transaction

7.2.6.1 Customize Response Values

Sometimes you would like to add additional information to the user by customizing the returned

response. This can be an additional description taken from the database or adding additional

information based on the calculation result. For this purpose, the PCE allows you to customize the

resulting elements created for the response.

For each of these elements a specialization of ResultDtoCustomizer exists that allow modifying the

created elements.

The following elements are created by the PCE in the transaction for the response and the related

customizer interface:

• FrequentShopperPointsModifier: FrequentShopperPointsModifierCustomizer

• LoyaltyRewardLineItem: LoyaltyRewardLineItemCustomizer

• RetailPriceModifier: RetailPriceModifierCustomizer

• PriceModificationLineItem: PriceModificationLineItemCustomizer

• RetailTransactionPromotionPriceDerivationRule:

RetailTransactionPromotionPriceDerivationRuleCustomizer

GETTING READY

Page 169: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

169

For adding a result customizer, the following steps must be taken:

• Add custom implementation of the corresponding ResultDtoCustomizer interface.

• Implement supports method in a way that the plugin is only used in the desired context

(PartialResult).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the

ResultDtoCustomizer .

HOW IT WORKS

The ResultDtoCustomizer plugins registered to the application context are managed by the

ResultCustomizerService bean. They are called using the Strategy extension pattern after a successful

PartialResult calculation, when the result is saved to the SummaryResult. All configured

ResultDtoCustomizer that are matching the given PartialResult context are called to customize the result.

This means they could override each other's values, so be aware when using multiple custom

ResultDtoCustomizers.

Here is an example how to customize the "reasonDescription" property of a RetailPriceModifier based

on some extension field stored in PromotionCondition.

In line 7, we check whether the PromotionCondition related to the PartialResult contains a String attribute

with key "extendedReason". If this is true, then the customize method is called by

the ResultCustomizerService.

In line 13, we set the value from the "extendedReason" attribute to the "reasonDescription" property

of the created RetailPriceModifier.

public class RetailPriceModifierReasonDescriptionCustomizer implements

RetailPriceModifierCustomizer {

private final static String EXTENDED_REASON = "extendedReason";

@Override

public boolean supports(PartialResult<?> partialResult) {

return partialResult.getConditionWrapper().getPromotionCondition().get(EXTENDED_REASON)

instanceof String;

}

@Override

public void customize(Context context, RetailPriceModifier modelObject, PartialResult<?>

partialResult,

LineItemSummaryResult lineItemSummaryResult) {

modelObject.setReasonDescription((String)

partialResult.getConditionWrapper().getPromotionCondition().get(EXTENDED_REASON));

}

}

Page 170: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

170

THERE IS MORE

The PCE core implementation does not provide any ResultDtoCustomizer plugins. However, all custom

plugin implementations added to the Spring application context will be processed and considered

as explained.

7.2.6.2 Update the transaction with the calculated results

The transaction must be updated with the calculated promotions and related values before sending

the response. The TransactionUpdater interface provides an extension point for updating any part of

the transaction.

The TransactionUpdater extension point with the Context

(com.gk_software.pricing_engine.api.context.Context) as supports context is defined in the interface

TransactionUpdater (com.gk_software.pricing_engine.api.transaction .TransactionUpdater).

GETTING READY

For adding a custom transaction updater, the following steps must be taken:

• Add custom implementation of the TransactionUpdater interface.

• Implement supports method in a way that the plugin is only used in the desired context.

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of

the RebateValidator.

HOW IT WORKS

The TransactionUpdater plugins registered to the application context will be are managed by the

PricingEngineImpl class. After the promotion calculation was finished the transaction updater

plugins are executed using the Strategy pattern, meaning all which have a supports method

designed to take action will be performed.

THERE IS MORE

The following PCE core implementations are provided for the TransactionUpdater plugin:

Plugin Supports criteria

Plugin order

Description

PriceDerivationRulesTransactionUpdaterForPosition Always 1000 Response customizer for position that add price derivation rules to line items if apply.

PriceDerivationRulesTransactionUpdaterForTransaction Always 2000 Response customizer for transaction that add price derivation rules to line items if apply.

Page 171: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

171

Plugin Supports criteria

Plugin order

Description

PriceModificationLineItemsTransactionUpdater If at least one transaction-related promotion is applied

3000 Response customizer to that add price modification to line items if apply.

LoyaltyRewardLineItemsTransactionUpdater Supported if at least one transaction-related bonus point promotion was applied

4000 Response customizer that add loyalty reward to line items if apply.

RetailTransactionCouponSummaryTransactionUpdater When at least one coupon was registered

5000 Response customizer updating the RetailTransactionCouponSummary when necessary.

7.2.7 Custom field mapping

7.2.7.1 Mapping from any fields (Transaction Model)

The PCE provides two extension points for mapping the XXCustom[0-15] fields in the GK model

from any fields in the PCE transaction model. By implementing plugins for these extension points, it

is possible to store such custom fields in the PCE internal model and access and use them during

calculation.

The ModelExtractor extension point with TransactionGk

(com.gk_software.pricing_engine.gk.model.transaction.TransactionGk ) as supports context is defined in the

interface GKModelExtractor (com.gk_software.pricing_engine.gk.model.plugin.GKModelExtractor ). It is responsible

for mapping the any fields to XXCustom[0-15] fields.

GETTING READY

For adding a new custom field mapper plugin, the following steps must be taken:

• Add custom implementation of the corresponding GKModelExtractor interface for

implementing the correct mapping from any fields to the XXCustom fields.

• Implement supports method in a way that the plugin is only used in the desired context

(TransactionGk).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the extension

point.

HOW IT WORKS

Execution is done by using the Strategy extension pattern, which means all implementing classes for

the plugin will be called and the ones that are designed to take action will execute the

corresponding logic.

Page 172: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

172

THERE IS MORE

The PCE core implementation does not provide any GKModelExtractor plugin implementations. A

GKModelExtractorImpl plugin example implementation can be found in the appendix.

7.2.7.2 Mapping to any fields (Transaction Model)

The PCE provides two extension points for mapping the XXCustom[0-15] fields in the GK transaction

model to any fields in the PCE transaction model. By implementing plugins for these extension

points, it is possible to provide custom values in the response.

The GKModelAdapter extension point with

TransactionGk (com.gk_software.pricing_engine.gk.model.transaction.TransactionGk ) as supports context is

defined in the interface GKModelAdapter (com.gk_software.pricing_engine.gk.model.plugin.GKModelAdapter ). It

is responsible for mapping the custom values in the opposite direction: the GK XXCustom[0-15]

fields into any fields.

GETTING READY

For adding a new custom field mapper plugin, the following steps must be taken:

• Add custom implementation of the corresponding GKModelAdapter interface for implementing

the correct mapping from the XXCustom fields to any fields.

• Implement supports method in a way that the plugin is only used in the desired context

(TransactionGk).

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the extension

point.

HOW IT WORKS

Execution is done by using the Strategy extension pattern, which means all implementing classes for

the plugin will be called and the ones that are designed to take action will execute the

corresponding logic.

THERE IS MORE

The PCE core implementation does not provide any GKModelAdapter plugin implementations. A

GKModelAdapterImpl plugin example implementation can be found in the appendix.

7.2.7.3 Mapping to any fields in Data Access Layer (DAL) level

It is also possible to perform a similar mapping in the DAL. PCE provide for this case an extension

point GKDataAccessModelAdapter. The generic data access model adapter is responsible to

aggregate the extension maps from the origin T to the extension map of target S.

GETTING READY

Page 173: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

173

For adding a new DAL custom field mapper plugin, the following steps must be taken:

• Add a custom implementation of the corresponding GKDataAccessModelAdapter interface

for implementing the desired mapping from XXCustom fields to any fields.

• Implements support method in a way that the plugin is only used in the desired context.

• Mark plugin with @Order annotation for predictable execution.

• Add bean to the Spring application context for the custom implementation of the extension

point.

HOW IT WORKS

Execution is done by using the Strategy extension pattern, which means all implementing classes for

the plugin will be called and the ones that are designed to take action will execute the

corresponding logic. THERE IS MORE The PCE core implementation does not provide

any GKDataAccessModelAdapter plugin implementations. A GKDataAccessPromotionModelAdapterImpl

plugin example implementation can be found in the appendix.

7.3 Custom Extension Samples

The PCE standard delivery includes a lot of commonly used features. However custom

enhancements might be requested, e.g. making customer specific promotions available or

performing custom validation checks. This chapter describes through concrete examples how such a

customer specific feature could be implemented using the Extension Concept provided by the PCE.

Disclaimer

The code samples provided with the SDK are intended to be a starting point for writing a

project specific extension - nothing more! Use at own risk.

Though inspired by real world project requirements or features of the Loyalty Engine and

basically running (actually some examples where implemented to be used in production), full

functionality described in this chapter or elsewhere is not necessarily covered by the code

samples, and not ensured by product development. The samples are not part of PCE product

and are not covered with any test cases, so in case functionality does not completely reflect

documentation or is buggy, product development is not responsible to "fix" it.

7.3.1 Plugin implementation of the PCE part

In the scope of the plugin-based extension of the PCE part, a specific plugin is implemented for each

logical step of the transaction processing according to the corresponding eligibilities and rules.

Different plugins are implemented for different types of promotions. As an example of plugins for a

specific promotion type, one of the implemented plugins realizes the transaction analyzer logic, the

other one handles the loading of the related eligibilities and their registration into the plugin

Page 174: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

174

context. Another one handles the processing of the rules and calculation of the rebate according to

these rules.

The implemented plugins for each type of promotion can share a number of specific contexts which

are called plugin contexts. A plugin context holds the transaction-related data specific to the

corresponding type of promotion. This data can include the normalized line items created for

internal processing by using the retail transaction line items, and the simple and interval eligibilities

which are activated for the transaction. The plugin registry context of the application context stores

the plugin contexts for different types of promotions.

The implementation of the brand promotion processing is integrated into the PCE based on the

introduced plugin concept. In order to avoid unnecessary coupling of implementation classes and

hierarchies, the development of this plugin has focused on the PCE API level interfaces. Thus, each

exposed class/interface implements or extends a related PCE API interface when necessary. For

instance, the brand promotion eligibility is modeled by the

BrandPromotionPriceDerivationRuleEligibilitySO interface and implemented by the

BrandPromotionPriceDerivationRuleEligibilityDefaultSO class. In order to avoid unnecessary coupling

of classes, the implementation contains all known items (fields) related to the eligibility object. The

implementation is in general only dependent of PCE data access, PCE core API, model, common,

standard Java classes and the related Spring Framework libraries.

In order to make the comprehension of the plugin-based processing of the transactions concrete,

the following items describe the plugins created for handling brand promotions during transaction

processing.

7.3.1.1 1. Initialization of Brand Promotion Plugin Context

The brand promotion plugin context provider object (an instance of the

BrandPromotionPluginContextProvider class) is responsible for creating and initializing the brand

promotion plugin context shared by the brand promotion plugins. This is performed during the

registration of the plugin contexts with the application context.

The brand promotion plugin context (an instance of the BrandPromotionPluginContext class) stores

the normalized items for the current transaction mapped by their brands, and the activated brand

promotion eligibilities for the transaction. Interval and simple eligibilities are stored in different lists.

The brand promotion plugin context instance can be retrieved by the other brand promotion

plugins by calling a specific method of the brand promotion plugin context provider object.

The below figure shows the corresponding classes and their relationships for creating and retrieving

the brand promotion plugin context.

Page 175: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

175

7.3.1.2 2. Brand Promotion Transaction Analyzer

The plugin for analyzing transactions for brand promotions (an instance of the

BrandPromotionTransactionAnalyzer class) is responsible for selecting the appropriate normalized

line items according to the corresponding brand by querying the transaction analyzer context stored

by the application context. The selected normalized line items are mapped according to their line

item keys and stored into the brand promotion plugin context. The below figure shows the

BrandPromotionTransactionAnalyzer class and the interface implemented by it.

7.3.1.3 3. Brand Promotion Eligibility Loader Fragment

The eligibility loader fragment for brand promotions (an instance of the

BrandPromotionEligibilityLoaderFragment class) is responsible for loading brand promotion

eligibilities into the PCE by querying the master data, filtering the normalized items for filling the

Page 176: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

176

item buckets of the corresponding eligibility wrappers, and registering the activated brand

promotion eligibilities into the brand promotion plugin context.

The BrandPromotionEligibilityLoaderFragment class implements the EligibilityLoaderFragment

interface which declares the general operations for the eligibility loader fragments. The brand

promotion eligibility loader fragment uses an instance of the BrandPromotionEligibilityDataAccess

class to query the master data for loading the brand promotion eligibilities.

The brand promotion eligibilities are modeled by the

BrandPromotionPriceDerivationRuleEligibilitySO interface and the

BrandPromotionPriceDerivationRuleEligibilityDefaultSO class, which implements this interface and

contains the brand field and setter/getter methods for this field as shown in the below class

diagram.

7.3.1.4 4. Brand Promotion Eligibility Rule Handler

The rule handler plugin for brand promotions is implemented by the

BrandPromotionEligibilityRuleHandler class. It implements the logic for the application of the

position and transaction rules for simple and interval brand promotion eligibilities. It implements the

EligibilityRuleHandler interface, which declares the general operations for the eligibility rule

handlers. The diagram below shows this class and the EligibilityRuleHandler interface.

Page 177: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

177

7.3.1.5 5. Brand Promotion Eligibility Parser

The eligibility plugin parser is used at calculation time to inform the rule handler whether there are

simple or interval eligibilities related to brand promotions to be applied to the current partial result.

This information is stored into the partial result as extended custom partial result values to be

carried through during the calculation process.

Page 178: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

178

7.3.2 Concurrence Control Vector Extension Sample

The PCE's exclusive promotion price derivation rule checking feature provided in the default delivery

enables the customer to define which promotions can be applied on top of each other and which

cannot be controlled by the promotion price derivation rule's exclusiveFlag. The default exclusivity

checks are implemented by the DefaultExclusiveCheckHandler plugin. As a custom requirement, it might

be necessary however to further detail the exclusion criteria. The ExclusiveCheckHandler interface

provides an extension point for such custom plugins, as described in chapter Extension Points.

Furthermore, the PCE internal data model's PromotionPriceDerivationRule.ConcurrenceControlVector field

serves as an exclusion control vector to allow further customization. The ConcurrenceControlVector

consists of 10 digits. Each digit serves as a flag for the exclusion of discount.

The following example shows a possible extension of the PCE to handle custom exclusions. The

ConcurrenceControlVectorExclusiveCheckHandler plugin implements the ExclusiveCheckHandler interface and

utilizes the ConcurrenceControlVector to apply custom exclusion rules. The

ConcurrenceControlVectorExclusiveCheckHandler plugin is not part of the standard delivery, but can be

used as a template for fulfilling custom requirements.

The ExclusiveCheckHandler plugins registered to the application context are executed using the

Chain of Responsibility pattern, meaning that the first supported plugin found will be used for

checking exclusivity. The Order annotation of the custom plugin must be less than the 1000,

which is the order of the default implementation.

HOW IT WORKS

The ConcurrenceControlVectorExclusiveCheckHandler processes the ConcurrenceControlVector with the

following meaning for each digit to determine whether a given promotion price derivation rule can

be applied or not depending on all previously applied line item-related or transaction-related

promotion price derivation rules. Only the below listed values and digits are used in this example.

For more complex requirements the remaining digits and values may also be utilized. Please note

that different digits are used by different methods listed in the second table bellow.

Digit Value Explanation

0 0 A line item-related promotion price derivation rule must not be deleted by an exclusive transaction-related promotion price derivation rule.

1 A line item-related promotion price derivation rule is deleted by an exclusive transaction-related promotion price derivation rule. Same if ConcurrenceControlVector is null.

2 A transaction-related promotion price derivation rule does not delete line item discounts.

3 A transaction-related promotion price derivation rule deletes line item discounts. Same if ConcurrenceControlVector is null.

Page 179: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

179

Digit Value Explanation

1 0 A transaction-related promotion price derivation rule can be combined with exclusive and non-exclusive item-related promotion price derivation rules.

1 A transaction-related promotion price derivation rule can only be combined with non-exclusive line item-related promotion price derivation rules.

Formally: The calculation base of a transaction-related promotion price derivation rule considers only line items for which no exclusive promotion price derivation rules were applied before.

2 A transaction-related promotion price derivation rule can only be combined with exclusive line item-related promotion price derivation rules.

Formally: The calculation base of a transaction-related promotion price derivation rule considers only line items for which any exclusive promotion price derivation rules were applied before.

3 A transaction-related promotion price derivation rule cannot be combined with any line item-related promotion price derivation rule.

Formally: The calculation base of a transaction-related promotion price derivation rule considers only line items for which no promotion price derivation rules were applied before.

3 0 If an exclusive line item-related price derivation rule is applied, line item-related price derivation rules with a higher sequence cannot be applied.

If an exclusive transaction-related price derivation rule is applied, transaction-related price derivation rules with a higher sequence cannot be applied.

1 If an exclusive line item-related price derivation rule is applied, line item-related price derivation rules with a higher sequence can be applied anyway.

If an exclusive transaction-related price derivation rule is applied, transaction-related price derivation rules with a higher sequence can be applied anyway.

The ExclusiveCheckHandler interface declares the following methods, which must be implemented by

all custom exclusivity plugins.

Page 180: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

180

Type

Method Description Used in the core implementation for

ConcurrenceControlVector's digit checked by ConcurrenceControlVectorExclusiveCheckHandler

boolean

isExclusiveTransactionCondition (PromotionConditionSO currentCondition, PromotionConditionSO condition)

Checks if the transaction condition can be applied with a previously applied condition.

Please note that the method name is a bit confusing, but we cannot change it as it would be an incompatible change. Better name would be canBeUsedWithPreviousCondition

Parameter currentCondition is the promotion price derivation rule to apply.

Parameter condition is the promotion price derivation rule which has already been applied for the line item.

Only checked for transaction-related promotion price derivation rule calculations. When initializing the transaction summary result, the check is performed for each position, to see if it can be used as a trigger position and if it should be included in the calculation base or not.

The method is called for each previously applied promotion price derivation rule and must return true for all of them to be the current promotion price derivation rule used.

1

boolean

isExclusiveLineItemCondition (PromotionConditionSO condition)

Checks if the promotion price derivation rule is an exclusive promotion price derivation rule.

The check is performed before both line item-related and transaction-related calculations. The return value is required for the promotion price derivation rule calculation, the PCE Context's ExclusiveTransactionConditionUsed flag is set based on it.

0

boolean

canApplyConditionExclusiveCheck (Context context, SummaryResult summaryResult, PromotionConditionSO promotionCondition)

Checks if the passed promotion price derivation rule can be applied based on the previously already applied promotion price derivation rules.

The check is made before each promotion price derivation rule calculation, the calculation is only performed in case True is returned by the method.

0

Page 181: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

181

Type

Method Description Used in the core implementation for

ConcurrenceControlVector's digit checked by ConcurrenceControlVectorExclusiveCheckHandler

boolean

canApplyExclusiveCondition (Context context, PromotionConditionSO condition, Long priceDerivationRuleEligibilityID)

Checks if the passed promotion price derivation rule can be applied based on the previously already applied promotion price derivation rules.

In case of line item-related promotion price derivation rule the check is made on each line item when performing the discountable line item check. It is performed against all previously applied price and points modifiers. In case of transaction-related calculation the check is made while validating the promotion price derivation rule, before the calculation.

3

For the sample implementation please refer to Appendix B.

7.3.3 Item Discount Control Vector Extension Sample

The PCE's item discount-ability filtering provided in the default delivery enables the customer to

define which items may receive discounts or bonus points. The item filtering is performed by

the RebatableLineItemSummaryResultBucketFilter, which executes all registered RebatableItemFilterPlugins.

As a custom requirement it might be necessary to apply additional acceptance criteria determining

which items can receive benefits from a given promotion price derivation rule.

The RebatableItemFilterPlugin interface provides an extension point for such custom plugins, as

described in the previous chapter. In addition the PromotionConditionSO.ItemDiscountControlVector field

together with the SaleReturnLineItem.DiscountTypeCode filed can be used for further customization.

The ItemDiscountControlVector's digits are serving as flags which describe which

discount DiscountTypeCodes are allowed for usage. The possible values of each digit are 0 meaning

the discount is not possible to apply and 1 meaning the discount is possible to apply.

HOW IT WORKS

The ItemDiscountControlVector is not considered in the standard PCE delivery for determining the

discount-able items. The following example shows a possible extension of the PCE which

implements custom item filtering based on the vector. The DiscountControlVectorFilterPlugin implements

the RebatableItemFilterPlugin interface and utilizes the ItemDiscountControlVector for this purpose as

follows.

If the discountVectorMethod configuration parameter's value is not "ALL", then the item is

considered discountable. If the discountVectorMethod configuration parameter is set to "ALL", then

the following applies:

Page 182: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

182

DiscountTypeCode ItemDiscountControlVector Description

null not checked The item is considered discountable.

< 0

not checked

The item is not considered discountable. > 9

> ItemDiscountControlVector's length

otherwise 0 The item is not considered discountable.

1 The item is considered discountable.

For the sample implementation please refer to chapter Appendix B.

7.4 PCE Annotations for categorizing API interfaces

There are several annotations used for marking the application programming interfaces (APIs)

provided by the PCE to its clients. The purpose of these annotations is to distinguish which part of

the public API each interface belongs to and to They can be extended and implemented by custom

development for clients if required.

The @Api annotation is used for marking the functional interfaces provided by the PCE's public API.

The @ModelApi annotation is used for marking the data model interfaces provided by the PCE

public API. They also serve to the purpose of distinguishing the APIs provided to the clients for

extension and custom development from the internal functional and data model interfaces.

The @ExtensionPoint annotation is used to mark interfaces available for custom implementations.

The extension type of the annotation controls what type of extension is supported by the interface.

The following extension types are available:

• Plugin: Implement extension as plugin to add additional features

• Override: Implement extension to override default implementation

• Implement: Add custom implementation

Page 183: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

183

8 Troubleshooting

8.1 Business Error Codes

To inform the caller about input that is not well-formed or unexpected behavior while processing a

request, Business Errors were defined for the different possible error scenarios. Business Error

Codes with ErrorID and further details are sent back in the PriceCalculateResponse response object's

ARTS header.

As the following example shows, the PriceCalculateResponse contains the original PriceCalculateBody

element from the request message unmodified and a BusinessError element in the ARTSHeader with

details of the error.

Page 184: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

184

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<PriceCalculateResponse xmlns="http://www.sap.com/IXRetail/namespace/" InternalMajorVersion="2"

InternalMinorVersion="0">

<ARTSHeader ActionCode="Calculate" MessageType="Response">

<MessageID>ee2c780a-a44e-4c4e-a8e3-eede4484caff</MessageID>

<DateTime>2017-04-12T16:14:22.483+02:00</DateTime>

<Response ResponseCode="Rejected">

<RequestID>9a89f2edfd1e413ea147e334b9c2ed4b</RequestID>

<ResponseTimestamp>2017-04-12T16:14:22.482+02:00</ResponseTimestamp>

<BusinessError Severity="Error">

<ErrorID>GKR-100500</ErrorID>

<Description>Value not supported. Element LineItem.SequenceNumber. Sent: 55.

Expected: 0.</Description>

</BusinessError>

</Response>

<BusinessUnit TypeCode="RetailStore">OS01</BusinessUnit>

</ARTSHeader>

<PriceCalculateBody TransactionType="SaleTransaction" NetPriceFlag="true"

CalculationMode="LineItem">

<TransactionID>9a89f2edfd1e413ea147e334b9c2ed4b</TransactionID>

<DateTime>2501-03-09T00:00:00.000Z</DateTime>

<ShoppingBasket>

<LineItem>

<Sale ItemType="Stock" NonDiscountableFlag="false" FixedPriceFlag="false">

<ItemID>ROC_SA_2</ItemID>

<RegularSalesUnitPrice Currency="EUR">24.55000</RegularSalesUnitPrice>

<Quantity Units="1" UnitOfMeasureCode="PCE">1</Quantity>

<TaxIncludedInPriceFlag>false</TaxIncludedInPriceFlag>

<NonPieceGoodFlag>false</NonPieceGoodFlag>

<FrequentShopperPointsEligibilityFlag>true</FrequentShopperPointsEligibilityFlag>

<PriceTypeCode>00</PriceTypeCode>

<NotConsideredByPriceEngineFlag>false</NotConsideredByPriceEngineFlag>

</Sale>

<SequenceNumber>55</SequenceNumber>

<MerchandiseHierarchy ID="1">RF16231</MerchandiseHierarchy>

</LineItem>

<LineItem>

<Sale ItemType="Stock" NonDiscountableFlag="false" FixedPriceFlag="false">

<ItemID>ROC_SA_1</ItemID>

<RegularSalesUnitPrice Currency="EUR">25.21008</RegularSalesUnitPrice>

<Quantity Units="1" UnitOfMeasureCode="CT">1</Quantity>

<TaxIncludedInPriceFlag>false</TaxIncludedInPriceFlag>

<NonPieceGoodFlag>false</NonPieceGoodFlag>

<FrequentShopperPointsEligibilityFlag>true</FrequentShopperPointsEligibilityFlag>

<PriceTypeCode>00</PriceTypeCode>

<NotConsideredByPriceEngineFlag>false</NotConsideredByPriceEngineFlag>

</Sale>

<SequenceNumber>1</SequenceNumber>

<MerchandiseHierarchy ID="1">RF16231</MerchandiseHierarchy>

</LineItem>

</ShoppingBasket>

</PriceCalculateBody>

Page 185: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

185

</PriceCalculateResponse>

Codeblock 7 Error code (GKR-100500) in response, line 9

8.1.1 Error message format

The business errors are returned in the following format.

<error number> - <narrative> [LineItem(<SequenceNumber of the current line item>). ][Element

<name of the current element>(<number of the current element>). ][Sent: <sent content>.

[Expected: <expected content>.]]

8.1.2 Business Error Codes

The following table contains all defined error scenarios and the corresponding Business Errors with

all information defined for them. Each BusinessError must have an ErrorID, a description of the

scenario, and the expected and received content as well.

Error number

Narrative LineItem info available?

Specific handling regarding to the element name

Sent content Expected content

GKR-100500

Value not supported

x The content of the element.

Enum where possible.

GKR-100501

Value too big

x The length of the content of the element.

The maximum length.

GKR-100502

Too many decimal places

x The number of decimal places of the content of the element.

The maximum count of decimal places.

GKR-100503

Value negative

x The content of the element

Not available

GKR-100504

Structure wrong

Depends on where the error occurs.

The content of the element.

Not available.

GKR-100505

ID not unique

x The content of the element.

Not available.

GKR-100506

Missing element or attribute

x "Coupon" "none" "PrimaryLabel element"

x "Quantity" "none" "UnitOfMeasureCode attribute"

x "Coupon" "none" "RewardType element"

Page 186: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

186

Error number

Narrative LineItem info available?

Specific handling regarding to the element name

Sent content Expected content

x "Coupon" "none" "RewardValue element"

- "ARTSHeader" "none" "MessageID element"

x "RetailPriceModifier" "none" "Quantity element"

x "PriceDerivationRuleEligibility" "none" "ReferenceID element"

x "PriceDerivationRuleEligibility" "none" "ReferenceSequenceNumber element"

x "ExternalAction" "none" "ID attribute"

x "ExternalActionText" "none" "element itself"

x "ExternalActionText" "none" "ID attribute"

x "ExternalActionParameter" "none" "element itself"

x "ExternalActionParameter" "none" "ID attribute"

x "FrequentShopperPointsModifier" "none" "AppliedQuantity element"

GKR-100507

Too many Quantity elements

x Not available The number of Quantity elements in the line item.

"1"

GKR-100508

Not existing or unknown

- Not available The content of the element

Not available

GKR-100509

Line item not allowed in line item calculation mode

x "Coupon" Not available Not available

GKR-100510

External benefit not allowed in line item calculation mode

x "SystemOriginatorFlag = true"

"SystemOriginatorFlag = false or missing"

GKR-100520

Calculation quantity limit reached

- Not available The total quantity of items in the corresponding request (calculated by considering units).

The maximum quantity of items allowed in a request that was configured.

Page 187: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

187

8.2 Debugging

Sometimes you have to check what the PCE is doing internally. Either you are looking for a bug or

try to see how an extension is used.

There are some typical use cases and situations that you will often encounter when checking the

PCE. Here we describe some starting points in the code where you can begin your investigation.

8.2.1 Request/Response mapping

If a value is not mapped from request to response, this can pose a problem regarding the client API

request mapping to GK model and/or response mapping to client API:

To debug the call regarding the client api request mapping:

DataMappingRequestMapper.mapRequest(PriceCalculate priceCalculate, Configuration

configuration)

To debug the mapping to client api response:

DataResponseMapper.mapResponse(Configuration conf, Transaction transaction,

PriceCalculate request)

These classes are the starting point to debug request and response mapping. Nevertheless, there

are more related sub services that have the responsibility to map certain specific parts.

In the following table, you find more details.

8.2.1.1 Request mapping

All request mapper are found under the package:

com.gk_software.pricing_engine.psi.sapmapping.request.*

Reference and entry point to debug Description

DataMappingRequestMapper.mapRequest(...) Main entry point to start the request mapping. This class in composed by two sub services:

DataMappingRequestHeader and DataMappingRequestBody.

DataMappingRequestHeader.mapARTSHeader(...) Mapper responsible for mapping all information regarding ARTS headers.

DataMappingRequestBody.mapBody(...) Mapper responsible for mapping the request body. This class checks also constraints regarding calculation mode LINE_ITEM and consistence of LineItem sequence numbers.

Request Body section

Page 188: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

188

Reference and entry point to debug Description

DataMappingRequestRetailTransactionCustomerGroupAssignment.

mapCustomerGroup(...)

Mapper responsible for mapping the customer group.

DataMappingRequestLineItem.mapLineItems(...) Starting point to map LineItems.

Into the LineItem mapping (DataMappingRequestLineItem), there is other sub service described

below:

Reference and entry point to debug Description

DataMappingRequestItemBase.

mapLineItemChoiceBase(...)

Starting point to map line items:

DataMappingRequestRetailPriceModifier.mapRetailPriceModifiers(...): Responsible for mapping retail price modifiers.

DataMappingRequestPromotionPriceDerivationRuleReference.mapPromotionPriceDerivationRuleReference(...): Responsible for mapping the data regarding the price derivation rules.

DataMappingRequestFrequentShopperPointsModifier.mapFrequentShopperPointsModifier(...):

Responsible for mapping the data regarding frequent shopper points.

DataMappingRequestMerchandiseHierarchyGroup.mapMerchandiseHierarchyCommonData(...):

Responsible for mapping the data regarding merchandise hierarchy.

DataMappingRequestSaleReturnLineItemPromotionTriggerType.mapPromotionManualTriggerTypeToSaleReturnLineItemPromotionTrigger(...): Responsible for mapping the data regarding promotion manual trigger.

DataMappingRequestRetailTransactionLineItemAssociation.mapRetailTransactionLineItemAssociation(...): Responsible for mapping the data regarding line item association (ItemLink).

DataMappingRequestPriceDerivationRuleEligibility.

mapPriceDerivationRuleEligibility(...)

Responsible for mapping the data regarding a price derivation rule eligibility.

DataMappingRequestPriceDerivationRuleBase.

mapPriceDerivationRuleBase(...)

Responsible for mapping the data regarding a price derivation rule base.

DataMappingRequestExternalActionText.

mapExternalActionTextType(...)

Responsible for mapping the data regarding external action.

DataMappingRequestExternalActionParameter.

mapExternalActionParameterType(...)

Responsible for mapping the data regarding external action.

DataMappingRequestLoyaltyReward.

mapLoyaltyRewardBase(...)

Responsible for mapping the data regarding loyalty reward.

Page 189: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

189

Reference and entry point to debug Description

DataMappingRequestMerchandiseHierarchyGroup.

mapMerchandiseHierarchyCommonData(...)

Responsible for mapping the data regarding merchandise hierarchy group.

DataMappingRequestPriceModificationLineItem.

mapRetailPriceModifierFromDiscount(...)

Responsible for mapping the data regarding price modifications.

DataMappingRequestRetailTransactionCouponSummary.

mapTenderCouponBase(...)

Responsible for mapping the data regarding a transaction coupon.

DataMappingRequestPromotionExternalTriggerType.

mapPromotionExternalTriggerType(...)

Responsible for mapping the data regarding a promotion external trigger.

DataMappingRequestSaleReturnLineItemSalesOrder.

mapSaleReturnLineItemSalesOrder(...)

Responsible for mapping the data regarding sales order.

DataMappingRequestRetailTransactionPromotionTrigger.

mapPromotionManualTriggerTypeToRetailTransactionPromotionTrigger(...)

Responsible for mapping the data regarding transaction promotion trigger.

8.2.1.2 Response mapping

All response mappers are found under the package:

com.gk_software.pricing_engine.psi.sapmapping.response.*

Reference and entry point to debug Description

DataResponseMapper.mapResponse(...) Main entry point to start the response mapping. This class in composed by two sub services:

DataResponseHeader and DataResponseBody.

DataResponseHeader.mapHeader(...) Mapper responsible for mapping all header information back including response code and error messages if existing.

DataResponseBody.mapBody(...) Mapper responsible for mapping the extended response body.

The response body section (DataResponseBody) is also composed by several mapper sub services:

Page 190: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

190

Reference and entry point to debug

Description

DataResponseLineItemMapperService.

mapLineItemItem(...)

Starting point to mapping back extended line items:

DataResponseRetailPriceModifierDomainSpecificMapperService.mapRetailPriceModifierDomainSpecific(...): Responsible for mapping the data regarding retail price modifiers.

DataResponseFrequentShopperPointsModifierTypeMapperService.mapFrequentShopperPointsModifierType(...): Responsible for mapping the data regarding frequent shopper points.

DataResponsePromotionPriceDerivationRuleReferenceTypeMapperService.mapPromotionPriceDerivationRuleReferenceType(...): Responsible for mapping the data regarding price derivation rules.

DataResponsePromotionManualTriggerTypeMapperService.mapPromotionManualTriggerType(...): Responsible for mapping the data regarding promotion manual triggers (LineItem level).

DataResponsePromotionManualTriggerTypeMapperService.

mapPromotionManualTriggerType(...)

Responsible for mapping the data regarding promotion manual triggers (Transaction level).

DataResponseLoyaltyRewardService.

mapLineItemLoyaltyReward(...)

Responsible for mapping the data regarding loyalty reward.

DataResponseCouponMapperService.

mapTenderCouponBase(...)

Responsible for mapping the data regarding coupon.

DataResponseExternalTriggerMapperService.

mapPromotionExternalTriggerTypeFromRequest(...)

Responsible for mapping the data regarding external triggers.

ReponseDataMapperCommons Utility mapper that puts together all common things used by others mappers.

8.2.2 PCE Configuration

Sometimes results are not as expected. Therefore, is important to check some configurations to be

sure and discard possible bug issues:

Symptom To check

If an expected eligibility/promotion is loaded but not considered.

Check whether the validity dates are still valid.

A starting debug point: com.gk_software.pricing_engine.common.utils.DateUtils.isDateValid(...)

Additionally, you have to check the "timeValidationMethod" (see below).

Page 191: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

191

Symptom To check

If an already invalidated eligibility is still active.

Check the validity level stored in configuration property "timeValidationMethod" to find out which are the invalidation criteria. Possible values are: PROMOTION or ELIGIBILITIES.

The properties are mapped on: com.gk_software.pricing_engine.core.configuration.ConfigurationInitializer.initializeConfiguration(...) and available overall in PCE Context via the method getConfiguration().

If you change some eligibility/promotion value in the data base, but this change is not reflected in the calculation.

Check whether the caching property "localMasterdataCacheEnabled" with cache size "cacheSize" is active. An active cache means that all already loaded data from the Data Access Layer in a transaction are cached. The default cache size is 300.

The properties are mapped on: com.gk_software.pricing_engine.core.configuration.ConfigurationInitializer.initializeConfiguration(...) and available overall in the PCE Context via the method getConfiguration().

If you get similar expected results that are not 100% according to your mathematical calculations.

Check the property "rebateShareRoundingMethod" which specifies the rounding strategy. Possible values are: NO_ROUNDING, HALF_UP, DOWN, UP and HALF_DOWN. See more details in enum com.gk_software.pricing_engine.model.typecodes.RoundingMethodEnum.

The properties are mapped on: com.gk_software.pricing_engine.core.configuration.ConfigurationInitializer.initializeConfiguration(...) and available overall in PCE Context via the method getConfiguration().

If your rebate is not applied in expected order.

Check the property "itemChooseMethod". It defines the order in which benefits apply to items. Possible values are:

• Lowest: Take items with lowest price first (lowest benefit first).

• Highest: Take items with highest price first (highest benefit first).

• LowestPerInterval: Lowest benefit per interval first.

• HighestPerInterval: Highest benefit per interval first.

The properties are mapped on: com.gk_software.pricing_engine.core.configuration.ConfigurationInitializer.initializeConfiguration(...) and available overall in PCE Context via the method getConfiguration().

If you get different results after a long debugging session.

Probably you exceeded the time calculation limit which defines the time limit in milliseconds (ms) for the best price algorithm. It is defined in property "calculationTimeLimit". The default value is 1000.

The properties are mapped on: com.gk_software.pricing_engine.core.configuration.ConfigurationInitializer.initializeConfiguration(...) and available overall in PCE Context via the method getConfiguration().

If a line item does not get an expected monetary discount.

Check whether the line item is able to get a monetary discount. The property "itemTypesWithoutReceiptRelatedDiscounts" contains a list of line item types which are not allowed for receipt-related monetary discounts.

The properties are mapped on: com.gk_software.pricing_engine.core.configuration.ConfigurationInitializer.initializeConfiguration(...) and available overall in PCE Context via the method getConfiguration().

Page 192: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

192

Symptom To check

If the expected decimal places are always fix.

Check the property "rebateShareDecimalPlacesCount" which defines the number of decimal places. Possible values are 0 to 4.

The properties are mapped on: com.gk_software.pricing_engine.core.configuration.ConfigurationInitializer.initializeConfiguration(...) and available overall in PCE Context via the method getConfiguration().

If you expected a zero rebate, but it does not appear in the results

Check whether zero rebates are enabled. This property is defined in "allowZeroRebate". The default value is false.

The properties are mapped on: com.gk_software.pricing_engine.core.configuration.ConfigurationInitializer.initializeConfiguration(...) and available overall in PCE Context via the method getConfiguration().

If the line items are calculated independently of the whole transaction.

Check the current calculation mode "calculationMode". This value is set to false in the configuration. But the value can appear into a request overriding the default config. This feature is available since API major version 2.

The properties are mapped on: com.gk_software.pricing_engine.core.configuration.ConfigurationInitializer.initializeConfiguration(...) and available overall in PCE Context via the method getConfiguration()

and controlled in the request in class: com.gk_software.pricing_engine.psi.service.PromotionPricingServiceImpl.checkCalculationModeIntoRequestBodyAndOverride(...)

If the expected multi-language feature does not appear in the response.

Check the requested API version. This feature is available since API major version 2.

The feature is checked with help of method: com.gk_software.pricing_engine.psi.util.ApiVersionUtils.checkAPIVersionWithNonnullValue(...).

8.2.3 Calculate Transaction

Reference and entry point to debug Description

DefaultPricingServiceImpl.calculateTransaction(...) This is the entry point to the Pricing Engine. In this method, a PricingEngineRequest is created which is processed inside the Pricing Engine. The result is stored in the PricingEngineResponse.

8.2.4 PCE Processing

Start Business Logic.

Reference and entry point to debug Description

PricingEngineImpl.process(...) The main Pricing Engine process. Here the configuration and the calculation mode are checked and the execution of all pricing engine steps is started.

PricingEngineImpl.execute(...) Here all steps of the calculation described below are executed. Finally, after the calculation the transaction will be updated via the TransactionUpdateHandler.

PricingEngineImpl.initializeContextItems(...)

Context initializations. Place to identify all relevant line items related to positions, transaction, and sale returns.

Page 193: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

193

Reference and entry point to debug Description

PricingEngineImpl.clearPromotionDataFromTransaction()

Clear all already used promotion data from the transaction.

PricingEngineImpl.executeTransactionAnalyzer()

Place to execute all registered transaction analyzers. For instance: CouponTransactionAnalizer, CustomCouponTransactionAnalyzer, CustomerGroupTransactionAnalyzer, ExternalPromotionsTransactionAnalyzer, ItemTransactionAnalyzer and PromotionManualTriggerTransactionAnalyzer

PricingEngineImpl.executeEligibilityLoader()

Place to execute all registered eligibility loaders. For instance: DefaultEligibilityLoader and ManualTriggerEligibilityLoader.

Inside the DefaultEligibilityLoader, all EligibilityLoaderFragments are executed to load respective eligibility information via the Data Access Layer. Some important debugging points are:

• DefaultEligibilityLoader.executeFragment: Execution of all fragments to load respective eligibility information.

• DefaultEligibilityLoader.fillItemBucket: Here the item Bucket for the requested fragment is filled.

• DefaultEligibilityLoader.activateEligibility: After loading the eligibilities regarding every fragment, here is the place to activate them.

The eligibilities are loaded via com.gk_software.pricing_engine.sapmapping.DataAccessServiceSAP. Just check the desired fragment to find out which methods are used to access the Data Access Layer.

After loading eligibilities via DataAccessServiceSAP, this information is mapped to the GK Model. Just check com.gk_software.pricing_engine.sapmapping.DataMappingSAP2GKImpl.

PricingEngineImpl.executeConditionLoader()

Place to load all conditions related to active eligibilities. See also com.gk_software.pricing_engine.core.engine.ConditionLoaderImpl.execute(..).

The promotion conditions are loaded from Context. If no promotion conditions are found, they are loaded with help of DataAccessServiceSAP. Just check com.gk_software.pricing_engine.sapmapping.DataAccessServiceSAP.getPromotionConditions().

Regarding every promotion condition, the respective condition rule is loaded: com.gk_software.pricing_engine.core.engine.ConditionLoaderImpl.loadConditionRule(..)

Page 194: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

194

Reference and entry point to debug Description

PricingEngineImpl.executeConditionCalculator()

Place to calculate all related conditions. See also com.gk_software.pricing_engine.common.engine.PromotionCalculator. Some important debugging points are:

• PromotionCalculatorImpl.calculateLineItemsConditions: Performs calculation of line item conditions.

• PromotionCalculatorImpl.calculateTransactionConditions: Performs calculation of transaction conditions.

• PromotionCalculatorImpl.checkExclusiveTransactionCondition: Checks whether exclusive transaction conditions exist and whether they are used in the calculation.

• PromotionCalculatorImpl.applyCalculationResult: Applies all valid PartialResults to the SummaryResult. In case of multiple valid PartialResults, the possible conflicts are handled with the best price calculation.

To debug how conflicts are handled, just check com.gk_software.pricing_engine.common.engine.ConflictHandler.

TransactionUpdateHandlerImpl Finally, the place to update the transaction after the calculation (SummaryResult -> TransactionResult). Just check com.gk_software.pricing_engine.core.transaction.TransactionUpdateHandlerImpl.

8.3 Performance Logging

8.3.1 Overview

The PCE core includes some basic performance monitoring features.

The monitoring is based on the JPerf Open Source library. This allows a fine-grained performance

logging with some advanced analysis capabilities. The monitoring is controlled via logger settings.

There are different measurement points with additional new loggers that allow controlling the detail

of the output.

8.3.2 Usage

To enable the performance logging, set the corresponding logger log level to INFO, DEBUG or

TRACE level and log the information to a specific performance.log file.

There are different loggers available, see below for details.

The performance.log contains log entries in the following format (depending on your log-format

configuration).

INFO [main]: start[1494336965104] time[171] tag[pricing.service.calculate.success]

message[MessageId: cha_basic_not_discountable_flag1_request]

Explanation:

Page 195: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

195

INFO : Log level at which the message is logged .

[main]: Thread name where the log is created.

start[1494336965104] : Timestamp (System.currentTimeMillis) at which the log was produced.

time[171] : This is the time in ms that was measured for the operation.

tag[pricing.service.calculate.success] : The tag is a formalized definition of the operation that is

measured. For details on the available tags, see below .

message[MessageId: cha_basic_not_discountable_flag1_request] : Some log entries have an

optional message that gives some more details on the measurement (that is, messageId of the

request).

For example:

Page 196: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

196

DEBUG [http-nio-9081-exec-1]: start[1494517222819] time[12]

tag[pricing.engine.internal.execute.prepareContext]

DEBUG [http-nio-9081-exec-1]: start[1494517222832] time[1]

tag[pricing.engine.internal.execute.clearPromotionDataFromTransaction]

DEBUG [http-nio-9081-exec-1]: start[1494517222834] time[18]

tag[pricing.engine.internal.execute.executeTransactionAnalyzer]

TRACE [http-nio-9081-exec-1]: start[1494517222853] time[184]

tag[pricing.data_access.DataAccessServiceDelegate.getItemEligibilities]

TRACE [http-nio-9081-exec-1]: start[1494517223039] time[40]

tag[pricing.data_access.DataAccessServiceDelegate.getMarketBasketAmountEligibilities]

DEBUG [http-nio-9081-exec-1]: start[1494517222852] time[227]

tag[pricing.engine.internal.execute.executeEligibilityLoader]

INFO [http-nio-9081-exec-1]: start[1494517222819] time[262] tag[pricing.engine.process]

INFO [http-nio-9081-exec-1]: start[1494517222723] time[362]

tag[pricing.service.calculate.success] message[MessageId:

i_can_calculate_large_baskets_1_request]

DEBUG [http-nio-9081-exec-2]: start[1494517223292] time[5]

tag[pricing.engine.internal.execute.executeTransactionAnalyzer]

TRACE [http-nio-9081-exec-2]: start[1494517223299] time[5]

tag[pricing.data_access.DataAccessServiceDelegate.getItemEligibilities]

TRACE [http-nio-9081-exec-2]: start[1494517223304] time[4]

tag[pricing.data_access.DataAccessServiceDelegate.getItemEligibilities]

TRACE [http-nio-9081-exec-2]: start[1494517223309] time[3]

tag[pricing.data_access.DataAccessServiceDelegate.getItemEligibilities]

TRACE [http-nio-9081-exec-2]: start[1494517223312] time[3]

tag[pricing.data_access.DataAccessServiceDelegate.getItemEligibilities]

TRACE [http-nio-9081-exec-2]: start[1494517223316] time[2]

tag[pricing.data_access.DataAccessServiceDelegate.getItemEligibilities]

TRACE [http-nio-9081-exec-2]: start[1494517223319] time[6]

tag[pricing.data_access.DataAccessServiceDelegate.getMarketBasketAmountEligibilities]

DEBUG [http-nio-9081-exec-2]: start[1494517223299] time[26]

tag[pricing.engine.internal.execute.executeEligibilityLoader]

INFO [http-nio-9081-exec-2]: start[1494517223292] time[34] tag[pricing.engine.process]

INFO [http-nio-9081-exec-2]: start[1494517223283] time[46]

tag[pricing.service.calculate.success] message[MessageId:

i_can_calculate_large_baskets_5_request]

DEBUG [http-nio-9081-exec-3]: start[1494517223390] time[45]

tag[pricing.engine.internal.execute.executeTransactionAnalyzer]

TRACE [http-nio-9081-exec-3]: start[1494517223436] time[5]

tag[pricing.data_access.DataAccessServiceDelegate.getItemEligibilities]

For performance logging, you should create a new log appender that logs all loggers starting

with performance.pricing-engine,

that is, for LogBack:

<logger name="performance.pricing-engine" level="info" additivity="false"> <appender-ref ref="PERF" /> </logger>

Recommended log formatter pattern for Log4j:

<param name="conversionPattern" value="%-5p [%t]: %m%n"/>

Page 197: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

197

Recommended log formatter pattern for LogBack:

<layout> <pattern>%-5level [%thread]: %message%n</pattern> </layout>

8.3.2.1 Measurement Points

All measurements are using a logger depending on the module and class name.

The logger name pattern used is: performance.<ModuleName>.<ClassName>,

for example: performance.engine.com.gk_software.pricing_engine.engine.PricingEngineImpl

Depending on the log level set for the different loggers, there may be additional more detailed

performance log entries measured. The overhead of the performance logging is very low (<1%

overhead), but it is recommended to use the DEBUG and TRACE level only if you need some more

detailed information, as it will add a lot more data to the performance log.

All operations that are measured with less than 1ms are not written to the performance log.

Module Class name Log Level

Tag Description

psi-sap com.gk_software.pricing_engine. psi.service.PromotionPricingServiceImpl

INFO pricing.service.calculate.success

pricing.service.calculate.error

Overall processing time of a PCE service call. Error and success tags used depending on result (BusinessError or Success).

engine com.gk_software.pricing_ engine.engine.PricingEngineImpl

INFO pricing.engine.process Overall processing time of the promotion calculation (excluding request and response parsing)

DEBUG pricing.engine.internal.execute. prepareContext

Time to initialize engine

Page 198: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

198

Module Class name Log Level

Tag Description

DEBUG pricing.engine.internal.execute. clearPromotionDataFromTransaction

Time to clear previous promotion data from transaction

DEBUG pricing.engine.internal.execute. executeTransactionAnalyzer

Time to parse and analyze the transaction data

DEBUG pricing.engine.internal.execute. executeAdhocPromotionHandler

Time to load ad hoc promotion data

DEBUG pricing.engine.internal.execute. executeEligibilityLoader

Overall time to load all relevant eligibilities, check, and activate them

DEBUG pricing.engine.internal.execute. executeConditionLoader

Time to load all conditions and rules for active eligibilities

DEBUG pricing.engine.internal.execute. executeConditionCalculator

Time to do the promotion calculation for all viable promotions

DEBUG pricing.engine.internal.execute. transactionUpdateHandler>

Time to update transaction data with calculation results

engine com.gk_software.pricing_engine. engine.PromotionCalculatorImpl

DEBUG pricing.calculation.calculate LineItemsConditions

Time to calculate all Position (LineItem) related promotions

DEBUG pricing.calculation.calculate TransactionConditions

Time to calculate all Transaction (Basket) related promotions

Page 199: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

199

Module Class name Log Level

Tag Description

data_access

com.gk_software.pricing_engine. api.data_access.DataAccess ServiceDelegate

TRACE pricing.data_access.DataAccess ServiceDelegate.getEligibility

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.getChildEligibilitiesCount

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.getItemEligibilities

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.getCustomerGroupEligibilities

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.getCouponEligibilities

Detailed logging of single data access method for loading data from DB

TRACE pricing.data_access.DataAccessService Delegate.getMerchandiseGroupEligibilities

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.getMerchandiseSetEligibilities

Detailed logging of single data access method for loading promotion data from DB

Page 200: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

200

Module Class name Log Level

Tag Description

TRACE pricing.data_access.DataAccessService Delegate.getCombinationEligibility

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.getMarketBasketAmountEligibilities

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.getParentEligibilities ForMerchandiseGroup

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.getChildEligibilitiesForParent EligibilitiesForMerchandiseGroup

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.getParentCombinationEligibilities ForMerchandiseGroup

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccess ServiceDelegate.getPromotion

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccess ServiceDelegate.getPromotion Conditions

Detailed logging of single data access method for loading promotion data from DB

Page 201: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

201

Module Class name Log Level

Tag Description

TRACE pricing.data_access.DataAccess ServiceDelegate.getItemRule

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccess ServiceDelegate.getGet3Pay2Rule

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.findAssociatedMhgByChildId

Detailed logging of single data access method for loading promotion data from DB.

TRACE pricing.data_access.DataAccessService Delegate.getMixAndMatchRule

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.getExternalActionRule

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.getMixAndMatchItems

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.DataAccessService Delegate.findRoundingRuleByKey

Detailed logging of single data access method for loading promotion data from DB

Page 202: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

202

Module Class name Log Level

Tag Description

TRACE pricing.data_access.DataAccessService Delegate.getManualPromotionEligibilities

Detailed logging of single data access method for loading promotion data from DB

TRACE pricing.data_access.Data AccessServiceDelegate.getRule

Detailed logging of single data access method for loading promotion data from DB

8.3.2.2 Analysis of Performance logs

The JPerf library has some built-in log parser to ease the evaluation of the performance logs.

Use it on the command line like follows (having the jperf-1.0.3.jar downloaded or got from

webapp/lib folder):

java -jar jperf-1.0.3.jar log/performance.log -o log/performance-summary.log <options>

Calling this script creates a new performance-summary.log file that summarizes the execution

times of the measured data and generates statistical information.

An example is shown in the following section:

Page 203: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

203

Performance Statistics 2017-05-09 15:36:00 - 2017-05-09 15:36:30

Tag Avg(ms)

Min Max Std-Dev Count Total

pricing.calculation.calculateLineItemsConditions 204,0

9 582 229,0 8 1632

pricing.calculation.calculateTransactionConditions 14,0

14 14 0,0 1 14

pricing.data_access.DataAccessServiceDelegate.getChildEligibilitiesCount 2,5

1 6 2,1 4 10

pricing.data_access.DataAccessServiceDelegate.getCombinationEligibility 3,8

3 6 1,3 4 15

pricing.data_access.DataAccessServiceDelegate.getCouponEligibilities 2,3

2 3 0,5 7 16

pricing.data_access.DataAccessServiceDelegate.getCustomerGroupEligibilities 1,7

1 3 0,7 18 31

pricing.data_access.DataAccessServiceDelegate.getExternalActionRule 5,0

3 7 2,0 2 10

pricing.data_access.DataAccessServiceDelegate.getItemEligibilities 3,3

1 52 4,2 155 519

pricing.data_access.DataAccessServiceDelegate.getItemRule 1,8

1 6 1,3 12 22

pricing.data_access.DataAccessServiceDelegate.getManualPromotionEligibilities 2,6

1 7 1,3 14 36

pricing.data_access.DataAccessServiceDelegate.getMarketBasketAmountEligibilities 3,9

2 24 3,9 32 126

pricing.data_access.DataAccessServiceDelegate.getMerchandiseGroupEligibilities 2,0

1 4 0,9 24 49

pricing.data_access.DataAccessServiceDelegate.getMixAndMatchItems 5,0

5 5 0,0 1 5

pricing.data_access.DataAccessServiceDelegate.getMixAndMatchRule 7,0

7 7 0,0 1 7

pricing.data_access.DataAccessServiceDelegate.getPromotion 3,8

1 22 4,9 15 57

pricing.data_access.DataAccessServiceDelegate.getPromotionConditions 10,1

3 50 10,0 18 181

pricing.engine.internal.execute.executeConditionCalculator 183,6

9 582 223,9 9 1652

pricing.engine.internal.execute.executeConditionLoader 26,4

4 88 23,6 12 317

pricing.engine.internal.execute.executeEligibilityLoader 34,7

5 341 59,7 32 1111

pricing.engine.internal.execute.executeTransactionAnalyzer 8,2

3 66 11,2 32 261

pricing.engine.internal.execute.prepareContext 6,0

6 6 0,0 1 6

pricing.engine.internal.execute.transactionUpdateHandler 114,3

4 460 180,4 9 1029

pricing.engine.process 148,0

10 1089 270,4 30 4441

pricing.service.calculate.error 9,8

5 18 4,2 6 59

pricing.service.calculate.success 182,5

16 1098 290,7 30 5474

Performance Statistics 2017-05-09 15:36:30 - 2017-05-09 15:37:00

Page 204: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

204

Tag Avg(ms)

Min Max Std-Dev Count Total

pricing.calculation.calculateLineItemsConditions 124,7

16 557 193,9 6 748

pricing.calculation.calculateTransactionConditions 5151,8

52 25534 10191,1 5 25759

pricing.data_access.DataAccessServiceDelegate.getChildEligibilitiesCount 2,0

1 3 0,7 4 8

pricing.data_access.DataAccessServiceDelegate.getCombinationEligibility 3,5

3 4 0,5 4 14

pricing.data_access.DataAccessServiceDelegate.getExternalActionRule 2,7

2 3 0,5 3 8

pricing.data_access.DataAccessServiceDelegate.getItemEligibilities 2,9

2 9 1,7 16 47

pricing.data_access.DataAccessServiceDelegate.getItemRule 1,4

1 3 0,6 14 20

pricing.data_access.DataAccessServiceDelegate.getMarketBasketAmountEligibilities 4,2

2 17 4,4 11 46

pricing.data_access.DataAccessServiceDelegate.getMerchandiseGroupEligibilities 2,0

2 2 0,0 2 4

pricing.data_access.DataAccessServiceDelegate.getPromotion 1,7

1 3 0,7 17 29

pricing.data_access.DataAccessServiceDelegate.getPromotionConditions 6,6

5 10 1,5 17 112

pricing.engine.internal.execute.executeConditionCalculator 2410,5

16 25535 7314,1 11 26515

pricing.engine.internal.execute.executeConditionLoader 19,0

10 53 11,5 11 209

pricing.engine.internal.execute.executeEligibilityLoader 17,0

8 37 9,5 11 187

pricing.engine.internal.execute.executeTransactionAnalyzer 1530,9

3 16795 4826,9 11 16840

pricing.engine.internal.execute.transactionUpdateHandler 130,1

7 511 147,6 10 1301

pricing.engine.process 269,2

61 1105 291,3 10 2692

pricing.service.calculate.success 279,1

69 1113 290,9 10 2791

For each operation, you get information on average execution time, minimum and maximum

execution times, standard deviation, invocation count of the method, and total execution time of all

calls.

The parser generates statistics for each 30 seconds time slice by default. This is configurable by

passing the parameter -t (time in ms). By passing the -r parameter, you get additional statistical

rollups that summarize tags with the same prefix.

There are the following additional options that can be used (use --help to print them out).

Page 205: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

205

Arguments:

logInputFile - The log file to be parsed. This is log/performance in the analyze-performance

script.

-o|--out|--output outputFile - The file where generated statistics should be written. If not

specified, statistics are written to stdout. This is fixed to log/performance-summary.log in

the analyze-performance script

-g|--graph graphingOutputFile - The file where generated perf graphs should be written. If

not specified, no graphs are written.

-t|--timeslice timeslice - The length of time (in ms) of each timeslice for which statistics

should be generated. Defaults to 30000 ms.

-r - Whether or not statistics rollups should be generated. If not specified, rollups are

not generated.

-f|--format text|csv - The format for the statistics output, either plain text or CSV.

Defaults to text.

If format is csv, then the columns output are tag, start, stop, mean,

min, max, stddev, and count.

Note that out, stdout, err and stderr can be used as aliases to the standard output streams

when specifying output files.

You can also output the data in a graphical format or as CSV to import into Excel.

See the JPerf documentation for more details.

8.3.3 Development

As a developer of a PCE extension, you may want to add additional measurement points in your own

code.

The basic class for measurement of execution times form JPerf library is LoggingStopWatch. Create

an instance of this class and use start, lap, and stop methods for trigger performance measurement.

See also JPerf developer guide for more details.

The creation of a LoggingStopWatch object is very cheap, so it adds no performance overhead.

There is a helper class com.gk_software.pricing_engine.common.utils.PerformanceUtils in commons project to

support you in doing so. This class contains several static methods to help you in using performance

measurement.

The following code can be used to create and start a new stopWatch at the beginning of a method:

LoggingStopWatch logWatch = PerformanceUtils.start(PERF_LOGGER, PerformanceLevel.DEBUG,

"pricing.engine.internal.execute", null);

You should create a new watch on each method call to be thread-safe. While this adds some

Garbage collector overhead, this is negligible compared to the business method execution.

Page 206: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

206

The newStopWatch method automatically adds a threshold of 1 ms to the LoggingStopWatch, which

means methods executing in less than 1ms are not logged. The PerformanceLevel defines on which

log level the measurement is logged.

You could also get a performance logger in your class and create stop watches from there:

private static final Logger PERF_LOGGER = PerformanceUtils.getPerfLog("engine",

PricingEngineImpl.class);

....

LoggingStopWatch watch = PerformanceUtils.newStopWatch(PERF_LOGGER, PerformanceLevel.INFO);

It is recommended to use a separate logger for performance logging to allow easy filtering in

the log config.

When you create a new instance of a LoggingStopWatch, it is automatically initialized with current time,

so there is no need to start it. If you want to reset or restart it inside your code, use the start() or lap()

methods.

To stop and log a watch, use the stop() method.

if(logWatch.isLogging()) {

PerformanceUtils.lap(logWatch, "pricing.engine.internal.execute.prepareContext", null);

}

PerformanceUtils.stop(logWatch, "pricing.engine.internal.execute.transactionUpdateHandler",

null);

Use watch.isLogging() when you generate some more complex tags to prevent unnecessary overhead

when performance monitoring is not enabled. You can pass the tag in start stop or lap method as

you need, recommended is to pass it on stop. You may optionally use stop(String,String) to pass

an additional message.

The tag should have several levels separated by a point (.), a similar syntax like a Log4j logger name.

It is used for grouping entries during the analysis. Best practice is to prefix the tag with some fixed

entry based on the module, class, and/or method measured and then some details if needed for

granular measurement.

Page 207: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

207

9 Configuration

For details on the configuration refer to the document Functional Guide for the Promotion

Calculation Engine.

Page 208: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

208

10 Glossary

The glossary is intended to support understanding of the main terms used in this documentation.

Term Definition

Ad hoc promotion Promotions loaded from external systems if available and not from the Data Access Layer.

ARTS The Association for of Retail Technology Standards (ARTS) is an organization providing application standards and guidance to the retail industry.

Business Error Feedback regarding problems caused by the data sent in with the request. Currently, only errors caused by wrong or missing data in the request are supported.

Calculation Rule Describes the benefit to be granted to the customer in case that the condition is applied.

Condition A condition can be understood as a single action granting a benefit to the customer. It consists of a set of triggers (eligibilities), time validity, and a rule describing the benefit. Multiple conditions can belong to a promotion.

Context Holds the complete state for transaction processing and promotion calculation.

Domain (Object) Model

Conceptual model of a problem or business domain.

Eligibility Precondition which has to be fulfilled in order to apply the condition. An eligibility triggers a condition.

Extension Map Possibility to define references to external data structures for the objects of a transaction.

Line Item An element of a transaction that contains information on goods or services delivered.

Manufacturer Coupon

A coupon provided by the manufacturer resulting in monetary discount for the customer. Manufacturer coupon barcodes are created in the GS1 coupon format.

Normalized Item Representation of a product, an article, a good, or a service that is bought or returned by a customer. An item is the smallest unit or customer pack that can be ordered independently and that cannot be split further into any smaller units.

Pricing Engine The core of the Promotion Calculation Engine. The Pricing Engine passes the request from the application, performs the price determination and returns the result.

Pricing Service Interface (PSI)

Standard interface schema provided by ARTS for integrating a pricing service with a price requesting or selling system.

Promotion Functional mapping of a campaign granting a benefit to the customer. A promotion consists of one or more conditions.

Request Message that contains common information pieces which are needed in order to process the message: A shopping basket with multiple line items and other information being relevant for the calculation of the benefits for the shopping basket.

The request is provided via the client API.

Page 209: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

209

Term Definition

Response Responding message regarding the request sent in. This can be the updated shopping basket including calculated discounts and bonus points as well as information about used promotion master data and applied coupons, or an error information in case that the request could not be processed.

Technical Error Error due to technical problems which prevents the calculation to be fulfilled (for example, a database exception).

Transaction The shopping basket with line item data and other information relevant for price calculation.

Page 210: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

210

11 Appendix

11.1 Appendix A: Request and Response Mapping

11.1.1 Mapping of PCE internal model to/from the interface

In order to enable the processing of data on the PCE, SAP data objects found under package

com.sap.ppengine.client.dto are mapped to internal models defined at package

com.gk_software.pricing_engine.model.transaction. This chapter describes the related mapping from Client

API to PCE Domain Object (DO) model.

The Promotion Calculation Engine receives a request via the client API. The request contains a

shopping basket with multiple line items. The service applies monetary discounts and loyalty points

to the given shopping basket based on its content (items, prices, scanned coupons, assigned

customer groups, etc.) on the one hand and the master data accessible via the data access API

on the other hand. Finally, it responds the shopping basket with added information about the

applied promotions. The transmitted content is based on the ARTS Pricing Service Interface schema

version 4.0.0. Where needed, extensions were added to it.

11.1.1.1 Client API DTOs

11.1.1.1.1 PriceCalculate

The request sent to the calculation engine.

Element/Attribute DO Entity

DO Field

Rule/Note

ARTSHeader - - GKR-100506 is sent back if the header is not included.

PriceCalculateBody - -

InternalMajorVersion - - Must not be less than the running PCE's major version, otherwise GKR-100500 is sent back. Must not be null, otherwise GKR-100508 is sent back.

InternalMinorVersion - - If null, then the mapped field will be set to 0. Must be 0, otherwise it is a business error. If the major version provided by the Client API matches the running PCE version, then must not be lower than the running PCE's minor version, otherwise GKR-100500 is sent back.

Any - -

11.1.1.1.2 PriceCalculateResponse

The response of the calculation engine. The content of the request is taken over and extended

where nothing else is stated below.

Page 211: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

211

Element/Attribute DO Entity DO Field Rule/Note

ARTSHeader - -

PriceCalculateBody - -

InternalMajorVersion - - The internal major version sent in the request message is mapped back.

InternalMinorVersion - - The internal minor version sent in the request message is mapped back.

Any - -

11.1.1.1.3 ARTSCommonHeaderType

Element/Attribute DO Entity DO Field Rule/Note

MessageID - - In the request the client sends a UUID. If null or empty GKR-100506 is sent back.

To the response a new UUID generated by the PCE is set.

DateTime - - The date and time when this message header was created. For example, 2015-01-13T04:48:30.427-05:00.

Response - -

Response.any - -

Requestor - - Is routed through simply.

BusinessUnit Transaction BusinessUnitID It is ensured by the client that minimally one BusinessUnit element of TypeCode "RetailStore" resp. with no type information is sent in the request. The first BusinessUnit element meeting that condition is considered. If no BusinessUnit sent in the request does not exist, business errorGKR-100506 is sent back.

BusinessUnit.TypeCode - -

WorkstationID Transaction WorkstationID Is routed through simply.

RequestedLanguage - - Language code in ISO 639-1 format for texts requested from client (deprecated: use RequestedMultiLanguage instead). If missing in the request, the first found language in the database is returned.

RequestedMultiLanguage List of Language codes in ISO 639-1 format for texts requested from client.

Any - -

ActionCode - - Only possible values are "Calculate" and "Lookup", this is checked in OData. "Calculate" (default): Pricing is requested for all line items in the shopping basket together. "Lookup": Pricing is requested per single line item without taking into consideration any other content of the shopping basket. This is not part of version 1. If the attribute is missing in the request, it is to be set to the default.

Page 212: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

212

Element/Attribute DO Entity DO Field Rule/Note

MessageType - - Only possible values are "Request" and "Response", this is checked in OData. "Request": Within PriceCalculate. "Response": Within PriceCalculateResponse. If the attribute is missing in the request, it is to be set to "Request". If "Response" is used in PriceCalculate, business errorGKR-100500 is sent back.

11.1.1.1.4 ResponseCommonData

Element/Attribute DO Entity

DO Field

Rule/Note

RequestID - - The MessageID of the request.

ResponseTimestamp - - The DateTime of the request header (ARTSCommonHeaderType).

BusinessError - - Only filled in case a BusinessError has occurred.

BusinessError.any - -

ResponseCode - - "Rejected" is used when a business error (price calculation impossible) occurred. Requests for which a price calculation could be processed are responded with "OK".

11.1.1.1.5 PriceCalculateBase

Element/Attribute DO Entity DO Field Rule/Note

TransactionID Transaction TransactionID No pricing-relevant information. Is routed through simply. If it exceeds 128 chars, it is truncated, the request message can be processed further. If it is not provided in the request, an internal identifier is generated by the PCE.

DateTime RetailTransaction PromotionTimestamp

Time zone considered.

Loyalty - - See mapping of LoyaltyAccountCommonData.

ShoppingBasket - - See mapping of ShoppingBasketBase. Only one shopping basket per request is supported.

Page 213: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

213

Element/Attribute DO Entity DO Field Rule/Note

RegularSalesUnitPriceRoundingRule

- - Rounding rule for regular prices (element RegularSalesUnitPrice and ExtendedAmount calculation from request). For more information see mapping of RoundingRuleType.

Any - -

TransactionType - - This information is not checked. The line item type is an important information for correct pricing. Currently, only sales transactions are supported. Of course, they can contain return line items. Assuming that a return transaction consists of return line items, it could be priced correctly either.

NetPriceFlag - - This information is not checked.

CalculationMode com.gk_software.pricing_engine.api.context.Configuration

calculationMode Calculation mode for the price calculation. The default is Basket. Valid values are Basket and LineItem. If not included in the request, GKR-100500 will be thrown. For version one only Basket mode is allowed, if other value is sent, then GKR-100500 will be thrown.

11.1.1.1.6 LoyaltyAccountCommonData

Element/Attribute DO Entity DO Field Rule/Note

CustomerID RetailTransactionCustomer CustomerID If the CustomerID element is set and the length of it in the request exceeds 40 chars, business error GKR-100501 is sent back. If the request contains minimally one LoyaltyProgramID element, but no CustomerID element, business error GKR-100506 is sent back.

LoyaltyProgram - - See mapping of LoyaltyAccountType.

Page 214: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

214

Element/Attribute DO Entity DO Field Rule/Note

CustomerIsEmployeeFlag - - Currently, we do not need this information as the only way for granting employee discounts in this context is to handle employees as customers (no employee discount groups available). Mapped back to the response.

11.1.1.1.7 LoyaltyAccountType

Element/Attribute DO Entity DO Field Rule/Note

LoyaltyProgramID RetailTransactionCustomerGroupAssignment CustomerGroupID If the LoyaltyProgramID element length exceeds 40 chars, business error GKR-100501 is sent back. If the LoyaltyProgramID element does not exist, business error GKR-100506 is sent back.

any - -

11.1.1.1.8 ShoppingBasketBase

Element/Attribute DO Entity DO Field Rule/Note

LineItem - - See mapping of LineItemDomainSpecific.

any - -

11.1.1.1.9 LineItemDomainSpecific

-> extends LineItemBase-> extends LineItemChoiceDomainSpecific-> extends LineItemChoiceBase

Element/Attribute DO Entity DO Field Rule/Note

LineItemChoiceBase.Sale - - See mapping of SaleBase.

LineItemChoiceBase.SaleForDelivery

- - See mapping of SaleForDeliveryBase.

LineItemChoiceBase.SaleForPickup - - See mapping of SaleForPickupBase.

LineItemChoiceBase.Return - - See mapping of ReturnBase.

LineItemChoiceBase.ReturnForDelivery

- - See mapping of ReturnForDeliveryBase.

LineItemChoiceBase.ReturnForPickup

- - See mapping of ReturnForPickupBase.

Page 215: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

215

Element/Attribute DO Entity DO Field Rule/Note

LineItemChoiceBase.CustomerOrderForDelivery

- - See mapping of CustomerOrderForDeliveryBase.

LineItemChoiceBase.CustomerOrderForPickup

- - See mapping of CustomerOrderForPickupBase.

LineItemChoiceBase.Discount - - See mapping of DiscountBase.

LineItemChoiceBase.LoyaltyReward - - See mapping of LoyaltyRewardBase.

LineItemChoiceBase.Coupon - - See mapping of TenderCouponBase.

LineItemChoiceDomainSpecific.PromotionManualTrigger

- - See mapping of PromotionManualTriggerType.

LineItemChoiceDomainSpecific.PromotionExternalTrigger

- - See mapping of PromotionExternalTriggerType.

LineItemChoiceDomainSpecific.any - -

Page 216: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

216

Element/Attribute DO Entity DO Field Rule/Note

LineItemBase.SequenceNumber RetailTransactionLineItem RetailTransactionLineItemSequenceNumber

For sub-types SaleReturnLineItem, PriceModificationLineItem, LoyaltyRewardLineItem only. This is as at DO side, coupons, manual triggers, and external triggers are not handled as line sub-types of RetailTransactionLineItem. In the request, if LineItem sub-type is one of the following:

• Sale

• SaleForDelivery

• SaleForPickup

• Return

• ReturnForDelivery

• ReturnForPickup

• CustomerOrderForDelivery

• CustomerOrderForPickup

• Discount

• LoyaltyReward

and SequenceNumber does not fall into the smallint/short range, then GKR-100501 if sent back. If the LineItem sub-type is one of the listed ones and the sequence number is not unique within the line items of those sub-types in the message, business error GKR-100505 is sent back. If for the above mentioned LineItem sub-types the sequence number is not sent or empty, GKR-100506 is sent back.

Page 217: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

217

Element/Attribute DO Entity DO Field Rule/Note

LineItemBase.MerchandiseHierarchy

SaleReturnLineItemMerchandiseHierarchyGroup

MerchandiseHierarchyGroupID

Calculation engine needs information about all merchandise hierarchy groups which are assigned to the line item directly or indirectly. Makes sense for sub-type SaleReturnLineItem only, otherwise it is to be ignored. If the length of the element in the request exceeds 30 chars, business error GKR-100501 is sent back.

LineItemBase.MerchandiseHierarchy.ID

SaleReturnLineItemMerchandiseHierarchyGroup

MerchandiseHierarchyGroupIDQualifier

See explanation of LineItemBase.MerchandiseHierarchy. If the length of the element in the request exceeds 4 chars, business error GKR-100501 is sent back.

11.1.1.1.10 SaleBase

Extends ItemDomainSpecific. Mapping to SaleReturnLineItem at DO side is the same with the

following extensions:

• SaleReturnLineItem.ActionCode = "SI" (sale) and

• SaleReturnLineItem.ItemType = "CO" (common)

11.1.1.1.11 SaleForDeliveryBase

Extends ItemDomainSpecific. Mapping to SaleReturnLineItem at DO side is the same with the

following extensions:

• SaleReturnLineItem.ActionCode = "SI" (sale) and

• SaleReturnLineItem.ItemType = "CO" (common)

plus to a SaleReturnLineItemSalesOrder related to the SaleReturnLineItem with

• SaleReturnLineItemSalesOrder.SalesOrderDeliveryTypeCode = "01" (delivery)

11.1.1.1.12 SaleForPickupBase

Extends ItemDomainSpecific. Mapping to SaleReturnLineItem at DO side is the same with the

following extensions:

• SaleReturnLineItem.ActionCode = "SI" (sale) and

• SaleReturnLineItem.ItemType = "CO" (common)

Page 218: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

218

plus to a SaleReturnLineItemSalesOrder related to the SaleReturnLineItem with

• SaleReturnLineItemSalesOrder.SalesOrderDeliveryTypeCode = "03" (pickup other store)

11.1.1.1.13 ReturnBase

Extends ItemDomainSpecific. Mapping to SaleReturnLineItem at DO side is the same with the

following extensions:

• SaleReturnLineItem.ActionCode = "RI" (return) and

• SaleReturnLineItem.ItemType = "CO" (common)

11.1.1.1.14 ReturnForDeliveryBase

Extends ItemDomainSpecific. Mapping to SaleReturnLineItem at DO side is the same with the

following extensions:

• SaleReturnLineItem.ActionCode = "RI" (return) and

• SaleReturnLineItem.ItemType = "CO" (common)

plus to a SaleReturnLineItemSalesOrder related to the SaleReturnLineItem with

• SaleReturnLineItemSalesOrder.SalesOrderDeliveryTypeCode = "01" (delivery)

11.1.1.1.15 ReturnForPickupBase

Extends ItemDomainSpecific. Mapping to SaleReturnLineItem at DO side is the same with the

following extensions:

• SaleReturnLineItem.ActionCode = "RI" (return) and

• SaleReturnLineItem.ItemType = "CO" (common)

plus to a SaleReturnLineItemSalesOrder related to the SaleReturnLineItem with

• SaleReturnLineItemSalesOrder.SalesOrderDeliveryTypeCode = "03" (pickup other store)

11.1.1.1.16 CustomerOrderForDeliveryBase

Extends ItemDomainSpecific. Mapping to SaleReturnLineItem at DO side is the same with the

following extensions:

• SaleReturnLineItem.ActionCode = "SI" (sale) and

• SaleReturnLineItem.ItemType = "SO" (sales order)

11.1.1.1.17 CustomerOrderForPickupBase

Extends ItemDomainSpecific. Mapping to SaleReturnLineItem at DO side is the same with the

following extensions:

• SaleReturnLineItem.ActionCode = "SI" (sale) and

• SaleReturnLineItem.ItemType = "PU" (sales order pickup)

Page 219: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

219

11.1.1.1.18 ItemDomainSpecific

extends ItemBase

Element/Attribute DO Entity DO Field Rule/Note

ItemBase.ItemID SaleReturnLineItem ItemID In the schema, there is a choice between ItemID and MerchandiseHierarchyGroup element. In case that no ItemID is provided, it is a merchandise category sale corresponding to the following SaleReturnLineItem structure:

• SaleReturnLineItem.ItemID = ItemBase.MerchandiseHierarchy

• SaleReturnLineItem.SubItemType = "MSTR" (Merchandise Category Sale)

If the length of the MerchandiseHierarchy element exceeds 30 chars, business error GKR-100501 is sent back.

Regarding the length of the itemID: please consider the restrictions of the environment the PCE is used. Validation of the length of this field is not performed by the PCE.

ItemBase.MerchandiseHierarchy SaleReturnLineItem MainMerchandiseHierarchyGroupID

SaleReturnLineItem POSItemID

ItemBase.MerchandiseHierarchy.ID

SaleReturnLineItem MainMerchandiseHierarchyGroupIDQualifier

If the length of the qualifier exceeds 4 chars, business error GKR-100501 is sent back.

ItemBase.RegularSalesUnitPrice SaleReturnLineItem ActualUnitPrice It is ensured by the client that this element is provided for FixedPriceFlag = true and for the use case with the client being responsible for price lookup.

ItemBase.RegularSalesUnitPrice.Currency

- -

- SaleReturnLineItem ExtendedAmount SaleReturnLineItem.Quantity * SaleReturnLineItem.Units * SaleReturnLineItem.ActualUnitPrice, rounded according to RoundingRuleType

ItemBase.ExtendedAmount - - As there is no corresponding element in the DO, this information needs to be calculated for response as: SaleReturnLineItem.ExtendedAmount + SaleReturnLineItem.ExtendedDiscountAmount + ∑(RetailPriceModifier.Amount with ProrateFrom <> null for the considered line item)

ItemBase.ExtendedAmount.Currency

- -

Page 220: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

220

Element/Attribute DO Entity DO Field Rule/Note

ItemBase.ExtendedDiscountAmount

SaleReturnLineItem ExtendedDiscountAmount

Mapped from the request only.

As there is no corresponding element in the DO (SaleReturnLineItem.ExtendedDiscountAmount does not fit as it does not differentiate between discounts and increasements), this information needs to be calculated for response as: absolute value of ∑(RetailPriceModifier.Amount with ProrateFrom is null and Amount < 0 for the considered line item)

ItemBase.ExtendedDiscountAmount.Currency

- -

ItemBase.Quantity SaleReturnLineItem Quantity The DO element does not support decimal places. In case decimal places are sent in request, a business errorGKR-100502 is sent back. The DO element does not support multiple quantities. In case that the Quantity element occurs more than once, a business error GKR-100500 is sent back. If the sent quantity value falls out of the Integer range, GKR-100501 will be sent back. In case that no Quantity element occurs in request, 1 is used.

ItemBase.Quantity.Units SaleReturnLineItem Units In case that this attribute is missing, 1 is used. It must fall into the (11,3) range. If the number of decimal places exceeds 8 business error GKR-100502 is sent back. If the length of the number otherwise exceeds 11, GKR-100501 is sent back.

ItemBase.Quantity.UnitOfMeasureCode

SaleReturnLineItem UnitOfMeasureCode If the element is missing in the request, business error GKR-100506 is sent back. If the length of the element in the request exceeds 4 chars, business error GKR-100501 is sent back.

ItemBase.RetailPriceModifier See mapping of RetailPriceModifierDomainSpecific.

ItemBase.ItemLink RetailTransactionLineItemAssociation

ToLineItemSequenceNumber

RetailTransactionLineItem.RetailTransactionLineItemSequenceNumber

Page 221: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

221

Element/Attribute DO Entity DO Field Rule/Note

RetailTransactionLineItemAssociation

LineItemSequenceNumber

If it does not fall into the smallint/short range or is not unique in the context of the given line item, business error GKR-100501 is sent back. Otherwise, the given value is taken. It is not checked whether that sequence number exists within the transaction.

RetailTransactionLineItemAssociation

LineItemAssociationTypeCode

"LINK"

ItemBase.ItemType SaleReturnLineItem ItemType Mapping:

Stock "CO" or "SO" or "PU" (see above)

GiftCertificate "GC"

any other business error GKR-100500

If this element is not provided in request, it is considered as "Stock". Note: The calculation engine cannot handle unknown values. If you want to use other values than those ones mapped above, you have to overwrite the enum adapter.

ItemBase.NonDiscountableFlag SaleReturnLineItem DiscountFlag Mapping: invert. If this element is not provided in request, default "false" is used.

ItemBase.FixedPriceFlag - - Affects price lookup only: Price must not be read again. However, promotions can be applied on top. If this element is not provided in the request, default "false" is used.

ItemDomainSpecific.TaxIncludedInPriceFlag

- - Mapped back to response as is.

ItemDomainSpecific.any - -

Page 222: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

222

Element/Attribute DO Entity DO Field Rule/Note

ItemDomainSpecific.NonPieceGoodFlag

SaleReturnLineItem QuantityInputMethod Mapping:

false "01" (piece)

true "06" (quantity with decimal places, automatic input request)

If this element is not provided in the request, default "false" is used.

ItemDomainSpecific.FrequentShopperPointsEligibilityFlag

SaleReturnLineItem FrequentShopperPointsEligibilityFlag

If this element is not provided in the request, default "false" is used.

ItemDomainSpecific.DiscountTypeCode

SaleReturnLineItem DiscountTypeCode If the length of the element in the request exceeds 1 char, business error GKR-100501 is sent back. If the element in the request does not contain a numeric char, business error GKR-100500 is sent back.

ItemDomainSpecific.PriceTypeCode

SaleReturnLineItem PriceTypeCode If the request element does not contain a value of the enumeration

• 00

• 01

business error GKR-100500 is sent back. If this element is not provided in the request or is empty, default "00" is used.

ItemDomainSpecific.NotConsideredByPriceEngineFlag

SaleReturnLineItem NotConsideredByLoyaltyEngineFlag

If this element is not provided in the request, default "false" is used.

ItemDomainSpecific.FrequentShopperPointsModifier

- - See mapping of FrequentShopperPointsModifierType.

ItemDomainSpecific.PromotionPriceDerivationRuleReference

- - See mapping of PromotionPriceDerivationRuleReferenceType.

ItemDomainSpecific.PromotionManualTrigger

- - See mapping of PromotionManualTriggerType.

11.1.1.1.19 RetailPriceModifierDomainSpecific

extends RetailPriceModifierBase

Element/Attribute DO Entity DO Field Rule/Note

RetailPriceModifierBase.SequenceNumber

RetailPriceModifier

RetailPriceModifierSequenceNumber

If it does not fall into the smallint/short range or is not

Page 223: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

223

Element/Attribute DO Entity DO Field Rule/Note

PriceModificationLineItem

RetailTransactionLineItemSequenceNumber

unique over all retail price modifiers of the current line item, business error GKR-100501 is sent back. If it is missing from the request GKR-100506 will be sent back.

RetailPriceModifierBase.Amount RetailPriceModifier

Amount For Action = "Add" or "Subtract", absolute value.

PriceModificationLineItem

Amount

RetailPriceModifierBase.Amount.Action RetailPriceModifier

AdjustmentMethodCode Mapping:

Add "IC"

Subtract "DC"

Replace n.a. - business error

For n.a. - business error

any other

business error GKR-100500

PriceModificationLineItem

- Only Action = "Subtract" is supported in that context.

RetailPriceModifierBase.Amount.Currency - -

RetailPriceModifierBase.Percent RetailPriceModifier

Percent Action "Subtract" and "Add" are supported otherwise business error GKR-100500 is sent back. If it contains more than 4 decimal places, business error GKR-100501 is sent back.

PriceModificationLineItem

Percentage Action "Subtract" and "Add" are supported otherwise business error GKR-100500 is sent back. If it contains more than 4 decimal places, business error GKR-100502 is sent back.

Page 224: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

224

Element/Attribute DO Entity DO Field Rule/Note

RetailPriceModifierBase.Percent.Action RetailPriceModifier

AdjustmentMethodCode Mapping:

Add "IC"

Subtract "DC"

Replace n.a. - business error

For n.a. - business error

any other

business error GKR-100500

PriceModificationLineItem

- Only Action = "Subtract" is supported in that context.

RetailPriceModifierBase.PreviousPrice RetailPriceModifier

ExtendedAmountBeforeModification

PriceModificationLineItem

ExtendedAmountBeforeModification

RetailPriceModifierBase.PreviousPrice.Currency

- -

RetailPriceModifierBase.NewPrice RetailPriceModifier

ExtendedAmountAfterModification

PriceModificationLineItem

ExtendedAmountAfterModification

RetailPriceModifierBase.NewPrice.Currency

- -

RetailPriceModifierBase.PromotionID - - See PriceDerivationRuleBase

RetailPriceModifierBase.ItemLink RetailPriceModifier

ProrateFrom If it does not fall into the smallint/short range, business error GKR-100501 is sent back. If multiple ItemLink elements occur in the request, only the first one is processed.

PriceModificationLineItem

-

Page 225: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

225

Element/Attribute DO Entity DO Field Rule/Note

RetailPriceModifierBase.Quantity RetailPriceModifier

AppliedQuantity Regarding to the request: Maximum length is 11 including 3 decimal places. If the number of integer digits exceeds 8 business error GKR-100502 is returned. If the number of decimal places exceeds 3, GKR-100501 is sent back. If it is missing for a RetailPriceModifier being not prorated from a Discount, business error GKR-100506 is sent back. Regarding to the response: In case of prorated RetailPriceModifier which was generated by the calculation engine, this element should not be provided in response.

PriceModificationLineItem

-

RetailPriceModifierBase.Rounding RetailPriceModifier

RoundingAmount Absolute value. If the request contains a negative value, business error GKR-100503 is sent back.

PriceModificationLineItem

RoundingAmount

RetailPriceModifierBase.Rounding.Currency

- -

RetailPriceModifierBase.Rounding.RoundingDirection

- - (RetailPriceModifier)

• if RoundingAmount < 0.0: Down

• if RoundingAmount > 0.0: Up

• else: no RoundingDirection attribute

If the request contains a value not being part of the enumeration (Up, Down), business error GKR-100500 is sent back.

Page 226: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

226

Element/Attribute DO Entity DO Field Rule/Note

- - (PriceModificationLineItem)

• if RoundingAmount < 0.0: Down

• if RoundingAmount > 0.0: Up

• else: no RoundingDirection attribute

If the request contains a value not being part of the enumeration (Up, Down), business error GKR-100500 is sent back.

RetailPriceModifierBase.ComputationBaseAmount

RetailPriceModifier

CalculationBaseAmount Available since interface version 3.0.

RetailPriceModifierBase.ComputationBaseAmount.Currency

- -

RetailPriceModifierDomainSpecific.PriceDerivationRule

- - If more than one PriceDerivationRule element is sent in request, business error GKR-100504 is sent back. See mapping of PriceDerivationRuleBase.PriceDerivationRuleBase.

any - -

RetailPriceModifierDomainSpecific.ManualTriggerSequenceNumber

RetailPriceModifier

TriggerSequenceNumber If it does not fall into the smallint/short range, business error GKR-100501 is sent back.

PriceModificationLineItem

TriggerSequenceNumber

RetailPriceModifierDomainSpecific.ExtraAmount

RetailPriceModifier

ExtraAmount Absolute value. If the request contains a negative value, business error GKR-100503 is sent back.

PriceModificationLineItem

ExtraAmount

RetailPriceModifierDomainSpecific.ExtraAmount.Currency

- -

RetailPriceModifierDomainSpecific.ExternalSystemOriginatorFlag

RetailPriceModifier

ExternalSystemOriginatorFlag

If the element is missing in the request, "false" is to be used.

PriceModificationLineItem

ExternalSystemOriginatorFlag

Page 227: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

227

11.1.1.1.20 LoyaltyRewardBase

Element/Attribute DO Entity DO Field Rule/Note

PromotionID LoyaltyRewardLineItem PromotionID If the element is missing from the request or is empty, GKR-100506 will be returned.

FrequentShopperPointsModifier

PromotionID

PointsAwarded LoyaltyRewardLineItem PointsAwardedCount Maximum length is 11 including 3 decimal places. If the number of integer digits exceeds 8 business error GKR-100502 is returned. If the number of decimal places exceeds 3, GKR-100501 is sent back.

FrequentShopperPointsModifier

FrequentShopperPointsEarnedCount

PointsAwarded.Type - - Fix "PointsEarned"

ManualTriggerSequenceNumber

LoyaltyRewardLineItem TriggerSequenceNumber If it does not fall into the smallint/short range, business error GKR-100501 is sent back.

FrequentShopperPointsModifier

TriggerSequenceNumber

PointsAwardedAmount LoyaltyRewardLineItem FrequentShopperPointsEarnedAmount

FrequentShopperPointsModifier

FrequentShopperPointsEarnedAmount

PointsAwardedAmount.Currency

- -

ComputationBaseAmount LoyaltyRewardLineItem ComputationBaseAmount

FrequentShopperPointsModifier

ComputationBaseAmount

ComputationBaseAmount.Currency

- -

ExternalSystemOriginatorFlag LoyaltyRewardLineItem ExternalSystemOriginatorFlag

FrequentShopperPointsModifier

ExternalSystemOriginatorFlag

PriceDerivationRule - - See mapping of PriceDerivationRuleBase.

Page 228: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

228

Element/Attribute DO Entity DO Field Rule/Note

any - -

TypeCode - - If the request element does not contain the value "Award", then business error GKR-100500 is sent back.

11.1.1.1.21 PriceDerivationRuleBase

In case of prorated RetailPriceModifier or prorated FrequentShopperPointsModifier which

were generated by the Pricing Engine, this element should not be provided in response.

Element/Attribute DO Entity DO Field Rule/Note

- RetailTransactionPromotionPriceDerivationRule

TransactionID = Transaction.TransactionID

RetailPriceModifierBase.PromotionID

RetailTransactionPromotionPriceDerivationRule

PromotionID If it is not provided in the request, an internal negative identifier is generated. Note: Generated IDs of promotions are negative in order to avoid collisions with existing internal ones. Generated IDs are kept in response mapping. They can be detected by their negative sign.

LoyaltyRewardBase.PromotionID

PriceDerivationRuleID RetailTransactionPromotionPriceDerivationRule

PriceDerivationRuleID The PriceDerivationRuleID element of the request is converted into longint. Even in case of failure, the request message can be processed further - an internal negative identifier is generated in that case. Note: This generated value will be responded back instead of the wrong request value. Entry in RetailTransactionPromotionPriceDerivationRule is created only if the combination TransactionID + PriceDerivationRuleID does not exist yet.

- RetailTransactionPromotionPriceDerivationRule

PriceDerivationRuleEligibilityID

When mapping the request, a negative value is generated as this information is not included in it. Note: Generated IDs of price derivation rule eligibilities are negative in order to avoid collisions with existing internal ones.

- RetailPriceModifier PriceDerivationRuleID = RetailTransactionPromotionPriceDerivationRule.PriceDerivationRuleID

FrequentShopperPointsModifier

PriceDerivationRuleID

PriceModificationLineItem

PriceDerivationRuleID

Page 229: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

229

Element/Attribute DO Entity DO Field Rule/Note

LoyaltyRewardLineItem PriceDerivationRuleID

- RetailPriceModifier PromotionID = RetailTransactionPromotionPriceDerivationRule.PromotionID

FrequentShopperPointsModifier

PromotionID

PriceModificationLineItem

PromotionID

LoyaltyRewardLineItem PromotionID

- RetailPriceModifier PriceDerivationRuleEligibilityID

= RetailTransactionPromotionPriceDerivationRule.PriceDerivationRuleEligibilityID

FrequentShopperPointsModifier

PriceDerivationRuleEligibilityID

PriceModificationLineItem

PriceDerivationRuleEligibilityID

LoyaltyRewardLineItem PriceDerivationRuleEligibilityID

Eligibility - - See mapping of PriceDerivationRuleEligibility.

any - -

PromotionDescription RetailTransactionPromotionPriceDerivationRule

PromotionDescription If it exceeds 255 chars, it is truncated; the request message can be processed further.

PromotionDescriptionMultiLanguage

PromotionTextSO Descriptions of the OPP promotion in different languages.

PromotionPriceDerivationRuleSequence

RetailTransactionPromotionPriceDerivationRule

PromotionPriceDerivationRuleSequence

If the element is not provided in request, 0 is taken as default.

PromotionPriceDerivationRuleResolution

RetailTransactionPromotionPriceDerivationRule

PromotionPriceDerivationRuleResolution

If the element is not provided in request, 0 is taken as default.

PromotionPriceDerivationRuleTypeCode

RetailTransactionPromotionPriceDerivationRule

PromotionPriceDerivationRuleTypeCode

If it exceeds 4 chars, it is truncated; the request message can be processed further.

Page 230: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

230

Element/Attribute DO Entity DO Field Rule/Note

TransactionControlBreakCode

RetailTransactionPromotionPriceDerivationRule

TransactionControlBreakCode

If the request element does not contain a value of the enumeration

• PO

• PC

• SP

• SU

business error GKR-100500 is sent back. If the request element is missing at all, "SU" is taken as default.

PriceDerivationRuleDescription

RetailTransactionPromotionPriceDerivationRule

PriceDerivationRuleDescription

If it exceeds 255 chars, it is truncated; the request message can be processed further.

PromotionOriginatorTypeCode

RetailTransactionPromotionPriceDerivationRule

PromotionOriginatorTypeCode

If it exceeds 2 chars, it is truncated; the request message can be processed further.

TriggerQuantity RetailTransactionPromotionPriceDerivationRule

TriggerQuantity Maximum length is 11 including 3 decimal places. If the number of integer digits exceeds 8 business error GKR-100502 is returned. If the number of decimal places exceeds 3, GKR-100501 is sent back.

DiscountMethodCode RetailTransactionPromotionPriceDerivationRule

DiscountMethodCode If the request element does not contain a value of the enumeration

• 00

• 01

• 02

• 03

• 04

business error GKR-100500 is sent back. If the request element is missing at all, "00" is taken as default.

FrequentShopperPointsFlag

RetailTransactionPromotionPriceDerivationRule

FrequentShopperPointsFlag

If the request element is missing at all, "false" is taken as default.

CustomerGroupLoyaltyPointsDefaultQuantity

RetailTransactionPromotionPriceDerivationRule

CustomerGroupLoyaltyPointsDefaultQuantity

Maximum length is 11 including 3 decimal places. If the number of integer digits exceeds 8 business error GKR-100502 is returned. If the number of decimal places exceeds 3, GKR-100501 is sent back.

ProhibitPrintFlag RetailTransactionPromotionPriceDerivationRule

ProhibitPrintFlag If the request element is missing at all, "false" is taken as default.

TenderTypeCode RetailTransactionPromotionPriceDerivationRule

TenderTypeCode If the length of the element in the request exceeds 4 chars, business error GKR-100501 is sent back.

PointsConversionAmount RetailTransactionPromotionPriceDerivationRule

PointsConversionAmount

Page 231: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

231

Element/Attribute DO Entity DO Field Rule/Note

PointsConversionAmount.Currency

- -

NoEffectOnSubsequentPriceDerivationRulesFlag

RetailTransactionPromotionPriceDerivationRule

NoEffectOnSubsequentPriceDerivationRulesFlag

If the request element is missing at all, "false" is taken as default.

ProhibitTransactionRelatedPriceDerivationRulesFlag

RetailTransactionPromotionPriceDerivationRule

ProhibitTransactionRelatedPriceDerivationRulesFlag

If the request element is missing at all, "false" is taken as default.

ExclusiveFlag RetailTransactionPromotionPriceDerivationRule

ExclusiveFlag If the request element is missing at all, "false" is taken as default.

ConcurrenceControlVector

RetailTransactionPromotionPriceDerivationRule

ConcurrenceControlVector

If the length of the element in the request exceeds 20 chars, business error GKR-100501 is sent back.

AppliedCount RetailTransactionPromotionPriceDerivationRule

AppliedCount Maximum length is 3 including no decimal places, if the value does not fit with this limitation, the request cannot be processed.

ReceiptLine RetailTransactionPromotionPriceDerivationRule

ReceiptPrinterName The text to be printed on the receipt (deprecated: use ReceiptLineMultiLanguage instead). The length must not exceed 40 characters in the request, otherwise the text is truncated.

ReceiptLineMultiLanguage

PromotionTextSO ReceiptText The texts to be printed on the receipt in different languages.

ExternalPromotionID RetailTransactionPromotionPriceDerivationRule

ExternalPromotionID If it exceeds 255 chars, it is truncated; the request message can be processed further.

ExternalPriceDerivationRuleID

RetailTransactionPromotionPriceDerivationRule

ExternalPriceDerivationRuleID

If it exceeds 255 chars, it is truncated; the request message can be processed further.

CouponPrintoutID RetailTransactionPromotionPriceDerivationRule

CouponPrintoutID If it exceeds 40 chars, it is truncated; the request message can be processed further.

CouponPrintoutRule RetailTransactionPromotionPriceDerivationRule

CouponPrintoutRule For DiscountMethodCode = 04 only: If the request element does not contain a value of the enumeration

• 00

• 01

business error GKR-100500 is sent back. If the request element is missing at all, "00" is taken as default.

CouponPrintoutText RetailTransactionPromotionPriceDerivationRule

CouponPrintoutText

Page 232: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

232

Element/Attribute DO Entity DO Field Rule/Note

PrintoutValidityPeriod RetailTransactionPromotionPriceDerivationRule

PrintoutValidityPeriod Maximum length is 3 including no decimal places, if the value does not fit with this limitation, it is truncated; the request message can be processed further. If the value is not provided at all, then default 0 is chosen.

GiftCertificateExpirationDate

RetailTransactionPromotionPriceDerivationRule

GiftCertificateExpirationDate

The end of the date range in which the gift certificate is valid. This value is only needed for DiscountMethodCode = 03.

ExternalAction RetailTransactionPromotionPriceDerivationRule

Contains an external action, for example, Shake hands with customer. For more information, see mapping of ExternalActionType.

OperatorDisplayText RetailTransactionPromotionPriceDerivationRule

PromotionTexts Texts in different languages shown to the operator.

CustomerDisplayText RetailTransactionPromotionPriceDerivationRule

PromotionTexts Texts in different languages shown to the customer.

PromotionType RetailTransactionPromotionPriceDerivationRule

PromotionTypeName The PromotionType is used to classify promotions. Note: The content of this element is passed to the requestor.

CalculationBaseSequence RetailTransactionPromotionPriceDerivationRule

CalculationBaseSequence The CalculationBaseSequence is used to define the basis for applying a promotion. Note: The type of this element is a String although its content has a numeric value. It could also contain a negative value. In that case, the corresponding sign is reflected as a postfix. For example, value "-1" is reflected in this element by type String as follows: "1-". The content of this element is passed to the requestor.

Page 233: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

233

Element/Attribute DO Entity DO Field Rule/Note

ApplicationType RetailTransactionPromotionPriceDerivationRule

PriceModificationMethodCode

Mapping:

Manual "RM"

Item n.a. - business error

MixMatch "MM"

FixPrice "PS"

PromotionalAward n.a. - business error

BuyOneGetOne "GP"

None "NO"

DiscountSingle "RS"

DiscountPercent "RP"

DiscountTotal "RT"

FixPriceTotal "PT"

DiscountPercentTotal "TP"

DiscountPercentTotal2 "T2"

DiscountTotalInterval n.a. - business error

ExternalAction "EX"

any other business error GKR-100500

Note: The calculation engine cannot handle unknown values. If you want to use other values than those mapped above, you have to overwrite the enum adapter.

11.1.1.1.22 PriceDerivationRuleEligibility

Element/Attribute DO Entity DO Field Rule/Note

- SaleReturnLineItemModifierCoupon

PromotionID

Page 234: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

234

Element/Attribute DO Entity DO Field Rule/Note

RetailTransactionModifierCoupon

= RetailTransactionPromotionPriceDerivationRule.PromotionID

- SaleReturnLineItemModifierCoupon

PriceDerivationRuleID

= RetailTransactionPromotionPriceDerivationRule.PriceDerivationRuleID

RetailTransactionModifierCoupon

- SaleReturnLineItemModifierCoupon

PriceDerivationRuleEligibilityID

= RetailTransactionPromotionPriceDerivationRule.PriceDerivationRuleEligibilityID

RetailTransactionModifierCoupon

ReferenceID SaleReturnLineItemModifierCoupon

CouponNumber Multiple coupons = multiple eligibilities. If the length of the element in the request exceeds 40 chars, business error GKR-100501 is sent back. If the element in the request is missing, business error GKR-100506 is sent back.

RetailTransactionModifierCoupon

any - -

ReferenceSequenceNumber

SaleReturnLineItemModifierCoupon

CouponSequenceNumber

If it does not fall into the smallint/short range, business error GKR-100501 is sent back. If the element in the request is missing, business error GKR-100506 is sent back.

RetailTransactionModifierCoupon

Type RetailPriceModifier EligibilityTypeCode Mapping in request:

StoreCoupon "COUP"

any other value GKR-100500 is sent back

In response: fix StoreCoupon. Note: The calculation engine cannot handle unknown values. If you want to use other values than this one mapped above, you have to overwrite the enum adapter.

FrequentShopperPointsModifier

EligibilityTypeCode

PriceModificationLineItem

-

LoyaltyRewardLineItem -

11.1.1.1.23 ExternalActionType

Element/Attribute DO Entity DO Field Rule/Note

ID RetailTransactionPromotionPriceDerivationRule ExternalActionID If the length of the element in the request exceeds 60 chars, business error GKR-100501 is sent back. If the element in the request is missing, business error GKR-100506 is sent back.

Text - - See mapping of ExternalActionTextType.

Page 235: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

235

Element/Attribute DO Entity DO Field Rule/Note

Parameter - - See mapping of ExternalActionParameterType.

any - -

11.1.1.1.24 ExternalActionTextType

Element/Attribute

DO Entity DO Field Rule/Note

- RetailTransactionPromotionExternalActionText

PromotionID = RetailTransactionPromotionPriceDerivationRule.PromotionID

- RetailTransactionPromotionExternalActionText

PriceDerivationRuleID

= RetailTransactionPromotionPriceDerivationRule.PriceDerivationRuleID

- RetailTransactionPromotionExternalActionText

PriceDerivationRuleEligibilityID

= RetailTransactionPromotionPriceDerivationRule.PriceDerivationRuleEligibilityID

Value (the content of the element itself)

RetailTransactionPromotionExternalActionText

Text If the length of the element in the request exceeds 255 chars, business error GKR-100501 is sent back. If the element in the request is missing or empty, business error GKR-100506 is sent back.

ID RetailTransactionPromotionExternalActionText

Key.TextID If the length of the element in the request exceeds 60 chars, business error GKR-100501 is sent back. If the element in the request is missing, business error GKR-100506 is sent back. It must be unique in the context of the current external action (applied price derivation rule), otherwise business error GKR-100505 is sent back.

11.1.1.1.25 ExternalActionParameterType

Element/Attribute

DO Entity DO Field Rule/Note

- RetailTransactionPromotionExternalActionParameter

PromotionID = RetailTransactionPromotionPriceDerivationRule.PromotionID

- RetailTransactionPromotionExternalActionParameter

PriceDerivationRuleID

= RetailTransactionPromotionPriceDerivationRule.PriceDerivationRuleID

- RetailTransactionPromotionExternalActionParameter

PriceDerivationRuleEligibilityID

= RetailTransactionPromotionPriceDerivationRule.PriceDerivationRuleEligibilityID

Page 236: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

236

Element/Attribute

DO Entity DO Field Rule/Note

Value (the content of the element itself)

RetailTransactionPromotionExternalActionParameter

ParameterValue If the length of the element in the request exceeds 255 chars, business error GKR-100501 is sent back. If the element in the request is missing or empty, business error GKR-100506 is sent back.

ID RetailTransactionPromotionExternalActionParameter

Key.ParameterID If the length of the element in the request exceeds 60 chars, business error GKR-100501 is sent back. If the element in the request is missing, business error GKR-100506 is sent back. It must be unique in the context of the current external action (applied price derivation rule), otherwise business error GKR-100505 is sent back.

11.1.1.1.26 FrequentShopperPointsModifierType

extends LoyaltyRewardBase

Element/Attribute

DO Entity DO Field Rule/Note

SequenceNumber

FrequentShopperPointsModifier

Key.FrequentShopperPointsModifierSequenceNumber

It must fall into the smallint/short range, otherwise business error GKR-100501 is sent back. It must be unique in the context of the current line item, otherwise business error GKR-100505 is sent back.

AppliedQuantity FrequentShopperPointsModifier

AppliedQuantity Regarding to the request: Maximum length is 11 including 3 decimal places. If the number of integer digits exceeds 8 business error GKR-100502 is returned. If the number of decimal places exceeds 3, GKR-100501 is sent back. If it is missing for a FrequentShopperPointsModifier being not prorated from a LoyaltyReward, business error GKR-100506 is sent back. Regarding to the response: In case of prorated FrequentShopperPointsModifier which was generated by the calculation engine, this element should not be provided in response.

Page 237: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

237

Element/Attribute

DO Entity DO Field Rule/Note

ItemLink FrequentShopperPointsModifier

ProrateFrom It must fall into the smallint/short range, otherwise business error GKR-100501 is sent back. If multiple ItemLink elements occur in the request, only the first one is processed.

11.1.1.1.27 PromotionPriceDerivationRuleReferenceType

Element/Attribute

DO Entity DO Field Rule/Note

PromotionID SaleReturnLineItemModifierReference

Key.PromotionID = RetailTransactionPromotionPriceDerivationRule.PromotionID

PriceDerivationRuleID

SaleReturnLineItemModifierReference

Key.PriceDerivationRuleID

= RetailTransactionPromotionPriceDerivationRule.PriceDerivationRuleID

ReferenceQuantity

SaleReturnLineItemModifierReference

ReferenceQuantity Maximum length is 11 including 3 decimal places. If the number of integer digits exceeds 8 business error GKR-100502 is returned. If the number of decimal places exceeds 3, GKR-100501 is sent back.

any - -

11.1.1.1.28 PromotionManualTriggerType

Contains manual triggers which were created by the client in order to make the transaction resp.

line item eligible for promotions containing eligibilities of type "manual trigger".

Element/Attribute DO Entity DO Field Rule/Note

ManualTriggerSequenceNumber

RetailTransactionPromotionTrigger Key.TriggerSequenceNumber

It must fall into the smallint/short range, otherwise business error GKR-100501 is sent back. It must be unique in the context of the current line item (for line item related-manual triggers) resp. the transaction (for transaction-related manual triggers), otherwise business errorGKR-100505 is sent back.

SaleReturnLineItemPromotionTrigger

TriggerSequenceNumber

Page 238: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

238

Element/Attribute DO Entity DO Field Rule/Note

ManualTriggerType RetailTransactionPromotionTrigger TriggerType If the length of the element in the request exceeds 2 chars, business error GKR-100501 is sent back.

SaleReturnLineItemPromotionTrigger

TriggerType

ManualTriggerValue RetailTransactionPromotionTrigger TriggerValue If the length of the element in the request exceeds 255 chars, business error GKR-100501 is sent back.

SaleReturnLineItemPromotionTrigger

TriggerValue

PrivilegeType RetailTransactionPromotionTrigger PrivilegeType If missing from the request GKR-100506 is sent back. If the sent value is not from values

• RS

• RP

• PS

• AM

, then GKR-100500 is sent back.

SaleReturnLineItemPromotionTrigger

PrivilegeType

PrivilegeValue RetailTransactionPromotionTrigger PrivilegeValue If the privilege type field does not have value "AM" and the privilege value is missing from the request or is empty, then GKR-100500 is returned. If it contains negative value, then GKR-100503 is returned.

SaleReturnLineItemPromotionTrigger

PrivilegeValue

PrivilegeValue.Currency - -

ManualTriggerSequenceAddend

RetailTransactionPromotionTrigger TriggerSequenceAddend

SaleReturnLineItemPromotionTrigger

TriggerSequenceAddend

any - -

Page 239: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

239

11.1.1.1.29 PromotionExternalTriggerType

Element/Attribute DO Entity DO Field Rule/Note

ExternalTriggerType RetailTransactionExternalTrigger Key.TriggerTypeCode If it is missing from the request, then GKR-100506 is sent back.

ExternalTriggerAmount RetailTransactionExternalTrigger TriggerAmount

ExternalTriggerAmount.Currency - -

any - -

11.1.1.1.30 DiscountBase

extends RetailPriceModifierDomainSpecific

Element/Attribute DO Entity

DO Field

Rule/Note

ProratedFlag - - Fix true, that is: If the attribute is not provided in request, this means "true". If "false" is provided in request, business error GKR-100500 is sent back. In the response, "true" is always used.

11.1.1.1.31 TenderCouponBase

Element/Attribute DO Entity DO Field Rule/Note

Quantity RetailTransactionCouponSummary InputCount Maximum length is 3 including no decimal places. If the number of integer digits exceeds 3 business error GKR-100502 is returned. If the number of decimal places exceeds 0, GKR-100501 is sent back. If the attribute is missing in the request, it is to be set to 1.

PrimaryLabel RetailTransactionCouponSummary Key.CouponNumber If the length of the element in the request exceeds 40 chars, business error GKR-100501 is sent back. If it is not provided in the request at all, business error GKR-100506 is sent back. If it is not unique (that is, if the same coupon number is used in multiple coupon line items), then GKR-100505 is sent back.

RewardValue RetailTransactionCouponSummary PrivilegeValue If RewardValue is sent but RewardType is not sent GKR-100506 is sent back. If RewardValue is sent but RewardType is not valid, business error GKR-100500 is sent back. If RewardValue is not sent in the request but RewardType is valid, business error GKR-100506 is sent back.

any - -

Page 240: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

240

Element/Attribute DO Entity DO Field Rule/Note

AppliedQuantity RetailTransactionCouponSummary AppliedCount In the request the maximum allowed length is 3 including no decimal places. If the number of integer digits exceeds 3 business error GKR-100502 is returned. If the number of decimal places exceeds 0, GKR-100501 is sent back. If the attribute is missing in the request, it is to be set to 0.

RewardType RetailTransactionCouponSummary PrivilegeType If the request element exists but does not contain a value of the enumeration

• RP - reduction percentage

• RS - reduction amount

• PS - new price amount

business error GKR-100500 is sent back.

11.1.1.1.32 RoundingRuleType

This information is used for rounding the RegularSalesUnitPrice of the line items in the

shopping basket. Only those items with FixedPriceFlag = false are subject to rounding. Rounding of

them is done in a second step after the mapping. Furthermore, this information is used for rounding

the SaleReturnLineItem.ExtendedAmount at all its occurrences.

Element/Attribute DO Entity

DO Field

Rule/Note

any - -

RoundingMethod - - If the attribute exists but does not contain a value of the enumeration

• Up

• Down

• Commercial

business error GKR-100500 is sent back. If the attribute is missing in the request, Commercial is used.

Multiple - - If the attribute exists but does not contain a valid value (valid means that the digit sequence must consist of 0..* zeroes + either one digit "1" or one digit "5" + 0..* zeroes, a decimal point may occur), business errorGKR-100500 is sent back. If the attribute is missing in the request, 0.01 is used.

11.1.1.1.33 DescriptionCommonData

DescriptionCommonData extends String.

This entity contains the descriptive text as, for example, the description text of a business error is in

the BusinessErrorCommonData entity:

<Description Language="EN">Text of the business error</Description>

The complete list of possible errors is described in chapter Business Error Codes.

Page 241: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

241

Name Type Attribute / Element

Cardinality Required Available since interface version

Description / Remarks

Language String Attribute No 2.0 Language code in ISO 639-1 format for the text. The default is EN (English).

value String 1.0 Description test

11.1.1.2 Enumerations

11.1.1.2.1 CalculationMode

This enum was introduced with version 2.0 and consists of the following values:

• Basket

• LineItem

The values are mapped to the Configuration property calculationMode internally.

11.1.1.2.2 PriceDerivationApplicationTypeCode

This enum consists of the following values and is mapped in the response

from com.gk_software.pricing_engine.common.typecodes.PriceModificationMethodTx.

These values correspond to promotion master data object

com.gk_software.pricing_engine.model.md.promotion.RebatePromotionConditionRuleSO field

priceModificationMethodCode.

PriceDerivationApplicationTypeCode PriceModificationMethodTx Description / Remarks

Manual RM

Item - Not supported by PCE

MixMatch MM

FixedPrice PS

PromotionalAward - Not supported by PCE

BuyOneGetOne GP

None NO

DiscountSingle RS

DiscountPercent RP

DiscountTotal RT

FixPriceTotal PT

Page 242: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

242

PriceDerivationApplicationTypeCode PriceModificationMethodTx Description / Remarks

DiscountPercentTotal TP

DiscountPercentTotal2 T2

DiscountTotalInterval TI

ExternalAction EX

SetPriceTotal ST Was introduced with version 2.0 for version 1.0.

Requests ST type is mapped to FixPriceTotal.

11.1.2 Request Mapper

The request mapping from client API to internal model is handled by DataMappingRequest classes in

package com.gk_software.pricing_engine.psi.sapmapping.request.

Class Description

DataMappingARTSCodes Static constants used in mapping.

DataMappingRequestBody Responsible of map com.sap.ppengine.client.dto.PriceCalculateBase.

DataMappingRequestCustomExtension Mapping for data not available in PCE DO model as custom extensions.

DataMappingRequestExternalActionParameter Mapping for com.sap.ppengine.client.dto.ExternalActionParameterType.

DataMappingRequestExternalActionText Mapping for com.sap.ppengine.client.dto.ExternalActionTextType.

DataMappingRequestFrequentShopperPointsModifier Mapping for com.sap.ppengine.client.dto.FrequentShopperPointsModifierType.

DataMappingRequestHeader Responsible to map ARTSCommonHeaderType to transaction.

DataMappingRequestItemBase Mapping for com.sap.ppengine.client.dto.ItemBase.

DataMappingRequestLineItem Responsible to map LineItems from ShoppingBasket to transaction.

DataMappingRequestLoyaltyReward Mapping for com.sap.ppengine.client.dto.LoyaltyRewardBase.

DataMappingRequestMapper Basic entry point for request mapping.

DataMappingRequestMerchandiseHierarchyGroup Mapping for com.sap.ppengine.client.dto.MerchandiseHierarchyCommonData.

Page 243: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

243

Class Description

DataMappingRequestPriceDerivationRuleBase Mapping for com.sap.ppengine.client.dto.PriceDerivationRuleBase.

DataMappingRequestPriceDerivationRuleEligibility Mapping for com.sap.ppengine.client.dto.PriceDerivationRuleEligibility.

DataMappingRequestPriceModificationLineItem Mapping for com.sap.ppengine.client.dto.DiscountBase.

DataMappingRequestPromotionExternalTriggerType Mapping for com.sap.ppengine.client.dto.PromotionExternalTriggerType.

DataMappingRequestPromotionPriceDerivationRuleReference

Mapping for com.sap.ppengine.client.dto.PromotionPriceDerivationRuleReferenceType.

DataMappingRequestRetailPriceModifier Mapping for com.sap.ppengine.client.dto.RetailPriceModifierDomainSpecific.

DataMappingRequestRetailTransactionCouponSummary Mapping for com.sap.ppengine.client.dto.TenderCouponBase.

DataMappingRequestRetailTransactionCustomerGroupAssignment

Mapping of com.sap.ppengine.client.dto.LoyaltyAccountType to custom extension map.

DataMappingRequestRetailTransactionLineItemAssociation

Mapping for com.sap.ppengine.client.dto.ItemBase.ItemLink.

DataMappingRequestRetailTransactionPromotionTrigger Mapping for com.sap.ppengine.client.dto.PromotionManualTriggerType on basket level.

DataMappingRequestSaleReturnLineItemPromotionTriggerType

Mapping for com.sap.ppengine.client.dto.PromotionManualTriggerType on item level.

DataMappingRequestSaleReturnLineItemSalesOrder Special mapping for SalesOrder type items.

DataMappingRequestAnyMapperHelper Any fields request mapping related helper methods.

DataMappingUtils Common helper methods for mapping.

11.1.3 Response Mapper

The request mapping from client API to internal model is handled by DataResponse classes in

package com.gk_software.pricing_engine.psi.sapmapping.response.

Class Description

DataResponseBody Response body data mapping.

DataResponseCouponMapperService Response mapper service for Coupon.

Page 244: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

244

Class Description

DataResponseExternalActionMapperService Data response mapper for ExternalAction.

DataResponseExternalTriggerMapperService Response mapper service for External Triggers.

DataResponseFrequentShopperPointsModifierTypeMapperService Response mapper service for FrequentShopperPointsModifierType.

DataResponseHeader Response header data mapping.

DataResponseLineItemMapperService Service to map LineItemDomainSpecific to the response.

DataResponseLoyaltyRewardService Data response mapper for LoyaltyReward.

DataResponseMapper The response of the Calculation Engine.

DataResponseMultiLanguagesService Data response mapper for MultiLanguages.

DataResponsePromotionManualTriggerTypeMapperService Data Response mapper for PromotionManualTriggerType.

DataResponsePromotionPriceDerivationRuleReferenceTypeMapperService

Data response mapper for PromotionPriceDerivationRuleReferenceType.

DataResponseRetailPriceModifierDomainSpecificMapperService Response mapper service for RetailPriceModifierDomainSpecific.

ReponseDataMapperCommons Response data mapper commons.

DataMappingResponseAnyMapperHelper Any fields response mapping related helper methods.

11.2 Appendix B: Extension Sample code

Disclaimer

The usage of following code by project is at own risk and might need adjustments in project

context that product development is not responsible for.

11.2.1 Custom Bean context com.gk-software.pricing-engine/extension/beans.xml

Page 245: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

245

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!-- Import core bean contexts -->

<import resource="classpath:/com.gk-software.pricing-engine/psi-sap/common.xml" />

<import resource="classpath:/com.gk-software.pricing-engine/psi-sap/beans.xml" />

<import resource="classpath:/com.gk-software.pricing-engine/dataaccess-sap/beans.xml" />

<!-- Extension of Transaction Analyzer, Overwrite standard one-->

<alias name="customCouponTransactionAnalyzer" alias="couponTransactionAnalyzer"/>

<bean id="customCouponTransactionAnalyzer"

class="com.gk_software.pricing_engine.extension.analyzer.CustomCouponTransactionAnalyzer" />

<!-- Extension of Eligibility Loader -->

<bean id="customCouponEligibilityLoader"

class="com.gk_software.pricing_engine.extension.eligibilities.CustomCouponEligibilityLoader"

parent="abstractEligibilityLoader" />

<!-- Add to existing eligibility loader list -->

<alias name="customEligibilityLoaderList" alias="eligibilityLoaderList"/>

<bean id="customEligibilityLoaderList" parent="gkEligibilityLoaderList"

class="org.springframework.beans.factory.config.ListFactoryBean">

<property name="sourceList">

<list merge="true">

<ref bean="customCouponEligibilityLoader"/>

</list>

</property>

</bean>

</beans>

11.2.2 External Coupon Context

A custom context for storing external coupon ids:

Page 246: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

246

package com.gk_software.pricing_engine.extension;

import java.util.HashSet;

import java.util.Set;

/**

* <p>

* <b>Disclaimer:</b> <i>Usage of this code by project is at own risk and might

* need adjustments in project context that product development is not

* responsible for.</i>

* </p>

*

* Custom context for external coupons

*

*/

public class ExternalCouponContext {

private Set<String> externalCouponNumbers = new HashSet<String>();

public Set<String> getExternalCouponNumbers() {

return externalCouponNumbers;

}

public void addExternalCouponNumber(String externalCouponNumber) {

this.externalCouponNumbers.add(externalCouponNumber);

}

}

11.2.3 Extension Context

A helper for accessing the extension context more easily:

Page 247: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

247

package com.gk_software.pricing_engine.extension;

import java.util.HashMap;

import java.util.Map;

import com.gk_software.pricing_engine.api.context.Context;

/**

* <p>

* <b>Disclaimer:</b> <i>Usage of this code by project is at own risk and might

* need adjustments in project context that product development is not

* responsible for.</i>

* </p>

*

* Utility class to get extension data from PCE context

*

*/

public class ExtensionContext {

public static final String EXTENSION_KEY = "SAMPLE_EXTENSION";

/**

* Get an extension context from transaction any object list

*

* @param ctx

* @param contextType

* @return

*/

@SuppressWarnings("unchecked")

public static <T> T getExtensionContext(Context ctx, Class<T> contextType) {

Map<Object, Map<Class<?>, Object>> customExtensionMap = null;

// Transaction.any list is not a right place, but extension context was

// removed

// Extensions should be stored on model directly

if (!ctx.getTransaction().getAny().isEmpty()) {

customExtensionMap = (Map<Object, Map<Class<?>, Object>>)

ctx.getTransaction().getAny().get(0);

}

if (customExtensionMap == null) {

customExtensionMap = new HashMap<>();

ctx.getTransaction().getAny().add(customExtensionMap);

}

Map<Class<?>, Object> ctxExtensionMap = customExtensionMap.get(EXTENSION_KEY);

if (ctxExtensionMap == null) {

ctxExtensionMap = new HashMap<>();

customExtensionMap.put(EXTENSION_KEY, ctxExtensionMap);

}

return (T) ctxExtensionMap.get(contextType);

}

/**

* Add an extension context to transaction any object list

*

* @param ctx The PCE Context

* @param extensionContext The extension context

Page 248: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

248

*/

@SuppressWarnings("unchecked")

public static <T> void addExtensionContext(Context ctx, T extensionContext) {

Map<Object, Map<Class<?>, Object>> customExtensionMap = null;

// Transaction.any list is not a right place, but extension context was

// removed

// Extensions should be stored on model directly

if (!ctx.getTransaction().getAny().isEmpty()) {

customExtensionMap = (Map<Object, Map<Class<?>, Object>>)

ctx.getTransaction().getAny().get(0);

}

if (customExtensionMap == null) {

customExtensionMap = new HashMap<>();

ctx.getTransaction().getAny().add(customExtensionMap);

}

Map<Class<?>, Object> ctxExtensionMap = customExtensionMap.get(EXTENSION_KEY);

if (ctxExtensionMap == null) {

ctxExtensionMap = new HashMap<>();

customExtensionMap.put(EXTENSION_KEY, ctxExtensionMap);

}

ctxExtensionMap.put(extensionContext.getClass(), extensionContext);

}

}

11.2.4 Custom Coupons Handling

11.2.4.1 Custom Coupon Transaction Analyzer

Replacement of standard coupon transaction analyzer to store external coupons in the extension

context:

Page 249: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

249

/**

* <p>

* <b>Disclaimer:</b> <i>Usage of this code by project is at own risk and might

* need adjustments in project context that product development is not

* responsible for.</i>

* </p>

*

* Sample {@link TransactionAnalyzer} implementation Checks Coupon elements in

* transaction for PrivilegeType=EXT.

*

* @author GK Software SE

*/

public class CustomCouponTransactionAnalyzer implements TransactionAnalyzer {

/**

* Logger for this class

*/

private static final Logger LOGGER =

LoggerFactory.getLogger(CustomCouponTransactionAnalyzer.class);

@Override

public void analyzeTransaction(Context context) {

LOGGER.debug("ENTER [analyzeTransaction]");

this.getCouponNumbers(context);

this.logAnalyzedData(context);

LOGGER.debug("LEAVE [analyzeTransaction]");

}

/**

* Analyze the coupons of the transaction for special external type

*

* @param context

*/

protected void getCouponNumbers(Context context) {

LOGGER.debug("ENTER [getCouponNumbers]");

// Get transaction coupon data from context

Transaction transaction = context.getTransaction();

RetailTransaction retailTransaction = transaction.getRetailTransaction();

List<RetailTransactionCouponSummary> retailTransactionCouponSummaryList =

retailTransaction

.getRetailTransactionCouponSummaryList();

if (CollectionUtils.isEmpty(retailTransactionCouponSummaryList)) {

LOGGER.debug("LEAVE [getCouponNumbers] No transaction coupons");

return;

}

for (RetailTransactionCouponSummary retailTransactionCouponSummary :

retailTransactionCouponSummaryList) {

String couponNumber = retailTransactionCouponSummary.getKey().getCouponNumber();

if (StringUtils.isNotEmpty(couponNumber)) {

// Add coupon to standard context.

context.getTransactionAnalyzerContext().addCouponNumber(couponNumber);

// Use SecureLogger to log external provided values to prevent CWE-117:

// Improper Output Neutralization for Logs

SecureLogger.debug(LOGGER, "Add couponNumber {} to context", couponNumber);

// required for POS mode

if (context.getConfiguration().getIncrementalCalculationMode() !=

IncrementalCalculationMode.Disabled

&& retailTransactionCouponSummary.getAppliedCount() != null) {

Page 250: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

250

// Clear applied count in case of incremental mode

retailTransactionCouponSummary.setAppliedCount(toBigDecimal(0.0));

SecureLogger.debug(LOGGER, "Reseted coupon with couponNumber {} to

AppliedCount=0.0", couponNumber);

}

checkExternalCoupon(context, retailTransactionCouponSummary, couponNumber);

}

}

LOGGER.debug("LEAVE [getCouponNumbers]");

}

protected void checkExternalCoupon(Context context, RetailTransactionCouponSummary

retailTransactionCouponSummary,

String couponNumber) {

// Check coupons for Privilege Type = EXT

if ("EXT".equalsIgnoreCase(retailTransactionCouponSummary.getPrivilegeType())) {

String extCouponNr = "EXT-" + couponNumber;

// Add to custom extension

ExternalCouponContext externalCoupons = ExtensionContext.getExtensionContext(context,

ExternalCouponContext.class);

if (externalCoupons == null) {

externalCoupons = new ExternalCouponContext();

ExtensionContext.addExtensionContext(context, externalCoupons);

}

externalCoupons.addExternalCouponNumber(extCouponNr);

// Use SecureLogger to log external provided values to prevent

// CWE-117:

// Improper Output Neutralization for Logs

SecureLogger.debug(LOGGER, "Add couponNumber {} to custom context", extCouponNr);

}

}

protected void logAnalyzedData(Context ctx) {

if (LOGGER.isDebugEnabled()) {

StringBuilder sb = new StringBuilder();

sb.append("CustomCouponTransactionAnalyzer summary:");

Set<String> couponNumbers = ctx.getTransactionAnalyzerContext().getCouponNumberSet();

if (couponNumbers != null) {

for (String couponNo : couponNumbers) {

sb.append(" - Coupon: ");

sb.append(couponNo);

}

}

ExternalCouponContext externalCoupons = ExtensionContext.getExtensionContext(ctx,

ExternalCouponContext.class);

if (externalCoupons != null) {

for (String couponNo : externalCoupons.getExternalCouponNumbers()) {

sb.append(" - ExtCoupon: ");

sb.append(couponNo);

}

}

LOGGER.debug(SecureLogger.sanitizeLogString(sb.toString()));

}

}

}

Page 251: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

251

11.2.4.2 Custom Coupon Eligibility Loader

A new eligibility loader to simulate loading coupon eligibilities from a different data source:

Page 252: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

252

package com.gk_software.pricing_engine.extension.eligibilities;

import java.util.List;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.gk_software.pricing_engine.api.EligibilityLoader;

import com.gk_software.pricing_engine.api.context.Context;

import com.gk_software.pricing_engine.api.context.EligibilityWrapper;

import com.gk_software.pricing_engine.api.context.EligibilityWrapper.EligibilityStatus;

import com.gk_software.pricing_engine.api.utils.ContextUtils;

import com.gk_software.pricing_engine.common.logging.SecureLogger;

import com.gk_software.pricing_engine.common.typecodes.EligibilityTypeCodes;

import com.gk_software.pricing_engine.eligibility_loader.AbstractEligibilityLoader;

import com.gk_software.pricing_engine.extension.ExtensionContext;

import com.gk_software.pricing_engine.extension.ExternalCouponContext;

import

com.gk_software.pricing_engine.model.md.promotion.CouponPromotionConditionEligibilitySO;

/**

* <p>

* <b>Disclaimer:</b> <i>Usage of this code by project is at own risk and might

* need adjustments in project context that product development is not

* responsible for.</i>

* </p>

*

* Coupon eligibility loader.

*

* It tries to find {@link CouponPromotionConditionEligibilitySO} for collected

* coupon data

* {@link ExternalCouponContext}.

* If one exists it will be activated.

*/

public class CustomCouponEligibilityLoader extends AbstractEligibilityLoader implements

EligibilityLoader {

private static final Logger LOGGER =

LoggerFactory.getLogger(CustomCouponEligibilityLoader.class);

@Override

public void execute(Context context) {

LOGGER.debug("ENTER [execute]");

// Get custom coupon numbers

ExternalCouponContext couponContext = ExtensionContext.getExtensionContext(context,

ExternalCouponContext.class);

Long businessUnitGroupID = context.getBusinessUnitGroupID();

for (String couponNumber : couponContext.getExternalCouponNumbers()) {

// Load eligibility from data access layer

List<CouponPromotionConditionEligibilitySO> loadedEligibilities =

this.dataAccessService.getCouponEligibilities(

Page 253: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

253

context, businessUnitGroupID, couponNumber,

ContextUtils.getSaleReturnTypeCodesForSales(context));

// Store loaded Eligibilities in this Context List

List<EligibilityWrapper<CouponPromotionConditionEligibilitySO>> couponEligibilities =

context

.getEligibilityLoaderContext().getCouponEligibilitiyList();

for (CouponPromotionConditionEligibilitySO loadedEligibility : loadedEligibilities) {

// Create EligibilityWrapper and add the loaded Eligibility to it

EligibilityWrapper<CouponPromotionConditionEligibilitySO> eligibilityWrapperCoupon =

getObjectFactory()

.createEligibilityWrapper();

// Check loaded Eligibility Status Code

String eligibilityStatusCode = loadedEligibility.getStatusCode();

// Set status to inactive if not activated in master data

if (eligibilityStatusCode != null &&

!EligibilityTypeCodes.STATUS_CODE_ACTIVE.equals(eligibilityStatusCode)) {

SecureLogger.debug(LOGGER, "Coupon eligibility id {} with coupon number {} has not

status 'Active'",

loadedEligibility.getInternalEligibilityID(),

loadedEligibility.getCouponNumber());

SecureLogger.trace(LOGGER, "{}", eligibilityWrapperCoupon);

eligibilityWrapperCoupon.setStatus(EligibilityStatus.INACTIVE);

continue;

}

eligibilityWrapperCoupon.setEligibility(loadedEligibility);

eligibilityWrapperCoupon.setStatus(EligibilityStatus.ACTIVE);

// Add EligibilityWrapper to Context List

couponEligibilities.add(eligibilityWrapperCoupon);

// Register the eligbility

super.registerEligibility(context, eligibilityWrapperCoupon);

// Activate elgibility

super.positionEligibilityActivated(context,

loadedEligibility.getInternalEligibilityID(),

loadedEligibility.getParentEligibilityID());

LOGGER.debug("--- finished activation of coupon eligibility: {}, consumptionTypeCode:

{}",

loadedEligibility.getInternalEligibilityID(),

loadedEligibility.getConsumptionTypeCode());

}

}

LOGGER.debug("LEAVE [execute]");

}

Page 254: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

254

}

11.2.5 Custom Exclusive Check Handler

A new plugin implementation of the ExclusiveCheckHandler extension point, example of using the

ConcurrenceControlVector:

Page 255: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

255

package com.gk_software.pricing_engine.pos.extension.concurrency_control_vector;

import java.util.Map;

import org.apache.commons.lang.BooleanUtils;

import org.apache.commons.lang.StringUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.core.annotation.Order;

import com.gk_software.pricing_engine.api.calculation.ExclusiveCheckHandler;

import com.gk_software.pricing_engine.api.context.Context;

import com.gk_software.pricing_engine.api.result.PositionSummaryResult;

import com.gk_software.pricing_engine.api.result.SummaryResult;

import com.gk_software.pricing_engine.api.rules.PromotionConditionWrapper;

import com.gk_software.pricing_engine.model.md.promotion.PromotionConditionSO;

/**

* <p>

* <b>Disclaimer:</b> <i>Usage of this code by project is at own risk and might

* need adjustments in project context that product development is not

* responsible for.</i>

* </p>

*

* The exclusion vector PromotionPriceDerivationRule.ConcurrenceControlVector

* consists of 10 digits. Each digit corresponds to a flag for the exclusion of

* discount.

*

*/

@Order(999)

public class ConcurrenceControlVectorExclusiveCheckHandler implements ExclusiveCheckHandler {

private static final Logger LOGGER =

LoggerFactory.getLogger(ConcurrenceControlVectorExclusiveCheckHandler.class);

@Override

public boolean isExclusiveTransactionCondition(PromotionConditionSO currentCondition,

PromotionConditionSO condition) {

if (currentCondition == null || condition == null) {

return true;

}

final boolean isCurrentConditionNonExclusive =

checkExclusionNonExclusive(currentCondition);

if (isCurrentConditionNonExclusive && isExclusiveCondition(condition)) {

return true;

}

final boolean isCurrentConditionExclusive = checkExclusionExclusive(currentCondition);

return isCurrentConditionExclusive && !isExclusiveCondition(condition);

}

@Override

Page 256: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

256

public boolean isExclusiveLineItemCondition(PromotionConditionSO condition) {

if (condition != null && isExclusiveCondition(condition)) {

String concurrenceVector = condition.getConcurrenceControlVector();

return concurrenceVector == null || concurrenceVector.length() > 0 &&

checkExclusionVector03(concurrenceVector);

}

return false;

}

@Override

public boolean canApplyConditionExclusiveCheck(Context context, SummaryResult summaryResult,

PromotionConditionSO promotionCondition) {

boolean isLineItemCalculation = summaryResult instanceof PositionSummaryResult;

return !isLineItemCalculation || !context.isExclusiveTransactionConditionUsed()

|| canConditionBeUsedWithExclusiveTxCondition(promotionCondition);

}

@Override

public boolean canApplyExclusiveCondition(Context context, PromotionConditionSO

testedCondition,

Long priceDerivationRuleEligibilityID) {

Map<Long, PromotionConditionWrapper> promotionConditionMap =

context.getPromotionConditionContext()

.getPromotionConditionMapByEligibilityID();

PromotionConditionWrapper conditionWrapper =

promotionConditionMap.get(priceDerivationRuleEligibilityID);

PromotionConditionSO condition = conditionWrapper.getPromotionCondition();

return !(isExclusiveCondition(condition) && testedCondition.getSequence() >

condition.getSequence()

&& !this.canBeCombinedWithExclusiveCondition(testedCondition));

}

/**

* Checks if the {@link PromotionConditionSO} is exclusive

*

* @param condition the condition

* @return True if the condition is exclusive

*/

protected boolean isExclusiveCondition(PromotionConditionSO condition) {

return BooleanUtils.isTrue(condition.getExclusiveFlag());

}

/**

* At digit 1:

* <p>

* value 1 -> A receipt related condition can only be combined with

* non-exclusive line item related conditions.

* <p>

* value 3 -> A receipt related condition cannot be combined with a line item

* related condition.

*

* @param condition condition to check

* @return True if condition is non-exclusive

Page 257: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

257

*/

private boolean checkExclusionNonExclusive(PromotionConditionSO condition) {

String concurrenceVector = condition.getConcurrenceControlVector();

return concurrenceVector == null || concurrenceVector.length() < 2

|| (!checkExclusionVector11(concurrenceVector) &&

!checkExclusionVector13(concurrenceVector));

}

/**

* At digit 1:

* <p>

* value 2 -> A receipt related condition can only be combined with exclusive

* line item related conditions.

* <p>

* value 3 -> A receipt related condition cannot be combined with a line item

* related condition.

*

* @param condition condition to check

* @return true if condition is exclusive

*/

private boolean checkExclusionExclusive(PromotionConditionSO condition) {

String concurrenceVector = condition.getConcurrenceControlVector();

return concurrenceVector == null || concurrenceVector.length() < 2

|| (!checkExclusionVector12(concurrenceVector) &&

!checkExclusionVector13(concurrenceVector));

}

/**

* Checks if the condition can be used with an exclusive transaction related

* condition

*

* @param condition The {@link PromotionConditionSO}

* @return True if can be used

*/

public boolean canConditionBeUsedWithExclusiveTxCondition(final PromotionConditionSO

condition) {

final String concurrenceControlVector = condition.getConcurrenceControlVector();

boolean canBeUsed = !(concurrenceControlVector == null

|| concurrenceControlVector.length() > 0 &&

checkExclusionVector01(concurrenceControlVector));

if (!canBeUsed) {

LOGGER.debug(

"Position condition with rule ID {} and eligibility ID {} cannot be used because of

exclusive transaction condition ",

condition.getInternalRuleID(), condition.getInternalEligibilityID());

}

return canBeUsed;

}

/**

* Checks if the condition could be combined with an exclusive condition

*

Page 258: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

258

* @param condition The {@link PromotionConditionSO}

* @return True if can be combined

*/

private boolean canBeCombinedWithExclusiveCondition(PromotionConditionSO condition) {

String concurrenceVector = condition.getConcurrenceControlVector();

return !(StringUtils.isEmpty(concurrenceVector)

|| concurrenceVector.length() < 4 || checkExclusionVector30(concurrenceVector));

}

/**

* A line item related condition is deleted by an exclusive receipt related

* condition.

*

* @param concurrenceControlVector The exclusion vector

* @return True if the exclusion vector's 0 position is 1

*/

protected boolean checkExclusionVector01(final String concurrenceControlVector) {

return concurrenceControlVector.charAt(0) == '1';

}

/**

* A receipt related condition deletes line item discounts.

*

* @param concurrenceControlVector The exclusion vector

* @return True if the exclusion vector's 0 position is 3

*/

protected boolean checkExclusionVector03(String concurrenceControlVector) {

return concurrenceControlVector.charAt(0) == '3';

}

/**

* A receipt related condition can only be combined with non-exclusive line

* item related conditions.

*

* @param concurrenceControlVector The exclusion vector

* @return True if the exclusion vector's 1 position is 1

*/

protected boolean checkExclusionVector11(String concurrenceControlVector) {

return concurrenceControlVector.charAt(1) == '1';

}

/**

* A receipt related condition can only be combined with exclusive line

* item related conditions.

*

* @param concurrenceControlVector The exclusion vector

* @return True if the exclusion vector's 1 position is 2

*/

protected boolean checkExclusionVector12(String concurrenceControlVector) {

return concurrenceControlVector.charAt(1) == '2';

}

/**

* A receipt related condition cannot be combined with a line item related

* condition.

Page 259: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

259

*

* @param concurrenceControlVector The exclusion vector

* @return True if the exclusion vector's 1 position is 3

*/

protected boolean checkExclusionVector13(String concurrenceControlVector) {

return concurrenceControlVector.charAt(1) == '3';

}

/**

* A line item/receipt related condition cannot be combined with a line

* item/receipt related exclusive condition.

*

* @param concurrenceControlVector The exclusion vector

* @return True if the exclusion vector's 3 position is 01

*/

protected boolean checkExclusionVector30(String concurrenceControlVector) {

return concurrenceControlVector.charAt(3) == '0';

}

@Override

public boolean supports(PromotionConditionSO condition) {

return condition != null;

}

}

11.2.6 Custom Rebate-able Item Filter

A new plugin implementation of the RebatableItemFilterPlugin extension point, example of using the

ItemDiscountControlVector:

Page 260: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

260

package com.gk_software.pricing_engine.extension.filter.plugin;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.core.annotation.Order;

import com.gk_software.pricing_engine.api.configuration.Configuration;

import com.gk_software.pricing_engine.api.context.Context;

import com.gk_software.pricing_engine.api.filter.plugin.RebatableItemFilterPlugin;

import com.gk_software.pricing_engine.api.rules.PromotionConditionWrapper;

import com.gk_software.pricing_engine.model.md.promotion.PromotionConditionSO;

import com.gk_software.pricing_engine.model.transaction.SaleReturnLineItem;

import com.gk_software.pricing_engine.model.typecodes.DiscountVectorMethodCodeEnum;

/**

* <p>

* <b>Disclaimer:</b> <i>Usage of this code by project is at own risk and might

* need adjustments in project context that product development is not

* responsible for.</i>

* </p>

*

* Filters items, if they are valid for given promotion based on itemDiscountControlVector and

discountTypeCode.

* Item is valid for promotion if position in itemDiscountControlVector defined by

discountTypeCode is 1.

* Example: valid - discountTypeCode=2, itemDiscountControlVector=111

* not valid - discountTypeCode=2, itemDiscountControlVector=110

*

* @since 2.9.3

*/

@Order(999)

public class DiscountControlVectorFilterPlugin implements RebatableItemFilterPlugin {

private static final Logger LOGGER =

LoggerFactory.getLogger(DiscountControlVectorFilterPlugin.class);

@Override

public boolean supports(PromotionConditionWrapper promotionConditionWrapper) {

return promotionConditionWrapper != null &&

promotionConditionWrapper.getPromotionCondition() != null &&

promotionConditionWrapper.getPromotionCondition().getItemDiscountControlVector() !=

null &&

!promotionConditionWrapper.getPromotionCondition().getItemDiscountControlVector().isEmpty();

}

/**

* {@link SaleReturnLineItem} is valid for {@link PromotionConditionWrapper}, if

*

* {@link Configuration#getDiscountVectorMethod()} is {@link

DiscountVectorMethodCodeEnum#ALL},

* {@link SaleReturnLineItem#getDiscountTypeCode()} is not null or empty,

* {@link PromotionConditionSO#getItemDiscountControlVector()} is not null or empty,

* position in vector defined by discountTypecode is 1.

*

Page 261: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

261

* @param context Context.

* @param srLineItem {@link SaleReturnLineItem} to be checked.

* @param promotionConditionWrapper Promotion to be applied.

* @return true, if promotion is possible, else false.

*/

@Override

public boolean accept(Context context, SaleReturnLineItem srLineItem,

PromotionConditionWrapper promotionConditionWrapper) {

String discountTypeCode = srLineItem != null ? srLineItem.getDiscountTypeCode() : null;

String itemDiscountControlVector =

promotionConditionWrapper.getPromotionCondition().getItemDiscountControlVector();

if (discountTypeCode != null && DiscountVectorMethodCodeEnum.ALL.is(

context.getConfiguration().getDiscountVectorMethod())) {

int index = discountTypeCode.charAt(0) - '0';

if (index < 0 || index > 9) {

LOGGER.error("Not accepted: discountTypecode must be in range 0-9, but is {}",

srLineItem);

return false;

}

else if (index >= itemDiscountControlVector.length() ||

itemDiscountControlVector.charAt(index) != '1') {

LOGGER.info("Not accepted: pos. {} on {}", discountTypeCode,

itemDiscountControlVector);

return false;

}

else {

LOGGER.debug("Accepted: pos. {} on {}", discountTypeCode, itemDiscountControlVector);

return true;

}

}

LOGGER.trace("Not tested: pos. {} on {} (conf: {})", discountTypeCode,

itemDiscountControlVector,

context.getConfiguration().getDiscountVectorMethod());

return true;

}

}

11.2.7 Custom Mix&Match Proration Customizer for Scale Discounts

A new plugin implementation of the MixAndMatchProrationCustomizer extension point, example of

customising Mix&Match rules to behave as scale discounts:

Page 262: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

262

package com.gk_software.pricing_engine.example.scale;

import static com.gk_software.pricing_engine.common.utils.NumberUtils.ZERO;

import static com.gk_software.pricing_engine.common.utils.NumberUtils.add;

import static com.gk_software.pricing_engine.common.utils.NumberUtils.isGreaterZero;

import java.math.BigDecimal;

import java.util.Collection;

import java.util.Collections;

import java.util.HashSet;

import java.util.Set;

import org.apache.commons.collections.CollectionUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.core.annotation.Order;

import com.gk_software.pricing_engine.api.PricingEngineAPIFactory;

import com.gk_software.pricing_engine.api.bucket.Bucket;

import com.gk_software.pricing_engine.api.bucket.NormalizedItem;

import com.gk_software.pricing_engine.api.context.Context;

import com.gk_software.pricing_engine.api.price_modification.PriceCalculationResult;

import com.gk_software.pricing_engine.api.result.LineItemSummaryResult;

import com.gk_software.pricing_engine.api.result.LineItemSummaryValues;

import com.gk_software.pricing_engine.api.result.PartialResult;

import com.gk_software.pricing_engine.api.result.PositionSummaryResult;

import com.gk_software.pricing_engine.api.rules.MixAndMatchProrationCustomizer;

import com.gk_software.pricing_engine.api.rules.PromotionConditionWrapper;

import com.gk_software.pricing_engine.api.rules.RebateShareResult;

import com.gk_software.pricing_engine.common.impl.result.LineItemSummaryValuesImpl;

import com.gk_software.pricing_engine.common.impl.result.PositionPartialResult;

import com.gk_software.pricing_engine.common.utils.MixAndMatchUtils;

import com.gk_software.pricing_engine.common.utils.NumberUtils;

import com.gk_software.pricing_engine.common.utils.PartialResultUtils;

import

com.gk_software.pricing_engine.core.price_modification.MixAndMatchPriceCalculationResult;

import com.gk_software.pricing_engine.model.md.promotion.MatchingItemSO;

import com.gk_software.pricing_engine.model.md.promotion.PromotionConditionRuleSO;

import com.gk_software.pricing_engine.model.md.promotion.PromotionConditionSO;

import com.gk_software.pricing_engine.model.typecodes.EligibilityActivationType;

import com.gk_software.pricing_engine.model.typecodes.promotion.ReductionMethodMixAndMatch;

import

com.gk_software.pricing_engine.model.typecodes.promotion.ReductionMethodMixAndMatchEnum;

/**

* <p>

* <b>Disclaimer:</b> <i>Usage of this code by project is at own risk and might

* need adjustments in project context that product development is not

* responsible for.</i>

* </p>

*

* Custom mix and match proration customizer to handle mix&match promotions

* created for scale discounts.

*

* Scale promotions created using mix&match must be created according to the

Page 263: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

263

* following:

*

* - Combination code of the mix&match rule is OR_QUANTITY

*

* - The matching items of the rule each represent a step of the scale discount

* and for each the requiredQuantity is set to the threshold quantity of the

* scale step.

*

* - The matching items' MatchingItemID is set increasing in order of the

* provided discount decreasing. Meaning that the MatchingItem providing the

* HIGHEST scale promotion must have the LOWEST MatchingItemID (and so will be

* processed first), and the MatchingItem granting the lowest scale discount

* amount must have the highest MatchingItemID (and so it will be processed

* last, when all higher scale discounts were not possible)

*

* @author GK Software SE

* @since 3.2.11

*/

@Order(111)

public class ScaleDiscountMixAndMatchProrationCustomizer implements

MixAndMatchProrationCustomizer {

private static final Logger LOGGER =

LoggerFactory.getLogger(ScaleDiscountMixAndMatchProrationCustomizer.class);

private PricingEngineAPIFactory objectFactory;

public ScaleDiscountMixAndMatchProrationCustomizer(PricingEngineAPIFactory objectFactory) {

this.objectFactory = objectFactory;

}

/*

* The plugin should only be executed in case of scale discounts.

*/

@Override

public boolean supports(PartialResult<PositionSummaryResult> partialResult, MatchingItemSO

matchingItem) {

return partialResult != null && partialResult.getConditionWrapper() != null

&& partialResult.getConditionWrapper().getPromotionCondition() != null &&

MappingConstantsCST.SCALE_PRICE_TYPE_CODE

.equals(partialResult.getConditionWrapper().getPromotionCondition().getTypeCode());

}

/*

* Retrieves the items for which the custom proration should be executed. In

* case of RequiredQuantity n applying the custom proration for the first n-1

* matching items will only be done on the matching item itself. Fort the n-th

* item all remaining matching items are returned, not yet prorated as well, so

* the promotion is applied on all available.

*/

@Override

public Collection<LineItemSummaryResult> getProrationItems(Context context,

PartialResult<PositionSummaryResult> partialResult, MatchingItemSO matchingItem) {

PositionPartialResult positionPartialResult = (PositionPartialResult) partialResult;

Page 264: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

264

Bucket<NormalizedItem> normalizedItemBucket = getMatchingNormalizedItems(context,

matchingItem,

positionPartialResult);

if (CollectionUtils.isEmpty(normalizedItemBucket)) {

// no matching items found

return Collections.emptySet();

}

Set<LineItemSummaryResult> prorationItems = new HashSet<>();

BigDecimal processedRequiredItemQuantity = ZERO;

for (NormalizedItem matchingNormalizedItem : normalizedItemBucket) {

LineItemSummaryResult lineItemSummaryResult =

PartialResultUtils.getLineItemSummaryResult(positionPartialResult,

matchingNormalizedItem.getKey());

if (isLineItemSummaryResultValidForCalculation(positionPartialResult.getConditionRule(),

lineItemSummaryResult)) {

processedRequiredItemQuantity = add(processedRequiredItemQuantity,

lineItemSummaryResult.getConditionValues().getActualTriggerQuantity());

// Get all Items to be used in the current interval

if

(lineItemSummaryResult.getMixAndMatchResult().getAppliedMixAndMatchItems().isEmpty()) {

prorationItems.add(lineItemSummaryResult);

if (NumberUtils.compareBD(processedRequiredItemQuantity,

matchingItem.getRequiredQuantity()) < 0) {

// The required quantity of the MatchingItem has not been reached,

// the proration

// must only be performed on the currently processed matching

// normalized item

break;

}

}

}

}

return prorationItems;

}

/**

* Returns all matching normalized items for the given {@link MatchingItemSO}

*

* @param context The PCE {@link Context}

* @param matchingItem The rule's {@link MatchingItemSO} currently processed

* @param positionPartialResult The current partial result

* @return The normalized matching items of the {@link MatchingItemSO}

*/

private Bucket<NormalizedItem> getMatchingNormalizedItems(Context context, MatchingItemSO

matchingItem,

PositionPartialResult positionPartialResult) {

Page 265: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

265

return MixAndMatchUtils.getLineItemsForMatchingItem(context, matchingItem,

positionPartialResult);

}

@Override

public RebateShareResult calculateRebateShare(Context context, Bucket<LineItemSummaryResult>

prorationItems,

MatchingItemSO matchingItem, LineItemSummaryResult currentLineItemSummaryResult,

PriceCalculationResult calculationResult) {

RebateShareResult result = this.objectFactory.createRebateShareResult();

PromotionConditionWrapper conditionWrapper = findPromotionCondition(context,

matchingItem.getInternalRuleID());

if (conditionWrapper == null || !(calculationResult instanceof

MixAndMatchPriceCalculationResult)) {

return result;

}

MixAndMatchPriceCalculationResult mixAndMatchCalculationResult =

(MixAndMatchPriceCalculationResult) calculationResult;

PromotionConditionRuleSO rule = conditionWrapper.getPromotionCondition().getRule();

boolean isCurrentlyCalculatedMatchingItem = currentLineItemSummaryResult

.equals(mixAndMatchCalculationResult.getCalculatedLineItemSummaryResult());

BigDecimal rebateShare = ZERO;

// The rebate share must only be calculated for the currently processed

// normalized matching item when the required quantity has not been reached yet.

// When the required quantity has already been reached, then all remaining

// matching normalized items must be incluede in the discount calculation.

if (isLineItemSummaryResultValidForCalculation(rule, currentLineItemSummaryResult)

&& (mixAndMatchCalculationResult.isLimitReached() ||

isCurrentlyCalculatedMatchingItem)) {

LineItemSummaryValues conditionValues =

currentLineItemSummaryResult.getConditionValues();

LineItemSummaryValues intervalValues = currentLineItemSummaryResult.getIntervalValues();

BigDecimal triggerQuantity = conditionValues.getActualTriggerQuantity();

if (isGreaterZero(triggerQuantity)) {

rebateShare = calculateUnroundedMixAndMatchRebate(conditionWrapper, matchingItem);

result.setShareQuantity(conditionValues.getActualTriggerQuantity());

intervalValues.setUsedTriggerAmount(conditionValues.getActualTriggerAmount());

intervalValues.setUsedTriggerQuantity(triggerQuantity);

if (!isCurrentlyCalculatedMatchingItem) {

// The matching item condition values must also be updated for items that would

// not be included in the promotion calculation without the custom proration

// plugin in order for the discount to be applied

LineItemSummaryValues matchingItemConditionValues =

currentLineItemSummaryResult.getConditionValues();

if(matchingItemConditionValues == null) {

matchingItemConditionValues = new LineItemSummaryValuesImpl("MatchingItem

condition values");

Page 266: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

266

currentLineItemSummaryResult.getMixAndMatchResult().getMatchingItemConditionValues().put(match

ingItem, matchingItemConditionValues);

}

}

}

}

result.setRebateShare(rebateShare);

return result;

}

/**

* Finds the condition in the context for the currently calculated rule

*

* @param context the PCE {@link Context}

* @param ruleID The ID of the calculated mix&match rule

* @return the corresponding condition

*/

private PromotionConditionWrapper findPromotionCondition(Context context, Long ruleID) {

for (PromotionConditionWrapper conditionWrapper : context.getPromotionConditionContext()

.getPromotionConditionMapByEligibilityID().values()) {

PromotionConditionSO promotionCondition = conditionWrapper.getPromotionCondition();

if (promotionCondition.getInternalRuleID().equals(ruleID)) {

return conditionWrapper;

}

}

return null;

}

/**

* Calculated the scale discount amount considering the possible return items as

* well

*

* @param conditionWrapper The currently calculated condition

* @param matchingItem The currently calculated {@link MatchingItemSO}

* @return Returns the scale discount amount

*/

private BigDecimal calculateUnroundedMixAndMatchRebate(PromotionConditionWrapper

conditionWrapper,

MatchingItemSO matchingItem) {

ReductionMethodMixAndMatch reductionMethodCode = matchingItem.getReductionMethodCode();

if (reductionMethodCode.is(ReductionMethodMixAndMatchEnum.REBATE_SINGLE)) {

return getAmountFromSaleReturnTypeCheck(matchingItem, conditionWrapper);

} else {

LOGGER.debug(

"Only absolute discount amounts are supported for scale rebates, "

+ "handling for other reduction methods must be added here as custom extension

whne necessary.");

return null;

}

}

private BigDecimal getAmountFromSaleReturnTypeCheck(MatchingItemSO matchingItem,

PromotionConditionWrapper conditionWrapper) {

Page 267: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

267

EligibilityActivationType activationType =

conditionWrapper.getEligibilityActivationType();

if (EligibilityActivationType.RETURNS.is(activationType)) {

return matchingItem.getPriceModificationAmount().negate();

} else {

return matchingItem.getPriceModificationAmount();

}

}

/**

* Checks if the given line item can be used in the calculation or not

*

* @param rule The currently calculated rule

* @param lineItemSummaryResult The line item summary result to check

* @return True if the line item can be used in the calculation, false otherwise

*/

private boolean isLineItemSummaryResultValidForCalculation(PromotionConditionRuleSO rule,

LineItemSummaryResult lineItemSummaryResult) {

if (lineItemSummaryResult == null ||

lineItemSummaryResult.isLineItemAlreadyUsedForCalculation()) {

return false;

}

if (rule.getBonusPointsFlag()) {

return lineItemSummaryResult.isBonuspointPosition();

} else {

return lineItemSummaryResult.isRebatablePosition();

}

}

}

11.2.8 Mapping of Custom Fields

11.2.8.1 GKModelExtractor implementation sample

Example of mapping any fields to GK XXCustom fields.

Page 268: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

268

package com.gk_software.pricing_engine.pos.extension.model_extractor;

import java.util.List;

import java.util.Map;

import org.springframework.core.annotation.Order;

import com.gk_software.gkr.api.txpool.dto.Transaction;

import com.gk_software.pricing_engine.gk.model.plugin.GKModelExtractor;

/**

* <p>

* <b>Disclaimer:</b> <i>Usage of this code by project is at own risk and might

* need adjustments in project context that product development is not

* responsible for.</i>

* </p>

*

* GK model extractor responsible to map any fields to XXCustom[0-15] fields

*

* @author GK Software AG

* @since 3.0.0

*/

@Order(1000)

public class GKModelExtractorImpl implements GKModelExtractor {

/**

* Map any fields to XXCustom[0-15] fields

* @param transactionGK

* POS transaction (will set in response)

*/

@SuppressWarnings("unchecked")

@Override

public void mapAnyToCustomFields(

final com.gk_software.pricing_engine.gk.model.transaction.TransactionGk transactionGK) {

if (transactionGK == null) {

throw new IllegalArgumentException("transaction or engineResponseTransaction can not be

null");

}

final Transaction adaptedObject = transactionGK.getAdaptedObject();

final List<Object> any = transactionGK.getAny();

// TODO do we check all fields into any to find a map?

if (any != null && any.get(0) instanceof Map) {

extractValues(adaptedObject, any);

}

}

@SuppressWarnings("unchecked")

private void extractValues(Transaction transaction, List<Object> any) {

final Map<String, String> extensions = (Map<String, String>) any.get(0);

if (extensions == null) {

return;

}

Page 269: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

269

for (Map.Entry<String, String> entry : extensions.entrySet()) {

if (entry.getValue() == null) {

continue;

}

if (entry.getKey().equalsIgnoreCase("xxCustom01")) {

transaction.setXXCustom01(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom02")) {

transaction.setXXCustom02(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom03")) {

transaction.setXXCustom03(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom04")) {

transaction.setXXCustom04(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom05")) {

transaction.setXXCustom05(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom06")) {

transaction.setXXCustom06(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom07")) {

transaction.setXXCustom07(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom08")) {

transaction.setXXCustom08(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom09")) {

transaction.setXXCustom09(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom10")) {

transaction.setXXCustom10(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom11")) {

transaction.setXXCustom11(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom12")) {

transaction.setXXCustom12(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom13")) {

transaction.setXXCustom13(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom14")) {

transaction.setXXCustom14(entry.getValue());

}

if (entry.getKey().equalsIgnoreCase("xxCustom15")) {

transaction.setXXCustom15(entry.getValue());

}

} // for

}

@Override

Page 270: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

270

public boolean supports(com.gk_software.pricing_engine.gk.model.transaction.TransactionGk

delimiter) {

return delimiter != null;

}

}

11.2.8.2 GKModelAdapter implementation sample

Example of mapping GK XXCustom fields to any fields.

Page 271: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

271

package com.gk_software.pricing_engine.pos.extension.model_adapter;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import org.springframework.core.annotation.Order;

import com.gk_software.gkr.api.txpool.dto.Transaction;

import com.gk_software.pricing_engine.gk.model.plugin.GKModelAdapter;

/**

* <p>

* <b>Disclaimer:</b> <i>Usage of this code by project is at own risk and might

* need adjustments in project context that product development is not

* responsible for.</i>

* </p>

*

* GK model adapter responsible to map GK XXCustom[0-15] fields into any fields.

*

* @author GK Software AG

* @since 3.0.0

*/

@Order(1000)

public class GKModelAdapterImpl implements GKModelAdapter {

/**

* Map GK XXCustom[0-15] fields into any fields.

*

* @param transactionGK

* the wrapper transaction for internal use in PCE

*/

@SuppressWarnings("unchecked")

@Override

public void mapCustomFieldsToAnyField(

final com.gk_software.pricing_engine.gk.model.transaction.TransactionGk transactionGK) {

if (transactionGK == null) {

throw new IllegalArgumentException("requestTransaction or transactionGK can not be

null");

}

final com.gk_software.gkr.api.txpool.dto.Transaction requestTransaction =

transactionGK.getAdaptedObject();

final Map<String, String> values = extractValues(requestTransaction);

final List<Object> any = transactionGK.getAny();

if (any != null) {

any.add(values);

}

}

private Map<String, String> extractValues(Transaction requestTransaction) {

final Map<String, String> values = new HashMap<String, String>();

final String xxCustom01 = requestTransaction.getXXCustom01();

if (xxCustom01 != null) {

Page 272: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

272

values.put("xxCustom01", xxCustom01);

}

final String xxCustom02 = requestTransaction.getXXCustom02();

if (xxCustom02 != null) {

values.put("xxCustom02", xxCustom02);

}

final String xxCustom03 = requestTransaction.getXXCustom03();

if (xxCustom03 != null) {

values.put("xxCustom03", xxCustom03);

}

final String xxCustom04 = requestTransaction.getXXCustom04();

if (xxCustom04 != null) {

values.put("xxCustom04", xxCustom04);

}

final String xxCustom05 = requestTransaction.getXXCustom05();

if (xxCustom05 != null) {

values.put("xxCustom05", xxCustom05);

}

final String xxCustom06 = requestTransaction.getXXCustom06();

if (xxCustom06 != null) {

values.put("xxCustom06", xxCustom06);

}

final String xxCustom07 = requestTransaction.getXXCustom07();

if (xxCustom07 != null) {

values.put("xxCustom07", xxCustom07);

}

final String xxCustom08 = requestTransaction.getXXCustom08();

if (xxCustom08 != null) {

values.put("xxCustom08", xxCustom08);

}

final String xxCustom09 = requestTransaction.getXXCustom09();

if (xxCustom09 != null) {

values.put("xxCustom09", xxCustom09);

}

final String xxCustom10 = requestTransaction.getXXCustom10();

if (xxCustom10 != null) {

values.put("xxCustom10", xxCustom10);

}

final String xxCustom11 = requestTransaction.getXXCustom11();

if (xxCustom11 != null) {

values.put("xxCustom11", xxCustom11);

}

final String xxCustom12 = requestTransaction.getXXCustom12();

if (xxCustom12 != null) {

values.put("xxCustom12", xxCustom12);

}

final String xxCustom13 = requestTransaction.getXXCustom13();

if (xxCustom13 != null) {

values.put("xxCustom13", xxCustom13);

}

final String xxCustom14 = requestTransaction.getXXCustom14();

if (xxCustom14 != null) {

values.put("xxCustom14", xxCustom14);

}

final String xxCustom15 = requestTransaction.getXXCustom15();

Page 273: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

273

if (xxCustom15 != null) {

values.put("xxCustom15", xxCustom15);

}

return values;

}

@Override

public boolean supports(com.gk_software.pricing_engine.gk.model.transaction.TransactionGk

delimiter) {

return delimiter != null;

}

}

11.2.8.3 GKDataAccessModelAdapter implementation sample

Example of mapping GK XXCustom fields to any fields.

Page 274: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

274

package com.gk_software.pricing_engine.pos.extension.dataaccess_model_adapter;

import java.util.HashMap;

import java.util.Map;

import org.springframework.core.annotation.Order;

import com.gk_software.pricing_engine.gk.model.plugin.GKDataAccessModelAdapter;

import com.gk_software.pricing_engine.model.md.promotion.PromotionSO;

/**

* <p>

* <b>Disclaimer:</b> <i>Usage of this code by project is at own risk and might

* need adjustments in project context that product development is not

* responsible for.</i>

* </p>

*

* Promotion model adapter useful to extract XX Custom [0-5] values and copy

* this values to custom extensions

*

* @author GK Software AG

* @since 3.1.0

*/

@Order(1000)

public class GKDataAccessPromotionModelAdapterImpl<T, S> implements

GKDataAccessModelAdapter<T, S> {

@SuppressWarnings("unchecked")

@Override

public void map(Object from, Object to) {

if (from instanceof com.gk_software.swee.ses.api.server.md.promotion.dto.so.PromotionSO &&

to instanceof PromotionSO) {

com.gk_software.swee.ses.api.server.md.promotion.dto.so.PromotionSO _from =

(com.gk_software.swee.ses.api.server.md.promotion.dto.so.PromotionSO) from;

PromotionSO _to = (PromotionSO) to;

final Map<String, String> xxCustomValues = extractXXCustomValues(_from);

final Map<String, String> toExtensions = (Map<String, String>) _to.getExtensions();

for (Map.Entry<String, String> entry : xxCustomValues.entrySet()) {

if (entry.getValue() == null) {

continue;

}

toExtensions.put(entry.getKey(), entry.getValue());

}

}

}

private Map<String, String> extractXXCustomValues(

com.gk_software.swee.ses.api.server.md.promotion.dto.so.PromotionSO _from) {

final Map<String, String> values = new HashMap<String, String>();

final String xxCustom01 = _from.getXXCustom01();

if (xxCustom01 != null) {

values.put("xxCustom01", xxCustom01);

}

final String xxCustom02 = _from.getXXCustom02();

Page 275: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

275

if (xxCustom02 != null) {

values.put("xxCustom02", xxCustom02);

}

final String xxCustom03 = _from.getXXCustom03();

if (xxCustom03 != null) {

values.put("xxCustom03", xxCustom03);

}

final String xxCustom04 = _from.getXXCustom04();

if (xxCustom04 != null) {

values.put("xxCustom04", xxCustom04);

}

final String xxCustom05 = _from.getXXCustom05();

if (xxCustom05 != null) {

values.put("xxCustom05", xxCustom05);

}

return values;

}

@Override

public boolean supports(Object delimiter) {

return delimiter instanceof PromotionSO;

}

}

11.2.9 Custom PriceModificationMethod RT transaction-related handling

A new plugin implementation of the PriceModification extension point. Example of customizing price

modification to handle method "RT" which results the granted discount is multiplied by the number

of completed intervals.

Page 276: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

276

package com.gk_software.pricing_engine.extension.pricemodification;

import java.math.BigDecimal;

import java.math.MathContext;

import java.math.RoundingMode;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.core.annotation.Order;

import com.gk_software.pricing_engine.api.PricingEngineAPIFactory;

import com.gk_software.pricing_engine.api.context.Context;

import com.gk_software.pricing_engine.api.price_modification.PriceCalculationContext;

import com.gk_software.pricing_engine.api.price_modification.PriceCalculationResult;

import com.gk_software.pricing_engine.api.price_modification.PriceModification;

import com.gk_software.pricing_engine.api.price_modification.TransactionPriceModificationType;

import com.gk_software.pricing_engine.api.result.LineItemSummaryResult;

import com.gk_software.pricing_engine.api.result.PartialResult;

import com.gk_software.pricing_engine.api.rules.PromotionConditionWrapper;

import com.gk_software.pricing_engine.model.md.promotion.MatchingItemSO;

import com.gk_software.pricing_engine.model.md.promotion.PromotionConditionRuleSO;

import com.gk_software.pricing_engine.model.md.promotion.RebatePromotionConditionRuleSO;

import com.gk_software.pricing_engine.model.typecodes.EligibilityActivationType;

import com.gk_software.pricing_engine.model.typecodes.RoundingMethod;

import com.gk_software.pricing_engine.model.typecodes.RoundingMethodEnum;

import com.gk_software.pricing_engine.model.typecodes.promotion.PriceModificationMethod;

import com.gk_software.pricing_engine.model.typecodes.promotion.ReductionMethodMixAndMatch;

/**

* <p>

* <b>Disclaimer:</b> <i>Usage of this code by project is at own risk and might

* need adjustments in project context that product development is not

* responsible for.</i>

* </p>

*

* Custom price modification method handling plugin with the following behavior:

*

* In case of transaction-related promotions with price modification method code

* RT the granted discount should be multiplied by the number of completed

* intervals. No other price modification logic should be affected by the

* change, only RT. As a result the total discount amount will be granted once

* per interval.

*

* Order annotation must define a lower value than the default price

* modification implementation for RT in order for the changes to take effect.

*

* @author GK Software SE

* @since 3.6.5

*/

@Order(99)

public class TotalAbsoluteDiscountPriceModificationCST implements PriceModification {

private static final BigDecimal ZERO = new BigDecimal("0.0");

private static final BigDecimal ONE = new BigDecimal("1.0");

private static final MathContext DEFAULT_MATH_CTX = new MathContext(11);

Page 277: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

277

private static final Logger LOGGER =

LoggerFactory.getLogger(TotalAbsoluteDiscountPriceModificationCST.class);

/**

* The default price modification implementation, only transaction related

* calculation is needed to be customized

*/

private PriceModification delegatePriceModification;

private PricingEngineAPIFactory objectFactory;

public TotalAbsoluteDiscountPriceModificationCST(PriceModification

delegatePriceModification,

PricingEngineAPIFactory objectFactory) {

this.delegatePriceModification = delegatePriceModification;

this.objectFactory = objectFactory;

}

@Override

public boolean supports(PromotionConditionRuleSO rule) {

return delegatePriceModification.supports(rule);

}

@Override

public PriceCalculationResult calculatePositionCondition(Context context, PartialResult<?>

partialResult,

RebatePromotionConditionRuleSO rule, PriceCalculationContext calculationContext) {

return delegatePriceModification.calculatePositionCondition(context, partialResult, rule,

calculationContext);

}

@Override

public PriceCalculationResult calculateMixAndMatchConditionValue(Context context, BigDecimal

condiQuantity,

MatchingItemSO matchingItem, PartialResult<?> partialResult, LineItemSummaryResult

lineItemSummarResult) {

return delegatePriceModification.calculateMixAndMatchConditionValue(context,

condiQuantity, matchingItem,

partialResult, lineItemSummarResult);

}

@Override

public boolean isEqualMixAndMatchReductionMethod(ReductionMethodMixAndMatch reductionMethod)

{

return delegatePriceModification.isEqualMixAndMatchReductionMethod(reductionMethod);

}

@Override

public PriceModificationMethod getPriceModificationMethod() {

return delegatePriceModification.getPriceModificationMethod();

}

@Override

public ReductionMethodMixAndMatch getReductionMethodMixAndMatch() {

return delegatePriceModification.getReductionMethodMixAndMatch();

}

Page 278: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

278

@Override

public boolean isPercentageDiscount() {

return delegatePriceModification.isPercentageDiscount();

}

@Override

public boolean isTotalRebateMethod() {

return delegatePriceModification.isTotalRebateMethod();

}

// Custom discount calculation

@Override

public PriceCalculationResult calculateTransactionCondition(Context context,

PartialResult<?> partialResult,

RebatePromotionConditionRuleSO rule, TransactionPriceModificationType type) {

switch (type) {

case TOTAL_AWARDED_POINTS:

case TOTAL_REBATE:

return calculateCustomResult(partialResult, rule);

default:

LOGGER.warn("Not supported discount type: {} for price modification method: {}", type,

getPriceModificationMethod());

return createEmptyResult();

}

}

private PriceCalculationResult calculateCustomResult(

final PartialResult<?> partialResult,

final RebatePromotionConditionRuleSO rule) {

BigDecimal priceModificationAmount = rule.getPriceModificationAmount();

// Calculate custom price modification amount considering completed interval

// count

int intervalCount = partialResult.getRealIntervalCount();

BigDecimal rebateAmount = priceModificationAmount.multiply(new BigDecimal(intervalCount));

BigDecimal roundingAmount = new BigDecimal("0.0");

if (partialResult.isBonusPointsCondition()) {

RoundingMethod roundingMethod = partialResult.getRoundingMethod();

Integer roundingScale = partialResult.getRoundingScale();

rebateAmount = scaleBigDecimal(priceModificationAmount, roundingScale, roundingMethod);

rebateAmount = roundDiscountAmount(partialResult, rebateAmount);

} else {

rebateAmount = getAmountFromSaleReturnTypeCheck(rebateAmount, partialResult);

}

return createCustomCalculationResult(rebateAmount, roundingAmount,

partialResult.getRebateBase());

}

Page 279: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

279

private BigDecimal getAmountFromSaleReturnTypeCheck(BigDecimal modificationValue,

PartialResult<?> partialResult) {

BigDecimal actualModificationValue = modificationValue;

if (isReturnCalculation(partialResult)) {

return actualModificationValue.negate();

} else {

return actualModificationValue;

}

}

/**

* Create new {@link PriceCalculationResult} set with the passed values

*

* @param amountResult The amount result to set

* @param roundingAmount The rounding amount to set. If null, the rounding

* amount of the result will not be set

* @param calculationBaseAmount The calculation base amount to set

* @param lineItemSummaryResult The {@link LineItemSummaryResult} that the

* result was calculated on

* @return The new {@link PriceCalculationResult} set with the given values

*/

private PriceCalculationResult createCustomCalculationResult(

final BigDecimal amountResult,

final BigDecimal roundingAmount,

final BigDecimal calculationBaseAmount) {

PriceCalculationResult result = this.objectFactory.createPriceCalculationResult();

result.setAmountResult(amountResult);

if (roundingAmount != null) {

result.setRoundingAmount(roundingAmount);

}

result.setCalculationBaseAmount(calculationBaseAmount);

result.setCalculatedLineItemSummaryResult(null);

return result;

}

private PriceCalculationResult createEmptyResult() {

PriceCalculationResult result = objectFactory.createPriceCalculationResult();

result.setAmountResult(ZERO);

result.setRoundingAmount(ZERO);

result.setCalculationBaseAmount(ZERO);

return result;

}

// ----------------

// Calculation utility methods, decoupled from internal PCE implementation to

// avoid issues with version upgrades!

private boolean isReturnCalculation(PartialResult<?> partialResult) {

PromotionConditionWrapper conditionWrapper = partialResult.getConditionWrapper();

EligibilityActivationType activationType =

conditionWrapper.getEligibilityActivationType();

return EligibilityActivationType.RETURNS.is(activationType);

Page 280: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

280

}

private BigDecimal roundDiscountAmount(

final PartialResult<?> partialResult,

final BigDecimal modificationAmount) {

BigDecimal roundValue = modificationAmount;

if (roundValue == null) {

roundValue = ZERO;

}

// used to avoid problems with scaling of values like 1.0000000000009

// (with rounding UP to 2 decimal places

// using round destination 5 this would be 1.05)

BigDecimal scaledValue = scaleBigDecimal(roundValue, 10, RoundingMethodEnum.HALF_UP);

return scaleBigDecimalToDenom(scaledValue, partialResult.getRoundingDenomination(),

partialResult.getRoundingMethod());

}

/**

* Rounding <tt>double</tt> value into required scale, using

* <tt>roundingMode</tt> type of rounding.

*

* @param value <tt>double</tt> value for rounding

* @param scale required scale

* @param roundingMethod rounding mode {@link RoundingMethod}

* @return rounded <tt>double</tt> value

*/

private BigDecimal scaleBigDecimal(BigDecimal value, int scale, RoundingMethod

roundingMethod) {

if (roundingMethod == null || roundingMethod.getRoundingMode() == null) {

return value;

} else {

BigDecimal result = value;

if (result.scale() != scale) {

result = value.setScale(scale, roundingMethod.getRoundingMode());

}

result = result.stripTrailingZeros();

if (scale > 0 && result.scale() < 0) {

result = result.setScale(0);

}

return result;

}

}

/**

* Rounding <tt>double</tt> value to required minimum quantum, using

* <tt>roundingMode</tt> type of rounding. The quantum is typically the smallest

* available denomination of currency (smallest coin) value.

*

* @param value <tt>double</tt> value for rounding

* @param quantum required minimum quantum to which the value is rounded

* @param roundingMode rounding mode (one of ROUND_UP, ROUND_HALF_UP, ROUND_DOWN

Page 281: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

281

* and ROUND_HALF_DOWN)

* @return rounded <tt>double</tt> value

*/

private BigDecimal scaleBigDecimalToDenom(BigDecimal value, BigDecimal quantum,

RoundingMethod roundingMode) {

BigDecimal roundValue = value != null ? value : ZERO;

if (roundingMode == null || roundingMode.getRoundingMode() == null) {

return roundValue;

}

BigDecimal minimumQuantum = (quantum == null || quantum.compareTo(ZERO) == 0) ? ONE :

quantum;

BigDecimal result = divide(roundValue, minimumQuantum);

result = result.setScale(0, roundingMode.getRoundingMode());

result = result.multiply(minimumQuantum).setScale(roundValue.scale(),

RoundingMode.HALF_UP);

result = result.stripTrailingZeros();

if (result.scale() < 1) { // Amounts should have at least one decimal place

result = result.setScale(1);

}

return result;

}

private BigDecimal divide(BigDecimal d1, BigDecimal d2) {

BigDecimal checkedD1 = d1 != null ? d1 : ZERO;

BigDecimal checkedD2 = d2 != null ? d2 : ZERO;

if (ZERO.compareTo(checkedD2) == 0) {

LOGGER.error("[divide] Dividing by zero: {}/{}", d1, d2, new

IllegalArgumentException("Dividing by zero"));

return checkedD1;

} else if (ZERO.compareTo(checkedD1) == 0) {

return ZERO;

} else if (ONE.compareTo(checkedD2) == 0) {

return checkedD1;

} else {

return checkedD1.divide(checkedD2, DEFAULT_MATH_CTX);

}

}

}

Bean context extension:

Page 282: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

282

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<!-- Extension of price modifications -->

<alias name="customTotalAbsoluteDiscountPriceModification"

alias="customTotalAbsoluteDiscountPriceModification" />

<bean id="customTotalAbsoluteDiscountPriceModification"

class="com.gk_software.pricing_engine.extension.pricemodification.TotalAbsoluteDiscountPriceMod

ificationCST">

<constructor-arg name="delegatePriceModification"

ref="totalAbsoluteDiscountPriceModification" />

<constructor-arg name="objectFactory" ref="pricingEngineObjectFactory" />

</bean>

</beans>

11.3 Appendix C: Diagrams

The sequence diagrams listed in the appendix and used in the documentation reflect the

implementation of PCE 2.9.x. As they show the sequence of involved classes and called

methods on a higher level only, they are not expected to change with newer releases. That

being said, the diagrams will be updated when necessary, to reflect the correct behavior of the

PCE.

Page 283: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

283

11.3.1 Pricing Engine Processing Flow

11.3.2 Price Calculation Logic (Buckets) Diagram

Page 284: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

284

11.3.3 Pricing Engine Request Processing

Page 285: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

285

11.3.4 Pricing Engine Calculation Process

Page 286: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

286

Page 287: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

287

Page 288: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

288

11.3.5 Eligibility Loading Process

Page 289: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

289

11.3.6 Condition Loading Process

Page 290: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

290

11.3.7 Condition Calculation Process

Page 291: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

291

11.3.8 Promotion Calculation Process

Page 292: GK/Retail SAP Promotion Calculation Engine SDK Promotion

SDK Promotion Calculation Engine

© 2020 SAP SE or an SAP affiliate company. All rights reserved.

292

11.3.9 Update Transaction Process