Source code for shuup.default_tax.module

# This file is part of Shuup.
#
# Copyright (c) 2012-2021, Shuup Commerce Inc. All rights reserved.
#
# This source code is licensed under the OSL-3.0 license found in the
# LICENSE file in the root directory of this source tree.
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
from itertools import groupby
from operator import attrgetter

from shuup.core import taxing
from shuup.core.taxing.utils import calculate_compounded_added_taxes
from shuup.default_tax.models import TaxRule
from shuup.utils.iterables import first


[docs]class DefaultTaxModule(taxing.TaxModule): identifier = "default_tax" name = _("Default Taxation")
[docs] def get_taxed_price(self, context, price, tax_class): return _calculate_taxes(price, context, tax_class)
def _calculate_taxes(price, taxing_context, tax_class): rules = _get_enabled_tax_rules(taxing_context, tax_class) tax_groups = get_taxes_of_effective_rules(taxing_context, rules) return calculate_compounded_added_taxes(price, tax_groups) def _get_enabled_tax_rules(taxing_context, tax_class): """ Get enabled tax rules from the db for given parameters. Returned rules are ordered desceding by override group and then ascending by priority (as required by `_filter_and_group_rules`). :type taxing_context: shuup.core.taxing.TaxingContext :type tax_class: shuup.core.models.TaxClass """ tax_rules = TaxRule.objects.may_match_postal_code(taxing_context.postal_code).filter( enabled=True, tax__enabled=True, tax_classes=tax_class ) if taxing_context.customer_tax_group: tax_rules = tax_rules.filter( Q(customer_tax_groups=taxing_context.customer_tax_group) | Q(customer_tax_groups=None) ) else: tax_rules = tax_rules.filter(customer_tax_groups=None) tax_rules = tax_rules.order_by("-override_group", "priority") return tax_rules
[docs]def get_taxes_of_effective_rules(taxing_context, tax_rules): """ Get taxes grouped by priority from effective tax rules. Effective tax rules is determined by first limiting the scope to the rules that match the given taxing context (see `TaxRule.match`) and then further limiting the matching rules by selecting only the rules in the highest numbered override group. The `Tax` objects in the effective rules will be grouped by the priority of the rules. The tax groups are returned as list of tax lists. :type taxing_context: shuup.core.taxing.TaxingContext :param tax_rules: Tax rules to filter from. These should be ordered desceding by override group and then ascending by priority. :type tax_rules: Iterable[TaxRule] :rtype: list[list[shuup.core.models.Tax]] """ # Limit our scope to only matching rules matching_rules = (tax_rule for tax_rule in tax_rules if tax_rule.matches(taxing_context)) # Further limit our scope to the highest numbered override group grouped_by_override = groupby(matching_rules, attrgetter("override_group")) highest_override_group = first(grouped_by_override, (None, []))[1] # Group rules by priority grouped_rules = groupby(highest_override_group, attrgetter("priority")) tax_groups = [[rule.tax for rule in rules] for (_, rules) in grouped_rules] return tax_groups