def test_custom_rules_business(event): tr = TaxRule(event=event, rate=Decimal('10.00'), price_includes_tax=False, custom_rules=json.dumps([ { 'country': 'ZZ', 'address_type': 'business', 'action': 'no' }, ])) ia = InvoiceAddress(is_business=True, country=Country('AT')) assert not tr.is_reverse_charge(ia) assert not tr._tax_applicable(ia) assert tr.tax_rate_for(ia) == Decimal('0.00') assert tr.tax(Decimal('100.00'), invoice_address=ia) == TaxedPrice( gross=Decimal('100.00'), net=Decimal('100.00'), tax=Decimal('0.00'), rate=Decimal('0.00'), name='', ) ia = InvoiceAddress(is_business=False, country=Country('DE')) assert not tr.is_reverse_charge(ia) assert tr._tax_applicable(ia) assert tr.tax_rate_for(ia) == Decimal('10.00') assert tr.tax(Decimal('100.00'), invoice_address=ia) == TaxedPrice( gross=Decimal('110.00'), net=Decimal('100.00'), tax=Decimal('10.00'), rate=Decimal('10.00'), name='', )
def test_from_net_price(event): tr = TaxRule(event=event, rate=Decimal('10.00'), price_includes_tax=False) tp = tr.tax(Decimal('100.00')) assert tp.gross == Decimal('110.00') assert tp.net == Decimal('100.00') assert tp.tax == Decimal('10.00') assert tp.rate == Decimal('10.00')
def test_reverse_charge_no_address(event): tr = TaxRule(event=event, eu_reverse_charge=True, rate=Decimal('10.00'), price_includes_tax=False) assert not tr.is_reverse_charge(None) assert tr._tax_applicable(None)
def test_from_gross_price(event): tr = TaxRule(event=event, rate=Decimal('10.00'), price_includes_tax=True) tp = tr.tax(Decimal('100.00')) assert tp.gross == Decimal('100') assert tp.net == Decimal('90.91') assert tp.tax == Decimal('100.00') - Decimal('90.91') assert tp.rate == Decimal('10.00')
def test_reverse_charge_no_country(event): tr = TaxRule(event=event, eu_reverse_charge=True, rate=Decimal('10.00'), price_includes_tax=False) ia = InvoiceAddress() assert not tr.is_reverse_charge(ia) assert tr._tax_applicable(ia) assert tr.tax_rate_for(ia) == Decimal('10.00')
def test_reverse_charge_individual_eu(event): tr = TaxRule(event=event, eu_reverse_charge=True, home_country=Country('DE'), rate=Decimal('10.00'), price_includes_tax=False) ia = InvoiceAddress(is_business=False, country=Country('AT')) assert not tr.is_reverse_charge(ia) assert tr._tax_applicable(ia) assert tr.tax_rate_for(ia) == Decimal('10.00')
def test_reverse_charge_disabled(event): tr = TaxRule(event=event, eu_reverse_charge=False, home_country=Country('DE'), rate=Decimal('10.00'), price_includes_tax=False) ia = InvoiceAddress(is_business=True, vat_id='AT12346', vat_id_validated=True, country=Country('AT')) assert not tr.is_reverse_charge(ia) assert tr._tax_applicable(ia) assert tr.tax_rate_for(ia) == Decimal('10.00')
def test_reverse_charge_valid_vat_id_business_3rdc(event): tr = TaxRule( event=event, eu_reverse_charge=True, home_country=Country('DE'), rate=Decimal('10.00'), price_includes_tax=False ) ia = InvoiceAddress( is_business=True, country=Country('US'), vat_id='US12346', vat_id_validated=True ) assert not tr.is_reverse_charge(ia) assert not tr.tax_applicable(ia)
def test_custom_rules_any_country(event): tr = TaxRule( event=event, rate=Decimal('10.00'), price_includes_tax=False, custom_rules=json.dumps([ {'country': 'ZZ', 'address_type': '', 'action': 'no'}, ]) ) ia = InvoiceAddress( is_business=True, country=Country('AT') ) assert not tr.is_reverse_charge(ia) assert not tr.tax_applicable(ia)
def test_custom_rules_override(event): tr = TaxRule( event=event, eu_reverse_charge=True, home_country=Country('DE'), rate=Decimal('10.00'), price_includes_tax=False, custom_rules=json.dumps([ {'country': 'ZZ', 'address_type': '', 'action': 'vat'} ]) ) ia = InvoiceAddress( is_business=True, vat_id='AT12346', vat_id_validated=True, country=Country('AT') ) assert not tr.is_reverse_charge(ia) assert tr.tax_applicable(ia)
def get_fees(event, total, invoice_address, mod=''): fee = event.settings.get('service_fee_abs' + mod, as_type=Decimal) if mod and fee is None: fee = event.settings.get('service_fee_abs', as_type=Decimal) if fee and total != Decimal('0.00'): tax_rule = event.settings.tax_rate_default or TaxRule.zero() if tax_rule.tax_applicable(invoice_address): tax = tax_rule.tax(fee) return [OrderFee( fee_type=OrderFee.FEE_TYPE_SERVICE, internal_type='', value=fee, tax_rate=tax.rate, tax_value=tax.tax, tax_rule=tax_rule )] else: return [OrderFee( fee_type=OrderFee.FEE_TYPE_SERVICE, internal_type='', value=fee, tax_rate=Decimal('0.00'), tax_value=Decimal('0.00'), tax_rule=tax_rule )] return []
def get_fees(event, total, invoice_address, mod='', request=None, positions=[]): if request is not None and not positions: positions = get_cart(request) positions = [ pos for pos in positions if not pos.addon_to and pos.price != Decimal('0.00') ] fee_per_ticket = event.settings.get('service_fee_per_ticket' + mod, as_type=Decimal) if mod and fee_per_ticket is None: fee_per_ticket = event.settings.get('service_fee_per_ticket', as_type=Decimal) fee_abs = event.settings.get('service_fee_abs' + mod, as_type=Decimal) if mod and fee_abs is None: fee_abs = event.settings.get('service_fee_abs', as_type=Decimal) fee_percent = event.settings.get('service_fee_percent' + mod, as_type=Decimal) if mod and fee_percent is None: fee_percent = event.settings.get('service_fee_percent', as_type=Decimal) fee_per_ticket = Decimal("0") if fee_per_ticket is None else fee_per_ticket fee_abs = Decimal("0") if fee_abs is None else fee_abs fee_percent = Decimal("0") if fee_percent is None else fee_percent if (fee_per_ticket or fee_abs or fee_percent) and total != Decimal('0.00'): fee = round_decimal( fee_abs + total * (fee_percent / 100) + len(positions) * fee_per_ticket, event.currency) tax_rule = event.settings.tax_rate_default or TaxRule.zero() if tax_rule.tax_applicable(invoice_address): tax = tax_rule.tax(fee) return [ OrderFee(fee_type=OrderFee.FEE_TYPE_SERVICE, internal_type='', value=fee, tax_rate=tax.rate, tax_value=tax.tax, tax_rule=tax_rule) ] else: return [ OrderFee(fee_type=OrderFee.FEE_TYPE_SERVICE, internal_type='', value=fee, tax_rate=Decimal('0.00'), tax_value=Decimal('0.00'), tax_rule=tax_rule) ] return []
def test_custom_rules_country_rate_subtract_from_gross(event): tr = TaxRule(event=event, rate=Decimal('10.00'), price_includes_tax=False, custom_rules=json.dumps([ { 'country': 'EU', 'address_type': 'business_vat_id', 'action': 'vat', 'rate': '100.00' }, ])) ia = InvoiceAddress(is_business=True, country=Country('DE'), vat_id='DE1234', vat_id_validated=True) assert tr.tax_rate_for(ia) == Decimal('100.00') assert not tr.is_reverse_charge(ia) assert tr._tax_applicable(ia) assert tr.tax( Decimal('100.00'), invoice_address=ia, subtract_from_gross=Decimal('20.00')) == TaxedPrice( gross=Decimal( '163.64'), # ((100 * 1.1) - 20) / (1 + 10%) * (1 + 100%) net=Decimal('81.82'), tax=Decimal('81.82'), rate=Decimal('100.00'), name='', )
def test_custom_rules_country_rate_keep_gross_if_rate_changes(event): tr = TaxRule(event=event, rate=Decimal('10.00'), price_includes_tax=False, keep_gross_if_rate_changes=True, custom_rules=json.dumps([ { 'country': 'EU', 'address_type': 'business_vat_id', 'action': 'vat', 'rate': '100.00' }, ])) ia = InvoiceAddress(is_business=True, country=Country('DE')) assert not tr.is_reverse_charge(ia) assert tr._tax_applicable(ia) assert tr.tax_rate_for(ia) == Decimal('10.00') assert tr.tax(Decimal('100.00'), invoice_address=ia) == TaxedPrice( gross=Decimal('110.00'), net=Decimal('100.00'), tax=Decimal('10.00'), rate=Decimal('10.00'), name='', ) ia = InvoiceAddress(is_business=True, country=Country('DE'), vat_id='DE1234', vat_id_validated=True) assert tr.tax_rate_for(ia) == Decimal('100.00') assert not tr.is_reverse_charge(ia) assert tr._tax_applicable(ia) assert tr.tax(Decimal('100.00'), invoice_address=ia) == TaxedPrice( gross=Decimal('110.00'), net=Decimal('55.00'), tax=Decimal('55.00'), rate=Decimal('100.00'), name='', )
def get_fee(event, total, invoice_address): payment_fee = round_decimal(Decimal('0.25') + Decimal('0.029') * total) 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') return 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: return 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)
def test_custom_rules_vat_id(event): tr = TaxRule(event=event, rate=Decimal('10.00'), price_includes_tax=False, custom_rules=json.dumps([ { 'country': 'EU', 'address_type': 'business_vat_id', 'action': 'reverse' }, ])) ia = InvoiceAddress(is_business=True, country=Country('AT')) assert not tr.is_reverse_charge(ia) assert tr._tax_applicable(ia) assert tr.tax_rate_for(ia) == Decimal('10.00') ia = InvoiceAddress(is_business=True, country=Country('DE'), vat_id='DE1234', vat_id_validated=True) assert tr.is_reverse_charge(ia) assert not tr._tax_applicable(ia) assert tr.tax_rate_for(ia) == Decimal('0.00')
def test_reverse_charge_no_country(event): tr = TaxRule(event=event, eu_reverse_charge=True, rate=Decimal('10.00'), price_includes_tax=False) ia = InvoiceAddress() assert not tr.is_reverse_charge(ia) assert tr._tax_applicable(ia) assert tr.tax_rate_for(ia) == Decimal('10.00') assert tr.tax(Decimal('100.00'), invoice_address=ia) == TaxedPrice( gross=Decimal('110.00'), net=Decimal('100.00'), tax=Decimal('10.00'), rate=Decimal('10.00'), name='', )
def test_reverse_charge_individual_3rdc(event): tr = TaxRule(event=event, eu_reverse_charge=True, home_country=Country('DE'), rate=Decimal('10.00'), price_includes_tax=False) ia = InvoiceAddress(is_business=False, country=Country('US')) assert not tr.is_reverse_charge(ia) assert not tr._tax_applicable(ia) assert tr.tax_rate_for(ia) == Decimal('0.00') assert tr.tax(Decimal('100.00'), invoice_address=ia) == TaxedPrice( gross=Decimal('100.00'), net=Decimal('100.00'), tax=Decimal('0.00'), rate=Decimal('0.00'), name='', )
def test_reverse_charge_valid_vat_id_business_eu(event): tr = TaxRule(event=event, eu_reverse_charge=True, home_country=Country('DE'), rate=Decimal('10.00'), price_includes_tax=False) ia = InvoiceAddress(is_business=True, vat_id='AT12346', vat_id_validated=True, country=Country('AT')) assert tr.is_reverse_charge(ia) assert not tr._tax_applicable(ia) assert tr.tax_rate_for(ia) == Decimal('0.00') assert tr.tax(Decimal('100.00'), invoice_address=ia) == TaxedPrice( gross=Decimal('100.00'), net=Decimal('100.00'), tax=Decimal('0.00'), rate=Decimal('0.00'), name='', )
def create(self, validated_data): fees_data = validated_data.pop( 'fees') if 'fees' in validated_data else [] positions_data = validated_data.pop( 'positions') if 'positions' in validated_data else [] payment_provider = validated_data.pop('payment_provider', None) payment_info = validated_data.pop('payment_info', '{}') payment_date = validated_data.pop('payment_date', now()) force = validated_data.pop('force', False) self._send_mail = validated_data.pop('send_mail', False) if 'invoice_address' in validated_data: iadata = validated_data.pop('invoice_address') name = iadata.pop('name', '') if name and not iadata.get('name_parts'): iadata['name_parts'] = {'_legacy': name} ia = InvoiceAddress(**iadata) else: ia = None with self.context['event'].lock() as now_dt: free_seats = set() seats_seen = set() consume_carts = validated_data.pop('consume_carts', []) delete_cps = [] quota_avail_cache = {} v_budget = {} voucher_usage = Counter() if consume_carts: for cp in CartPosition.objects.filter( event=self.context['event'], cart_id__in=consume_carts, expires__gt=now()): quotas = (cp.variation.quotas.filter(subevent=cp.subevent) if cp.variation else cp.item.quotas.filter( subevent=cp.subevent)) for quota in quotas: if quota not in quota_avail_cache: quota_avail_cache[quota] = list( quota.availability()) if quota_avail_cache[quota][1] is not None: quota_avail_cache[quota][1] += 1 if cp.voucher: voucher_usage[cp.voucher] -= 1 if cp.expires > now_dt: if cp.seat: free_seats.add(cp.seat) delete_cps.append(cp) errs = [{} for p in positions_data] for i, pos_data in enumerate(positions_data): if pos_data.get('voucher'): v = pos_data['voucher'] if pos_data.get('addon_to'): errs[i]['voucher'] = [ 'Vouchers are currently not supported for add-on products.' ] continue if not v.applies_to(pos_data['item'], pos_data.get('variation')): errs[i]['voucher'] = [ error_messages['voucher_invalid_item'] ] continue if v.subevent_id and pos_data.get( 'subevent').pk != v.subevent_id: errs[i]['voucher'] = [ error_messages['voucher_invalid_subevent'] ] continue if v.valid_until is not None and v.valid_until < now_dt: errs[i]['voucher'] = [ error_messages['voucher_expired'] ] continue voucher_usage[v] += 1 if voucher_usage[v] > 0: redeemed_in_carts = CartPosition.objects.filter( Q(voucher=pos_data['voucher']) & Q(event=self.context['event']) & Q(expires__gte=now_dt)).exclude( pk__in=[cp.pk for cp in delete_cps]) v_avail = v.max_usages - v.redeemed - redeemed_in_carts.count( ) if v_avail < voucher_usage[v]: errs[i]['voucher'] = [ 'The voucher has already been used the maximum number of times.' ] if v.budget is not None: price = pos_data.get('price') if price is None: price = get_price( item=pos_data.get('item'), variation=pos_data.get('variation'), voucher=v, custom_price=None, subevent=pos_data.get('subevent'), addon_to=pos_data.get('addon_to'), invoice_address=ia, ).gross pbv = get_price( item=pos_data['item'], variation=pos_data.get('variation'), voucher=None, custom_price=None, subevent=pos_data.get('subevent'), addon_to=pos_data.get('addon_to'), invoice_address=ia, ) if v not in v_budget: v_budget[v] = v.budget - v.budget_used() disc = pbv.gross - price if disc > v_budget[v]: new_disc = v_budget[v] v_budget[v] -= new_disc if new_disc == Decimal('0.00') or pos_data.get( 'price') is not None: errs[i]['voucher'] = [ 'The voucher has a remaining budget of {}, therefore a discount of {} can not be ' 'given.'.format(v_budget[v] + new_disc, disc) ] continue pos_data['price'] = price + (disc - new_disc) else: v_budget[v] -= disc seated = pos_data.get('item').seat_category_mappings.filter( subevent=pos_data.get('subevent')).exists() if pos_data.get('seat'): if not seated: errs[i]['seat'] = [ 'The specified product does not allow to choose a seat.' ] try: seat = self.context['event'].seats.get( seat_guid=pos_data['seat'], subevent=pos_data.get('subevent')) except Seat.DoesNotExist: errs[i]['seat'] = [ 'The specified seat does not exist.' ] else: pos_data['seat'] = seat if (seat not in free_seats and not seat.is_available( sales_channel=validated_data.get( 'sales_channel', 'web')) ) or seat in seats_seen: errs[i]['seat'] = [ ugettext_lazy( 'The selected seat "{seat}" is not available.' ).format(seat=seat.name) ] seats_seen.add(seat) elif seated: errs[i]['seat'] = [ 'The specified product requires to choose a seat.' ] if not force: for i, pos_data in enumerate(positions_data): if pos_data.get('voucher'): if pos_data['voucher'].allow_ignore_quota or pos_data[ 'voucher'].block_quota: continue new_quotas = (pos_data.get('variation').quotas.filter( subevent=pos_data.get('subevent')) if pos_data.get('variation') else pos_data.get('item').quotas.filter( subevent=pos_data.get('subevent'))) if len(new_quotas) == 0: errs[i]['item'] = [ ugettext_lazy( 'The product "{}" is not assigned to a quota.' ).format(str(pos_data.get('item'))) ] else: for quota in new_quotas: if quota not in quota_avail_cache: quota_avail_cache[quota] = list( quota.availability()) if quota_avail_cache[quota][1] is not None: quota_avail_cache[quota][1] -= 1 if quota_avail_cache[quota][1] < 0: errs[i]['item'] = [ ugettext_lazy( 'There is not enough quota available on quota "{}" to perform the operation.' ).format(quota.name) ] if any(errs): raise ValidationError({'positions': errs}) if validated_data.get('locale', None) is None: validated_data['locale'] = self.context[ 'event'].settings.locale order = Order(event=self.context['event'], **validated_data) order.set_expires( subevents=[p.get('subevent') for p in positions_data]) order.meta_info = "{}" order.total = Decimal('0.00') order.save() if ia: ia.order = order ia.save() pos_map = {} for pos_data in positions_data: answers_data = pos_data.pop('answers', []) addon_to = pos_data.pop('addon_to', None) attendee_name = pos_data.pop('attendee_name', '') if attendee_name and not pos_data.get('attendee_name_parts'): pos_data['attendee_name_parts'] = { '_legacy': attendee_name } pos = OrderPosition(**pos_data) pos.order = order if addon_to: pos.addon_to = pos_map[addon_to] if pos.price is None: price = get_price( item=pos.item, variation=pos.variation, voucher=pos.voucher, custom_price=None, subevent=pos.subevent, addon_to=pos.addon_to, invoice_address=ia, ) pos.price = price.gross pos.tax_rate = price.rate pos.tax_value = price.tax pos.tax_rule = pos.item.tax_rule else: pos._calculate_tax() pos.price_before_voucher = get_price( item=pos.item, variation=pos.variation, voucher=None, custom_price=None, subevent=pos.subevent, addon_to=pos.addon_to, invoice_address=ia, ).gross if pos.voucher: Voucher.objects.filter(pk=pos.voucher.pk).update( redeemed=F('redeemed') + 1) pos.save() pos_map[pos.positionid] = pos for answ_data in answers_data: options = answ_data.pop('options', []) answ = pos.answers.create(**answ_data) answ.options.add(*options) for cp in delete_cps: cp.delete() order.total = sum([p.price for p in order.positions.all()]) for fee_data in fees_data: is_percentage = fee_data.pop('_treat_value_as_percentage', False) if is_percentage: fee_data['value'] = round_decimal( order.total * (fee_data['value'] / Decimal('100.00')), self.context['event'].currency) is_split_taxes = fee_data.pop('_split_taxes_like_products', False) if is_split_taxes: d = defaultdict(lambda: Decimal('0.00')) trz = TaxRule.zero() for p in pos_map.values(): tr = p.tax_rule d[tr] += p.price - p.tax_value base_values = sorted([tuple(t) for t in d.items()], key=lambda t: (t[0] or trz).rate) sum_base = sum(t[1] for t in base_values) fee_values = [ (t[0], round_decimal(fee_data['value'] * t[1] / sum_base, self.context['event'].currency)) for t in base_values ] sum_fee = sum(t[1] for t in fee_values) # If there are rounding differences, we fix them up, but always leaning to the benefit of the tax # authorities if sum_fee > fee_data['value']: fee_values[0] = (fee_values[0][0], fee_values[0][1] + (fee_data['value'] - sum_fee)) elif sum_fee < fee_data['value']: fee_values[-1] = (fee_values[-1][0], fee_values[-1][1] + (fee_data['value'] - sum_fee)) for tr, val in fee_values: fee_data['tax_rule'] = tr fee_data['value'] = val f = OrderFee(**fee_data) f.order = order f._calculate_tax() f.save() else: f = OrderFee(**fee_data) f.order = order f._calculate_tax() f.save() order.total += sum([f.value for f in order.fees.all()]) order.save(update_fields=['total']) if order.total == Decimal('0.00') and validated_data.get( 'status') == Order.STATUS_PAID and not payment_provider: payment_provider = 'free' if order.total == Decimal( '0.00') and validated_data.get('status') != Order.STATUS_PAID: order.status = Order.STATUS_PAID order.save() order.payments.create(amount=order.total, provider='free', state=OrderPayment.PAYMENT_STATE_CONFIRMED, payment_date=now()) elif payment_provider == "free" and order.total != Decimal('0.00'): raise ValidationError( 'You cannot use the "free" payment provider for non-free orders.' ) elif validated_data.get('status') == Order.STATUS_PAID: if not payment_provider: raise ValidationError( 'You cannot create a paid order without a payment provider.' ) order.payments.create(amount=order.total, provider=payment_provider, info=payment_info, payment_date=payment_date, state=OrderPayment.PAYMENT_STATE_CONFIRMED) elif payment_provider: order.payments.create(amount=order.total, provider=payment_provider, info=payment_info, state=OrderPayment.PAYMENT_STATE_CREATED) return order
def get_fees(event, total, invoice_address, mod='', request=None, positions=[], gift_cards=None): if request is not None and not positions: positions = get_cart(request) skip_free = event.settings.get('service_fee_skip_free', as_type=bool) if skip_free: positions = [pos for pos in positions if pos.price != Decimal('0.00')] skip_addons = event.settings.get('service_fee_skip_addons', as_type=bool) if skip_addons: positions = [pos for pos in positions if not pos.addon_to_id] skip_non_admission = event.settings.get('service_fee_skip_non_admission', as_type=bool) if skip_non_admission: positions = [pos for pos in positions if pos.item.admission] fee_per_ticket = event.settings.get('service_fee_per_ticket' + mod, as_type=Decimal) if mod and fee_per_ticket is None: fee_per_ticket = event.settings.get('service_fee_per_ticket', as_type=Decimal) fee_abs = event.settings.get('service_fee_abs' + mod, as_type=Decimal) if mod and fee_abs is None: fee_abs = event.settings.get('service_fee_abs', as_type=Decimal) fee_percent = event.settings.get('service_fee_percent' + mod, as_type=Decimal) if mod and fee_percent is None: fee_percent = event.settings.get('service_fee_percent', as_type=Decimal) fee_per_ticket = Decimal("0") if fee_per_ticket is None else fee_per_ticket fee_abs = Decimal("0") if fee_abs is None else fee_abs fee_percent = Decimal("0") if fee_percent is None else fee_percent if event.settings.get('service_fee_skip_if_gift_card', as_type=bool): gift_cards = gift_cards or [] if request: cs = cart_session(request) if cs.get('gift_cards'): gift_cards = event.organizer.accepted_gift_cards.filter( pk__in=cs.get('gift_cards'), currency=event.currency) summed = 0 for gc in gift_cards: fval = Decimal(gc.value) # TODO: don't require an extra query fval = min(fval, total - summed) if fval > 0: total -= fval summed += fval if (fee_per_ticket or fee_abs or fee_percent) and total != Decimal('0.00'): fee = round_decimal( fee_abs + total * (fee_percent / 100) + len(positions) * fee_per_ticket, event.currency) tax_rule = event.settings.tax_rate_default or TaxRule.zero() tax = tax_rule.tax(fee, invoice_address=invoice_address, base_price_is='gross') return [ OrderFee(fee_type=OrderFee.FEE_TYPE_SERVICE, internal_type='', value=fee, tax_rate=tax.rate, tax_value=tax.tax, tax_rule=tax_rule) ] return []