mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-04-24 17:48:41 +02:00
feat: add Currency Converter
This commit is contained in:
37
app/apps/common/templatetags/decimal.py
Normal file
37
app/apps/common/templatetags/decimal.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
from django import template
|
||||||
|
from decimal import Decimal, DecimalException
|
||||||
|
|
||||||
|
from django.utils.formats import number_format
|
||||||
|
from django.utils.translation import to_locale, get_language
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def drop_trailing_zeros(value):
|
||||||
|
if not isinstance(value, (float, Decimal, str)):
|
||||||
|
return value
|
||||||
|
|
||||||
|
try:
|
||||||
|
decimal_value = Decimal(str(value))
|
||||||
|
return decimal_value.normalize()
|
||||||
|
except Exception:
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def localize_number(value):
|
||||||
|
if value is None:
|
||||||
|
return value
|
||||||
|
|
||||||
|
try:
|
||||||
|
value = Decimal(str(value))
|
||||||
|
except (TypeError, ValueError, DecimalException):
|
||||||
|
return value
|
||||||
|
|
||||||
|
return number_format(
|
||||||
|
value,
|
||||||
|
decimal_pos=abs(value.as_tuple().exponent),
|
||||||
|
use_l10n=True,
|
||||||
|
force_grouping=True,
|
||||||
|
)
|
||||||
29
app/apps/mini_tools/forms.py
Normal file
29
app/apps/mini_tools/forms.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
from crispy_forms.helper import FormHelper
|
||||||
|
from crispy_forms.layout import Layout, Row, Column
|
||||||
|
from django import forms
|
||||||
|
from apps.currencies.models import Currency
|
||||||
|
from apps.common.widgets.tom_select import TomSelect
|
||||||
|
|
||||||
|
|
||||||
|
class CurrencyConverterForm(forms.Form):
|
||||||
|
from_currency = forms.ModelChoiceField(
|
||||||
|
queryset=Currency.objects.all(),
|
||||||
|
label="",
|
||||||
|
widget=TomSelect(clear_button=False),
|
||||||
|
)
|
||||||
|
|
||||||
|
to_currency = forms.ModelChoiceField(
|
||||||
|
queryset=Currency.objects.all(),
|
||||||
|
label="",
|
||||||
|
widget=TomSelect(clear_button=False),
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(CurrencyConverterForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
self.helper = FormHelper()
|
||||||
|
self.helper.form_tag = False
|
||||||
|
self.helper.layout = Layout(
|
||||||
|
"from_currency",
|
||||||
|
"to_currency",
|
||||||
|
)
|
||||||
@@ -8,4 +8,14 @@ urlpatterns = [
|
|||||||
views.unit_price_calculator,
|
views.unit_price_calculator,
|
||||||
name="unit_price_calculator",
|
name="unit_price_calculator",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"tools/currency-converter/",
|
||||||
|
views.currency_converter,
|
||||||
|
name="currency_converter",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"tools/currency-converter/convert/",
|
||||||
|
views.currency_converter_convert,
|
||||||
|
name="currency_converter_convert",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,7 +1,59 @@
|
|||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
from apps.common.widgets.decimal import convert_to_decimal
|
||||||
|
from apps.currencies.models import Currency
|
||||||
|
from apps.currencies.utils.convert import convert
|
||||||
|
from apps.mini_tools.forms import CurrencyConverterForm
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def unit_price_calculator(request):
|
def unit_price_calculator(request):
|
||||||
return render(request, "mini_tools/unit_price_calculator.html")
|
return render(request, "mini_tools/unit_price_calculator.html")
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def currency_converter(request):
|
||||||
|
form = CurrencyConverterForm()
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"mini_tools/currency_converter/currency_converter.html",
|
||||||
|
context={"form": form},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def currency_converter_convert(request):
|
||||||
|
from_value = request.GET.get("from_value")
|
||||||
|
from_currency = request.GET.get("from_currency")
|
||||||
|
to_currency = request.GET.get("to_currency")
|
||||||
|
|
||||||
|
if from_currency:
|
||||||
|
from_currency = Currency.objects.filter(id=from_currency).first()
|
||||||
|
if to_currency:
|
||||||
|
to_currency = Currency.objects.filter(id=to_currency).first()
|
||||||
|
if from_value:
|
||||||
|
from_value = convert_to_decimal(from_value)
|
||||||
|
|
||||||
|
if from_currency and to_currency and from_value:
|
||||||
|
converted_amount, prefix, suffix, decimal_places = convert(
|
||||||
|
amount=from_value,
|
||||||
|
from_currency=from_currency,
|
||||||
|
to_currency=to_currency,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
converted_amount = None
|
||||||
|
prefix = ""
|
||||||
|
suffix = ""
|
||||||
|
decimal_places = 0
|
||||||
|
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"mini_tools/currency_converter/converted_value.html",
|
||||||
|
context={
|
||||||
|
"converted_amount": converted_amount,
|
||||||
|
"prefix": prefix,
|
||||||
|
"suffix": suffix,
|
||||||
|
"decimal_places": decimal_places,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link dropdown-toggle {% active_link views='dca_strategy_index||dca_strategy_detail_index||unit_price_calculator' %}"
|
<a class="nav-link dropdown-toggle {% active_link views='dca_strategy_index||dca_strategy_detail_index||unit_price_calculator||currency_converter' %}"
|
||||||
href="#" role="button"
|
href="#" role="button"
|
||||||
data-bs-toggle="dropdown"
|
data-bs-toggle="dropdown"
|
||||||
aria-expanded="false">
|
aria-expanded="false">
|
||||||
@@ -78,6 +78,9 @@
|
|||||||
<li><a class="dropdown-item {% active_link views='unit_price_calculator' %}"
|
<li><a class="dropdown-item {% active_link views='unit_price_calculator' %}"
|
||||||
href="{% url 'unit_price_calculator' %}">{% translate 'Unit Price Calculator' %}</a></li>
|
href="{% url 'unit_price_calculator' %}">{% translate 'Unit Price Calculator' %}</a></li>
|
||||||
<li>
|
<li>
|
||||||
|
<li><a class="dropdown-item {% active_link views='currency_converter' %}"
|
||||||
|
href="{% url 'currency_converter' %}">{% translate 'Currency Converter' %}</a></li>
|
||||||
|
<li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{% load decimal %}
|
||||||
|
{% load currency_display %}
|
||||||
|
{% load formats %}
|
||||||
|
<input class="form-control form-control-lg mb-3"
|
||||||
|
type="text"
|
||||||
|
value="{{ converted_amount|drop_trailing_zeros|localize_number|default:'-' }}"
|
||||||
|
name="to_value"
|
||||||
|
id="to_value"
|
||||||
|
disabled>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
{% extends "layouts/base.html" %}
|
||||||
|
{% load formats %}
|
||||||
|
{% load crispy_forms_filters %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load webpack_loader %}
|
||||||
|
|
||||||
|
{% block title %}{% translate 'Unit Price Calculator' %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container px-md-3 py-3 column-gap-5" _="install init_tom_select">
|
||||||
|
<div class="tw-text-3xl fw-bold font-monospace tw-w-full mb-3">
|
||||||
|
<div>{% translate 'Currency Converter' %}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-5">
|
||||||
|
<div>
|
||||||
|
<input class="form-control form-control-lg mb-3"
|
||||||
|
type="text"
|
||||||
|
value="1"
|
||||||
|
name="from_value"
|
||||||
|
id="from_value"
|
||||||
|
x-data
|
||||||
|
x-mask:dynamic="$money($input, '{% get_decimal_separator %}', '{% get_thousand_separator %}', '30')">
|
||||||
|
</div>
|
||||||
|
<div>{{ form.from_currency|as_crispy_field }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="col text-primary tw-flex tw-items-center tw-justify-center">
|
||||||
|
<i class="fa-solid fa-equals"></i>
|
||||||
|
</div>
|
||||||
|
<div class="col-5">
|
||||||
|
<div hx-get="{% url 'currency_converter_convert' %}"
|
||||||
|
hx-trigger="input from:#from_value, input from:#id_from_currency, input from:#id_to_currency"
|
||||||
|
hx-include="#from_value, #id_from_currency, #id_to_currency">
|
||||||
|
<input class="form-control form-control-lg mb-3"
|
||||||
|
type="text"
|
||||||
|
name="to_value"
|
||||||
|
id="to_value"
|
||||||
|
disabled>
|
||||||
|
</div>
|
||||||
|
<div>{{ form.to_currency|as_crispy_field }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user