def test_append_klarna_data_tax_included( mocked_checkout_line_total, mocked_plugins_manager, dummy_payment_data, payment_dummy, checkout_ready_to_complete, ): # given net = Money(100, "USD") gross = Money(123, "USD") # tax 23 % mocked_checkout_line_total.return_value = quantize_price( TaxedMoney(net=net, gross=gross), "USD" ) manager = get_plugins_manager() unit_price = mock.MagicMock() unit_price.return_value = quantize_price(TaxedMoney(net=net, gross=gross), "USD") manager.calculate_checkout_line_unit_price = unit_price mocked_plugins_manager.return_value = manager country_code = checkout_ready_to_complete.get_country() checkout_ready_to_complete.payments.add(payment_dummy) line = checkout_ready_to_complete.lines.first() payment_data = { "reference": "test", } # when result = append_klarna_data(dummy_payment_data, payment_data) # then expected_result = { "reference": "test", "shopperLocale": get_shopper_locale_value(country_code), "shopperReference": dummy_payment_data.customer_email, "countryCode": country_code, "lineItems": [ { "description": f"{line.variant.product.name}, {line.variant.name}", "quantity": line.quantity, "id": line.variant.sku, "taxAmount": price_to_minor_unit((gross - net).amount, "USD"), "taxPercentage": 2300, "amountExcludingTax": price_to_minor_unit(net.amount, "USD"), "amountIncludingTax": price_to_minor_unit(gross.amount, "USD"), }, { "amountExcludingTax": "1000", "amountIncludingTax": "1000", "description": "Shipping - DHL", "id": f"Shipping:{checkout_ready_to_complete.shipping_method.id}", "quantity": 1, "taxAmount": "0", "taxPercentage": 0, }, ], } assert result == expected_result
def test_calculate_checkout_shipping( reset_sequences, # pylint: disable=unused-argument checkout_with_item, shipping_zone, discount_info, address_usa_tx, address, site_settings, plugin_configuration, ): plugin_configuration() manager = get_plugins_manager() site_settings.company_address = address site_settings.save() checkout_with_item.shipping_address = address_usa_tx checkout_with_item.shipping_method = shipping_zone.shipping_methods.get() checkout_with_item.save() lines = fetch_checkout_lines(checkout_with_item) checkout_info = fetch_checkout_info(checkout_with_item, lines, [discount_info], manager) shipping_price = manager.calculate_checkout_shipping( checkout_info, lines, address, [discount_info]) shipping_price = quantize_price(shipping_price, shipping_price.currency) assert shipping_price == TaxedMoney(net=Money("10.00", "USD"), gross=Money("10.00", "USD"))
def test_calculate_checkout_total( reset_sequences, # pylint: disable=unused-argument with_discount, expected_net, expected_gross, voucher_amount, taxes_in_prices, checkout_with_item, product_with_single_variant, discount_info, shipping_zone, address_usa_tx, address_usa, site_settings, monkeypatch, plugin_configuration, non_default_category, ): plugin_configuration() # Required ATE variant data metadata = { get_metadata_key("UnitQuantity"): 1, } ProductVariant.objects.filter(sku="SKU_SINGLE_VARIANT").update( sku="202127000", private_metadata=metadata) monkeypatch.setattr( "saleor.plugins.avatax.excise.plugin.AvataxExcisePlugin._skip_plugin", lambda *_: False, ) manager = get_plugins_manager() checkout_with_item.shipping_address = address_usa_tx checkout_with_item.save() site_settings.company_address = address_usa site_settings.include_taxes_in_prices = taxes_in_prices site_settings.save() voucher_amount = Money(voucher_amount, "USD") checkout_with_item.shipping_method = shipping_zone.shipping_methods.get() checkout_with_item.discount = voucher_amount checkout_with_item.save() product_with_single_variant.charge_taxes = False product_with_single_variant.category = non_default_category product_with_single_variant.save() discounts = [discount_info] if with_discount else None discount_amount = Decimal("1.00") if with_discount else Decimal("0.00") checkout_with_item.discount_amount = discount_amount checkout_info = fetch_checkout_info(checkout_with_item, [], discounts, manager) add_variant_to_checkout(checkout_info, product_with_single_variant.variants.get()) lines = fetch_checkout_lines(checkout_with_item) total = manager.calculate_checkout_total(checkout_info, lines, address_usa_tx, discounts) total = quantize_price(total, total.currency) assert total == TaxedMoney(net=Money(expected_net, "USD"), gross=Money(expected_gross, "USD"))
def test_append_checkout_details_tax_included( mocked_calculate_checkout_line_unit_price, dummy_payment_data, payment_dummy, checkout_ready_to_complete, ): # given net = Money(100, "USD") gross = Money(123, "USD") # tax 23 % unit_price = quantize_price(TaxedMoney(net=net, gross=gross), "USD") country_code = checkout_ready_to_complete.get_country() mocked_calculate_checkout_line_unit_price.return_value = CheckoutTaxedPricesData( price_with_sale=unit_price, undiscounted_price=unit_price, price_with_discounts=unit_price, ) checkout_ready_to_complete.payments.add(payment_dummy) line = checkout_ready_to_complete.lines.first() payment_data = { "reference": "test", } # when result = append_checkout_details(dummy_payment_data, payment_data) # then expected_result = { "reference": "test", "shopperLocale": get_shopper_locale_value(country_code), "countryCode": country_code, "lineItems": [ { "description": f"{line.variant.product.name}, {line.variant.name}", "quantity": line.quantity, "id": line.variant.sku, "taxAmount": price_to_minor_unit((gross - net).amount, "USD"), "taxPercentage": 2300, "amountExcludingTax": price_to_minor_unit(net.amount, "USD"), "amountIncludingTax": price_to_minor_unit(gross.amount, "USD"), }, { "amountExcludingTax": "1000", "amountIncludingTax": "1000", "description": "Shipping - DHL", "id": f"Shipping:{checkout_ready_to_complete.shipping_method.id}", "quantity": 1, "taxAmount": "0", "taxPercentage": 0, }, ], } assert result == expected_result
def test_calculate_checkout_line_total( reset_sequences, # pylint: disable=unused-argument with_discount, expected_net, expected_gross, taxes_in_prices, discount_info, checkout_with_item, address_usa_tx, address_usa, site_settings, shipping_zone, plugin_configuration, ): plugin_configuration() manager = get_plugins_manager() checkout_with_item.shipping_address = address_usa_tx checkout_with_item.shipping_method = shipping_zone.shipping_methods.get() checkout_with_item.save() site_settings.company_address = address_usa site_settings.include_taxes_in_prices = taxes_in_prices site_settings.save() line = checkout_with_item.lines.first() product = line.variant.product product.metadata = {} # TODO consider adding ATE fields here product.charge_taxes = True product.save() product.product_type.save() discounts = [discount_info] if with_discount else None discount_amount = Decimal("1.00") if with_discount else Decimal("0.00") checkout_with_item.discount_amount = discount_amount lines = fetch_checkout_lines(checkout_with_item) checkout_info = fetch_checkout_info(checkout_with_item, lines, discounts, manager) checkout_line_info = lines[0] total = manager.calculate_checkout_line_total( checkout_info, lines, checkout_line_info, checkout_with_item.shipping_address, discounts, ) total = quantize_price(total, total.currency) assert total == TaxedMoney(net=Money(expected_net, "USD"), gross=Money(expected_gross, "USD"))
def calculate_checkout_line_total( self, checkout_line: "CheckoutLine", discounts: Iterable[DiscountInfo], previous_value: TaxedMoney, ) -> TaxedMoney: if self._skip_plugin(previous_value): return previous_value base_total = previous_value if not checkout_line.variant.product.charge_taxes: return base_total checkout = checkout_line.checkout if not _validate_checkout(checkout, [checkout_line]): return base_total taxes_data = get_checkout_tax_data(checkout, discounts, self.config) if not taxes_data or "Error" in taxes_data["Status"]: return base_total tax_meta = json.dumps(taxes_data["TransactionTaxes"]) process_checkout_metadata(tax_meta, checkout) line_tax_total = Decimal(0) for line in taxes_data.get("TransactionTaxes", []): if line.get("InvoiceLine") == checkout_line.id: line_tax_total += Decimal(line.get("TaxAmount", 0.0)) if not line_tax_total > 0: return base_total currency = checkout.currency tax = Decimal(line_tax_total) line_net = Decimal(base_total.net.amount) line_gross = Money(amount=line_net + tax, currency=currency) line_net = Money(amount=line_net, currency=currency) return quantize_price(TaxedMoney(net=line_net, gross=line_gross), currency)
def calculate_checkout_total( self, checkout: "Checkout", lines: Iterable["CheckoutLine"], discounts: Iterable[DiscountInfo], previous_value: TaxedMoney, ) -> TaxedMoney: if self._skip_plugin(previous_value): logger.debug("Skip Plugin in Calculate Checkout Total") return previous_value checkout_total = previous_value if not _validate_checkout(checkout, lines): logger.debug("Checkout Invalid in Calculate Checkout Total") return checkout_total response = get_checkout_tax_data(checkout, discounts, self.config) if not response or "Errors found" in response["Status"]: return checkout_total if len(response["TransactionTaxes"]) == 0: raise TaxError("ATE did not return TransactionTaxes") currency = checkout.currency tax = Money(Decimal(response.get("TotalTaxAmount", 0.0)), currency) net = checkout_total.net total_gross = net + tax taxed_total = quantize_price(TaxedMoney(net=net, gross=total_gross), currency) total = self._append_prices_of_not_taxed_lines( taxed_total, lines, discounts, ) voucher_value = checkout.discount if voucher_value: total -= voucher_value return max(total, zero_taxed_money(total.currency))
def calculate_checkout_line_total( self, checkout_info: "CheckoutInfo", lines: Iterable["CheckoutLineInfo"], checkout_line_info: "CheckoutLineInfo", address: Optional["Address"], discounts: Iterable["DiscountInfo"], previous_value: TaxedMoney, ) -> TaxedMoney: if self._skip_plugin(previous_value): return previous_value if not checkout_line_info.product.charge_taxes: return previous_value checkout = checkout_info.checkout if not _validate_checkout(checkout_info, lines): return previous_value response = get_checkout_tax_data(checkout_info, lines, discounts, self.config) if not response or "Error" in response["Status"]: return previous_value tax = Decimal(response.get("TotalTaxAmount", "0.00")) tax_lines = response.get("TransactionTaxes", []) if not tax_lines: return previous_value tax_meta = json.dumps(tax_lines) process_checkout_metadata(tax_meta, checkout) currency = checkout.currency net = Decimal(previous_value.net.amount) line_net = Money(amount=net, currency=currency) line_gross = Money(amount=net + tax, currency=currency) return quantize_price(TaxedMoney(net=line_net, gross=line_gross), currency)
def calculate_checkout_total( self, checkout_info: "CheckoutInfo", lines: Iterable["CheckoutLineInfo"], address: Optional["Address"], discounts: Iterable[DiscountInfo], previous_value: TaxedMoney, ) -> TaxedMoney: if self._skip_plugin(previous_value): logger.debug("Skip Plugin in Calculate Checkout Total") return previous_value checkout_total = previous_value if not _validate_checkout(checkout_info, lines): logger.debug("Checkout Invalid in Calculate Checkout Total") return checkout_total checkout = checkout_info.checkout response = get_checkout_tax_data(checkout_info, lines, discounts, self.config) if not response or "Errors found" in response["Status"]: return checkout_total currency = checkout.currency tax = Money(Decimal(response.get("TotalTaxAmount", 0.0)), currency) net = checkout_total.net gross = net + tax taxed_total = quantize_price(TaxedMoney(net=net, gross=gross), currency) total = self._append_prices_of_not_taxed_lines( taxed_total, lines, checkout_info.channel, discounts, ) voucher_value = checkout.discount if voucher_value: total -= voucher_value return max(total, zero_taxed_money(total.currency))
def test_calculate_checkout_shipping( reset_sequences, # pylint: disable=unused-argument checkout_with_item, shipping_zone, discount_info, address_usa_va, address, site_settings, plugin_configuration, ): plugin_configuration() manager = get_plugins_manager() site_settings.company_address = address site_settings.save() checkout_with_item.shipping_address = address_usa_va checkout_with_item.shipping_method = shipping_zone.shipping_methods.get() checkout_with_item.save() lines, _ = fetch_checkout_lines(checkout_with_item) checkout_info = fetch_checkout_info(checkout_with_item, lines, [discount_info], manager) shipping_price = manager.calculate_checkout_shipping( checkout_info, lines, address, [discount_info]) shipping_price = quantize_price(shipping_price, shipping_price.currency) assert shipping_price == TaxedMoney(net=Money("10.00", "USD"), gross=Money("10.00", "USD")) checkout_with_item.refresh_from_db() taxes_metadata = checkout_with_item.metadata.get( get_metadata_key("itemized_taxes")) sales_tax = checkout_with_item.metadata.get(get_metadata_key("sales_tax")) other_tax = checkout_with_item.metadata.get(get_metadata_key("other_tax")) assert taxes_metadata is not None assert len(taxes_metadata) > 0 assert sales_tax >= 0 assert other_tax >= 0
def test_calculate_checkout_total_excise_data( reset_sequences, # pylint: disable=unused-argument expected_net, expected_gross, taxes_in_prices, variant_sku, price, destination, metadata, checkout, product, shipping_zone, address_usa, site_settings, monkeypatch, plugin_configuration, cigar_product_type, ): plugin_configuration() monkeypatch.setattr( "saleor.plugins.avatax.excise.plugin.AvataxExcisePlugin._skip_plugin", lambda *_: False, ) manager = get_plugins_manager() address_usa.city = destination["city"] address_usa.postal_code = destination["postal_code"] address_usa.country_area = destination["country_area"] address_usa.save() checkout.shipping_address = address_usa checkout.billing_address = address_usa shipping_method = shipping_zone.shipping_methods.get() shipping_method.price_amount = 0 shipping_method.save() checkout.shipping_method = shipping_method metadata = { get_metadata_key("UnitQuantity"): metadata["UnitQuantity"], get_metadata_key("CustomNumeric1"): metadata["CustomNumeric1"], get_metadata_key("CustomNumeric2"): metadata["CustomNumeric2"], get_metadata_key("CustomNumeric3"): metadata["CustomNumeric3"], } product.product_type = cigar_product_type product.save() variant = product.variants.get() variant.sku = variant_sku variant.private_metadata = metadata variant.price_amount = Decimal(price) variant.save() checkout_info = fetch_checkout_info(checkout, [], [], manager) add_variant_to_checkout(checkout_info, variant, 1) checkout.save() site_settings.company_address = address_usa site_settings.include_taxes_in_prices = taxes_in_prices site_settings.save() lines = fetch_checkout_lines(checkout) total = manager.calculate_checkout_total(checkout_info, lines, address_usa, []) total = quantize_price(total, total.currency) assert total == TaxedMoney(net=Money(expected_net, "USD"), gross=Money(expected_gross, "USD"))
def test_calculate_checkout_total( reset_sequences, # pylint: disable=unused-argument with_discount, expected_net, expected_gross, voucher_amount, taxes_in_prices, checkout_with_item, product_with_single_variant, discount_info, shipping_zone, address_usa_va, address_usa, site_settings, monkeypatch, plugin_configuration, non_default_category, ): plugin_configuration() monkeypatch.setattr( "saleor.plugins.avatax.excise.plugin.AvataxExcisePlugin._skip_plugin", lambda *_: False, ) manager = get_plugins_manager() checkout_with_item.shipping_address = address_usa_va checkout_with_item.save() checkout_variant = checkout_with_item.lines.first().variant checkout_variant.sku = "202015500" checkout_variant.save(update_fields=["sku"]) site_settings.company_address = address_usa site_settings.include_taxes_in_prices = taxes_in_prices site_settings.save() voucher_amount = Money(voucher_amount, "USD") checkout_with_item.shipping_method = shipping_zone.shipping_methods.get() checkout_with_item.discount = voucher_amount checkout_with_item.save() product_with_single_variant.charge_taxes = False product_with_single_variant.category = non_default_category product_with_single_variant.save() variant = product_with_single_variant.variants.first() variant.sku = "202165300" variant.save(update_fields=["sku"]) discounts = [discount_info] if with_discount else None checkout_info = fetch_checkout_info(checkout_with_item, [], discounts, manager) add_variant_to_checkout(checkout_info, product_with_single_variant.variants.get()) lines, _ = fetch_checkout_lines(checkout_with_item) total = manager.calculate_checkout_total(checkout_info, lines, address_usa_va, discounts) total = quantize_price(total, total.currency) assert total == TaxedMoney(net=Money(expected_net, "USD"), gross=Money(expected_gross, "USD"))
def test_calculate_checkout_line_total( reset_sequences, # pylint: disable=unused-argument with_discount, expected_net, expected_gross, taxes_in_prices, discount_info, checkout_with_item, address_usa_va, address_usa, site_settings, shipping_zone, plugin_configuration, ): plugin_configuration() manager = get_plugins_manager() checkout_with_item.shipping_address = address_usa_va checkout_with_item.shipping_method = shipping_zone.shipping_methods.get() checkout_with_item.save() site_settings.company_address = address_usa site_settings.include_taxes_in_prices = taxes_in_prices site_settings.save() line = checkout_with_item.lines.first() product = line.variant.product product.metadata = {} # TODO consider adding ATE fields here product.charge_taxes = True product.save() product.product_type.save() discounts = [discount_info] if with_discount else None lines, _ = fetch_checkout_lines(checkout_with_item) checkout_info = fetch_checkout_info(checkout_with_item, lines, discounts, manager) total = manager.calculate_checkout_line_total( checkout_info, lines, lines[0], checkout_with_item.shipping_address, discounts, ) price_with_discounts = total.price_with_discounts price_with_discounts = quantize_price(price_with_discounts, price_with_discounts.currency) assert price_with_discounts == TaxedMoney(net=Money(expected_net, "USD"), gross=Money( expected_gross, "USD")) checkout_with_item.refresh_from_db() taxes_metadata = checkout_with_item.metadata.get( get_metadata_key("itemized_taxes")) sales_tax = checkout_with_item.metadata.get(get_metadata_key("sales_tax")) other_tax = checkout_with_item.metadata.get(get_metadata_key("other_tax")) assert taxes_metadata is not None assert len(taxes_metadata) > 0 assert sales_tax >= 0 assert other_tax >= 0