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() |