def get_order_lines_data(order: "Order", discounted: bool = False, discounts=None) -> List[TransactionLine]: data: List[TransactionLine] = [] order_lines = order.lines.all() tax_included = Site.objects.get_current().settings.include_taxes_in_prices shipping_address = order.shipping_address if shipping_address is None: raise TaxError("Shipping address required for ATE tax calculation") for line in order_lines: variant = line.variant if variant is None: continue channel_id = order.channel.id variant_channel_listing = line.variant.channel_listings.get( channel_id=order.channel.id) append_line_to_data( amount=line.unit_price_net_amount * line.quantity, data=data, line_id=line.id, quantity=line.quantity, shipping_address=shipping_address, tax_included=tax_included, variant=variant, variant_channel_listing=variant_channel_listing, discounted=discounted, ) return data
def get_order_tax_data(order: "Order", config: AvataxConfiguration, force_refresh=False) -> Dict[str, Any]: data = get_order_request_data(order) response = get_cached_response_or_fetch(data, "order_%s" % order.token, config, force_refresh) if response.get("Status") != "Success": transaction_errors = response.get("TransactionErrors") customer_msg = "" if isinstance(transaction_errors, list): for error in transaction_errors: error_message = error.get("ErrorMessage") if error_message: customer_msg += error_message error_code = response.get("ErrorCode", "") logger.warning( "Unable to calculate taxes for order %s, error_code: %s, " "error_msg: %s", order.token, error_code, error_message, ) if error_code == "-1003": raise ValidationError(error_message) raise TaxError(customer_msg) return response
def get_checkout_lines_data( checkout_info: "CheckoutInfo", lines_info: Iterable["CheckoutLineInfo"], config: AvataxConfiguration, discounted: bool = False, discounts=None, ) -> List[TransactionLine]: data: List[TransactionLine] = [] channel = checkout_info.channel tax_included = Site.objects.get_current().settings.include_taxes_in_prices shipping_address = checkout_info.shipping_address if shipping_address is None: raise TaxError("Shipping address required for ATE tax calculation") for line_info in lines_info: append_line_to_data( amount=base_calculations.base_checkout_line_total( line_info, channel, discounts).net.amount, data=data, line_id=line_info.line.id, quantity=line_info.line.quantity, shipping_address=shipping_address, tax_included=tax_included, variant=line_info.line.variant, variant_channel_listing=line_info.channel_listing, discounted=discounted, ) append_shipping_to_data( data, config.shipping_product_code, shipping_address, checkout_info.shipping_method_channel_listings, ) return data
def preprocess_order_creation( self, checkout_info: "CheckoutInfo", discounts: List["DiscountInfo"], lines: Optional[Iterable["CheckoutLineInfo"]], previous_value: Any, ): """ Ensure all the data is correct and we can proceed with creation of order. Raise an error when can't receive taxes. """ if self._skip_plugin(previous_value): return previous_value data = generate_request_data_from_checkout( checkout_info, lines_info=lines, config=self.config, transaction_type=TRANSACTION_TYPE, discounts=discounts, ) if not data.TransactionLines: return previous_value transaction_url = urljoin( get_api_url(self.config.use_sandbox), "AvaTaxExcise/transactions/create", ) with opentracing.global_tracer().start_active_span( "avatax_excise.transactions.create") as scope: span = scope.span span.set_tag(opentracing.tags.COMPONENT, "tax") span.set_tag("service.name", "avatax_excise") taxes_data = api_post_request(transaction_url, data, self.config) if not taxes_data or taxes_data.get("Status") != "Success": transaction_errors = taxes_data.get("TransactionErrors") customer_msg = "" if isinstance(transaction_errors, list): for error in transaction_errors: error_message = error.get("ErrorMessage") if error_message: customer_msg += error_message error_code = taxes_data.get("ErrorCode", "") logger.warning( "Unable to calculate taxes for checkout %s" "error_code: %s error_msg: %s", checkout_info.checkout.token, error_code, error_message, ) if error_code == "-1003": raise ValidationError(error_message) raise TaxError(customer_msg) return previous_value
def get_checkout_lines_data( checkout_info: "CheckoutInfo", lines_info: Iterable["CheckoutLineInfo"], config: AvataxConfiguration, discounted: bool = False, discounts=None, ) -> List[TransactionLine]: data: List[TransactionLine] = [] channel = checkout_info.channel tax_included = Site.objects.get_current().settings.include_taxes_in_prices shipping_address = checkout_info.shipping_address if shipping_address is None: raise TaxError("Shipping address required for ATE tax calculation") for sequence_number, line_info in enumerate(lines_info): prices_data = base_calculations.base_checkout_line_total( line_info, channel, discounts) # plugin requires int as invoice number - the line id was used for that # as order line id changes to `uuid` cannot be used anymore # the index of element + 1 in queryset is used instead; # the index value is increased be 1, as the line id 0 is # reserved for shipping append_line_to_data(amount=prices_data.price_with_discounts.net.amount, data=data, line_id=sequence_number + 1, quantity=line_info.line.quantity, shipping_address=shipping_address, tax_included=tax_included, variant=line_info.variant, variant_channel_listing=line_info.channel_listing, channel=channel, discounted=discounted, product_type=line_info.product_type) if checkout_info.delivery_method_info.delivery_method: price = checkout_info.delivery_method_info.delivery_method.price append_shipping_to_data( data, config.shipping_product_code, shipping_address, price.amount if price else None, ) return data
def get_checkout_lines_data( checkout: "Checkout", discounts=None ) -> List[TransactionLine]: data: List[TransactionLine] = [] lines_info = fetch_checkout_lines(checkout) tax_included = Site.objects.get_current().settings.include_taxes_in_prices shipping_address = checkout.shipping_address if shipping_address is None: raise TaxError("Shipping address required for ATE tax calculation") for line_info in lines_info: append_line_to_data( data, line_info.line.id, line_info.line.quantity, tax_included, line_info.line.variant, shipping_address, ) return data
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 get_order_lines_data(order: "Order", discounted: bool = False, discounts=None) -> List[TransactionLine]: data: List[TransactionLine] = [] lines = order.lines.order_by("created_at").prefetch_related( "variant__channel_listings", "variant__product__product_type") tax_included = Site.objects.get_current().settings.include_taxes_in_prices shipping_address = order.shipping_address if shipping_address is None: raise TaxError("Shipping address required for ATE tax calculation") for sequence_number, line in enumerate(lines): variant = line.variant if variant is None: continue variant_channel_listing = line.variant.channel_listings.get( channel_id=order.channel_id) # plugin requires int as invoice number - the line id was used for that # as order line id changes to `uuid` cannot be used anymore # the index of element in queryset is used instead append_line_to_data( data=data, line_id=sequence_number, quantity=line.quantity, amount=line.unit_price_net_amount * line.quantity, tax_included=tax_included, variant=variant, shipping_address=shipping_address, variant_channel_listing=variant_channel_listing, channel=order.channel, discounted=discounted, ) return data
def get_order_lines_data(order: "Order", discounts=None) -> List[TransactionLine]: data: List[TransactionLine] = [] order_lines = order.lines.all() tax_included = Site.objects.get_current().settings.include_taxes_in_prices shipping_address = order.shipping_address if shipping_address is None: raise TaxError("Shipping address required for ATE tax calculation") for line in order_lines: variant = line.variant if variant is None: continue append_line_to_data( data, line.id, line.quantity, tax_included, variant, shipping_address, ) return data