Report template currency updates (#4469)

* Move render_currency into helpers.py

- Add duplicate tag to report.py
- Add option for currency conversion (optional)

* Update report templates

- Use "render_currency" instead of including price_data template

* Remove 'price_data.html' template entirely
This commit is contained in:
Oliver 2023-03-08 23:26:26 +11:00 committed by GitHub
parent beac7d15df
commit 34875828d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 84 additions and 65 deletions

View File

@ -21,9 +21,11 @@ from django.http import StreamingHttpResponse
from django.test import TestCase
from django.utils.translation import gettext_lazy as _
import moneyed.localization
import regex
import requests
from bleach import clean
from djmoney.contrib.exchange.models import convert_money
from djmoney.money import Money
from PIL import Image
@ -1105,3 +1107,47 @@ def notify_responsible(instance, sender, content: NotificationBody = InvenTreeNo
target_exclude=[exclude],
context=context,
)
def render_currency(money, decimal_places=None, currency=None, include_symbol=True):
"""Render a currency / Money object to a formatted string (e.g. for reports)
Arguments:
money: The Money instance to be rendered
decimal_places: The number of decimal places to render to. If unspecified, uses the PRICING_DECIMAL_PLACES setting.
currency: Optionally convert to the specified currency
include_symbol: Render with the appropriate currency symbol
"""
if money is None or money.amount is None:
return '-'
if currency is not None:
# Attempt to convert to the provided currency
# If cannot be done, leave the original
try:
money = convert_money(money, currency)
except Exception:
pass
if decimal_places is None:
decimal_places = InvenTreeSetting.get_setting('PRICING_DECIMAL_PLACES', 6)
value = Decimal(str(money.amount)).normalize()
value = str(value)
if '.' in value:
decimals = len(value.split('.')[-1])
decimals = max(decimals, 2)
decimals = min(decimals, decimal_places)
decimal_places = decimals
else:
decimal_places = max(decimal_places, 2)
return moneyed.localization.format_money(
money,
decimal_places=decimal_places,
include_symbol=include_symbol,
)

View File

@ -195,7 +195,7 @@ src="{% static 'img/blank_image.png' %}"
{% if tp == None %}
<span class='badge bg-warning'>{% trans "Total cost could not be calculated" %}</span>
{% else %}
{% include "price_data.html" with price=tp %}
{% render_currency tp currency=order.supplier.currency %}
{% endif %}
{% endwith %}
</td>

View File

@ -193,7 +193,7 @@ src="{% static 'img/blank_image.png' %}"
{% if tp == None %}
<span class='badge bg-warning'>{% trans "Total cost could not be calculated" %}</span>
{% else %}
{% include "price_data.html" with price=tp %}
{% render_currency tp currency=order.customer.currency %}
{% endif %}
{% endwith %}
</td>

View File

@ -46,8 +46,8 @@
{% endif %}
</td>
<th>{% trans "Internal Pricing" %}</th>
<td>{% include "price_data.html" with price=pricing.internal_cost_min %}</td>
<td>{% include "price_data.html" with price=pricing.internal_cost_max %}</td>
<td>{% render_currency pricing.internal_cost_min %}</td>
<td>{% render_currency pricing.internal_cost_max %}</td>
</tr>
{% if part.purchaseable %}
<tr>
@ -59,8 +59,8 @@
{% endif %}
</td>
<th>{% trans "Purchase History" %}</th>
<td>{% include "price_data.html" with price=pricing.purchase_cost_min %}</td>
<td>{% include "price_data.html" with price=pricing.purchase_cost_max %}</td>
<td>{% render_currency pricing.purchase_cost_min %}</td>
<td>{% render_currency pricing.purchase_cost_max %}</td>
</tr>
<tr>
<td>
@ -71,8 +71,8 @@
{% endif %}
</td>
<th>{% trans "Supplier Pricing" %}</th>
<td>{% include "price_data.html" with price=pricing.supplier_price_min %}</td>
<td>{% include "price_data.html" with price=pricing.supplier_price_max %}</td>
<td>{% render_currency pricing.supplier_price_min %}</td>
<td>{% render_currency pricing.supplier_price_max %}</td>
</tr>
{% endif %}
{% if part.assembly %}
@ -85,23 +85,23 @@
{% endif %}
</td>
<th>{% trans "BOM Pricing" %}</th>
<td>{% include "price_data.html" with price=pricing.bom_cost_min %}</td>
<td>{% include "price_data.html" with price=pricing.bom_cost_max %}</td>
<td>{% render_currency pricing.bom_cost_min %}</td>
<td>{% render_currency pricing.bom_cost_max %}</td>
</tr>
{% endif %}
{% if part.is_template %}
<tr>
<td><a href='#variant-cost'><span class='fas fa-shapes'></span></a></td>
<th>{% trans "Variant Pricing" %}</th>
<td>{% include "price_data.html" with price=pricing.variant_cost_min %}</td>
<td>{% include "price_data.html" with price=pricing.variant_cost_max %}</td>
<td>{% render_currency pricing.variant_cost_min %}</td>
<td>{% render_currency pricing.variant_cost_max %}</td>
</tr>
{% endif %}
<tr>
<td></td>
<th>{% trans "Overall Pricing" %}</th>
<th>{% include "price_data.html" with price=pricing.overall_min %}</th>
<th>{% include "price_data.html" with price=pricing.overall_max %}</th>
<th>{% render_currency pricing.overall_min %}</th>
<th>{% render_currency pricing.overall_max %}</th>
</tr>
</tbody>
</table>
@ -126,8 +126,8 @@
</a>
</td>
<th>{% trans "Sale Price" %}</th>
<td>{% include "price_data.html" with price=pricing.sale_price_min %}</td>
<td>{% include "price_data.html" with price=pricing.sale_price_max %}</td>
<td>{% render_currency pricing.sale_price_min %}</td>
<td>{% render_currency pricing.sale_price_max %}</td>
</tr>
<tr>
<td>
@ -136,8 +136,8 @@
</a>
</td>
<th>{% trans "Sale History" %}</th>
<td>{% include "price_data.html" with price=pricing.sale_history_min %}</td>
<td>{% include "price_data.html" with price=pricing.sale_history_max %}</td>
<td>{% render_currency pricing.sale_history_min %}</td>
<td>{% render_currency pricing.sale_history_max %}</td>
</tr>
</tbody>
</table>

View File

@ -4,7 +4,6 @@ import logging
import os
import sys
from datetime import date, datetime
from decimal import Decimal
from django import template
from django.conf import settings as djangosettings
@ -14,8 +13,6 @@ from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
import moneyed.localization
import InvenTree.helpers
from common.models import ColorTheme, InvenTreeSetting, InvenTreeUserSetting
from common.settings import currency_code_default
@ -104,33 +101,10 @@ def render_date(context, date_object):
@register.simple_tag
def render_currency(money, decimal_places=None, include_symbol=True):
def render_currency(money, **kwargs):
"""Render a currency / Money object"""
if money is None or money.amount is None:
return '-'
if decimal_places is None:
decimal_places = InvenTreeSetting.get_setting('PRICING_DECIMAL_PLACES', 6)
value = Decimal(str(money.amount)).normalize()
value = str(value)
if '.' in value:
decimals = len(value.split('.')[-1])
decimals = max(decimals, 2)
decimals = min(decimals, decimal_places)
decimal_places = decimals
else:
decimal_places = 2
return moneyed.localization.format_money(
money,
decimal_places=decimal_places,
include_symbol=include_symbol,
)
return InvenTree.helpers.render_currency(money, **kwargs)
@register.simple_tag()

View File

@ -107,8 +107,8 @@ table td.expand {
</td>
<td>{{ line.reference }}</td>
<td>{% decimal line.quantity %}</td>
<td>{% include "price_data.html" with price=line.purchase_price %}</td>
<td>{% include "price_data.html" with price=line.total_line_price %}</td>
<td>{% render_currency line.price decimal_places=2 %}</td>
<td>{% render_currency line.total_line_price decimal_places=2 %}</td>
<td>{{ line.notes }}</td>
</tr>
{% endfor %}
@ -120,8 +120,8 @@ table td.expand {
<td><!-- No part --></td>
<td>{{ line.reference }}</td>
<td>{% decimal line.quantity %}</td>
<td>{% include "price_data.html" with price=line.price %}</td>
<td>{% include "price_data.html" with price=line.total_line_price %}</td>
<td>{% render_currency line.price decimal_places=2 %}</td>
<td>{% render_currency line.total_line_price decimal_places=2 %}</td>
<td>{{ line.notes }}</td>
</tr>
{% endfor %}
@ -132,7 +132,7 @@ table td.expand {
<td></td>
<td></td>
<th>{% trans "Total" %}</th>
<td>{% include "price_data.html" with price=order.total_price %}</td>
<td>{% render_currency order.total_price decimal_places=2 currency=order.supplier.currency %}</td>
<td></td>
</tr>

View File

@ -108,8 +108,8 @@ table td.expand {
</td>
<td>{{ line.reference }}</td>
<td>{% decimal line.quantity %}</td>
<td>{% include "price_data.html" with price=line.sale_price %}</td>
<td>{% include "price_data.html" with price=line.total_line_price %}</td>
<td>{% render_currency line.price %}</td>
<td>{% render_currency line.total_line_price %}</td>
<td>{{ line.notes }}</td>
</tr>
{% endfor %}
@ -121,8 +121,8 @@ table td.expand {
<td><!-- No part --></td>
<td>{{ line.reference }}</td>
<td>{% decimal line.quantity %}</td>
<td>{% include "price_data.html" with price=line.price %}</td>
<td>{% include "price_data.html" with price=line.total_line_price %}</td>
<td>{% render_currency line.price %}</td>
<td>{% render_currency line.total_line_price %}</td>
<td>{{ line.notes }}</td>
</tr>
{% endfor %}
@ -133,7 +133,7 @@ table td.expand {
<td></td>
<td></td>
<th>{% trans "Total" %}</th>
<td>{% include "price_data.html" with price=order.total_price %}</td>
<td>{% render_currency order.total_price currency=order.customer.currency %}</td>
<td></td>
</tr>
</tbody>

View File

@ -208,3 +208,10 @@ def multiply(x, y):
def divide(x, y):
"""Divide one number by another"""
return x / y
@register.simple_tag
def render_currency(money, **kwargs):
"""Render a currency / Money object"""
return InvenTree.helpers.render_currency(money, **kwargs)

View File

@ -188,7 +188,7 @@
<td><span class='fas fa-dollar-sign'></span></td>
<td>{% trans "Purchase Price" %}</td>
<td>
{% include "price_data.html" with price=item.purchase_price %}
{% render_currency item.purchase_price %}
{% if item.part.units %} / {{ item.part.units }}{% endif %}
</td>
</tr>

View File

@ -1,8 +0,0 @@
{% load inventree_extras %}
{% load i18n %}
{% if price %}
{% render_currency price %}
{% else %}
<em>{% trans "No data" %}</em>
{% endif %}