def __init__(self, tax_id, tax_code, tax_name, tax_rate, based_on, raw_based_on, tax_amount): self.tax_id = tax_id self.tax_code = tax_code self.tax_name = tax_name self.tax_rate = tax_rate self.raw_based_on = ensure_decimal_places(raw_based_on) self.based_on = ensure_decimal_places(based_on) self.tax_amount = ensure_decimal_places(tax_amount) self.taxful = (self.raw_based_on + tax_amount).as_rounded()
def __init__(self, tax_id, tax_code, tax_name, tax_rate, based_on, raw_based_on, tax_amount): self.tax_id = tax_id self.tax_code = tax_code self.tax_name = tax_name self.tax_rate = tax_rate self.raw_based_on = ensure_decimal_places(raw_based_on) self.based_on = ensure_decimal_places(based_on) self.tax_amount = ensure_decimal_places(tax_amount) self.taxful = (self.raw_based_on + tax_amount).as_rounded()
def __init__(self, source, **kwargs): """ Initialize SourceLine with given source and data. :param source: The `OrderSource` this `SourceLine` belongs to. :type source: OrderSource :param kwargs: Data for the `SourceLine`. """ assert isinstance(source, OrderSource) self.source = source self.line_id = kwargs.pop("line_id", None) self.parent_line_id = kwargs.pop("parent_line_id", None) self.type = kwargs.pop("type", None) self.shop = kwargs.pop("shop", None) self.product = kwargs.pop("product", None) tax_class = kwargs.pop("tax_class", None) if not self.product: # Only set tax_class when there is no product set, since # tax_class property will get the value from the product and # setter will fail when trying to set conflicting tax class # (happens when tax_class of the Product has changed) self.tax_class = tax_class self.supplier = kwargs.pop("supplier", None) self.quantity = kwargs.pop("quantity", 0) self.base_unit_price = ensure_decimal_places( kwargs.pop("base_unit_price", source.zero_price)) self.discount_amount = ensure_decimal_places( kwargs.pop("discount_amount", source.zero_price)) self.sku = kwargs.pop("sku", "") self.text = kwargs.pop("text", "") self.require_verification = kwargs.pop("require_verification", False) self.accounting_identifier = kwargs.pop("accounting_identifier", "") self.on_parent_change_behavior = kwargs.pop( "on_parent_change_behavior", OrderLineBehavior.INHERIT) self.line_source = kwargs.pop("line_source", LineSource.CUSTOMER) self._taxes = None self._data = kwargs.copy() self._state_check()
def __init__(self, source, **kwargs): """ Initialize SourceLine with given source and data. :param source: The `OrderSource` this `SourceLine` belongs to. :type source: OrderSource :param kwargs: Data for the `SourceLine`. """ assert isinstance(source, OrderSource) self.source = source self.line_id = kwargs.pop("line_id", None) self.parent_line_id = kwargs.pop("parent_line_id", None) self.type = kwargs.pop("type", None) self.shop = kwargs.pop("shop", None) self.product = kwargs.pop("product", None) tax_class = kwargs.pop("tax_class", None) if not self.product: # Only set tax_class when there is no product set, since # tax_class property will get the value from the product and # setter will fail when trying to set conflicting tax class # (happens when tax_class of the Product has changed) self.tax_class = tax_class self.supplier = kwargs.pop("supplier", None) self.quantity = kwargs.pop("quantity", 0) self.base_unit_price = ensure_decimal_places(kwargs.pop("base_unit_price", source.zero_price)) self.discount_amount = ensure_decimal_places(kwargs.pop("discount_amount", source.zero_price)) self.sku = kwargs.pop("sku", "") self.text = kwargs.pop("text", "") self.require_verification = kwargs.pop("require_verification", False) self.accounting_identifier = kwargs.pop("accounting_identifier", "") self.line_source = kwargs.pop("line_source", LineSource.CUSTOMER) self._taxes = None self._data = kwargs.copy() self._state_check()
def tax_amount(self): """ :rtype: shuup.utils.money.Money """ self.source.calculate_taxes_or_raise() zero = self.source.zero_price.amount taxes = self._taxes if taxes is None: # Taxes were calculated to a different line instance. Get # taxes from there. for line in self.source.get_final_lines(): if line.line_id == self.line_id and line.price == self.price: taxes = line.taxes return sum((ensure_decimal_places(x.amount) for x in taxes), zero)
def tax_amount(self): """ :rtype: shuup.utils.money.Money """ self.source.calculate_taxes_or_raise() zero = self.source.zero_price.amount taxes = self._taxes if taxes is None: # Taxes were calculated to a different line instance. Get # taxes from there. for line in self.source.get_final_lines(): if line.line_id == self.line_id and line.price == self.price: taxes = line.taxes return sum((ensure_decimal_places(x.amount) for x in taxes), zero)
def price(self): """ Total price for the specified quantity with discount. For scenarios like below quantize the returned price. base_unit_price * quantity - discount_amount 940.234529877 EUR (excl. tax) 1.000000000 0E-9 EUR (excl. tax) return 40.234529877000000000 EUR (excl. tax) :rtype: shuup.core.pricing.Price """ return ensure_decimal_places(self.base_unit_price * self.quantity - self.discount_amount)
def test_broken_order(admin_user): """""" quantities = [44, 23, 65] expected = sum(quantities) * 50 expected_based_on = expected / 1.5 # Shuup is calculating taxes per line so there will be some "errors" expected_based_on = ensure_decimal_places( Decimal("%s" % (expected_based_on + 0.01))) shop = get_default_shop() supplier = get_default_supplier() product1 = create_product("simple-test-product1", shop, supplier, 50) product2 = create_product("simple-test-product2", shop, supplier, 50) product3 = create_product("simple-test-product3", shop, supplier, 50) tax = get_default_tax() source = BasketishOrderSource(get_default_shop()) billing_address = get_address(country="US") shipping_address = get_address(name="Test street", country="US") source.status = get_initial_order_status() source.billing_address = billing_address source.shipping_address = shipping_address source.customer = create_random_person() source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() source.add_line( type=OrderLineType.PRODUCT, product=product1, supplier=get_default_supplier(), quantity=quantities[0], base_unit_price=source.create_price(50), ) source.add_line( type=OrderLineType.PRODUCT, product=product2, supplier=get_default_supplier(), quantity=quantities[1], base_unit_price=source.create_price(50), ) source.add_line( type=OrderLineType.PRODUCT, product=product3, supplier=get_default_supplier(), quantity=quantities[2], base_unit_price=source.create_price(50), ) currency = "EUR" summary = source.get_tax_summary() assert len(summary) == 1 summary = summary[0] assert summary.taxful == Money(expected, "EUR") assert summary.based_on == Money(expected_based_on, "EUR") # originally non-rounded value assert bankers_round(source.get_total_tax_amount()) == summary.tax_amount assert source.taxless_total_price.value == expected_based_on assert summary.taxful.value == source.taxful_total_price.value assert summary.tax_amount == Money( bankers_round(source.taxful_total_price.value - source.taxless_total_price.value), currency) assert summary.taxful == summary.raw_based_on + summary.tax_amount assert summary.tax_rate == tax.rate assert summary.taxful.value == ( summary.based_on + summary.tax_amount).value - Decimal("%s" % 0.01) # create order from basket creator = OrderCreator() order = creator.create_order(source) assert order.taxless_total_price.value == expected_based_on # originally non-rounded value assert bankers_round(order.get_total_tax_amount()) == summary.tax_amount
def test_broken_order(admin_user): """ """ quantities = [44, 23, 65] expected = sum(quantities) * 50 expected_based_on = expected / 1.5 # Shuup is calculating taxes per line so there will be some "errors" expected_based_on = ensure_decimal_places(Decimal("%s" % (expected_based_on + 0.01))) shop = get_default_shop() supplier = get_default_supplier() product1 = create_product("simple-test-product1", shop, supplier, 50) product2 = create_product("simple-test-product2", shop, supplier, 50) product3 = create_product("simple-test-product3", shop, supplier, 50) tax = get_default_tax() source = BasketishOrderSource(get_default_shop()) billing_address = get_address(country="US") shipping_address = get_address(name="Test street", country="US") source.status = get_initial_order_status() source.billing_address = billing_address source.shipping_address = shipping_address source.customer = create_random_person() source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() source.add_line( type=OrderLineType.PRODUCT, product=product1, supplier=get_default_supplier(), quantity=quantities[0], base_unit_price=source.create_price(50), ) source.add_line( type=OrderLineType.PRODUCT, product=product2, supplier=get_default_supplier(), quantity=quantities[1], base_unit_price=source.create_price(50), ) source.add_line( type=OrderLineType.PRODUCT, product=product3, supplier=get_default_supplier(), quantity=quantities[2], base_unit_price=source.create_price(50), ) currency = "EUR" summary = source.get_tax_summary() assert len(summary) == 1 summary = summary[0] assert summary.taxful == Money(expected, "EUR") assert summary.based_on == Money(expected_based_on, "EUR") # originally non-rounded value assert bankers_round(source.get_total_tax_amount()) == summary.tax_amount assert source.taxless_total_price.value == expected_based_on assert summary.taxful.value == source.taxful_total_price.value assert summary.tax_amount == Money(bankers_round(source.taxful_total_price.value - source.taxless_total_price.value), currency) assert summary.taxful == summary.raw_based_on + summary.tax_amount assert summary.tax_rate == tax.rate assert summary.taxful.value == (summary.based_on + summary.tax_amount).value - Decimal("%s" % 0.01) # create order from basket creator = OrderCreator() order = creator.create_order(source) assert order.taxless_total_price.value == expected_based_on # originally non-rounded value assert bankers_round(order.get_total_tax_amount()) == summary.tax_amount