unit4-checkout 0.2.0 → 0.2.1
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 +0 -2
- data/Gemfile.lock +1 -3
- data/lib/unit4/checkout/checkout.rb +10 -42
- data/lib/unit4/checkout/connection.rb +24 -0
- data/lib/unit4/checkout/exceptions.rb +16 -0
- data/lib/unit4/checkout/price_query.rb +16 -0
- data/lib/unit4/checkout/version.rb +1 -1
- data/lib/unit4/checkout.rb +3 -0
- metadata +9 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3539766a2698101358c85167d1f34d563461cdc23b24098439e1948c2e815fba
|
|
4
|
+
data.tar.gz: 40bc469e6c776039f1d2d424b73d9904e08546181af2f95a117fbd9b4e39d553
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7abf3c6c31eeaff5105c9f966d8751e14e94aeb585c31a7a6c3e42321797429ce6ae1e6a7fcd083e30801df9b4795144be22967bb5d759c81ca94af447ce146d
|
|
7
|
+
data.tar.gz: d5c3abb4a0ce0c7599fc5193d44d73560b7de229b1bdb8c9a1607ee71ab2dd569a860292487a9b05fac605082f950a0e6d001fc20a9e119940b03490c6e4a073
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
unit4-checkout (0.
|
|
4
|
+
unit4-checkout (0.2.0)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
@@ -57,7 +57,6 @@ 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)
|
|
61
60
|
tzinfo (2.0.5)
|
|
62
61
|
concurrent-ruby (~> 1.0)
|
|
63
62
|
unicode-display_width (2.1.0)
|
|
@@ -71,7 +70,6 @@ DEPENDENCIES
|
|
|
71
70
|
rake (~> 13.0)
|
|
72
71
|
rspec (~> 3.0)
|
|
73
72
|
rubocop (~> 1.21)
|
|
74
|
-
sqlite3
|
|
75
73
|
unit4-checkout!
|
|
76
74
|
|
|
77
75
|
BUNDLED WITH
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "active_record"
|
|
4
|
-
require "erb"
|
|
5
|
-
|
|
6
3
|
class Checkout
|
|
7
|
-
attr_reader :
|
|
4
|
+
attr_reader :total
|
|
8
5
|
|
|
9
6
|
def initialize(promotional_rules = {})
|
|
10
|
-
raise
|
|
11
|
-
raise
|
|
7
|
+
raise PromotionalRulesTypeError, promotional_rules.class.name unless promotional_rules.is_a? Hash
|
|
8
|
+
raise PromotionalRulesForbiddenKeys unless correct_keys?(promotional_rules)
|
|
12
9
|
|
|
13
10
|
@promotional_rules = promotional_rules
|
|
14
11
|
@total = 0
|
|
15
12
|
@basket = Basket.new
|
|
16
|
-
|
|
13
|
+
create_db_connection
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
def correct_keys?(promotional_rules)
|
|
20
17
|
(promotional_rules.keys - %i[product_discounts total_price_discount]).empty?
|
|
21
18
|
end
|
|
22
19
|
|
|
20
|
+
def create_db_connection
|
|
21
|
+
Connection.new
|
|
22
|
+
end
|
|
23
|
+
|
|
23
24
|
# maybe facilitate scanning multiple items at once
|
|
24
25
|
# no structure for item given, assumed id
|
|
25
26
|
def scan(item)
|
|
@@ -27,7 +28,6 @@ class Checkout
|
|
|
27
28
|
add_to_basket(item)
|
|
28
29
|
calculate_total(item)
|
|
29
30
|
puts "Item with ID '#{item}' has been added to the basket successfully!"
|
|
30
|
-
@total
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def calculate_total(item)
|
|
@@ -38,18 +38,12 @@ class Checkout
|
|
|
38
38
|
item_discounted?(item) ? apply_item_discount(item, item_price) : @total += item_price
|
|
39
39
|
apply_total_discount if total_price_discounted?
|
|
40
40
|
end
|
|
41
|
-
@total = @total.
|
|
41
|
+
@total = @total.round(2)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def item_price(item)
|
|
45
|
-
# TODO: check if user has supplied price
|
|
46
45
|
# TODO: facilitate DB name different from products, i.e. ask gem user for db name???
|
|
47
|
-
|
|
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])
|
|
46
|
+
PriceQuery.new(item).find_price
|
|
53
47
|
end
|
|
54
48
|
|
|
55
49
|
def apply_item_and_total_discount(item, item_price)
|
|
@@ -106,32 +100,6 @@ class Checkout
|
|
|
106
100
|
@total_price_discount_applied_flag = true
|
|
107
101
|
end
|
|
108
102
|
|
|
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?
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def establish_connection
|
|
116
|
-
db_config = setup_db_config
|
|
117
|
-
ActiveRecord::Base.establish_connection(adapter: db_config["adapter"], database: db_config["database"])
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def setup_db_config
|
|
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"]
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# maybe add remove item function
|
|
134
|
-
|
|
135
103
|
def add_to_basket(item)
|
|
136
104
|
@basket.items[item] ? @basket.items[item] += 1 : @basket.items[item] = 1
|
|
137
105
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_record"
|
|
4
|
+
require "erb"
|
|
5
|
+
|
|
6
|
+
class Connection
|
|
7
|
+
def initialize
|
|
8
|
+
db_config = setup_db_config
|
|
9
|
+
ActiveRecord::Base.establish_connection(adapter: db_config["adapter"], database: db_config["database"])
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def setup_db_config
|
|
13
|
+
defined?(Rails) && defined?(Rails.env) ? rails_db_config : non_rails_db_config
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def rails_db_config
|
|
17
|
+
Rails.application.config.database_configuration[Rails.env]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def non_rails_db_config
|
|
21
|
+
# TODO: use current database instead of development
|
|
22
|
+
YAML.safe_load(ERB.new(File.read("./config/database.yml")).result, aliases: true)["development"]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class PromotionalRulesTypeError < TypeError
|
|
4
|
+
def initialize(class_name, msg = "expected a Hash, got ", exception_type = "custom")
|
|
5
|
+
msg += class_name
|
|
6
|
+
@exception_type = exception_type
|
|
7
|
+
super(msg)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class PromotionalRulesForbiddenKeys < TypeError
|
|
12
|
+
def initialize(msg = "expected Hash with optional keys 'product_discounts' and 'total_price_discount", exception_type = "custom")
|
|
13
|
+
@exception_type = exception_type
|
|
14
|
+
super(msg)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class PriceQuery
|
|
2
|
+
|
|
3
|
+
def initialize(item)
|
|
4
|
+
@sanitized_query = prepare_sql_statement(item)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def prepare_sql_statement(item)
|
|
8
|
+
# TODO: keep seen items in cache or variable !!!!!!!!!
|
|
9
|
+
ActiveRecord::Base.sanitize_sql_array(["SELECT 'products'.'price' FROM 'products' WHERE 'products'.'id' = ?", item])
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def find_price
|
|
13
|
+
results = ActiveRecord::Base.connection.exec_query(@sanitized_query)
|
|
14
|
+
results.rows.first.first if results.present?
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/unit4/checkout.rb
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
require_relative "checkout/version"
|
|
4
4
|
require_relative "checkout/checkout"
|
|
5
5
|
require_relative "checkout/basket"
|
|
6
|
+
require_relative "checkout/connection"
|
|
7
|
+
require_relative "checkout/price_query"
|
|
8
|
+
require_relative "checkout/exceptions"
|
|
6
9
|
|
|
7
10
|
module Unit4
|
|
8
11
|
module Checkout
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: unit4-checkout
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Boyan Georgiev
|
|
@@ -10,7 +10,8 @@ bindir: exe
|
|
|
10
10
|
cert_chain: []
|
|
11
11
|
date: 2022-07-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
|
-
description:
|
|
13
|
+
description: A Ruby gem that helps the user implement a checkout system by supplying
|
|
14
|
+
only the promotional rules
|
|
14
15
|
email:
|
|
15
16
|
- bbgeorgiev96@gmail.com
|
|
16
17
|
executables: []
|
|
@@ -26,10 +27,14 @@ files:
|
|
|
26
27
|
- lib/unit4/checkout.rb
|
|
27
28
|
- lib/unit4/checkout/basket.rb
|
|
28
29
|
- lib/unit4/checkout/checkout.rb
|
|
30
|
+
- lib/unit4/checkout/connection.rb
|
|
31
|
+
- lib/unit4/checkout/exceptions.rb
|
|
32
|
+
- lib/unit4/checkout/price_query.rb
|
|
29
33
|
- lib/unit4/checkout/version.rb
|
|
30
34
|
- sig/unit4/checkout.rbs
|
|
31
35
|
homepage: https://github.com/BoyanGeorgiev96/unit4-checkout
|
|
32
|
-
licenses:
|
|
36
|
+
licenses:
|
|
37
|
+
- MIT
|
|
33
38
|
metadata:
|
|
34
39
|
allowed_push_host: https://rubygems.org/
|
|
35
40
|
homepage_uri: https://github.com/BoyanGeorgiev96/unit4-checkout
|
|
@@ -52,5 +57,5 @@ requirements: []
|
|
|
52
57
|
rubygems_version: 3.3.3
|
|
53
58
|
signing_key:
|
|
54
59
|
specification_version: 4
|
|
55
|
-
summary:
|
|
60
|
+
summary: Checkout gem for Unit4 technical task
|
|
56
61
|
test_files: []
|