Skip to content

A huge retail store wants a rule engine that qualifies orders' transactions to discounts based on a set of "qualifying rules" and automatically calculates the proper discount based on some "calculation rules". The program is written in Scala in a pure functional manner.

License

Notifications You must be signed in to change notification settings

mennamamdouh/Building-a-Flexible-Discount-Engine-for-a-Retail-Store-with-Scala

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Building-a-Flexible-Discount-Engine-for-a-Retail-Store-with-Scala

Table of Contents


Overview

A huge retail store wants a rule engine that qualifies orders' transactions to discounts based on a set of qualifying rules and automatically calculates the proper discount based on some calculation rules. The program is written in Scala in a pure functional manner.


Business Requirements

As mentioned above, the retail store has many orders to specify whether they need a discount or not, then add discount to them according to a specific criteria. This criteria has some qualifying rules and each qualifying rule has a corresponding calculation rule to be applied on the orders that meet this qualifying rule. It's a hard process to be performed manually, so a Discount Engine is used to ease this process and make changing the criteria at any time a more flexible action.

Let's dig deeper into the discount engine's qualifying rules and their corresponding calculation rules:

Image

Discount Engine Criteria: Qualifying Rules and their corresponding Calculation Rules

Extra Rules:

  • Transactions that didn't qualify to any discount will have 0% discount
  • Transactions that qualified to more than one discount will get the average of the top 2 discounts
  • Extra qualifying and calculation rules may be added at any time

Business also needs to store the processed information into any database, I chose Oracle DBMS.


Technical Requirements

Our discount engine needs to be written in Scala. Scala supports many programming paradigms, Imperative Programming, Functional Programming, and OOP.

But, to have this discount engine to be flexible in enhancement, the code has to be written in pure functional manner. So, many technical requirements need to be satisfied in our code:

  • No mutable variables or data structures allowed
  • No loops allowed
  • All functions must be pure:
    • Output depends solely on input
    • Inputs to the functions don't get mutated
    • Have a predictable behavior
    • No side effects

Also, a log file is required for the purpose of monitoring the flow of the program and for debugging.

So in this project, I'll to write some code in Scala with Functional Programming Paradigm to implement this Discount Engine so that our Retail Store can use it, add discounts to orders, and get their customers' satisfaction!


Data Source

Data source is simply a csv file which contains information about large number of orders such as:

  • Order's date and time
  • Product name of this order
  • Expiry date of the product
  • Quantity of the product
  • Unit price of the product
  • Channel of the order → Store - App
  • Payment method → Cash - Visa

To explore the data and download it please check TRX1000.csv file.


Code Explaination

The program's code is divided into 3 files, DiscountEngine, CriteriaFunctions, and DBConnection.

  • DiscountEngine: Has the main flow of the program.

    • Reading the orders' data from a csv file
    • Parsing each line as an object of Order datatype
    • Applying a list of qualifying and calculation rule paris to each order
    • Calculates the final discount of the order

      Final discount is the average of the top 2 discounts.

    • Finally storing orders with the price before discount and the final price after applying the discount into an Oracle table.
  • CriteriaFunctions: Has all the qualifying rules and their corresponding calculation rules.

    • All qualifying rules takes an object of Order data type and returns true if it satisfies the rule, and false if not.
    • All calculation rules takes an object of Order data type (that satisfied the corresponding qualifying rule) and returns a decimal value which represents the discount that may be applied on that order.
  • DBConnection: Has the database functionalities such as openning a database connection, writing into Orders table, and closing the connection.

Each file has its own Logger which logs the events of that file. Loggers are explained below ↓ in the Logging Functionality section.

In codes directory, there's another sql file which is OrdersTable. It containes the creation code of the table on Oracle DBMS.

Note: All codes are well-commented and all functions are well-explained using scaladoc.


Logging Functionality

It was required to generate a log file which logs the engine's events. It's built using scala-logging library with the help of scala-logging repository.

Logging system has 3 loggers, discount.engine, criteria.functions, and database.connection. Also, it has 3 levels of logs, info, debug, and error.

Here's a snapshot of the log file:

Image

A snapshot from the log file of our Discount Engine

Click here to explore the whole log file → rules_engine.log


How to run the project ?

  1. Download the project folder DiscountEngine under the IntelliJ directory.

  2. Open it using IntelliJ Community Edition software.

  3. Download the required libraries under the libraries directory.

    a. ojdbc7-12.1.0.2 to connect to Oracle DBMS.

    It's compatible with Oracle Database 11g Express Edition Release 11.2.0.2.0 and Java SE 8 - jdk8. If you've another versions, please download the proper JDBC version.

    b. kotlin-stdlib-1.4.0, java-dotenv-5.2.2, and annotations-13.0 to hanle the environment variables. [Optional]

  4. Import the libraries in IntelliJ through Files → Project Structure → Modules → Dependencies.

  5. Replace your database credentials in the .env file, or you can add them in DBConnection file itself by assigning them to the varibales.

  6. Run the code, show the data inserted into Orders table in the database, explore the log file for more information about the flow, and enjoy your Discount Engine !

About

A huge retail store wants a rule engine that qualifies orders' transactions to discounts based on a set of "qualifying rules" and automatically calculates the proper discount based on some "calculation rules". The program is written in Scala in a pure functional manner.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages