/
discount.go
73 lines (60 loc) · 2.23 KB
/
discount.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package decorator
import (
"flamingo.me/flamingo-commerce/v3/cart/domain/cart"
"flamingo.me/flamingo/v3/framework/flamingo"
)
const (
decoratedDiscountError = "Unable to collect discounts, stopping and returning empty slice"
)
type (
// DecoratedWithDiscount interface for a decorated object to be able to handle discounts
// the difference to cart.WithDiscount is, that these functions do NOT provide the client
// with an error, errors are just logged
DecoratedWithDiscount interface {
HasAppliedDiscounts() bool
MergeDiscounts() cart.AppliedDiscounts
}
)
var (
// interface assertions
_ DecoratedWithDiscount = new(DecoratedCartItem)
_ DecoratedWithDiscount = new(DecoratedDelivery)
_ DecoratedWithDiscount = new(DecoratedCart)
)
// HasAppliedDiscounts checks whether decorated item has discounts
func (dci *DecoratedCartItem) HasAppliedDiscounts() bool {
return hasAppliedDiscounts(dci)
}
// MergeDiscounts sum up discounts applied to item
func (dci DecoratedCartItem) MergeDiscounts() cart.AppliedDiscounts {
return collectDiscounts(&dci.Item, dci.logger)
}
// HasAppliedDiscounts checks whether decorated delivery has discounts
func (dc DecoratedDelivery) HasAppliedDiscounts() bool {
return hasAppliedDiscounts(dc)
}
// MergeDiscounts sum up discounts applied to delivery
func (dc DecoratedDelivery) MergeDiscounts() cart.AppliedDiscounts {
return collectDiscounts(&dc.Delivery, dc.logger)
}
// HasAppliedDiscounts checks whether decorated cart has discounts
func (dc DecoratedCart) HasAppliedDiscounts() bool {
return hasAppliedDiscounts(dc)
}
// MergeDiscounts sum up discounts applied to cart
func (dc DecoratedCart) MergeDiscounts() cart.AppliedDiscounts {
return collectDiscounts(&dc.Cart, dc.Logger)
}
// private helpers as all implementations of decorated entities are based on underlying
// interface cart.WithDiscount and can therefore be abstracted
func hasAppliedDiscounts(discountable DecoratedWithDiscount) bool {
return len(discountable.MergeDiscounts()) > 0
}
func collectDiscounts(discountable cart.WithDiscount, logger flamingo.Logger) cart.AppliedDiscounts {
discounts, err := discountable.MergeDiscounts()
if err != nil {
logger.Error(decoratedDiscountError)
return make(cart.AppliedDiscounts, 0)
}
return discounts
}