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

Add 'currency' option for company

- e.g. an external supplier might have a default currency
- Adds a form input which only allows selection of allowed currency codes
- Add unit testing for currency validation
This commit is contained in:
Oliver Walters 2020-11-12 11:02:10 +11:00
parent ebac06ebee
commit 1532be9c1e
7 changed files with 158 additions and 19 deletions

View File

@ -6,11 +6,22 @@ from django.conf import settings
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from moneyed import CURRENCIES
import common.models
import re
def validate_currency_code(code):
"""
Check that a given code is a valid currency code.
"""
if code not in CURRENCIES:
raise ValidationError(_('Not a valid currency code'))
def allowable_url_schemes():
""" Return the list of allowable URL schemes.
In addition to the default schemes allowed by Django,

View File

@ -0,0 +1,23 @@
"""
User-configurable settings for the common app
"""
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from moneyed import CURRENCIES
from common.models import InvenTreeSetting
def currency_code_default():
"""
Returns the default currency code (or USD if not specified)
"""
code = InvenTreeSetting.get_setting('INVENTREE_DEFAULT_CURRENCY')
if code not in CURRENCIES:
code = 'USD'
return code

View File

@ -9,10 +9,13 @@ from InvenTree.forms import HelperForm
from InvenTree.fields import RoundingDecimalFormField
from django.utils.translation import ugettext as _
import django.forms
import djmoney.settings
from djmoney.forms.fields import MoneyField
from common.models import InvenTreeSetting
import common.settings
from .models import Company
from .models import SupplierPart
@ -30,6 +33,13 @@ class EditCompanyForm(HelperForm):
'phone': 'fa-phone',
}
currency = django.forms.ChoiceField(
required=False,
help_text=_('Default currency used for this company'),
choices=[('', '----------')] + djmoney.settings.CURRENCY_CHOICES,
initial=common.settings.currency_code_default,
)
class Meta:
model = Company
fields = [
@ -37,6 +47,7 @@ class EditCompanyForm(HelperForm):
'description',
'website',
'address',
'currency',
'phone',
'email',
'contact',

View File

@ -0,0 +1,19 @@
# Generated by Django 3.0.7 on 2020-11-11 23:22
import InvenTree.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('company', '0028_remove_supplierpricebreak_cost'),
]
operations = [
migrations.AddField(
model_name='company',
name='currency',
field=models.CharField(blank=True, help_text='Default currency used for this company', max_length=3, validators=[InvenTree.validators.validate_currency_code], verbose_name='Currency'),
),
]

View File

@ -26,6 +26,8 @@ from InvenTree.helpers import normalize
from InvenTree.fields import InvenTreeURLField
from InvenTree.status_codes import PurchaseOrderStatus
import InvenTree.validators
import common.models
@ -77,6 +79,7 @@ class Company(models.Model):
is_customer: boolean value, is this company a customer
is_supplier: boolean value, is this company a supplier
is_manufacturer: boolean value, is this company a manufacturer
currency_code: Specifies the default currency for the company
"""
class Meta:
@ -126,6 +129,14 @@ class Company(models.Model):
is_manufacturer = models.BooleanField(default=False, help_text=_('Does this company manufacture parts?'))
currency = models.CharField(
max_length=3,
verbose_name=_('Currency'),
blank=True,
help_text=_('Default currency used for this company'),
validators=[InvenTree.validators.validate_currency_code],
)
def __str__(self):
""" Get string representation of a Company """
return "{n} - {d}".format(n=self.name, d=self.description)

View File

@ -8,25 +8,64 @@
<h4>{% trans "Company Details" %}</h4>
<hr>
<table class='table table-striped'>
<col width='25'>
<col>
<tr>
<td><span class='fas fa-industry'></span></td>
<td>{% trans "Manufacturer" %}</td>
<td>{% include "yesnolabel.html" with value=company.is_manufacturer %}</td>
</tr>
<tr>
<td><span class='fas fa-building'></span></td>
<td>{% trans "Supplier" %}</td>
<td>{% include 'yesnolabel.html' with value=company.is_supplier %}</td>
</tr>
<tr>
<td><span class='fas fa-user-tie'></span></td>
<td>{% trans "Customer" %}</td>
<td>{% include 'yesnolabel.html' with value=company.is_customer %}</td>
</tr>
</table>
<div class='row'>
<div class='col-sm-6'>
<table class='table table-striped'>
<col width='25'>
<col>
<tr>
<td><span class='fas fa-font'></span></td>
<td>{% trans "Company Name" %}</td>
<td>{{ company.name }}</td>
</tr>
<tr>
<td><span class='fas fa-info'></span></td>
<td>{% trans "Description" %}</td>
<td>{{ company.description }}</td>
</tr>
<tr>
<td><span class='fas fa-globe'></span></td>
<td>{% trans "Website" %}</td>
<td>
{% if company.website %}<a href='{{ company.website }}'>{{ company.website }}</a>
{% else %}<i>{% trans "No website specified" %}</i>
{% endif %}
</td>
</tr>
<tr>
<td><span class='fas fa-dollar-sign'></span></td>
<td>{% trans "Currency" %}</td>
<td>
{% if company.currency %}{{ company.currency }}
{% else %}<i>{% trans "Uses default currency" %}</i>
{% endif %}
</td>
</tr>
</table>
</div>
<div class='col-sm-6'>
<table class='table table-striped'>
<col width='25'>
<col>
<tr>
<td><span class='fas fa-industry'></span></td>
<td>{% trans "Manufacturer" %}</td>
<td>{% include "yesnolabel.html" with value=company.is_manufacturer %}</td>
</tr>
<tr>
<td><span class='fas fa-building'></span></td>
<td>{% trans "Supplier" %}</td>
<td>{% include 'yesnolabel.html' with value=company.is_supplier %}</td>
</tr>
<tr>
<td><span class='fas fa-user-tie'></span></td>
<td>{% trans "Customer" %}</td>
<td>{% include 'yesnolabel.html' with value=company.is_customer %}</td>
</tr>
</table>
</div>
</div>
{% endblock %}
{% block js_ready %}

View File

@ -1,4 +1,5 @@
from django.test import TestCase
from django.core.exceptions import ValidationError
import os
@ -119,6 +120,30 @@ class CompanySimpleTest(TestCase):
self.assertIsNone(m3x12.get_price_info(3))
self.assertIsNotNone(m3x12.get_price_info(50))
def test_currency_validation(self):
"""
Test validation for currency selection
"""
# Create a company with a valid currency code (should pass)
company = Company.objects.create(
name='Test',
description='Toast',
currency='AUD',
)
company.full_clean()
# Create a company with an invalid currency code (should fail)
company = Company.objects.create(
name='test',
description='Toasty',
currency='XZY',
)
with self.assertRaises(ValidationError):
company.full_clean()
class ContactSimpleTest(TestCase):