Esempio n. 1
0
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()
Esempio n. 2
0
    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
Esempio n. 3
0
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()
Esempio n. 4
0
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()
Esempio n. 5
0
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()
Esempio n. 6
0
    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
Esempio n. 7
0
    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)
Esempio n. 8
0
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()
Esempio n. 9
0
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()
Esempio n. 10
0
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)
Esempio n. 11
0
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)
Esempio n. 12
0
 def _calculate_taxes(self, lines):
     tax_module = taxing.get_tax_module()
     tax_module.add_taxes(self, lines)
     self._taxes_calculated = True
Esempio n. 13
0
 def _calculate_taxes(self, lines):
     tax_module = taxing.get_tax_module()
     tax_module.add_taxes(self, lines)
     self._taxes_calculated = True