View difference between Paste ID: G07X8x2H and LSS5SiH6
SHOW: | | - or go back to the newest paste.
1
# -*- coding: utf8 -*-
2
3
from collections import defaultdict
4
5
6
def discount_together(order_items, discounts, products=[], percent=0):
7
    ''' Скидки для групп товаров, присутствующих в заказе '''
8
    
9
    # выходим, если хотя бы один товар не найден
10
    if not set(products).issubset(order_items.keys()):
11
        return discounts
12
    
13
    # определяем кол-во найденных групп
14
    pairs = min([len(order_items[x]) for x in products])
15
    
16
    for p in products:
17
        for idx in range(pairs):
18
            key = order_items[p][idx]
19
            
20
            # пропускаем, если скидка для товара установлена
21
            if key in discounts:
22
                continue
23
24
            discounts[key] = percent
25
            print "discount_and: %s - %.2f" % (key, percent)
26
27
    return discounts
28
29
30
def discount_oneof(order_items, discounts, products=[], percent=0, condition = []):
31
    ''' Скидки для каждого товара из группы, [при наличии другого товара из условия] '''
32
    
33
    # если задано условия, проверяем его в первую очередь
34
    if len(condition) and not set(condition).issubset(order_items.keys()):
35
        return basket
36
        
37
    for p in products:
38
        for key in order_items.get(p, []):
39
            
40
            # пропускаем, если скидка для товара уже задана
41
            if key in discounts:
42
                continue
43
            
44
            discounts[key] = percent
45
            print "discount_or: %s - %.2f" % (key, percent)
46
            
47
    return discounts
48
49
50
def order_discount(order_items, ranges, exclude = []):
51
    ''' Скидка на сумму заказа, в зависимости от кол-ва товаров, [исключая некоторые позиции] '''
52
53
    # количество товаров в заказе, исключая позиции exclude
54
    total_len = sum([ len(items) for key, items in order_items.iteritems() if not key in exclude ])
55
56
    # выбираем скидку, соответствующую кол-ву товаров в заказе
57
    discount = ranges.get(str(total_len), 0)
58
59
    if discount > 0:
60
        print "total_discount: %.2f" % (discount)
61
62
    return discount
63
64
65
def get_basket(order, products, discount_types=[], total_discount_options={}):
66
    ''' Расчёт потребительской корзины '''
67
68
    basket = {'items': [], 'total': {}}
69
    
70
    order_items = defaultdict(list)
71
    
72
    # преобразуем список в словарь (по уникальным товарам) - в значениях индексы исходного списка
73
    for i, item in enumerate(order):
74
        order_items[item].append(i)
75
76
    discounts = {}
77
    
78
    # вычисляем скидки в порядке следования
79
    for discount_item in discount_types:
80
        d_type = discount_item.get('type')
81
        d_options = discount_item.get('options')
82
        
83
        if d_type == 'together':
84
            discount_together(order_items, discounts, **d_options)
85
86
        if d_type == 'oneof':
87
            discount_oneof(order_items, discounts, **d_options)
88
89
90
    subtotal = 0
91
92
    # формируем корзину, подсчитываем подитог
93
    for i, item in enumerate(order):
94
        price = products[item]
95
        discount = discounts[i] if i in discounts else 0
96
        basket['items'].append({
97
            'product': item,
98
            'price': price,
99
            'discount': discount
100
        })
101
102
        subtotal+=price*discount
103
104
    # вычисляем скидку на сумму заказа
105
    total_discount = order_discount(order_items, **total_discount_options)
106
107
    basket['total'] = {'subtotal': subtotal, 'discount': total_discount, 'total': subtotal*td}
108
      
109
    return basket
110
111
112
113
def main():
114
115
    ''' Товары с ценами '''
116
    products = {
117
        'A': 100,
118
        'B': 100,
119
        'C': 100,
120
        'D': 100,
121
        'E': 100,
122
        'F': 100,
123
        'G': 100,
124
        'H': 100,
125
        'I': 100,
126
        'K': 100,
127
        'L': 100,
128
        'M': 100
129
    }
130
131
    ''' Список установленных скидок '''
132
    discounts = [
133
        {'type': 'together', 'options': {'products': ['A','B'], 'percent': 0.9 }},
134
        {'type': 'together', 'options': {'products': ['D','E'], 'percent': 0.95 }},
135
        {'type': 'together', 'options': {'products': ['E','F','G'], 'percent': 0.95 }},
136
        {'type': 'oneof', 'options': {'products': ['K','L','M'], 'percent': 0.95 , 'condition': ['A']}},
137
    ]
138
139
    ''' Скидки по сумме заказа '''
140
    total_discount_options = {'ranges': {'3': 0.95, '4': 0.9, '5': 0.8}, 'exclude': ['A','C']}
141
142
143
    ''' Исходный список товаров в заказе '''    
144
    myorder = ['A', 'B', 'C', 'K', 'L', 'D', 'D', 'E']
145
146
    print get_basket(myorder, products, discounts, total_discount_options)
147
148
149
main()