unit4-checkout 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: