From 774bd75e490f76a2f943b6fbdc8ac7e09afabb9e Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 29 Mar 2017 14:34:41 +1100 Subject: [PATCH 1/2] Updated installer script --- install.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/install.py b/install.py index 45e83288f3..090fdd3e79 100644 --- a/install.py +++ b/install.py @@ -1,6 +1,7 @@ from __future__ import print_function import subprocess +import argparse def manage(*arg): args = ["python", "InvenTree/manage.py"] @@ -10,12 +11,20 @@ def manage(*arg): subprocess.call(args) -# Install django requirements -subprocess.call(["pip", "install", "django", "-q"]) -subprocess.call(["pip", "install", "djangorestframework", "-q"]) +parser = argparse.ArgumentParser(description="Install InvenTree inventory management system") -# Initial database setup -manage("migrate") +parser.add_argument('-u', '--update', help='Update only, do not try to install required components', action='store_true') + +args = parser.parse_args() + +# If 'update' is specified, don't perform initial installation +if not args.update: + # Install django requirements + subprocess.call(["pip", "install", "django", "-q"]) + subprocess.call(["pip", "install", "djangorestframework", "-q"]) + + # Initial database setup + manage("migrate") # Make migrations for all apps manage("makemigrations", "part") @@ -30,5 +39,6 @@ manage("migrate") # Check for errors manage("check") -print("\n\nAdmin account:\nIf a superuser is not already installed,") -print("run the command 'python InvenTree/manage.py createsuperuser'") +if not args.update: + print("\n\nAdmin account:\nIf a superuser is not already installed,") + print("run the command 'python InvenTree/manage.py createsuperuser'") From 11b790c3ececa08bbfe01eb817719ad2858b430e Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 29 Mar 2017 15:02:59 +1100 Subject: [PATCH 2/2] Added Part Templates --- InvenTree/part/admin.py | 14 ++++++++- InvenTree/part/models.py | 62 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/InvenTree/part/admin.py b/InvenTree/part/admin.py index eb0c32e751..e7e3b4b675 100644 --- a/InvenTree/part/admin.py +++ b/InvenTree/part/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from .models import PartCategory, Part +from .models import PartCategory, Part, PartParameter, PartParameterTemplate class PartAdmin(admin.ModelAdmin): @@ -12,5 +12,17 @@ class PartCategoryAdmin(admin.ModelAdmin): list_display = ('name', 'path', 'description') + +class ParameterTemplateAdmin(admin.ModelAdmin): + list_display = ('name', 'units', 'category') + + +class ParameterAdmin(admin.ModelAdmin): + list_display = ('part', 'template', 'value') + + admin.site.register(Part, PartAdmin) admin.site.register(PartCategory, PartCategoryAdmin) + +admin.site.register(PartParameter, ParameterAdmin) +admin.site.register(PartParameterTemplate, ParameterTemplateAdmin) \ No newline at end of file diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 6780aad57c..776b12d60e 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from django.db import models from django.db.models import Sum -from django.core.exceptions import ObjectDoesNotExist +from django.core.exceptions import ObjectDoesNotExist, ValidationError from InvenTree.models import InvenTreeTree @@ -75,7 +75,67 @@ class Part(models.Model): projects.append(pp.project) return projects + +class PartParameterTemplate(models.Model): + """ A PartParameterTemplate pre-defines a parameter field, + ready to be copied for use with a given Part. + A PartParameterTemplate can be optionally associated with a PartCategory + """ + + category = models.ForeignKey(PartCategory, on_delete=models.CASCADE, blank=True, null=True) + + name = models.CharField(max_length=20) + description = models.CharField(max_length=100, blank=True) + units = models.CharField(max_length=10, blank=True) + + default_value = models.CharField(max_length=50, blank=True) + default_min = models.CharField(max_length=50, blank=True) + default_max = models.CharField(max_length=50, blank=True) + + def __str__(self): + return "{name} ({units})".format( + name=self.name, + units=self.units) + + class Meta: + verbose_name = "Parameter Template" + verbose_name_plural = "Parameter Templates" + +class PartParameter(models.Model): + """ PartParameter is associated with a single part + """ + + part = models.ForeignKey(Part, on_delete=models.CASCADE) + + template = models.ForeignKey(PartParameterTemplate) + + # Value data + value = models.CharField(max_length=50, blank=True) + min_value = models.CharField(max_length=50, blank=True) + max_value = models.CharField(max_length=50, blank=True) + + # Prevent multiple parameters of the same template + # from being added to the same part + def save(self, *args, **kwargs): + params = PartParameter.objects.filter(part=self.part, template=self.template) + if len(params) > 0: + raise ValidationError("Parameter '{param}' already exists for {part}".format( + param=self.template.name, + part=self.part.name)) + + super(PartParameter, self).save(*args, **kwargs) + + def __str__(self): + return "{name} : {val}{units}".format( + name=self.template.name, + val=self.value, + units=self.template.units) + + class Meta: + verbose_name = "Part Parameter" + verbose_name_plural = "Part Parameters" + class PartRevision(models.Model): """ A PartRevision represents a change-notification to a Part