mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add a "sales_order" reference to the Build model
- If a build order is made to fulfil a sales order - Add sales_order filtering to the Build API - Pass initial information through to the BuildCreate view
This commit is contained in:
parent
b351976ae9
commit
d5f3498238
@ -38,6 +38,8 @@ class BuildList(generics.ListCreateAPIView):
|
||||
]
|
||||
|
||||
filter_fields = [
|
||||
'part',
|
||||
'sales_order',
|
||||
]
|
||||
|
||||
def get_queryset(self):
|
||||
@ -48,12 +50,6 @@ class BuildList(generics.ListCreateAPIView):
|
||||
|
||||
build_list = super().get_queryset()
|
||||
|
||||
# Filter by part
|
||||
part = self.request.query_params.get('part', None)
|
||||
|
||||
if part is not None:
|
||||
build_list = build_list.filter(part=part)
|
||||
|
||||
# Filter by build status?
|
||||
status = self.request.query_params.get('status', None)
|
||||
|
||||
|
@ -22,6 +22,7 @@ class EditBuildForm(HelperForm):
|
||||
fields = [
|
||||
'title',
|
||||
'part',
|
||||
'sales_order',
|
||||
'quantity',
|
||||
'take_from',
|
||||
'batch',
|
||||
|
20
InvenTree/build/migrations/0012_build_sales_order.py
Normal file
20
InvenTree/build/migrations/0012_build_sales_order.py
Normal file
@ -0,0 +1,20 @@
|
||||
# Generated by Django 3.0.5 on 2020-04-24 22:51
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('order', '0029_auto_20200423_1042'),
|
||||
('build', '0011_auto_20200406_0123'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='build',
|
||||
name='sales_order',
|
||||
field=models.ForeignKey(blank=True, help_text='SalesOrder to which this build is allocated', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='builds', to='order.SalesOrder'),
|
||||
),
|
||||
]
|
@ -33,6 +33,7 @@ class Build(models.Model):
|
||||
part: The part to be built (from component BOM items)
|
||||
title: Brief title describing the build (required)
|
||||
quantity: Number of units to be built
|
||||
sales_order: References to a SalesOrder object for which this Build is required (e.g. the output of this build will be used to fulfil a sales order)
|
||||
take_from: Location to take stock from to make this build (if blank, can take from anywhere)
|
||||
status: Build status code
|
||||
batch: Batch code transferred to build parts (optional)
|
||||
@ -51,9 +52,12 @@ class Build(models.Model):
|
||||
title = models.CharField(
|
||||
blank=False,
|
||||
max_length=100,
|
||||
help_text=_('Brief description of the build'))
|
||||
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',
|
||||
limit_choices_to={
|
||||
'is_template': False,
|
||||
@ -64,7 +68,17 @@ class Build(models.Model):
|
||||
help_text=_('Select part to build'),
|
||||
)
|
||||
|
||||
take_from = models.ForeignKey('stock.StockLocation', on_delete=models.SET_NULL,
|
||||
sales_order = models.ForeignKey(
|
||||
'order.SalesOrder',
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='builds',
|
||||
null=True, blank=True,
|
||||
help_text=_('SalesOrder to which this build is allocated')
|
||||
)
|
||||
|
||||
take_from = models.ForeignKey(
|
||||
'stock.StockLocation',
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='sourcing_builds',
|
||||
null=True, blank=True,
|
||||
help_text=_('Select location to take stock from for this build (leave blank to take from any stock location)')
|
||||
|
@ -39,6 +39,7 @@ class BuildSerializer(InvenTreeModelSerializer):
|
||||
'completion_date',
|
||||
'part',
|
||||
'part_detail',
|
||||
'sales_order',
|
||||
'quantity',
|
||||
'status',
|
||||
'status_text',
|
||||
|
@ -8,6 +8,14 @@
|
||||
InvenTree | {% trans "Build" %} - {{ build }}
|
||||
{% endblock %}
|
||||
|
||||
{% block pre_content %}
|
||||
{% if build.sales_order %}
|
||||
<div class='alert alert-block alert-info'>
|
||||
{% trans "This build is allocated to Sales Order" %} <b><a href="{% url 'so-detail' build.sales_order.id %}">{{ build.sales_order }}</a></b>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block thumbnail %}
|
||||
<img class="part-thumb"
|
||||
{% if build.part.image %}
|
||||
@ -54,7 +62,7 @@ src="{% static 'img/blank_image.png' %}"
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class='fas fa-shapes'></span></td>
|
||||
<td>Part</td>
|
||||
<td>{% trans "Part" %}</td>
|
||||
<td><a href="{% url 'part-detail' build.part.id %}">{{ build.part.full_name }}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -67,6 +75,13 @@ src="{% static 'img/blank_image.png' %}"
|
||||
<td>{% trans "Status" %}</td>
|
||||
<td>{% build_status_label build.status %}</td>
|
||||
</tr>
|
||||
{% if build.sales_order %}
|
||||
<tr>
|
||||
<td><span class='fas fa-dolly'></span></td>
|
||||
<td>{% trans "Sales Order" %}</td>
|
||||
<td><a href="{% url 'so-detail' build.sales_order.id %}">{{ build.sales_order }}</a></td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td><span class='fas fa-dollar-sign'></span></td>
|
||||
<td>{% trans "BOM Price" %}</td>
|
||||
|
@ -393,13 +393,13 @@ class BuildCreate(AjaxCreateView):
|
||||
|
||||
initials = super(BuildCreate, self).get_initial().copy()
|
||||
|
||||
part_id = self.request.GET.get('part', None)
|
||||
# User has provided a Part ID
|
||||
initials['part'] = self.request.GET.get('part', None)
|
||||
|
||||
if part_id:
|
||||
try:
|
||||
initials['part'] = Part.objects.get(pk=part_id)
|
||||
except Part.DoesNotExist:
|
||||
pass
|
||||
# User has provided a SalesOrder ID
|
||||
initials['sales_order'] = self.request.GET.get('sales_order', None)
|
||||
|
||||
initials['quantity'] = self.request.GET.get('quantity', 1)
|
||||
|
||||
return initials
|
||||
|
||||
|
@ -6,6 +6,9 @@
|
||||
{% load static %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
{% include "order/so_tabs.html" with tab='details' %}
|
||||
|
||||
<hr>
|
||||
|
||||
<h4>{% trans "Sales Order Items" %}</h4>
|
||||
@ -45,6 +48,7 @@ $("#so-lines-table").inventreeTable({
|
||||
part_detail: true,
|
||||
allocations: true,
|
||||
},
|
||||
uniqueId: 'pk',
|
||||
url: "{% url 'api-so-line-list' %}",
|
||||
onPostBody: setupCallbacks,
|
||||
detailViewByClick: true,
|
||||
@ -242,12 +246,28 @@ function setupCallbacks() {
|
||||
});
|
||||
|
||||
table.find(".button-build").click(function() {
|
||||
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
// Extract the row data from the table!
|
||||
var idx = $(this).closest('tr').attr('data-index');
|
||||
|
||||
var row = table.bootstrapTable('getData')[idx];
|
||||
|
||||
console.log('Row ' + idx + ' - ' + row.pk + ', ' + row.quantity);
|
||||
|
||||
var quantity = 1;
|
||||
|
||||
if (row.allocated < row.quantity) {
|
||||
quantity = row.quantity - row.allocated;
|
||||
}
|
||||
|
||||
launchModalForm(`/build/new/`, {
|
||||
follow: true,
|
||||
data: {
|
||||
part: pk,
|
||||
sales_order: {{ order.id }},
|
||||
quantity: quantity,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user