InvenTree/InvenTree/build/models.py

149 lines
4.4 KiB
Python
Raw Normal View History

2019-04-27 10:35:14 +00:00
"""
2019-04-27 10:43:27 +00:00
Build database model definitions
2019-04-27 10:35:14 +00:00
"""
2018-04-16 14:32:02 +00:00
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
2018-04-17 06:58:37 +00:00
from django.utils.translation import ugettext as _
from django.urls import reverse
2018-04-16 14:32:02 +00:00
from django.db import models
from django.core.validators import MinValueValidator
2018-04-17 14:03:42 +00:00
2018-04-16 14:32:02 +00:00
class Build(models.Model):
2019-04-27 10:35:14 +00:00
""" A Build object organises the creation of new parts from the component parts.
Attributes:
part: The part to be built (from component BOM items)
title: Brief title describing the build (required)
quantity: Number of units to be built
status: Build status code
batch: Batch code transferred to build parts (optional)
creation_date: Date the build was created (auto)
completion_date: Date the build was completed
URL: External URL for extra information
notes: Text notes
2018-04-16 14:32:02 +00:00
"""
def get_absolute_url(self):
return reverse('build-detail', kwargs={'pk': self.id})
2019-04-27 10:35:14 +00:00
part = models.ForeignKey('part.Part', on_delete=models.CASCADE,
related_name='builds',
limit_choices_to={'buildable': True},
)
title = models.CharField(max_length=100, help_text='Brief description of the build')
quantity = models.PositiveIntegerField(
default=1,
validators=[MinValueValidator(1)],
help_text='Number of parts to build'
)
2018-04-17 06:58:37 +00:00
# Build status codes
PENDING = 10 # Build is pending / active
2018-04-17 14:03:42 +00:00
HOLDING = 20 # Build is currently being held
CANCELLED = 30 # Build was cancelled
COMPLETE = 40 # Build is complete
2018-04-17 06:58:37 +00:00
2019-04-27 10:35:14 +00:00
#: Build status codes
2018-04-17 14:03:42 +00:00
BUILD_STATUS_CODES = {PENDING: _("Pending"),
HOLDING: _("Holding"),
CANCELLED: _("Cancelled"),
COMPLETE: _("Complete"),
}
2018-04-16 14:32:02 +00:00
2018-04-17 06:58:37 +00:00
status = models.PositiveIntegerField(default=PENDING,
choices=BUILD_STATUS_CODES.items(),
validators=[MinValueValidator(0)])
2019-04-27 10:35:14 +00:00
batch = models.CharField(max_length=100, blank=True, null=True,
help_text='Batch code for this build output')
2019-04-27 10:35:14 +00:00
creation_date = models.DateField(auto_now=True, editable=False)
2019-04-27 10:35:14 +00:00
completion_date = models.DateField(null=True, blank=True)
URL = models.URLField(blank=True, help_text='Link to external URL')
notes = models.TextField(blank=True)
""" Notes attached to each build output """
2018-04-30 22:55:51 +00:00
@property
def required_parts(self):
2019-04-27 10:35:14 +00:00
""" Returns a dict of parts required to build this part (BOM) """
2018-04-30 22:55:51 +00:00
parts = []
for item in self.part.bom_items.all():
part = {'part': item.sub_part,
'per_build': item.quantity,
'quantity': item.quantity * self.quantity
}
parts.append(part)
return parts
@property
def can_build(self):
2019-04-27 10:35:14 +00:00
""" Return true if there are enough parts to supply build """
for item in self.required_parts:
if item['part'].total_stock < item['quantity']:
return False
return True
@property
def is_active(self):
2019-04-27 10:35:14 +00:00
""" Is this build active? An active build is either:
- PENDING
- HOLDING
"""
return self.status in [
self.PENDING,
self.HOLDING
]
@property
def is_complete(self):
2019-04-27 10:35:14 +00:00
""" Returns True if the build status is COMPLETE """
return self.status == self.COMPLETE
class BuildItemAllocation(models.Model):
""" A BuildItemAllocation links multiple StockItem objects to a Build.
These are used to allocate part stock to a build.
Once the Build is completed, the parts are removed from stock and the
BuildItemAllocation objects are removed.
Attributes:
build: Link to a Build object
stock: Link to a StockItem object
quantity: Number of units allocated
"""
build = models.ForeignKey(
Build,
on_delete=models.CASCADE,
related_name='allocated_stock',
)
stock = models.ForeignKey(
'stock.StockItem',
on_delete=models.CASCADE,
related_name='allocations',
help_text='Stock Item to allocate to build',
)
quantity = models.PositiveIntegerField(
default=1,
validators=[MinValueValidator(1)],
help_text='Stock quantity to allocate to build'
)