def get_price(item: Item, variation: ItemVariation = None, voucher: Voucher = None, custom_price: Decimal = None, subevent: SubEvent = None, custom_price_is_net: bool = False, addon_to: AbstractPosition = None, invoice_address: InvoiceAddress = None) -> TaxedPrice: if addon_to: try: iao = addon_to.item.addons.get(addon_category_id=item.category_id) if iao.price_included: return TAXED_ZERO except ItemAddOn.DoesNotExist: pass price = item.default_price if subevent and item.pk in subevent.item_price_overrides: price = subevent.item_price_overrides[item.pk] if variation is not None: if variation.default_price is not None: price = variation.default_price if subevent and variation.pk in subevent.var_price_overrides: price = subevent.var_price_overrides[variation.pk] if voucher: price = voucher.calculate_price(price) if item.tax_rule: tax_rule = item.tax_rule else: tax_rule = TaxRule( name='', rate=Decimal('0.00'), price_includes_tax=True, eu_reverse_charge=False, ) price = tax_rule.tax(price) if item.free_price and custom_price is not None and custom_price != "": if not isinstance(custom_price, Decimal): custom_price = Decimal(str(custom_price).replace(",", ".")) if custom_price > 100000000: raise ValueError('price_too_high') if custom_price_is_net: price = tax_rule.tax(max(custom_price, price.net), base_price_is='net') else: price = tax_rule.tax(max(custom_price, price.gross), base_price_is='gross') if invoice_address and not tax_rule.tax_applicable(invoice_address): price.tax = Decimal('0.00') price.rate = Decimal('0.00') price.gross = price.net price.name = '' price.gross = round_decimal(price.gross, item.event.currency) price.net = round_decimal(price.net, item.event.currency) price.tax = price.gross - price.net return price
def get_fees(event, request, total, invoice_address, provider): fees = [] if provider and total != 0: provider = event.get_payment_providers().get(provider) if provider: payment_fee = provider.calculate_fee(total) if payment_fee: payment_fee_tax_rule = event.settings.tax_rate_default or TaxRule.zero() if payment_fee_tax_rule.tax_applicable(invoice_address): payment_fee_tax = payment_fee_tax_rule.tax(payment_fee, base_price_is='gross') fees.append(OrderFee( fee_type=OrderFee.FEE_TYPE_PAYMENT, value=payment_fee, tax_rate=payment_fee_tax.rate, tax_value=payment_fee_tax.tax, tax_rule=payment_fee_tax_rule )) else: fees.append(OrderFee( fee_type=OrderFee.FEE_TYPE_PAYMENT, value=payment_fee, tax_rate=Decimal('0.00'), tax_value=Decimal('0.00'), tax_rule=payment_fee_tax_rule )) for recv, resp in fee_calculation_for_cart.send(sender=event, request=request, invoice_address=invoice_address, total=total): fees += resp return fees
def get_fees(event, request, total, invoice_address, provider): fees = [] if provider and total != 0: provider = event.get_payment_providers().get(provider) if provider: payment_fee = provider.calculate_fee(total) if payment_fee: payment_fee_tax_rule = event.settings.tax_rate_default or TaxRule.zero( ) if payment_fee_tax_rule.tax_applicable(invoice_address): payment_fee_tax = payment_fee_tax_rule.tax( payment_fee, base_price_is='gross') fees.append( OrderFee(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=payment_fee, tax_rate=payment_fee_tax.rate, tax_value=payment_fee_tax.tax, tax_rule=payment_fee_tax_rule)) else: fees.append( OrderFee(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=payment_fee, tax_rate=Decimal('0.00'), tax_value=Decimal('0.00'), tax_rule=payment_fee_tax_rule)) for recv, resp in fee_calculation_for_cart.send( sender=event, request=request, invoice_address=invoice_address): fees += resp return fees
def get_price(item: Item, variation: ItemVariation = None, voucher: Voucher = None, custom_price: Decimal = None, subevent: SubEvent = None, custom_price_is_net: bool = False, addon_to: AbstractPosition = None, invoice_address: InvoiceAddress = None) -> TaxedPrice: if addon_to: try: iao = addon_to.item.addons.get(addon_category_id=item.category_id) if iao.price_included: return TAXED_ZERO except ItemAddOn.DoesNotExist: pass price = item.default_price if subevent and item.pk in subevent.item_price_overrides: price = subevent.item_price_overrides[item.pk] if variation is not None: if variation.default_price is not None: price = variation.default_price if subevent and variation.pk in subevent.var_price_overrides: price = subevent.var_price_overrides[variation.pk] if voucher: price = voucher.calculate_price(price) if item.tax_rule: tax_rule = item.tax_rule else: tax_rule = TaxRule( name='', rate=Decimal('0.00'), price_includes_tax=True, eu_reverse_charge=False, ) price = tax_rule.tax(price) if item.free_price and custom_price is not None and custom_price != "": if not isinstance(custom_price, Decimal): custom_price = Decimal(str(custom_price).replace(",", ".")) if custom_price > 100000000: raise ValueError('price_too_high') if custom_price_is_net: price = tax_rule.tax(max(custom_price, price.net), base_price_is='net') else: price = tax_rule.tax(max(custom_price, price.gross), base_price_is='gross') if invoice_address and not tax_rule.tax_applicable(invoice_address): price.tax = Decimal('0.00') price.rate = Decimal('0.00') price.gross = price.net price.name = '' return price
def get_price(item: Item, variation: ItemVariation = None, voucher: Voucher = None, custom_price: Decimal = None, subevent: SubEvent = None, custom_price_is_net: bool = False, custom_price_is_tax_rate: Decimal=None, addon_to: AbstractPosition = None, invoice_address: InvoiceAddress = None, force_custom_price: bool = False, bundled_sum: Decimal = Decimal('0.00'), max_discount: Decimal = None, tax_rule=None) -> TaxedPrice: if addon_to: try: iao = addon_to.item.addons.get(addon_category_id=item.category_id) if iao.price_included: return TAXED_ZERO except ItemAddOn.DoesNotExist: pass price = item.default_price if subevent and item.pk in subevent.item_price_overrides: price = subevent.item_price_overrides[item.pk] if variation is not None: if variation.default_price is not None: price = variation.default_price if subevent and variation.pk in subevent.var_price_overrides: price = subevent.var_price_overrides[variation.pk] if voucher: price = voucher.calculate_price(price, max_discount=max_discount) if tax_rule is not None: tax_rule = tax_rule elif item.tax_rule: tax_rule = item.tax_rule else: tax_rule = TaxRule( name='', rate=Decimal('0.00'), price_includes_tax=True, eu_reverse_charge=False, ) if force_custom_price and custom_price is not None and custom_price != "": if custom_price_is_net: price = tax_rule.tax(custom_price, base_price_is='net', invoice_address=invoice_address, subtract_from_gross=bundled_sum) else: price = tax_rule.tax(custom_price, base_price_is='gross', invoice_address=invoice_address, subtract_from_gross=bundled_sum) elif item.free_price and custom_price is not None and custom_price != "": if not isinstance(custom_price, Decimal): custom_price = Decimal(str(custom_price).replace(",", ".")) if custom_price > 100000000: raise ValueError('price_too_high') price = tax_rule.tax(price, invoice_address=invoice_address) if custom_price_is_net: price = tax_rule.tax(max(custom_price, price.net), base_price_is='net', invoice_address=invoice_address, subtract_from_gross=bundled_sum) else: price = tax_rule.tax(max(custom_price, price.gross), base_price_is='gross', gross_price_is_tax_rate=custom_price_is_tax_rate, invoice_address=invoice_address, subtract_from_gross=bundled_sum) else: price = tax_rule.tax(price, invoice_address=invoice_address, subtract_from_gross=bundled_sum) price.gross = round_decimal(price.gross, item.event.currency) price.net = round_decimal(price.net, item.event.currency) price.tax = price.gross - price.net return price
def get_cart(self, answers=False, queryset=None, order=None, downloads=False): if queryset: prefetch = [] if answers: prefetch.append('item__questions') prefetch.append('answers') cartpos = queryset.order_by('item', 'variation').select_related( 'item', 'variation', 'addon_to', 'subevent', 'subevent__event', 'subevent__event__organizer').prefetch_related(*prefetch) else: cartpos = self.positions lcp = list(cartpos) has_addons = {cp.addon_to.pk for cp in lcp if cp.addon_to} pos_additional_fields = defaultdict(list) for cp in lcp: responses = question_form_fields.send(sender=self.request.event, position=cp) data = cp.meta_info_data for r, response in sorted(responses, key=lambda r: str(r[0])): for key, value in response.items(): pos_additional_fields[cp.pk].append({ 'answer': data.get('question_form_data', {}).get(key), 'question': value.label }) # Group items of the same variation # We do this by list manipulations instead of a GROUP BY query, as # Django is unable to join related models in a .values() query def keyfunc(pos): if isinstance(pos, OrderPosition): if pos.addon_to: i = pos.addon_to.positionid else: i = pos.positionid else: if pos.addon_to: i = pos.addon_to.pk else: i = pos.pk has_attendee_data = pos.item.admission and ( self.request.event.settings.attendee_names_asked or self.request.event.settings.attendee_emails_asked or pos_additional_fields.get(pos.pk)) addon_penalty = 1 if pos.addon_to else 0 if downloads or pos.pk in has_addons or pos.addon_to: return i, addon_penalty, pos.pk, 0, 0, 0, 0, (pos.subevent_id or 0) if answers and (has_attendee_data or pos.item.questions.all()): return i, addon_penalty, pos.pk, 0, 0, 0, 0, (pos.subevent_id or 0) return (0, addon_penalty, 0, pos.item_id, pos.variation_id, pos.price, (pos.voucher_id or 0), (pos.subevent_id or 0)) positions = [] for k, g in groupby(sorted(lcp, key=keyfunc), key=keyfunc): g = list(g) group = g[0] group.count = len(g) group.total = group.count * group.price group.net_total = group.count * group.net_price group.has_questions = answers and k[0] != "" group.tax_rule = group.item.tax_rule if answers: group.cache_answers() group.additional_answers = pos_additional_fields.get(group.pk) positions.append(group) total = sum(p.total for p in positions) net_total = sum(p.net_total for p in positions) tax_total = sum(p.total - p.net_total for p in positions) if order: payment_fee = order.payment_fee tax_total += order.payment_fee_tax_value payment_fee_net = order.payment_fee - order.payment_fee_tax_value net_total += payment_fee_net payment_fee_tax_rule = order.payment_fee_tax_rule payment_fee_tax_rate = order.payment_fee_tax_rate else: payment_fee = self.get_payment_fee(total) payment_fee_tax_rule = self.request.event.settings.tax_rate_default or TaxRule.zero( ) iapk = self.request.session.get('invoice_address_{}'.format( self.request.event.pk)) ia = None if payment_fee_tax_rule.eu_reverse_charge and iapk: try: ia = InvoiceAddress.objects.get(pk=iapk, order__isnull=True) except InvoiceAddress.DoesNotExist: pass if payment_fee_tax_rule.tax_applicable(ia): payment_fee_tax = payment_fee_tax_rule.tax( payment_fee, base_price_is='gross') tax_total += payment_fee_tax.tax net_total += payment_fee_tax.net payment_fee_net = payment_fee_tax.net payment_fee_tax_rate = payment_fee_tax.rate else: net_total += payment_fee payment_fee_net = payment_fee payment_fee_tax_rate = Decimal('0.00') try: first_expiry = min(p.expires for p in positions) if positions else now() minutes_left = max(first_expiry - now(), timedelta()).seconds // 60 except AttributeError: first_expiry = None minutes_left = None return { 'positions': positions, 'raw': cartpos, 'total': total + payment_fee, 'net_total': net_total, 'tax_total': tax_total, 'payment_fee': payment_fee, 'payment_fee_net': payment_fee_net, 'payment_fee_tax_rate': payment_fee_tax_rate, 'payment_fee_tax_rule': payment_fee_tax_rule, 'answers': answers, 'minutes_left': minutes_left, 'first_expiry': first_expiry, }