Reputation: 1867
What would be the best practice to get the shipping address in a pricing strategy? Based on the country selected, I would like to apply tax, or not.
I have an instance of CheckoutSessionData
in my Selector
, and the Selector
inherits from CheckoutSessionMixin
. But, CheckoutSessionMixin
needs a basket for many operations, especially for getting a shipping address. And, the BasketMiddleware
gets it's strategy first, and only then sets the basket on the current request.
So, how to get the shipping address, before? Any best practices?
oscar version is 1.6.3
Upvotes: 1
Views: 624
Reputation: 1867
for now, I'm using this solution, enabling me to apply tax or not throughout my complete site, where SwissStrategy
includes taxes, and InternationalStrategy
not. Glad for any feedback.
class Selector(CheckoutSessionMixin):
"""
Responsible for returning the appropriate strategy class for a given
user/session.
This can be called in three ways:
#) Passing a request and user. This is for determining
prices/availability for a normal user browsing the site.
#) Passing just the user. This is for offline processes that don't
have a request instance but do know which user to determine prices for.
#) Passing nothing. This is for offline processes that don't
correspond to a specific user. Eg, determining a price to store in
a search index.
"""
def strategy(self, request=None, user=None, **kwargs):
# TODO: if request, decide based on location/geoip,
# if to use swiss or international strategy
country_id = request.session.get(
'checkout_data', {}).get('shipping', {}).get('new_address_fields', {}).get('country_id', None)
try:
country = Country.objects.get(iso_3166_1_a2=country_id)
except ObjectDoesNotExist:
country = None
if not country or country.iso_3166_1_a2 == 'CH':
return SwissStrategy(request)
else:
return InternationalStrategy(request)
Upvotes: 1
Reputation: 31474
I think your issue is addressed in this part of the documentation - how to address US taxes. You basically need to:
Use a DeferredTax
strategy that returns prices without taxes applied.
Override and adjust the checkout views to apply taxes once they are known:
def build_submission(self, **kwargs):
submission = super().build_submission(**kwargs)
if submission['shipping_address'] and submission['shipping_method']:
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
Where tax.apply_to
is a function that you define, that determines the appropriate tax for the country of delivery (there's an example in the documentation).
Upvotes: 2