unit4-checkout 0.1.1 → 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: 25e056e024c30930dc8e8dcd397bee9feb0abd6bcdb2a28c964d7c9328a64e0f
4
- data.tar.gz: 72ed5b82d6d72c2506794a561980fb1bc1885839c21f29e5f03dbd92f5003e3b
3
+ metadata.gz: daaa49e8775ebbc94ab1fcd91ebc047772dcf21a129487c1a7661ee4137071ff
4
+ data.tar.gz: 64c3fcd3083a1d907505c05df723ae6b380968ebdf99f7e3b59a87a8b7e4a46e
5
5
  SHA512:
6
- metadata.gz: 348646bf3be47c132984c6f21d12375321e1d30846ab5b1bf7194063629721a86db078199fc21762ab6294e9ef310ef851156c75e584baf78e6f750e895a27bc
7
- data.tar.gz: cceaee303633c791c525b05cfd769a4f38ffc56085c1f5af3101ea73eacae5d26746285060172eb818676a6c78fb7a262d0ca6fc518dfcdd52d65d8e37fb5696
6
+ metadata.gz: ea07d980c46d2cb90f2d8b2e3db5049438472b70d6562246a59d457548d8066b42b0b0566f768372a44c89cc18540185e8b70763cb68d36483bb805136b4993e
7
+ data.tar.gz: fc7d39fe9a7b4b383d1b8d77f4f96f1a46f6b279f1d501302f00bac20f7575c246c1534134d50c238549e1656dcbaceaffbac965de79aee4b1ddde8ed18d2041
data/Gemfile CHANGED
@@ -15,4 +15,4 @@ gem "activerecord"
15
15
 
16
16
  gem "erb"
17
17
 
18
- # gem "sqlite3"
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.0)
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
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
- item_price = find_item_price(item)
31
- new_discount_available?(item) ? apply_discounts : @total += item_price
32
- @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
68
+ end
69
+
70
+ def apply_total_discount_on_item(item_price)
71
+ @total += item_price * (1 - @promotional_rules[:total_price_discount][:percent] / 100.00)
33
72
  end
34
73
 
35
- def find_item_price(item)
36
- query = "SELECT * FROM 'users' WHERE 'users'.'id' = ?"
37
- sanitized_query = ActiveRecord::Base.sanitize_sql_array([query, item])
38
- execute_statement(sanitized_query)
39
- ActiveRecord::Base.connection.exec_query(sanitized_query)
74
+ def item_discounted?(item)
75
+ return false unless item_in_discounts?(item)
76
+
77
+ @basket.items[item] >= @promotional_rules[:product_discounts][item][:count]
40
78
  end
41
79
 
42
- def apply_discounts; end
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
43
93
 
44
- def new_discount_available?(item); end
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
45
103
 
46
- def execute_statement(sql)
47
- results = ActiveRecord::Base.connection.exec_query(sql)
48
- results if results.present?
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
108
+
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
@@ -54,17 +118,21 @@ class Checkout
54
118
  end
55
119
 
56
120
  def setup_db_config
57
- if defined? Rails && defined? Rails.env
58
- Rails.application.config.database_configuration[Rails.env]
59
- else
60
- # TODO: use current database instead of development
61
- YAML.safe_load(ERB.new(File.read("./config/database.yml")).result, aliases: true)["development"]
62
- end
121
+ defined?(Rails) && defined?(Rails.env) ? rails_db_config : non_rails_db_config
122
+ end
123
+
124
+ def rails_db_config
125
+ Rails.application.config.database_configuration[Rails.env]
126
+ end
127
+
128
+ def non_rails_db_config
129
+ # TODO: use current database instead of development
130
+ YAML.safe_load(ERB.new(File.read("./config/database.yml")).result, aliases: true)["development"]
63
131
  end
64
132
 
65
133
  # maybe add remove item function
66
134
 
67
135
  def add_to_basket(item)
68
- @basket[item] ? @basket["item"] += 1 : @basket["item"] = 1
136
+ @basket.items[item] ? @basket.items[item] += 1 : @basket.items[item] = 1
69
137
  end
70
138
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Unit4
4
4
  module Checkout
5
- VERSION = "0.1.1"
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.1
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: