unit4-checkout 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83982e7ddae1c09934ca1125ae9cfb0b0b8b845638fbce0eb19472137057652b
4
- data.tar.gz: fb8982c906834e642dcaedbd81cdb89f258555c1dcbab7f73dc1387a9cd609fa
3
+ metadata.gz: daaa49e8775ebbc94ab1fcd91ebc047772dcf21a129487c1a7661ee4137071ff
4
+ data.tar.gz: 64c3fcd3083a1d907505c05df723ae6b380968ebdf99f7e3b59a87a8b7e4a46e
5
5
  SHA512:
6
- metadata.gz: 514d5a25a55f090eb87ebcd5d49ce013b7638efa885e79dd59270c361bcb0462f929140706413d04624a5bfdfdad757f07648dc8403f188d72b07fe36b48bee3
7
- data.tar.gz: 1721ec7136a1c447903ffbfdbad3ce2c7d0fea7ff11c19eed5ca57a5adfcdd3895b16d930d3a34a910dfd2a21ccf5dc08cf7d200f2945872ceb80502fa74b4da
6
+ metadata.gz: ea07d980c46d2cb90f2d8b2e3db5049438472b70d6562246a59d457548d8066b42b0b0566f768372a44c89cc18540185e8b70763cb68d36483bb805136b4993e
7
+ data.tar.gz: fc7d39fe9a7b4b383d1b8d77f4f96f1a46f6b279f1d501302f00bac20f7575c246c1534134d50c238549e1656dcbaceaffbac965de79aee4b1ddde8ed18d2041
data/Gemfile CHANGED
@@ -14,3 +14,5 @@ gem "rubocop", "~> 1.21"
14
14
  gem "activerecord"
15
15
 
16
16
  gem "erb"
17
+
18
+ gem "sqlite3"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- unit4-checkout (0.1.2)
4
+ unit4-checkout (0.1.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -57,6 +57,7 @@ GEM
57
57
  rubocop-ast (1.15.2)
58
58
  parser (>= 3.0.1.1)
59
59
  ruby-progressbar (1.11.0)
60
+ sqlite3 (1.4.4)
60
61
  tzinfo (2.0.5)
61
62
  concurrent-ruby (~> 1.0)
62
63
  unicode-display_width (2.1.0)
@@ -70,6 +71,7 @@ DEPENDENCIES
70
71
  rake (~> 13.0)
71
72
  rspec (~> 3.0)
72
73
  rubocop (~> 1.21)
74
+ sqlite3
73
75
  unit4-checkout!
74
76
 
75
77
  BUNDLED WITH
@@ -4,12 +4,11 @@ require "active_record"
4
4
  require "erb"
5
5
 
6
6
  class Checkout
7
- attr_reader :promotional_rules, :total, :basket, :price_discount_applied_flag, :result
7
+ attr_reader :promotional_rules, :total, :basket, :total_price_discount_applied_flag, :result
8
8
 
9
- # {product_discounts: {001: {count:2, price: 3.25}, 004: {count:2, price: 3.25}}, total_price_discount: $50}
10
- def initialize(promotional_rules)
11
- # maybe raise another error if keys aren't ids or total price, possibly total_item_count
9
+ def initialize(promotional_rules = {})
12
10
  raise TypeError, "expected a Hash, got #{promotional_rules.class.name}" unless promotional_rules.is_a? Hash
11
+ raise KeyError, "expected Hash with optional keys 'product_discounts' and 'total_price_discount" unless correct_keys?(promotional_rules)
13
12
 
14
13
  @promotional_rules = promotional_rules
15
14
  @total = 0
@@ -17,35 +16,100 @@ class Checkout
17
16
  establish_connection
18
17
  end
19
18
 
19
+ def correct_keys?(promotional_rules)
20
+ (promotional_rules.keys - %i[product_discounts total_price_discount]).empty?
21
+ end
22
+
20
23
  # maybe facilitate scanning multiple items at once
21
24
  # no structure for item given, assumed id
22
25
  def scan(item)
23
26
  # check for item id
24
27
  add_to_basket(item)
25
28
  calculate_total(item)
26
- puts "#{item.capitalize} has been added to the basket successfully!"
29
+ puts "Item with ID '#{item}' has been added to the basket successfully!"
30
+ @total
27
31
  end
28
32
 
29
33
  def calculate_total(item)
30
- find_item_price(item)
31
- item_price = 3
32
- new_discount_available?(item) ? apply_discounts : @total += item_price
33
- @total
34
+ item_price = item_price(item)
35
+ if @total_price_discount_applied_flag
36
+ item_discounted?(item) ? apply_item_and_total_discount(item, item_price) : apply_total_discount_on_item(item_price)
37
+ else
38
+ item_discounted?(item) ? apply_item_discount(item, item_price) : @total += item_price
39
+ apply_total_discount if total_price_discounted?
40
+ end
41
+ @total = @total.ceil(2)
42
+ end
43
+
44
+ def item_price(item)
45
+ # TODO: check if user has supplied price
46
+ # TODO: facilitate DB name different from products, i.e. ask gem user for db name???
47
+ find_price_sql(item)
48
+ end
49
+
50
+ def prepare_sql_statement(item)
51
+ # TODO: keep seen items in cache or variable !!!!!!!!!
52
+ ActiveRecord::Base.sanitize_sql_array(["SELECT 'products'.'price' FROM 'products' WHERE 'products'.'id' = ?", item])
53
+ end
54
+
55
+ def apply_item_and_total_discount(item, item_price)
56
+ item_prom_rules = @promotional_rules[:product_discounts][item]
57
+ item_basket_count = @basket.items[item]
58
+ total_discount = (1 - @promotional_rules[:total_price_discount][:percent] / 100.00)
59
+ @total += item_and_total(item_basket_count, item_prom_rules, total_discount, item_price)
60
+ end
61
+
62
+ def item_and_total(item_basket_count, item_prom_rules, total_discount, item_price)
63
+ if item_basket_count == item_prom_rules[:count]
64
+ (item_basket_count * item_prom_rules[:price] - (item_basket_count - 1) * item_price) * total_discount
65
+ else
66
+ item_basket_count * item_prom_rules[:price] * total_discount
67
+ end
34
68
  end
35
69
 
36
- def find_item_price(item)
37
- query = "SELECT * FROM 'users' WHERE 'users'.'id' = ?"
38
- sanitized_query = ActiveRecord::Base.sanitize_sql_array([query, item])
39
- execute_statement(sanitized_query)
70
+ def apply_total_discount_on_item(item_price)
71
+ @total += item_price * (1 - @promotional_rules[:total_price_discount][:percent] / 100.00)
40
72
  end
41
73
 
42
- def apply_discounts; end
74
+ def item_discounted?(item)
75
+ return false unless item_in_discounts?(item)
43
76
 
44
- def new_discount_available?(item); end
77
+ @basket.items[item] >= @promotional_rules[:product_discounts][item][:count]
78
+ end
79
+
80
+ def item_in_discounts?(item)
81
+ @promotional_rules[:product_discounts] && @promotional_rules[:product_discounts][item]
82
+ end
83
+
84
+ def apply_item_discount(item, item_price)
85
+ item_prom_rules = @promotional_rules[:product_discounts][item]
86
+ item_basket_count = @basket.items[item]
87
+ @total += if item_basket_count == item_prom_rules[:count]
88
+ item_basket_count * item_prom_rules[:price] - (item_basket_count - 1) * item_price
89
+ else
90
+ item_prom_rules[:price]
91
+ end
92
+ end
93
+
94
+ def total_price_discounted?
95
+ return false unless total_price_in_discounts?
96
+
97
+ @total >= @promotional_rules[:total_price_discount][:price]
98
+ end
99
+
100
+ def total_price_in_discounts?
101
+ @promotional_rules[:total_price_discount] && @promotional_rules[:total_price_discount][:price]
102
+ end
103
+
104
+ def apply_total_discount
105
+ @total *= (1 - @promotional_rules[:total_price_discount][:percent] / 100.00)
106
+ @total_price_discount_applied_flag = true
107
+ end
45
108
 
46
- def execute_statement(sql)
47
- results = ActiveRecord::Base.connection.exec_query(sql)
48
- @result = results if results.present?
109
+ def find_price_sql(item)
110
+ sanitized_query = prepare_sql_statement(item)
111
+ results = ActiveRecord::Base.connection.exec_query(sanitized_query)
112
+ results.rows.first.first if results.present?
49
113
  end
50
114
 
51
115
  def establish_connection
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Unit4
4
4
  module Checkout
5
- VERSION = "0.1.3"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unit4-checkout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boyan Georgiev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-21 00:00:00.000000000 Z
11
+ date: 2022-07-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Initial commit
14
14
  email: