Reputation: 369
I want to apply 18% tax to all products on Django Oscar. What is the best and simple way to achieve this?
I have followed this documentation.
checkout/tax.py
from decimal import Decimal as D
def apply_to(submission):
# Assume 7% sales tax on sales to New Jersey You could instead use an
# external service like Avalara to look up the appropriates taxes.
STATE_TAX_RATES = {
'NJ': D('0.07')
}
shipping_address = submission['shipping_address']
rate = D('0.18')
for line in submission['basket'].all_lines():
line_tax = calculate_tax(
line.line_price_excl_tax_incl_discounts, rate)
unit_tax = (line_tax / line.quantity).quantize(D('0.01'))
line.purchase_info.price.tax = unit_tax
# Note, we change the submission in place - we don't need to
# return anything from this function
shipping_charge = submission['shipping_charge']
if shipping_charge is not None:
shipping_charge.tax = calculate_tax(
shipping_charge.excl_tax, rate)
def calculate_tax(price, rate):
tax = price * rate
print(tax)
return tax.quantize(D('0.01'))
checkout/session.py
from . import tax
def build_submission(self, **kwargs):
"""
Return a dict of data that contains everything required for an order
submission. This includes payment details (if any).
This can be the right place to perform tax lookups and apply them to
the basket.
"""
# Pop the basket if there is one, because we pass it as a positional
# argument to methods below
basket = kwargs.pop('basket', self.request.basket)
shipping_address = self.get_shipping_address(basket)
shipping_method = self.get_shipping_method(
basket, shipping_address)
billing_address = self.get_billing_address(shipping_address)
if not shipping_method:
total = shipping_charge = None
else:
shipping_charge = shipping_method.calculate(basket)
total = self.get_order_totals(
basket, shipping_charge=shipping_charge, **kwargs)
submission = {
'user': self.request.user,
'basket': basket,
'shipping_address': shipping_address,
'shipping_method': shipping_method,
'shipping_charge': shipping_charge,
'billing_address': billing_address,
'order_total': total,
'order_kwargs': {},
'payment_kwargs': {}}
# If there is a billing address, add it to the payment kwargs as calls
# to payment gateways generally require the billing address. Note, that
# it normally makes sense to pass the form instance that captures the
# billing address information. That way, if payment fails, you can
# render bound forms in the template to make re-submission easier.
if billing_address:
submission['payment_kwargs']['billing_address'] = billing_address
# Allow overrides to be passed in
submission.update(kwargs)
# Set guest email after overrides as we need to update the order_kwargs
# entry.
user = submission['user']
if (not user.is_authenticated
and 'guest_email' not in submission['order_kwargs']):
email = self.checkout_session.get_guest_email()
submission['order_kwargs']['guest_email'] = email
tax.apply_to(submission)
return submission
Now, the order total is supposed to have included 18% tax but I only see this is applied to cart total and not order total. And even in product detail view tax should show up as 18%.
Upvotes: 2
Views: 869
Reputation: 31514
You have missed a step that is mentioned in the documentation - where the order total is recalculated after applying the tax:
tax.apply_to(submission)
# Recalculate order total to ensure we have a tax-inclusive total
submission['order_total'] = self.get_order_totals(
submission['basket'],
submission['shipping_charge']
)
return submission
And even in product detail view tax should show up as 18%.
That is not going to happen automatically - the logic above is only applied when placing an order. If you're using the DeferredTax
strategy then the tax is not known at the point of adding a product to the basket, so it cannot be displayed. You would need to add some display logic to the detail view to indicate what the likely taxes are.
Upvotes: 5