Class: Checkout

Inherits:
Object
  • Object
show all
Defined in:
lib/unit4/checkout/checkout.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(promotional_rules = {}) ⇒ Checkout

Returns a new instance of Checkout.



6
7
8
9
10
11
12
13
14
# File 'lib/unit4/checkout/checkout.rb', line 6

def initialize(promotional_rules = {})
  raise PromotionalRulesTypeError, promotional_rules.class.name unless promotional_rules.is_a? Hash
  raise PromotionalRulesForbiddenKeys unless correct_keys?(promotional_rules)

  @promotional_rules = promotional_rules
  @total = 0
  @basket = Basket.new
  create_db_connection
end

Instance Attribute Details

#totalObject (readonly)

Returns the value of attribute total.



4
5
6
# File 'lib/unit4/checkout/checkout.rb', line 4

def total
  @total
end

Instance Method Details

#add_to_basket(item) ⇒ Object



103
104
105
# File 'lib/unit4/checkout/checkout.rb', line 103

def add_to_basket(item)
  @basket.items[item] ? @basket.items[item] += 1 : @basket.items[item] = 1
end

#apply_item_and_total_discount(item, item_price) ⇒ Object



49
50
51
52
53
54
# File 'lib/unit4/checkout/checkout.rb', line 49

def apply_item_and_total_discount(item, item_price)
  item_prom_rules = @promotional_rules[:product_discounts][item]
  item_basket_count = @basket.items[item]
  total_discount = (1 - @promotional_rules[:total_price_discount][:percent] / 100.00)
  @total += item_and_total(item_basket_count, item_prom_rules, total_discount, item_price)
end

#apply_item_discount(item, item_price) ⇒ Object



78
79
80
81
82
83
84
85
86
# File 'lib/unit4/checkout/checkout.rb', line 78

def apply_item_discount(item, item_price)
  item_prom_rules = @promotional_rules[:product_discounts][item]
  item_basket_count = @basket.items[item]
  @total += if item_basket_count == item_prom_rules[:count]
              item_basket_count * item_prom_rules[:price] - (item_basket_count - 1) * item_price
            else
              item_prom_rules[:price]
            end
end

#apply_total_discountObject



98
99
100
101
# File 'lib/unit4/checkout/checkout.rb', line 98

def apply_total_discount
  @total *= (1 - @promotional_rules[:total_price_discount][:percent] / 100.00)
  @total_price_discount_applied_flag = true
end

#apply_total_discount_on_item(item_price) ⇒ Object



64
65
66
# File 'lib/unit4/checkout/checkout.rb', line 64

def apply_total_discount_on_item(item_price)
  @total += item_price * (1 - @promotional_rules[:total_price_discount][:percent] / 100.00)
end

#calculate_total(item) ⇒ Object



33
34
35
36
37
38
39
40
41
42
# File 'lib/unit4/checkout/checkout.rb', line 33

def calculate_total(item)
  item_price = item_price(item)
  if @total_price_discount_applied_flag
    item_discounted?(item) ? apply_item_and_total_discount(item, item_price) : apply_total_discount_on_item(item_price)
  else
    item_discounted?(item) ? apply_item_discount(item, item_price) : @total += item_price
    apply_total_discount if total_price_discounted?
  end
  @total = @total.round(2)
end

#correct_keys?(promotional_rules) ⇒ Boolean

Returns:

  • (Boolean)


16
17
18
# File 'lib/unit4/checkout/checkout.rb', line 16

def correct_keys?(promotional_rules)
  (promotional_rules.keys - i[product_discounts total_price_discount]).empty?
end

#create_db_connectionObject



20
21
22
# File 'lib/unit4/checkout/checkout.rb', line 20

def create_db_connection
  Connection.new
end

#item_and_total(item_basket_count, item_prom_rules, total_discount, item_price) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/unit4/checkout/checkout.rb', line 56

def item_and_total(item_basket_count, item_prom_rules, total_discount, item_price)
  if item_basket_count == item_prom_rules[:count]
    (item_basket_count * item_prom_rules[:price] - (item_basket_count - 1) * item_price) * total_discount
  else
    item_basket_count * item_prom_rules[:price] * total_discount
  end
end

#item_discounted?(item) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
71
72
# File 'lib/unit4/checkout/checkout.rb', line 68

def item_discounted?(item)
  return false unless item_in_discounts?(item)

  @basket.items[item] >= @promotional_rules[:product_discounts][item][:count]
end

#item_in_discounts?(item) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/unit4/checkout/checkout.rb', line 74

def item_in_discounts?(item)
  @promotional_rules[:product_discounts] && @promotional_rules[:product_discounts][item]
end

#item_price(item) ⇒ Object



44
45
46
47
# File 'lib/unit4/checkout/checkout.rb', line 44

def item_price(item)
  # TODO: facilitate DB name different from products, i.e. ask gem user for db name???
  PriceQuery.new(item).find_price
end

#scan(item) ⇒ Object

maybe facilitate scanning multiple items at once no structure for item given, assumed id



26
27
28
29
30
31
# File 'lib/unit4/checkout/checkout.rb', line 26

def scan(item)
  # check for item id
  add_to_basket(item)
  calculate_total(item)
  puts "Item with ID '#{item}' has been added to the basket successfully!"
end

#total_price_discounted?Boolean

Returns:

  • (Boolean)


88
89
90
91
92
# File 'lib/unit4/checkout/checkout.rb', line 88

def total_price_discounted?
  return false unless total_price_in_discounts?

  @total >= @promotional_rules[:total_price_discount][:price]
end

#total_price_in_discounts?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/unit4/checkout/checkout.rb', line 94

def total_price_in_discounts?
  @promotional_rules[:total_price_discount] && @promotional_rules[:total_price_discount][:price]
end