2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-29 12:06:44 +00:00

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.test import TestCase
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
import moneyed.localization
import regex import regex
import requests import requests
from bleach import clean from bleach import clean
from djmoney.contrib.exchange.models import convert_money
from djmoney.money import Money from djmoney.money import Money
from PIL import Image from PIL import Image
@ -1105,3 +1107,47 @@ def notify_responsible(instance, sender, content: NotificationBody = InvenTreeNo
target_exclude=[exclude], target_exclude=[exclude],
context=context, 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 %} {% if tp == None %}
<span class='badge bg-warning'>{% trans "Total cost could not be calculated" %}</span> <span class='badge bg-warning'>{% trans "Total cost could not be calculated" %}</span>
{% else %} {% else %}
{% include "price_data.html" with price=tp %} {% render_currency tp currency=order.supplier.currency %}
{% endif %} {% endif %}
{% endwith %} {% endwith %}
</td> </td>

View File

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

View File

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

View File

@ -4,7 +4,6 @@ import logging
import os import os
import sys import sys
from datetime import date, datetime from datetime import date, datetime
from decimal import Decimal
from django import template from django import template
from django.conf import settings as djangosettings 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.safestring import mark_safe
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
import moneyed.localization
import InvenTree.helpers import InvenTree.helpers
from common.models import ColorTheme, InvenTreeSetting, InvenTreeUserSetting from common.models import ColorTheme, InvenTreeSetting, InvenTreeUserSetting
from common.settings import currency_code_default from common.settings import currency_code_default
@ -104,33 +101,10 @@ def render_date(context, date_object):
@register.simple_tag @register.simple_tag
def render_currency(money, decimal_places=None, include_symbol=True): def render_currency(money, **kwargs):
"""Render a currency / Money object""" """Render a currency / Money object"""
if money is None or money.amount is None: return InvenTree.helpers.render_currency(money, **kwargs)
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,
)
@register.simple_tag() @register.simple_tag()

View File

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

View File

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

View File

@ -208,3 +208,10 @@ def multiply(x, y):
def divide(x, y): def divide(x, y):
"""Divide one number by another""" """Divide one number by another"""
return x / y 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><span class='fas fa-dollar-sign'></span></td>
<td>{% trans "Purchase Price" %}</td> <td>{% trans "Purchase Price" %}</td>
<td> <td>
{% include "price_data.html" with price=item.purchase_price %} {% render_currency item.purchase_price %}
{% if item.part.units %} / {{ item.part.units }}{% endif %} {% if item.part.units %} / {{ item.part.units }}{% endif %}
</td> </td>
</tr> </tr>

View File

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