def test_module(address, expected_taxes): """ Test the DefaultTaxModule. """ # Create a product shop = get_shop(prices_include_tax=False, currency='USD') product = create_product('PROD', shop=shop, default_price=1000) price = product.get_shop_instance(shop).default_price # Put the tax rules into database for ruledef in shuffled(TAX_RULE_DEFS): rule = ruledef.get_tax_rule() rule.tax.save() rule.tax = rule.tax # refresh the id rule.save() rule.tax_classes.add(product.tax_class) assert TaxRule.objects.count() == len(TAX_RULE_DEFS) with override_settings(SHUUP_TAX_MODULE='default_tax'): module = get_tax_module() assert isinstance(module, DefaultTaxModule) context = TaxingContext(location=address) taxed_price = module.get_taxed_price_for(context, product, price) expected_codes = set(sum([x.split() for x in expected_taxes], [])) assert set(x.tax.code for x in taxed_price.taxes) == expected_codes expected_tax = Money(TAX_AMOUNTS[expected_taxes], 'USD') assert taxed_price.taxful.amount == price.amount + expected_tax # Clean-up the rules TaxRule.objects.all().delete()
def _refund_amount(self, index, text, amount, tax_proportions): taxmod = taxing.get_tax_module() ctx = taxmod.get_context_from_order_source(self) taxes = (list(chain.from_iterable( taxmod.get_taxed_price(ctx, TaxfulPrice(amount * factor), tax_class).taxes for (tax_class, factor) in tax_proportions))) base_amount = amount if not self.prices_include_tax: base_amount /= (1 + sum([tax.tax.rate for tax in taxes])) refund_line = OrderLine.objects.create( text=text, order=self, type=OrderLineType.REFUND, ordering=index, base_unit_price_value=-base_amount, quantity=1, ) for line_tax in taxes: refund_line.taxes.create( tax=line_tax.tax, name=_("Refund for %s" % line_tax.name), amount_value=-line_tax.amount, base_amount_value=-line_tax.base_amount, ordering=1 ) return refund_line
def test_rules_with_disabled_tax(): """ Test whether rules match when tax is disabled """ tax_class = TaxClass.objects.create(name="test") # Create a product shop = get_shop(prices_include_tax=False, currency='USD') product = create_product('PROD', shop=shop, default_price=1000) product.tax_class = tax_class product.save() price = product.get_shop_instance(shop).default_price # create disabled tax tax = Tax.objects.create(code="any", rate=0.1, name="Tax for any customer", enabled=False) tax_rule = TaxRule.objects.create(tax=tax) tax_rule.tax_classes.add(tax_class) with override_settings(SHUUP_TAX_MODULE='default_tax'): module = get_tax_module() assert isinstance(module, DefaultTaxModule) # 1) check the tax for anonymous anonymous_context = TaxingContext() taxed_price = module.get_taxed_price_for(anonymous_context, product, price) assert len(list(taxed_price.taxes)) == 0 # Clean-up the rules TaxRule.objects.all().delete()
def test_module(address, expected_taxes): """ Test the DefaultTaxModule. """ # Create a product shop = get_shop(prices_include_tax=False, currency='USD') product = create_product('PROD', shop=shop, default_price=1000) price = product.get_shop_instance(shop).default_price # Put the tax rules into database for ruledef in shuffled(TAX_RULE_DEFS): rule = ruledef.get_tax_rule() rule.tax.save() rule.tax = rule.tax # refresh the id rule.save() rule.tax_classes.add(product.tax_class) assert TaxRule.objects.count() == len(TAX_RULE_DEFS) with override_settings(SHUUP_TAX_MODULE='default_tax'): module = get_tax_module() assert isinstance(module, DefaultTaxModule) context = TaxingContext(location=address) taxed_price = module.get_taxed_price_for(context, product, price) expected_codes = set(sum([x.split() for x in expected_taxes], [])) assert set(x.tax.code for x in taxed_price.taxes) == expected_codes expected_tax = Money(TAX_AMOUNTS[expected_taxes], 'USD') assert taxed_price.taxful.amount == price.amount + expected_tax # Clean-up the rules TaxRule.objects.all().delete()
def test_rules_with_disabled_tax(): """ Test whether rules match when tax is disabled """ tax_class = TaxClass.objects.create(name="test") # Create a product shop = get_shop(prices_include_tax=False, currency='USD') product = create_product('PROD', shop=shop, default_price=1000) product.tax_class = tax_class product.save() price = product.get_shop_instance(shop).default_price # create disabled tax tax = Tax.objects.create(code="any", rate=0.1, name="Tax for any customer", enabled=False) tax_rule = TaxRule.objects.create(tax=tax) tax_rule.tax_classes.add(tax_class) with override_settings(SHUUP_TAX_MODULE='default_tax'): module = get_tax_module() assert isinstance(module, DefaultTaxModule) # 1) check the tax for anonymous anonymous_context = TaxingContext() taxed_price = module.get_taxed_price_for(anonymous_context, product, price) assert len(list(taxed_price.taxes)) == 0 # Clean-up the rules TaxRule.objects.all().delete()
def _refund_amount(self, index, text, amount, tax_proportions): taxmod = taxing.get_tax_module() ctx = taxmod.get_context_from_order_source(self) taxes = (list( chain.from_iterable( taxmod.get_taxed_price(ctx, TaxfulPrice(amount * factor), tax_class).taxes for (tax_class, factor) in tax_proportions))) base_amount = amount if not self.prices_include_tax: base_amount /= (1 + sum([tax.tax.rate for tax in taxes])) refund_line = OrderLine.objects.create( text=text, order=self, type=OrderLineType.REFUND, ordering=index, base_unit_price_value=-base_amount, quantity=1, ) for line_tax in taxes: refund_line.taxes.create(tax=line_tax.tax, name=_("Refund for %s" % line_tax.name), amount_value=-line_tax.amount, base_amount_value=-line_tax.base_amount, ordering=1) return refund_line
def create_refund(self, refund_data, created_by=None, supplier=None): """ Create a refund if passed a list of refund line data. Refund line data is simply a list of dictionaries where each dictionary contains data for a particular refund line. Additionally, if the parent line is of `enum` type `OrderLineType.PRODUCT` and the `restock_products` boolean flag is set to `True`, the products will be restocked with the exact amount set in the order supplier's `quantity` field. :param refund_data: List of dicts containing refund data. :type refund_data: [dict] :param created_by: Refund creator's user instance, used for adjusting supplier stock. :type created_by: django.contrib.auth.User|None """ tax_module = taxing.get_tax_module() refund_lines = tax_module.create_refund_lines( self, supplier, created_by, refund_data ) self.cache_prices() self.save() self.update_shipping_status() self.update_payment_status() refund_created.send(sender=type(self), order=self, refund_lines=refund_lines)
def test_rules_with_anonymous(): """ Test the DefaultTaxModule with anonymous customer. """ tax_class = TaxClass.objects.create(name="test") # Create a product shop = get_shop(prices_include_tax=False, currency='USD') product = create_product('PROD', shop=shop, default_price=1000) product.tax_class = tax_class product.save() price = product.get_shop_instance(shop).default_price # create taxes # When customer is company, it should pay additional taxes tax_for_anyone = Tax.objects.create(code="any", rate=0.1, name="Tax for any customer") tax_for_companies = Tax.objects.create(code="companies", rate=0.3, name="Additional tax for companies") # create tax group for companies companies_tax_group = CustomerTaxGroup.get_default_company_group() # create the tax rule as follows: # - 10% for any kind of customer, no matter what # - 30% only for companies any_tax_rule = TaxRule.objects.create(tax=tax_for_anyone) any_tax_rule.tax_classes.add(tax_class) company_tax_rule = TaxRule.objects.create(tax=tax_for_companies) company_tax_rule.tax_classes.add(tax_class) company_tax_rule.customer_tax_groups.add(companies_tax_group) with override_settings(SHUUP_TAX_MODULE='default_tax'): module = get_tax_module() assert isinstance(module, DefaultTaxModule) # 1) check the tax for anonymous anonymous_context = TaxingContext() taxed_price = module.get_taxed_price_for(anonymous_context, product, price) expected_anonymous_codes = set(["any"]) assert set(x.tax.code for x in taxed_price.taxes) == expected_anonymous_codes # 2) check the tax for comanies company_context = TaxingContext(customer_tax_group=companies_tax_group) taxed_price = module.get_taxed_price_for(company_context, product, price) expected_companies_codes = set(["any", "companies"]) assert set(x.tax.code for x in taxed_price.taxes) == expected_companies_codes # Clean-up the rules TaxRule.objects.all().delete()
def test_rules_with_anonymous(): """ Test the DefaultTaxModule with anonymous customer. """ tax_class = TaxClass.objects.create(name="test") # Create a product shop = get_shop(prices_include_tax=False, currency='USD') product = create_product('PROD', shop=shop, default_price=1000) product.tax_class = tax_class product.save() price = product.get_shop_instance(shop).default_price # create taxes # When customer is company, it should pay additional taxes tax_for_anyone = Tax.objects.create(code="any", rate=0.1, name="Tax for any customer") tax_for_companies = Tax.objects.create(code="companies", rate=0.3, name="Additional tax for companies") # create tax group for companies companies_tax_group = CustomerTaxGroup.get_default_company_group() # create the tax rule as follows: # - 10% for any kind of customer, no matter what # - 30% only for companies any_tax_rule = TaxRule.objects.create(tax=tax_for_anyone) any_tax_rule.tax_classes.add(tax_class) company_tax_rule = TaxRule.objects.create(tax=tax_for_companies) company_tax_rule.tax_classes.add(tax_class) company_tax_rule.customer_tax_groups.add(companies_tax_group) with override_settings(SHUUP_TAX_MODULE='default_tax'): module = get_tax_module() assert isinstance(module, DefaultTaxModule) # 1) check the tax for anonymous anonymous_context = TaxingContext() taxed_price = module.get_taxed_price_for(anonymous_context, product, price) expected_anonymous_codes = set(["any"]) assert set(x.tax.code for x in taxed_price.taxes) == expected_anonymous_codes # 2) check the tax for comanies company_context = TaxingContext(customer_tax_group=companies_tax_group) taxed_price = module.get_taxed_price_for(company_context, product, price) expected_companies_codes = set(["any", "companies"]) assert set(x.tax.code for x in taxed_price.taxes) == expected_companies_codes # Clean-up the rules TaxRule.objects.all().delete()
def _make_taxed(request, item, priceful, with_taxes): """ :type request: django.http.HttpRequest :type item: shuup.core.taxing.TaxableItem :type priceful: shuup.core.pricing.Priceful :rtype: shuup.core.pricing.Priceful|None """ try: tax_amount = getattr(priceful, 'tax_amount', None) except TypeError: # e.g. shuup.core.order_creator.TaxesNotCalculated tax_amount = None if tax_amount is not None: if with_taxes: return TaxedPriceInfo(priceful.taxful_price, priceful.taxful_base_price, quantity=priceful.quantity, tax_amount=tax_amount) else: return TaxedPriceInfo(priceful.taxless_price, priceful.taxless_base_price, quantity=priceful.quantity, tax_amount=tax_amount) if not should_calculate_taxes_automatically(): return None taxmod = get_tax_module() taxctx = taxmod.get_context_from_request(request) price = taxmod.get_taxed_price_for(taxctx, item, priceful.price) base_price = taxmod.get_taxed_price_for(taxctx, item, priceful.base_price) if with_taxes: return TaxedPriceInfo(price.taxful, base_price.taxful, quantity=priceful.quantity, tax_amount=price.tax_amount) else: return TaxedPriceInfo(price.taxless, base_price.taxless, quantity=priceful.quantity, tax_amount=price.tax_amount)
def _make_taxed(request, item, priceful, with_taxes): """ :type request: django.http.HttpRequest :type item: shuup.core.taxing.TaxableItem :type priceful: shuup.core.pricing.Priceful :rtype: shuup.core.pricing.Priceful|None """ try: tax_amount = getattr(priceful, 'tax_amount', None) except TypeError: # e.g. shuup.core.order_creator.TaxesNotCalculated tax_amount = None if tax_amount is not None: if with_taxes: return TaxedPriceInfo( priceful.taxful_price, priceful.taxful_base_price, quantity=priceful.quantity, tax_amount=tax_amount) else: return TaxedPriceInfo( priceful.taxless_price, priceful.taxless_base_price, quantity=priceful.quantity, tax_amount=tax_amount) if not should_calculate_taxes_automatically(): return None taxmod = get_tax_module() taxctx = taxmod.get_context_from_request(request) price = taxmod.get_taxed_price_for(taxctx, item, priceful.price) base_price = taxmod.get_taxed_price_for(taxctx, item, priceful.base_price) if with_taxes: return TaxedPriceInfo( price.taxful, base_price.taxful, quantity=priceful.quantity, tax_amount=price.tax_amount) else: return TaxedPriceInfo( price.taxless, base_price.taxless, quantity=priceful.quantity, tax_amount=price.tax_amount)
def _calculate_taxes(self, lines): tax_module = taxing.get_tax_module() tax_module.add_taxes(self, lines) self._taxes_calculated = True
def _calculate_taxes(self, lines): tax_module = taxing.get_tax_module() tax_module.add_taxes(self, lines) self._taxes_calculated = True