-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
save currency code in session (rather than Currency object)
- Loading branch information
Showing
7 changed files
with
119 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from django.conf import settings | ||
|
||
SESSION_PREFIX = getattr(settings, 'CURRENCY_SESSION_PREFIX', 'session') | ||
SESSION_KEY = '%s:currency_code' % SESSION_PREFIX |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,16 @@ | ||
from currencies.models import Currency | ||
# -*- coding: utf-8 -*- | ||
|
||
from .models import Currency | ||
from .utils import get_currency_code | ||
from .conf import SESSION_KEY | ||
|
||
def currencies(request): | ||
currencies = Currency.objects.active() | ||
|
||
if not request.session.get('currency'): | ||
try: | ||
currency = Currency.objects.get(is_default__exact=True) | ||
except Currency.DoesNotExist: | ||
currency = None | ||
request.session['currency'] = currency | ||
def currencies(request): | ||
# make sure that currency was initialized | ||
if not SESSION_KEY in request.session or request.session.get(SESSION_KEY) is None: | ||
request.session[SESSION_KEY] = get_currency_code(False) | ||
|
||
return { | ||
'CURRENCIES': currencies, | ||
'CURRENCY': request.session['currency'] | ||
'CURRENCIES': Currency.active.all(), # get all active currencies | ||
'CURRENCY_CODE': request.session[SESSION_KEY], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,59 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from decimal import Decimal | ||
|
||
from django import template | ||
from django.template.defaultfilters import stringfilter | ||
from currencies.models import Currency | ||
from currencies.utils import calculate_price | ||
|
||
register = template.Library() | ||
from classytags.core import Tag, Options | ||
from classytags.arguments import Argument | ||
|
||
from ..models import Currency | ||
from ..utils import get_currency_code, calculate | ||
|
||
@register.filter(name='currency') | ||
@stringfilter | ||
def set_currency(value, arg): | ||
return calculate_price(value, arg) | ||
|
||
register = template.Library() | ||
|
||
class ChangeCurrencyNode(template.Node): | ||
|
||
def __init__(self, price, currency): | ||
self.price = template.Variable(price) | ||
self.currency = template.Variable(currency) | ||
class CurrentCurrencyTag(Tag): | ||
name = 'get_current_currency' | ||
options = Options( | ||
'as', | ||
Argument('varname', resolve=False, required=False), | ||
) | ||
|
||
def render(self, context): | ||
def render_tag(self, context, varname): | ||
code = get_currency_code(context['request']) | ||
try: | ||
return calculate_price(self.price.resolve(context), | ||
self.currency.resolve(context)) | ||
except template.VariableDoesNotExist: | ||
currency = Currency.active.get(code=code) | ||
except Currency.DoesNotExist: | ||
try: | ||
currency = Currency.active.default() | ||
except Currency.DoesNotExist: | ||
currency = None # shit happens... | ||
|
||
if varname: | ||
context[varname] = currency | ||
return '' | ||
else: | ||
return currency | ||
|
||
register.tag(CurrentCurrencyTag) | ||
|
||
@register.tag(name='change_currency') | ||
def change_currency(parser, token): | ||
try: | ||
tag_name, current_price, new_currency = token.split_contents() | ||
except ValueError: | ||
tag_name = token.contents.split()[0] | ||
raise template.TemplateSyntaxError('%r tag requires exactly two arguments' % (tag_name)) | ||
return ChangeCurrencyNode(current_price, new_currency) | ||
|
||
class ChangeCurrencyTag(Tag): | ||
name = 'change_currency' | ||
options = Options( | ||
Argument('price', resolve=True, required=True), | ||
Argument('code', resolve=True, required=True), | ||
) | ||
|
||
def render_tag(self, context, price, code): | ||
return calculate(price, code) | ||
|
||
register.tag(ChangeCurrencyTag) | ||
|
||
|
||
@stringfilter | ||
@register.filter(name='currency') | ||
def do_currency(price, code): | ||
return calculate(price, code) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
from django.conf.urls import url, patterns | ||
from currencies.views import set_currency | ||
# -*- coding: utf-8 -*- | ||
|
||
from django.conf.urls import url, patterns | ||
|
||
urlpatterns = patterns('', | ||
url(r'^setcurrency/$', set_currency, | ||
name='currencies_set_currency'), | ||
urlpatterns = patterns('currencies.views', | ||
url(r'^setcurrency/$', 'set_currency', name='currencies_set_currency'), | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,41 @@ | ||
from decimal import Decimal, ROUND_UP | ||
from currencies.models import Currency | ||
# -*- coding: utf-8 -*- | ||
|
||
from decimal import Decimal as D, ROUND_UP | ||
|
||
def calculate_price(price, currency): | ||
price = Decimal(price) | ||
currency = Currency.objects.get(code__exact=currency) | ||
default = Currency.objects.get(is_default=True) | ||
from .models import Currency as C | ||
from .conf import SESSION_KEY | ||
|
||
# First, convert from the default currency to the base currency | ||
price = price / default.factor | ||
|
||
# Now, convert from the base to the given currency | ||
price = price * currency.factor | ||
def calculate(price, code): | ||
to, default = C.active.get(code=code), C.active.default() | ||
|
||
return price.quantize(Decimal("0.01"), rounding=ROUND_UP) | ||
# First, convert from the default currency to the base currency, | ||
# then convert from the base to the given currency | ||
price = (D(price) / default.factor) * to.factor | ||
|
||
return price.quantize(D("0.01"), rounding=ROUND_UP) | ||
|
||
def price_to_base(price, currency): | ||
price = Decimal(price) | ||
|
||
# Convert from the given currency to the base currency | ||
price = price / currency.factor | ||
def convert(amount, from_code, to_code): | ||
if from_code == to_code: | ||
return amount | ||
|
||
return price.quantize(Decimal("0.01"), rounding=ROUND_UP) | ||
from_, to = C.active.get(code=from_code), C.active.get(code=to_code) | ||
|
||
amount = D(amount) * (to.factor / from_.factor) | ||
return amount.quantize(D("0.01"), rounding=ROUND_UP) | ||
|
||
|
||
def get_currency_code(request): | ||
for attr in ('session', 'COOKIES'): | ||
if hasattr(request, attr): | ||
try: | ||
return getattr(request, attr)[SESSION_KEY] | ||
except KeyError: | ||
continue | ||
|
||
# fallback to default... | ||
try: | ||
return C.active.default().code | ||
except C.DoesNotExist: | ||
return None # shit happens... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,27 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from django.utils.http import is_safe_url | ||
from django.http import HttpResponseRedirect | ||
from currencies.models import Currency | ||
from django.views.decorators.cache import never_cache | ||
|
||
from .models import Currency | ||
from .conf import SESSION_KEY | ||
|
||
|
||
@never_cache | ||
def set_currency(request): | ||
if request.method == 'POST': | ||
currency_code = request.POST.get('currency', None) | ||
next = request.POST.get('next', None) | ||
else: | ||
currency_code = request.GET.get('currency', None) | ||
next = request.GET.get('next', None) | ||
if not next: | ||
next = request.META.get('HTTP_REFERER', None) | ||
if not next: | ||
next = '/' | ||
next, currency_code = ( | ||
request.REQUEST.get('next'), request.REQUEST.get('currency_code', None)) | ||
|
||
if not is_safe_url(url=next, host=request.get_host()): | ||
next = request.META.get('HTTP_REFERER') | ||
if not is_safe_url(url=next, host=request.get_host()): | ||
next = '/' | ||
|
||
response = HttpResponseRedirect(next) | ||
if currency_code: | ||
if currency_code and Currency.active.filter(code=currency_code).exists(): | ||
if hasattr(request, 'session'): | ||
request.session['currency'] = \ | ||
Currency.objects.get(code__exact=currency_code) | ||
request.session[SESSION_KEY] = currency_code | ||
else: | ||
response.set_cookie('currency', currency_code) | ||
response.set_cookie(SESSION_KEY, currency_code) | ||
return response |