This project implements a simple cashier function for a small supermarket chain. The cashier function allows adding products to a cart and displaying the total price. It is designed with flexibility to accommodate frequently changing pricing rules.
- Programming Language: Elixir
- Methodology: Test-Driven Development (TDD)
- Repository: GitHub (public)
- Database: Not required
The following test products are registered in the system:
Product Code | Name | Price |
---|---|---|
GR1 | Green tea | £3.11 |
SR1 | Strawberries | £5.00 |
CF1 | Coffee | £11.23 |
- Green Tea (GR1): Buy-one-get-one-free offer.
- Strawberries (SR1): Price drops to £4.50 per strawberry if 3 or more are purchased.
- Coffee (CF1): Price drops to two-thirds of the original price if 3 or more are purchased.
The checkout system can scan items in any order. Below are some test cases:
Total Price Expected: £22.45
Total Price Expected: £3.11
Total Price Expected: £16.61
Total Price Expected: £30.57
- Clone the repository:
git clone https://github.com/ivanovskairena/supermarket_cashier.git
cd supermarket_cashier
- Install dependencies:
mix deps.get
- Run tests:
mix test
- Run credo and dialyzer checks
mix credo
mix dialyzer
- Generate test coverage report
mix coveralls.html
To interact with the SupermarketCashier module in IEx, follow these steps:
- Start IEx session
Navigate to your project directory and start an IEx session with Mix:
iex -S mix
- Define pricing rules:
pricing_rules = [
{SupermarketCashier.PricingRules.BuyOneGetOneFree, :apply_rule},
{SupermarketCashier.PricingRules.BulkDiscount, :apply_rule},
{SupermarketCashier.PricingRules.MultiDiscount, :apply_rule}
]
- Start the Checkout process
{:ok, pid} = SupermarketCashier.Checkout.new(pricing_rules)
- Test individual scans:
SupermarketCashier.Checkout.scan(pid, "GR1")
IO.puts("Total after scanning GR1: #{SupermarketCashier.Checkout.total(pid)}")
SupermarketCashier.Checkout.scan(pid, "SR1")
IO.puts("Total after scanning SR1: #{SupermarketCashier.Checkout.total(pid)}")
SupermarketCashier.Checkout.scan(pid, "GR1")
IO.puts("Total after scanning GR1: #{SupermarketCashier.Checkout.total(pid)}")
SupermarketCashier.Checkout.scan(pid, "GR1")
IO.puts("Total after scanning GR1: #{SupermarketCashier.Checkout.total(pid)}")
SupermarketCashier.Checkout.scan(pid, "CF1")
IO.puts("Total after scanning CF1: #{SupermarketCashier.Checkout.total(pid)}")
SupermarketCashier.Checkout.total(pid)
IO.puts("Total: #{total}")
- Start IEx session
Navigate to your project directory and start an IEx session with Mix:
iex -S mix
- Alias the BasketScan Helper
alias SupermarketCashier.BasketScan
- Define pricing rules:
pricing_rules = [
{SupermarketCashier.PricingRules.BuyOneGetOneFree, :apply_rule},
{SupermarketCashier.PricingRules.BulkDiscount, :apply_rule},
{SupermarketCashier.PricingRules.MultiDiscount, :apply_rule}
]
- Start the Checkout process
{:ok, pid} = SupermarketCashier.Checkout.new(pricing_rules)
- Add Items to the Basket
items = ["GR1", "SR1", "GR1", "GR1", "CF1"]
- Test the result
total = BasketScan.test_basket(pricing_rules, items)
IO.puts("Total: #{total}")