From 5c8cc035a48c1880aa6ea811b514652e7541c31a Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 28 Mar 2017 21:24:00 +1100 Subject: [PATCH] Started work on cross-referencing - part admin now shows total quantity in stock - part model can return a list of projects it is associated with --- InvenTree/part/admin.py | 2 +- InvenTree/part/models.py | 38 +++++++++++++++++++++++++++++++++++++ InvenTree/project/models.py | 12 +++++++++--- InvenTree/stock/models.py | 3 ++- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/InvenTree/part/admin.py b/InvenTree/part/admin.py index fce0c2d257..3cc2ad10bb 100644 --- a/InvenTree/part/admin.py +++ b/InvenTree/part/admin.py @@ -4,7 +4,7 @@ from .models import PartCategory, Part class PartAdmin(admin.ModelAdmin): - list_display = ('name', 'IPN', 'category') + list_display = ('name', 'IPN', 'quantity', 'category') # Custom form for PartCategory class PartCategoryAdmin(admin.ModelAdmin): diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 5fe39656bf..80d4728c93 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals from django.db import models +from django.db.models import Sum from django.core.exceptions import ObjectDoesNotExist from InvenTree.models import InvenTreeTree @@ -35,6 +36,43 @@ class Part(models.Model): class Meta: verbose_name = "Part" verbose_name_plural = "Parts" + + @property + def stock_list(self): + """ Return a list of all stock objects associated with this part + """ + + return self.stockitem_set.all() + + @property + def quantity(self): + """ Return the total stock quantity for this part. + Part may be stored in multiple locations + """ + + stocks = self.stock_list + if len(stocks) == 0: + return 0 + + result = stocks.aggregate(total=Sum('quantity')) + return result['total'] + + @property + def projects(self): + """ Return a list of unique projects that this part is associated with + """ + + project_ids = set() + project_parts = self.projectpart_set.all() + + projects = [] + + for pp in project_parts: + if pp.project.id not in project_ids: + project_ids.add(pp.project.id) + projects.append(pp.project) + + return projects class PartRevision(models.Model): """ A PartRevision represents a change-notification to a Part diff --git a/InvenTree/project/models.py b/InvenTree/project/models.py index 18da1221f4..b7d0800fc1 100644 --- a/InvenTree/project/models.py +++ b/InvenTree/project/models.py @@ -26,7 +26,12 @@ class Project(models.Model): def __str__(self): return self.name - + + @property + def projectParts(self): + """ Return a list of all project parts associated with this project + """ + return self.projectpart_set.all() class ProjectPart(models.Model): """ A project part associates a single part with a project @@ -40,9 +45,10 @@ class ProjectPart(models.Model): part = models.ForeignKey(Part, on_delete=models.CASCADE) project = models.ForeignKey(Project, on_delete=models.CASCADE) - quantity = models.IntegerField() - overage = models.FloatField() + quantity = models.IntegerField(default=1) + overage = models.FloatField(default=0) overage_type = models.IntegerField( + default=1, choices=[ (OVERAGE_PERCENT, "Percent"), (OVERAGE_ABSOLUTE, "Absolute") diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index a07308a435..2cc5e4c727 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -9,7 +9,8 @@ class Warehouse(InvenTreeTree): pass class StockItem(models.Model): - part = models.ForeignKey(Part, on_delete=models.CASCADE) + part = models.ForeignKey(Part, + on_delete=models.CASCADE) location = models.ForeignKey(Warehouse, on_delete=models.CASCADE) quantity = models.IntegerField() updated = models.DateField(auto_now=True)