From 4de12033bb0b3ff0a31af28d6cd76d647776ef39 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 2 Sep 2019 15:51:58 +1000 Subject: [PATCH 01/19] Change pip3 to python3-pip --- docs/start.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/start.rst b/docs/start.rst index 5e08bf8634..f5e770796a 100644 --- a/docs/start.rst +++ b/docs/start.rst @@ -17,7 +17,7 @@ Requirements To install InvenTree you will need the following: * python3 -* pip3 +* python3-pip * make Installation From 31f3ead5dc75c75a39a0ac8080c7c03881e1b2e4 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 2 Sep 2019 15:52:19 +1000 Subject: [PATCH 02/19] Andrew's eagle eyes --- docs/start.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/start.rst b/docs/start.rst index f5e770796a..75a13159cc 100644 --- a/docs/start.rst +++ b/docs/start.rst @@ -35,10 +35,10 @@ To setup the InvenTree environment, *cd into the inventree directory* and run th which installs all required Python packages using pip package manager. It also creates a (default) database configuration file which needs to be edited to meet user needs before proceeding (see next step below). -Additionally, this step creates a *SECREY_KEY* file which is used for the django authentication framework. +Additionally, this step creates a *SECRET_KEY* file which is used for the django authentication framework. .. important:: - The *SECREY_KEY* file should never be shared or made public. + The *SECRET_KEY* file should never be shared or made public. Database Configuration ----------------------- From d30cad2341bba6f1da032a82bb008f5cbb5d3d73 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 2 Sep 2019 16:05:19 +1000 Subject: [PATCH 03/19] Emphasis on config.yaml --- docs/start.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/start.rst b/docs/start.rst index 75a13159cc..fcce9a9131 100644 --- a/docs/start.rst +++ b/docs/start.rst @@ -14,7 +14,7 @@ A makefile in the root directory provides shortcuts for the installation process Requirements ------------ -To install InvenTree you will need the following: +To install InvenTree you will need the following system components installed: * python3 * python3-pip @@ -45,7 +45,7 @@ Database Configuration Once the required packages are installed, the database configuration must be adjusted to suit your particular needs. InvenTree provides a simple default setup which should work *out of the box* for testing and debug purposes. -As part of the previous *install* step, a configuration file (*config.yaml*) is created. The configuration file provides administrators control over various setup options without digging into the Django ``settings.py`` script. The default setup uses a local sqlite database with *DEBUG* mode enabled. +As part of the previous *install* step, a configuration file (``config.yaml``) is created. The configuration file provides administrators control over various setup options without digging into the Django *settings.py* script. The default setup uses a local sqlite database with *DEBUG* mode enabled. For further information on installation configuration, refer to the `Configuration `_ section. From 92940f133399659cfe214652190debb8afc702f9 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 2 Sep 2019 16:05:26 +1000 Subject: [PATCH 04/19] Update makefile docs --- docs/start.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/start.rst b/docs/start.rst index fcce9a9131..4abf01436c 100644 --- a/docs/start.rst +++ b/docs/start.rst @@ -82,9 +82,10 @@ Development and Testing Other shorthand functions are provided for the development and testing process: -* ``make requirements`` - Install all required underlying packages using PIP -* ``make setup`` - Perform one-time setup functions +* ``make install`` - Install all required underlying packages using PIP * ``make superuser`` - Create a superuser account +* ``make migrate`` - Perform database migrations +* ``make mysql`` - Install packages required for MySQL database backend * ``make backup`` - Backup database tables and media files * ``make test`` - Run all unit tests * ``make coverage`` - Run all unit tests and generate code coverage report From b0c420858b57d79c819a48426a18791232a3bf52 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 2 Sep 2019 16:44:01 +1000 Subject: [PATCH 05/19] Comments for settings.py --- InvenTree/InvenTree/settings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index d89a57cb78..1e993e5068 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -231,16 +231,20 @@ USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.10/howto/static-files/ +# Web URL endpoint for served static files STATIC_URL = '/static/' +# The filesystem location for served static files STATIC_ROOT = CONFIG.get('static_root', os.path.join(BASE_DIR, 'static')) STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'InvenTree', 'static'), ] +# Web URL endpoint for served media files MEDIA_URL = '/media/' +# The filesystem location for served static files MEDIA_ROOT = CONFIG.get('media_root', os.path.join(BASE_DIR, 'media')) # crispy forms use the bootstrap templates From 47e9c44c437614ded6a27fa04e1cac64779dc7db Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 2 Sep 2019 17:04:44 +1000 Subject: [PATCH 06/19] Prefix correct directory in docs --- docs/deploy.rst | 4 +++- docs/migrate.rst | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/deploy.rst b/docs/deploy.rst index 2ce5e7b255..8708243dc6 100644 --- a/docs/deploy.rst +++ b/docs/deploy.rst @@ -31,7 +31,9 @@ Directories for storing *media* files and *static* files should be specified in Collect Static Files -------------------- -The required static files must be collected into the specified ``STATIC_ROOT`` directory. Run ``python3 manage.py collectstatic`` +The required static files must be collected into the specified ``STATIC_ROOT`` directory: + +``python3 InvenTree/manage.py collectstatic`` Configure Gunicorn ------------------ diff --git a/docs/migrate.rst b/docs/migrate.rst index 78dfb39a6a..03e2aa8514 100644 --- a/docs/migrate.rst +++ b/docs/migrate.rst @@ -12,7 +12,7 @@ In the case that data needs to be migrated from one database installation to ano Export Data ----------- -``python3 manage.py dumpdata --exclude contenttypes --exclude auth.permission --indent 2 > data.json`` +``python3 InvenTree/manage.py dumpdata --exclude contenttypes --exclude auth.permission --indent 2 > data.json`` This will export all data (including user information) to a json data file. @@ -21,13 +21,13 @@ Initialize Database Configure the new database using the normal processes (see `Getting Started `_): -``python3 manage.py makemigrations`` +``python3 InvenTree/manage.py makemigrations`` -``python3 manage.py migrate --run-syncdb`` +``python3 InvenTree/manage.py migrate --run-syncdb`` Import Data ----------- The new database should now be correctly initialized with the correct table structures requried to import the data. -``python3 manage.py loaddata data.json`` \ No newline at end of file +``python3 InvenTree/manage.py loaddata data.json`` \ No newline at end of file From 37507f2b438735a681cd5243edc9a1e86cce1db6 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 2 Sep 2019 17:43:20 +1000 Subject: [PATCH 07/19] More cleanup of docs --- docs/config.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config.rst b/docs/config.rst index 1cdb4c3fc6..64667a9cb1 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -9,9 +9,9 @@ InvenTree Configuration Admin users will need to adjust the InvenTree installation to meet the particular needs of their setup. For example, pointing to the correct database backend, or specifying a list of allowed hosts. -The Django configuration parameters are found in the normal place (``settings.py``). However the settings presented in this file should not be adjusted as they will alter the core behaviour of the InvenTree application. +The Django configuration parameters are found in the normal place (*settings.py*). However the settings presented in this file should not be adjusted as they will alter the core behaviour of the InvenTree application. -To support install specific settings, a simple configuration file ``config.yaml`` is provided. This configuration file is loaded by ``settings.py`` at runtime. Settings specific to a given install should be adjusted in ``config.yaml``. +To support install specific settings, a simple configuration file ``config.yaml`` is provided. This configuration file is loaded by **settings.py** at runtime. Settings specific to a given install should be adjusted in ``config.yaml``. The default configuration file launches a *DEBUG* configuration with a simple SQLITE database backend. This default configuration file is shown below: From 90254d157201e0162125a8b0ddad2167e0482b76 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 2 Sep 2019 17:46:42 +1000 Subject: [PATCH 08/19] add a note about file encoding --- docs/migrate.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/migrate.rst b/docs/migrate.rst index 03e2aa8514..ccb9341640 100644 --- a/docs/migrate.rst +++ b/docs/migrate.rst @@ -30,4 +30,7 @@ Import Data The new database should now be correctly initialized with the correct table structures requried to import the data. -``python3 InvenTree/manage.py loaddata data.json`` \ No newline at end of file +``python3 InvenTree/manage.py loaddata data.json`` + +.. important:: + If the character encoding of the data file does not exactly match the target database, the import operation may not succeed. In this case, some manual editing of the data file may be required. \ No newline at end of file From c988f9486e2f69dd547d50a2dff7a5ddfc78b122 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 2 Sep 2019 17:59:10 +1000 Subject: [PATCH 09/19] Re-order docs index --- docs/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 5e7279066f..5e658b8b59 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,11 +10,11 @@ InvenTree Source Documentation Getting Started Configuration Deployment + Migrate Data + Backup and Restore Modal Forms Tables REST API - Backup and Restore - Migrate Data InvenTree Modules Module Reference From f3e161564d9e9fcb6b1c7a63034b20cdb80767f1 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 2 Sep 2019 22:06:42 +1000 Subject: [PATCH 10/19] Fix for serialization of company images --- InvenTree/company/serializers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/InvenTree/company/serializers.py b/InvenTree/company/serializers.py index 77a4bddbf3..624a9b6157 100644 --- a/InvenTree/company/serializers.py +++ b/InvenTree/company/serializers.py @@ -32,6 +32,8 @@ class CompanySerializer(InvenTreeModelSerializer): url = serializers.CharField(source='get_absolute_url', read_only=True) part_count = serializers.CharField(read_only=True) + image = serializers.CharField(source='get_image_url', read_only=True) + class Meta: model = Company fields = [ From 273412b63d5fb55b3b4f3409a61d2ec00bf7dc9d Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 2 Sep 2019 22:14:50 +1000 Subject: [PATCH 11/19] Add 'bug report' button --- InvenTree/templates/about.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/InvenTree/templates/about.html b/InvenTree/templates/about.html index 2516812d1c..da5b4ddc5b 100644 --- a/InvenTree/templates/about.html +++ b/InvenTree/templates/about.html @@ -28,6 +28,10 @@ View Code on GitHub{% inventree_github %} + + + + From aeb25e4c34b3ff8126a266e98d28acb086bf05d5 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 3 Sep 2019 08:30:14 +1000 Subject: [PATCH 12/19] startapp common --- InvenTree/common/__init__.py | 0 InvenTree/common/admin.py | 3 +++ InvenTree/common/apps.py | 5 +++++ InvenTree/common/migrations/__init__.py | 0 InvenTree/common/models.py | 3 +++ InvenTree/common/tests.py | 3 +++ InvenTree/common/views.py | 3 +++ 7 files changed, 17 insertions(+) create mode 100644 InvenTree/common/__init__.py create mode 100644 InvenTree/common/admin.py create mode 100644 InvenTree/common/apps.py create mode 100644 InvenTree/common/migrations/__init__.py create mode 100644 InvenTree/common/models.py create mode 100644 InvenTree/common/tests.py create mode 100644 InvenTree/common/views.py diff --git a/InvenTree/common/__init__.py b/InvenTree/common/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/InvenTree/common/admin.py b/InvenTree/common/admin.py new file mode 100644 index 0000000000..8c38f3f3da --- /dev/null +++ b/InvenTree/common/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/InvenTree/common/apps.py b/InvenTree/common/apps.py new file mode 100644 index 0000000000..5f2f078473 --- /dev/null +++ b/InvenTree/common/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class CommonConfig(AppConfig): + name = 'common' diff --git a/InvenTree/common/migrations/__init__.py b/InvenTree/common/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py new file mode 100644 index 0000000000..71a8362390 --- /dev/null +++ b/InvenTree/common/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/InvenTree/common/tests.py b/InvenTree/common/tests.py new file mode 100644 index 0000000000..7ce503c2dd --- /dev/null +++ b/InvenTree/common/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/InvenTree/common/views.py b/InvenTree/common/views.py new file mode 100644 index 0000000000..91ea44a218 --- /dev/null +++ b/InvenTree/common/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. From 7824b8561d82c6a40cd3650b3a865099480227af Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 3 Sep 2019 09:07:03 +1000 Subject: [PATCH 13/19] Create a currency model --- InvenTree/InvenTree/settings.py | 1 + InvenTree/common/admin.py | 9 ++- InvenTree/common/migrations/0001_initial.py | 26 ++++++ .../migrations/0002_auto_20190902_2304.py | 17 ++++ InvenTree/common/models.py | 80 ++++++++++++++++++- Makefile | 5 +- 6 files changed, 133 insertions(+), 5 deletions(-) create mode 100644 InvenTree/common/migrations/0001_initial.py create mode 100644 InvenTree/common/migrations/0002_auto_20190902_2304.py diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 1e993e5068..6c9d4a9b55 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -83,6 +83,7 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', # InvenTree apps + 'common.apps.CommonConfig', 'part.apps.PartConfig', 'stock.apps.StockConfig', 'company.apps.CompanyConfig', diff --git a/InvenTree/common/admin.py b/InvenTree/common/admin.py index 8c38f3f3da..faf6dd578e 100644 --- a/InvenTree/common/admin.py +++ b/InvenTree/common/admin.py @@ -1,3 +1,10 @@ from django.contrib import admin -# Register your models here. +from .models import Currency + + +class CurrencyAdmin(admin.ModelAdmin): + list_display = ('symbol', 'suffix', 'description', 'value', 'base') + + +admin.site.register(Currency, CurrencyAdmin) \ No newline at end of file diff --git a/InvenTree/common/migrations/0001_initial.py b/InvenTree/common/migrations/0001_initial.py new file mode 100644 index 0000000000..a3a357b86f --- /dev/null +++ b/InvenTree/common/migrations/0001_initial.py @@ -0,0 +1,26 @@ +# Generated by Django 2.2.4 on 2019-09-02 23:02 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Currency', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('symbol', models.CharField(help_text='Currency Symbol e.g. $', max_length=10)), + ('suffix', models.CharField(help_text='Currency Suffix e.g. AUD', max_length=10, unique=True)), + ('description', models.CharField(help_text='Currency Description', max_length=100)), + ('value', models.DecimalField(decimal_places=5, help_text='Currency Value', max_digits=10, validators=[django.core.validators.MinValueValidator(1e-05), django.core.validators.MaxValueValidator(100000)])), + ('base', models.BooleanField(default=False, help_text='Use this currency as the base currency')), + ], + ), + ] diff --git a/InvenTree/common/migrations/0002_auto_20190902_2304.py b/InvenTree/common/migrations/0002_auto_20190902_2304.py new file mode 100644 index 0000000000..a8daf16139 --- /dev/null +++ b/InvenTree/common/migrations/0002_auto_20190902_2304.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.4 on 2019-09-02 23:04 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('common', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='currency', + options={'verbose_name_plural': 'Currencies'}, + ), + ] diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 71a8362390..43bc41db34 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -1,3 +1,79 @@ -from django.db import models +""" +Common database model definitions. +These models are 'generic' and do not fit a particular business logic object. +""" -# Create your models here. +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models +from django.utils.translation import ugettext as _ +from django.core.validators import MinValueValidator, MaxValueValidator + + +class Currency(models.Model): + """ + A Currency object represents a particular unit of currency. + Each Currency has a scaling factor which relates it to the base currency. + There must be one (and only one) currency which is selected as the base currency, + and each other currency is calculated relative to it. + + Attributes: + symbol: Currency symbol e.g. $ + suffix: Currency suffix e.g. AUD + description: Long-form description e.g. "Australian Dollars" + value: The value of this currency compared to the base currency. + base: True if this currency is the base currency + + """ + + symbol = models.CharField(max_length=10, blank=False, unique=False, help_text=_('Currency Symbol e.g. $')) + + suffix = models.CharField(max_length=10, blank=False, unique=True, help_text=_('Currency Suffix e.g. AUD')) + + description = models.CharField(max_length=100, blank=False, help_text=_('Currency Description')) + + value = models.DecimalField(max_digits=10, decimal_places=5, validators=[MinValueValidator(0.00001), MaxValueValidator(100000)], help_text=_('Currency Value')) + + base = models.BooleanField(default=False, help_text=_('Use this currency as the base currency')) + + class Meta: + verbose_name_plural = 'Currencies' + + def __str__(self): + """ Format string for currency representation """ + s = "{sym} {suf} - {desc}".format( + sym=self.symbol, + suf=self.suffix, + desc=self.description + ) + + if self.base: + s += " (Base)" + + else: + s += " = {v}".format(v=self.value) + + return s + + def save(self, *args, **kwargs): + """ Validate the model before saving + + - Ensure that there is only one base currency! + """ + + # If this currency is set as the base currency, ensure no others are + if self.base: + for cur in Currency.objects.filter(base=True).exclude(pk=self.pk): + cur.base = False + cur.save() + + # If there are no currencies set as the base currency, set this as base + if not Currency.objects.filter(base=True).exists(): + self.base = True + + # If this is the base currency, ensure value is set to unity + if self.base: + self.value = 1.0 + + super().save(*args, **kwargs) diff --git a/Makefile b/Makefile index c898af195d..0b3379a724 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ clean: # Perform database migrations (after schema changes are made) migrate: + python3 InvenTree/manage.py makemigrations common python3 InvenTree/manage.py makemigrations company python3 InvenTree/manage.py makemigrations part python3 InvenTree/manage.py makemigrations stock @@ -40,12 +41,12 @@ style: # Run unit tests test: python3 InvenTree/manage.py check - python3 InvenTree/manage.py test build company part stock order + python3 InvenTree/manage.py test build common company order part stock # Run code coverage coverage: python3 InvenTree/manage.py check - coverage run InvenTree/manage.py test build company part stock order InvenTree + coverage run InvenTree/manage.py test build common company order part stock InvenTree coverage html # Install packages required to generate code docs From 32d09d2d37f1ae405d7892b4b8bc8da2963d1aa1 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 3 Sep 2019 09:10:36 +1000 Subject: [PATCH 14/19] Add default value for currency --- .../migrations/0003_auto_20190902_2310.py | 19 +++++++++++++++++++ InvenTree/common/models.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 InvenTree/common/migrations/0003_auto_20190902_2310.py diff --git a/InvenTree/common/migrations/0003_auto_20190902_2310.py b/InvenTree/common/migrations/0003_auto_20190902_2310.py new file mode 100644 index 0000000000..7bfdefa8c4 --- /dev/null +++ b/InvenTree/common/migrations/0003_auto_20190902_2310.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.4 on 2019-09-02 23:10 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('common', '0002_auto_20190902_2304'), + ] + + operations = [ + migrations.AlterField( + model_name='currency', + name='value', + field=models.DecimalField(decimal_places=5, default=1.0, help_text='Currency Value', max_digits=10, validators=[django.core.validators.MinValueValidator(1e-05), django.core.validators.MaxValueValidator(100000)]), + ), + ] diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 43bc41db34..de3b9bab2c 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -33,7 +33,7 @@ class Currency(models.Model): description = models.CharField(max_length=100, blank=False, help_text=_('Currency Description')) - value = models.DecimalField(max_digits=10, decimal_places=5, validators=[MinValueValidator(0.00001), MaxValueValidator(100000)], help_text=_('Currency Value')) + value = models.DecimalField(default=1.0, max_digits=10, decimal_places=5, validators=[MinValueValidator(0.00001), MaxValueValidator(100000)], help_text=_('Currency Value')) base = models.BooleanField(default=False, help_text=_('Use this currency as the base currency')) From 9f91797f4224b805f1f3dc6683a82b2414a4da53 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 3 Sep 2019 09:19:37 +1000 Subject: [PATCH 15/19] Simple test case for currency --- InvenTree/common/admin.py | 2 +- InvenTree/common/fixtures/currency.yaml | 16 ++++++++++++++++ InvenTree/common/tests.py | 18 +++++++++++++++++- InvenTree/common/views.py | 2 -- 4 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 InvenTree/common/fixtures/currency.yaml diff --git a/InvenTree/common/admin.py b/InvenTree/common/admin.py index faf6dd578e..1628f811a7 100644 --- a/InvenTree/common/admin.py +++ b/InvenTree/common/admin.py @@ -7,4 +7,4 @@ class CurrencyAdmin(admin.ModelAdmin): list_display = ('symbol', 'suffix', 'description', 'value', 'base') -admin.site.register(Currency, CurrencyAdmin) \ No newline at end of file +admin.site.register(Currency, CurrencyAdmin) diff --git a/InvenTree/common/fixtures/currency.yaml b/InvenTree/common/fixtures/currency.yaml new file mode 100644 index 0000000000..639b0751df --- /dev/null +++ b/InvenTree/common/fixtures/currency.yaml @@ -0,0 +1,16 @@ +# Test fixtures for Currency objects + +- model: common.currency + fields: + symbol: '$' + suffix: 'AUD' + description: 'Australian Dollars' + base: True + +- model: common.currency + fields: + symbol: '$' + suffix: 'USD' + description: 'US Dollars' + base: False + value: 1.4 \ No newline at end of file diff --git a/InvenTree/common/tests.py b/InvenTree/common/tests.py index 7ce503c2dd..5c6171a65c 100644 --- a/InvenTree/common/tests.py +++ b/InvenTree/common/tests.py @@ -1,3 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + from django.test import TestCase -# Create your tests here. +from .models import Currency + + +class CurrencyTest(TestCase): + """ Tests for Currency model """ + + fixtures = [ + 'currency', + ] + + def test_currency(self): + # Simple test for now (improve this later!) + + self.assertEqual(Currency.objects.count(), 2) diff --git a/InvenTree/common/views.py b/InvenTree/common/views.py index 91ea44a218..60f00ef0ef 100644 --- a/InvenTree/common/views.py +++ b/InvenTree/common/views.py @@ -1,3 +1 @@ -from django.shortcuts import render - # Create your views here. From c6a435eba01e196ab72bf86f5e63b43f8954b586 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 3 Sep 2019 09:34:32 +1000 Subject: [PATCH 16/19] Add currency field to SupplierPriceBreak --- .../0006_supplierpricebreak_currency.py | 20 +++++++++++++++++++ InvenTree/company/models.py | 16 ++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 InvenTree/company/migrations/0006_supplierpricebreak_currency.py diff --git a/InvenTree/company/migrations/0006_supplierpricebreak_currency.py b/InvenTree/company/migrations/0006_supplierpricebreak_currency.py new file mode 100644 index 0000000000..94f533cf66 --- /dev/null +++ b/InvenTree/company/migrations/0006_supplierpricebreak_currency.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.4 on 2019-09-02 23:34 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('common', '0003_auto_20190902_2310'), + ('company', '0005_auto_20190525_2356'), + ] + + operations = [ + migrations.AddField( + model_name='supplierpricebreak', + name='currency', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='common.Currency'), + ), + ] diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index 9d09557f17..eb8d7e5215 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -19,6 +19,7 @@ from django.conf import settings from django.contrib.staticfiles.templatetags.staticfiles import static from InvenTree.status_codes import OrderStatus +from common.models import Currency def rename_company_image(instance, filename): @@ -310,7 +311,7 @@ class SupplierPart(models.Model): # If this price-break quantity is the largest so far, use it! if pb.quantity > pb_quantity: pb_quantity = pb.quantity - pb_cost = pb.cost + pb_cost = pb.get_cost() if pb_found: cost = pb_cost * quantity @@ -369,6 +370,7 @@ class SupplierPriceBreak(models.Model): part: Link to a SupplierPart object that this price break applies to quantity: Quantity required for price break cost: Cost at specified quantity + currency: Reference to the currency of this pricebreak (leave empty for base currency) """ part = models.ForeignKey(SupplierPart, on_delete=models.CASCADE, related_name='pricebreaks') @@ -377,6 +379,18 @@ class SupplierPriceBreak(models.Model): cost = models.DecimalField(max_digits=10, decimal_places=5, validators=[MinValueValidator(0)]) + currency = models.ForeignKey(Currency, blank=True, null=True, on_delete=models.SET_NULL) + + def get_cost(self): + """ Return the cost of this price break, converted to the base currency """ + + scaler = 1.0 + + if self.currency: + scaler = self.currency.value + + return self.cost * scaler + class Meta: unique_together = ("part", "quantity") From 09cb82cdc0bb9a5229f10b8ce1db0c82bd35f6f7 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 3 Sep 2019 09:46:32 +1000 Subject: [PATCH 17/19] Fix converted_cost - Incompatibility between float and decimal --- InvenTree/company/models.py | 9 ++++++--- InvenTree/company/templates/company/partdetail.html | 5 ++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index eb8d7e5215..f62b2f27a2 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -8,6 +8,7 @@ from __future__ import unicode_literals import os import math +from decimal import Decimal from django.core.validators import MinValueValidator from django.db import models @@ -311,7 +312,8 @@ class SupplierPart(models.Model): # If this price-break quantity is the largest so far, use it! if pb.quantity > pb_quantity: pb_quantity = pb.quantity - pb_cost = pb.get_cost() + # Convert everything to base currency + pb_cost = pb.converted_cost if pb_found: cost = pb_cost * quantity @@ -381,10 +383,11 @@ class SupplierPriceBreak(models.Model): currency = models.ForeignKey(Currency, blank=True, null=True, on_delete=models.SET_NULL) - def get_cost(self): + @property + def converted_cost(self): """ Return the cost of this price break, converted to the base currency """ - scaler = 1.0 + scaler = Decimal(1.0) if self.currency: scaler = self.currency.value diff --git a/InvenTree/company/templates/company/partdetail.html b/InvenTree/company/templates/company/partdetail.html index d945ec31c4..00e1d03b63 100644 --- a/InvenTree/company/templates/company/partdetail.html +++ b/InvenTree/company/templates/company/partdetail.html @@ -88,7 +88,10 @@ InvenTree | {{ company.name }} - Parts {% for pb in part.price_breaks.all %} {{ pb.quantity }} - {{ pb.cost }} + + {% if pb.currency %}{{ pb.currency.symbol }}{% endif %} + {{ pb.cost }} + {% if pb.currency %}{{ pb.currency.suffix }}{% endif %}
From af8a96e08029e2dc746cfa1ecbd7a6d02be1c374 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 3 Sep 2019 09:55:15 +1000 Subject: [PATCH 18/19] Add option to edit currency --- InvenTree/company/forms.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/InvenTree/company/forms.py b/InvenTree/company/forms.py index 76b1c1342c..3fec44cf63 100644 --- a/InvenTree/company/forms.py +++ b/InvenTree/company/forms.py @@ -70,5 +70,6 @@ class EditPriceBreakForm(HelperForm): fields = [ 'part', 'quantity', - 'cost' + 'cost', + 'currency', ] From 0325f042b53ef75334f1eb3c93929de1a1661df8 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 3 Sep 2019 09:59:14 +1000 Subject: [PATCH 19/19] Bump version number --- InvenTree/InvenTree/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/InvenTree/version.py b/InvenTree/InvenTree/version.py index 4aba826044..4a9a23e7ef 100644 --- a/InvenTree/InvenTree/version.py +++ b/InvenTree/InvenTree/version.py @@ -4,7 +4,7 @@ Provides information on the current InvenTree version import subprocess -INVENTREE_SW_VERSION = "0.0.3" +INVENTREE_SW_VERSION = "0.0.4" def inventreeVersion():