mirror of
https://github.com/pretix/pretix.git
synced 2026-05-09 15:54:03 +00:00
cache potential discount information
relevant if shop has multiple categories with cross_selling_condition=discounts
This commit is contained in:
@@ -164,54 +164,55 @@ class ItemCategory(LoggedModel):
|
|||||||
match = set(match.pk for match in self.cross_selling_match_products.only('pk')) # TODO prefetch this
|
match = set(match.pk for match in self.cross_selling_match_products.only('pk')) # TODO prefetch this
|
||||||
return (self.items.all(), {}) if any(pos.item.pk in match for pos in cart) else (None, {})
|
return (self.items.all(), {}) if any(pos.item.pk in match for pos in cart) else (None, {})
|
||||||
if self.cross_selling_condition == 'discounts':
|
if self.cross_selling_condition == 'discounts':
|
||||||
potential_discounts_by_cartpos = defaultdict(list)
|
if not hasattr(self.event, '_potential_discounts_by_item_for_current_cart'):
|
||||||
|
potential_discounts_by_cartpos = defaultdict(list)
|
||||||
|
|
||||||
from ..services.pricing import apply_discounts
|
from ..services.pricing import apply_discounts
|
||||||
apply_discounts(
|
apply_discounts(
|
||||||
self.event,
|
self.event,
|
||||||
sales_channel,
|
sales_channel,
|
||||||
[
|
[
|
||||||
(cp.item_id, cp.subevent_id, cp.line_price_gross, bool(cp.addon_to), cp.is_bundled,
|
(cp.item_id, cp.subevent_id, cp.line_price_gross, bool(cp.addon_to), cp.is_bundled,
|
||||||
cp.listed_price - cp.price_after_voucher)
|
cp.listed_price - cp.price_after_voucher)
|
||||||
for cp in cart
|
for cp in cart
|
||||||
],
|
],
|
||||||
collect_potential_discounts=potential_discounts_by_cartpos
|
collect_potential_discounts=potential_discounts_by_cartpos
|
||||||
)
|
|
||||||
|
|
||||||
# technically, this is a dict, but we use it as an OrderedSet here
|
|
||||||
potential_discount_set = dict.fromkeys(info for lst in potential_discounts_by_cartpos.values() for info in lst)
|
|
||||||
|
|
||||||
# sum up the max_counts and pass them on (also pass on the discount_rules so we can calculate actual discounted prices later):
|
|
||||||
# group by benefit product
|
|
||||||
# - max_count for product: sum up max_counts
|
|
||||||
# - discount_rule for product: take first discount_rule
|
|
||||||
|
|
||||||
def discount_info(item, infos_for_item):
|
|
||||||
infos_for_item = list(infos_for_item)
|
|
||||||
return (
|
|
||||||
item,
|
|
||||||
sum(max_count for (item, discount_rule, max_count, i) in infos_for_item),
|
|
||||||
next(discount_rule for (item, discount_rule, max_count, i) in infos_for_item)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
grouped_by_item = [
|
# technically, this is a dict, but we use it as an OrderedSet here
|
||||||
discount_info(item, infos_for_item) for item, infos_for_item in
|
potential_discount_set = dict.fromkeys(info for lst in potential_discounts_by_cartpos.values() for info in lst)
|
||||||
groupby(
|
|
||||||
sorted(
|
# sum up the max_counts and pass them on (also pass on the discount_rules so we can calculate actual discounted prices later):
|
||||||
(
|
# group by benefit product
|
||||||
(item, discount_rule, max_count, i)
|
# - max_count for product: sum up max_counts
|
||||||
for (discount_rule, max_count, i) in potential_discount_set.keys()
|
# - discount_rule for product: take first discount_rule
|
||||||
for item in discount_rule.benefit_limit_products.all()
|
|
||||||
|
def discount_info(item, infos_for_item):
|
||||||
|
infos_for_item = list(infos_for_item)
|
||||||
|
return (
|
||||||
|
item,
|
||||||
|
sum(max_count for (item, discount_rule, max_count, i) in infos_for_item),
|
||||||
|
next(discount_rule for (item, discount_rule, max_count, i) in infos_for_item)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.event._potential_discounts_by_item_for_current_cart = [
|
||||||
|
discount_info(item, infos_for_item) for item, infos_for_item in
|
||||||
|
groupby(
|
||||||
|
sorted(
|
||||||
|
(
|
||||||
|
(item, discount_rule, max_count, i)
|
||||||
|
for (discount_rule, max_count, i) in potential_discount_set.keys()
|
||||||
|
for item in discount_rule.benefit_limit_products.all()
|
||||||
|
),
|
||||||
|
key=lambda tup: tup[0].pk
|
||||||
),
|
),
|
||||||
key=lambda tup: tup[0].pk
|
lambda tup: tup[0])
|
||||||
),
|
]
|
||||||
lambda tup: tup[0])
|
|
||||||
]
|
|
||||||
|
|
||||||
my_item_pks = self.items.values_list('pk', flat=True)
|
my_item_pks = self.items.values_list('pk', flat=True)
|
||||||
potential_discount_items = {
|
potential_discount_items = {
|
||||||
item.pk: (max_count, discount_rule)
|
item.pk: (max_count, discount_rule)
|
||||||
for item, max_count, discount_rule in grouped_by_item
|
for item, max_count, discount_rule in self.event._potential_discounts_by_item_for_current_cart
|
||||||
if max_count > 0 and item.pk in my_item_pks and item.is_available()
|
if max_count > 0 and item.pk in my_item_pks and item.is_available()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user