mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-30 04:26:44 +00:00
commit
be144c0d35
@ -21,6 +21,7 @@ class EditBuildForm(HelperForm):
|
|||||||
'title',
|
'title',
|
||||||
'part',
|
'part',
|
||||||
'quantity',
|
'quantity',
|
||||||
|
'take_from',
|
||||||
'batch',
|
'batch',
|
||||||
'URL',
|
'URL',
|
||||||
'notes',
|
'notes',
|
||||||
|
20
InvenTree/build/migrations/0013_build_take_from.py
Normal file
20
InvenTree/build/migrations/0013_build_take_from.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 2.2 on 2019-05-10 08:50
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('stock', '0015_stockitem_delete_on_deplete'),
|
||||||
|
('build', '0012_auto_20190508_2332'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='build',
|
||||||
|
name='take_from',
|
||||||
|
field=models.ForeignKey(blank=True, help_text='Select location to take stock from for this build (leave blank to take from any stock location', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sourcing_builds', to='stock.StockLocation'),
|
||||||
|
),
|
||||||
|
]
|
@ -27,6 +27,7 @@ class Build(models.Model):
|
|||||||
part: The part to be built (from component BOM items)
|
part: The part to be built (from component BOM items)
|
||||||
title: Brief title describing the build (required)
|
title: Brief title describing the build (required)
|
||||||
quantity: Number of units to be built
|
quantity: Number of units to be built
|
||||||
|
take_from: Location to take stock from to make this build (if blank, can take from anywhere)
|
||||||
status: Build status code
|
status: Build status code
|
||||||
batch: Batch code transferred to build parts (optional)
|
batch: Batch code transferred to build parts (optional)
|
||||||
creation_date: Date the build was created (auto)
|
creation_date: Date the build was created (auto)
|
||||||
@ -41,6 +42,11 @@ class Build(models.Model):
|
|||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('build-detail', kwargs={'pk': self.id})
|
return reverse('build-detail', kwargs={'pk': self.id})
|
||||||
|
|
||||||
|
title = models.CharField(
|
||||||
|
blank=False,
|
||||||
|
max_length=100,
|
||||||
|
help_text='Brief description of the build')
|
||||||
|
|
||||||
part = models.ForeignKey('part.Part', on_delete=models.CASCADE,
|
part = models.ForeignKey('part.Part', on_delete=models.CASCADE,
|
||||||
related_name='builds',
|
related_name='builds',
|
||||||
limit_choices_to={
|
limit_choices_to={
|
||||||
@ -50,10 +56,11 @@ class Build(models.Model):
|
|||||||
help_text='Select part to build',
|
help_text='Select part to build',
|
||||||
)
|
)
|
||||||
|
|
||||||
title = models.CharField(
|
take_from = models.ForeignKey('stock.StockLocation', on_delete=models.SET_NULL,
|
||||||
blank=False,
|
related_name='sourcing_builds',
|
||||||
max_length=100,
|
null=True, blank=True,
|
||||||
help_text='Brief description of the build')
|
help_text='Select location to take stock from for this build (leave blank to take from any stock location'
|
||||||
|
)
|
||||||
|
|
||||||
quantity = models.PositiveIntegerField(
|
quantity = models.PositiveIntegerField(
|
||||||
default=1,
|
default=1,
|
||||||
@ -139,6 +146,11 @@ class Build(models.Model):
|
|||||||
|
|
||||||
stock = StockItem.objects.filter(part=item.sub_part)
|
stock = StockItem.objects.filter(part=item.sub_part)
|
||||||
|
|
||||||
|
# Ensure that the available stock items are in the correct location
|
||||||
|
if self.take_from is not None:
|
||||||
|
# Filter for stock that is located downstream of the designated location
|
||||||
|
stock = stock.filter(location__in=[loc for loc in self.take_from.getUniqueChildren()])
|
||||||
|
|
||||||
# Only one StockItem to choose from? Default to that one!
|
# Only one StockItem to choose from? Default to that one!
|
||||||
if len(stock) == 1:
|
if len(stock) == 1:
|
||||||
stock_item = stock[0]
|
stock_item = stock[0]
|
||||||
|
@ -45,6 +45,16 @@ InvenTree | Build - {{ build }}
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Quantity</td><td>{{ build.quantity }}</td>
|
<td>Quantity</td><td>{{ build.quantity }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Stock Source</td>
|
||||||
|
<td>
|
||||||
|
{% if build.take_from %}
|
||||||
|
<a href="{% url 'stock-location-detail' build.take_from.id %}">{{ build.take_from }}</a>
|
||||||
|
{% else %}
|
||||||
|
Stock can be taken from any available location.
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Status</td><td>{% include "build_status.html" with build=build %}</td>
|
<td>Status</td><td>{% include "build_status.html" with build=build %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -374,6 +374,16 @@ class BuildItemCreate(AjaxCreateView):
|
|||||||
query = query.filter(part=part_id)
|
query = query.filter(part=part_id)
|
||||||
|
|
||||||
if build_id is not None:
|
if build_id is not None:
|
||||||
|
try:
|
||||||
|
build = Build.objects.get(id=build_id)
|
||||||
|
|
||||||
|
if build.take_from is not None:
|
||||||
|
# Limit query to stock items that are downstream of the 'take_from' location
|
||||||
|
query = query.filter(location__in=[loc for loc in build.take_from.getUniqueChildren()])
|
||||||
|
|
||||||
|
except Build.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
# Exclude StockItem objects which are already allocated to this build and part
|
# Exclude StockItem objects which are already allocated to this build and part
|
||||||
query = query.exclude(id__in=[item.stock_item.id for item in BuildItem.objects.filter(build=build_id, stock_item__part=part_id)])
|
query = query.exclude(id__in=[item.stock_item.id for item in BuildItem.objects.filter(build=build_id, stock_item__part=part_id)])
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user