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
Example #4
0
    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
Example #7
0
    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