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 +4 -4
- data/Gemfile +2 -0
- data/Gemfile.lock +3 -1
- data/lib/unit4/checkout/checkout.rb +82 -18
- data/lib/unit4/checkout/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: daaa49e8775ebbc94ab1fcd91ebc047772dcf21a129487c1a7661ee4137071ff
|
4
|
+
data.tar.gz: 64c3fcd3083a1d907505c05df723ae6b380968ebdf99f7e3b59a87a8b7e4a46e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea07d980c46d2cb90f2d8b2e3db5049438472b70d6562246a59d457548d8066b42b0b0566f768372a44c89cc18540185e8b70763cb68d36483bb805136b4993e
|
7
|
+
data.tar.gz: fc7d39fe9a7b4b383d1b8d77f4f96f1a46f6b279f1d501302f00bac20f7575c246c1534134d50c238549e1656dcbaceaffbac965de79aee4b1ddde8ed18d2041
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
unit4-checkout (0.1.
|
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, :
|
7
|
+
attr_reader :promotional_rules, :total, :basket, :total_price_discount_applied_flag, :result
|
8
8
|
|
9
|
-
|
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
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
37
|
-
|
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
|
74
|
+
def item_discounted?(item)
|
75
|
+
return false unless item_in_discounts?(item)
|
43
76
|
|
44
|
-
|
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
|
47
|
-
|
48
|
-
|
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
|
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.
|
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-
|
11
|
+
date: 2022-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Initial commit
|
14
14
|
email:
|