mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-30 20:46:47 +00:00
Auto-allocation form now working
- Displays a list of stock items which will be allocated
This commit is contained in:
parent
793b4f8063
commit
7835562396
@ -27,6 +27,18 @@ class EditBuildForm(HelperForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class AutoAllocateBuildForm(HelperForm):
|
||||||
|
""" Form for auto-allocation of stock to a build """
|
||||||
|
|
||||||
|
confirm = forms.BooleanField(required=False, help_text='Confirm stock allocation')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Build
|
||||||
|
fields = [
|
||||||
|
'confirm'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class CompleteBuildForm(HelperForm):
|
class CompleteBuildForm(HelperForm):
|
||||||
""" Form for marking a Build as complete """
|
""" Form for marking a Build as complete """
|
||||||
|
|
||||||
|
@ -127,10 +127,10 @@ class Build(models.Model):
|
|||||||
- If there are multiple StockItems available, ignore (leave up to the user)
|
- If there are multiple StockItems available, ignore (leave up to the user)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A dict object containing the StockItem objects to be allocated (and the quantities)
|
A list object containing the StockItem objects to be allocated (and the quantities)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
allocations = {}
|
allocations = []
|
||||||
|
|
||||||
for item in self.part.bom_items.all():
|
for item in self.part.bom_items.all():
|
||||||
|
|
||||||
@ -151,12 +151,17 @@ class Build(models.Model):
|
|||||||
|
|
||||||
# Are there any parts available?
|
# Are there any parts available?
|
||||||
if stock_item.quantity > 0:
|
if stock_item.quantity > 0:
|
||||||
|
|
||||||
# Only take as many as are available
|
# Only take as many as are available
|
||||||
if stock_item.quantity < q_required:
|
if stock_item.quantity < q_required:
|
||||||
q_required = stock_item.quantity
|
q_required = stock_item.quantity
|
||||||
|
|
||||||
# Add the item to the allocations list
|
allocation = {
|
||||||
allocations[stock_item] = q_required
|
'stock_item': stock_item,
|
||||||
|
'quantity': q_required,
|
||||||
|
}
|
||||||
|
|
||||||
|
allocations.append(allocation)
|
||||||
|
|
||||||
return allocations
|
return allocations
|
||||||
|
|
||||||
@ -164,6 +169,13 @@ class Build(models.Model):
|
|||||||
def autoAllocate(self):
|
def autoAllocate(self):
|
||||||
""" Run auto-allocation routine to allocate StockItems to this Build.
|
""" Run auto-allocation routine to allocate StockItems to this Build.
|
||||||
|
|
||||||
|
Returns a list of dict objects with keys like:
|
||||||
|
|
||||||
|
{
|
||||||
|
'stock_item': item,
|
||||||
|
'quantity': quantity,
|
||||||
|
}
|
||||||
|
|
||||||
See: getAutoAllocations()
|
See: getAutoAllocations()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -173,8 +185,8 @@ class Build(models.Model):
|
|||||||
# Create a new allocation
|
# Create a new allocation
|
||||||
build_item = BuildItem(
|
build_item = BuildItem(
|
||||||
build=self,
|
build=self,
|
||||||
stock_item=item,
|
stock_item=item['stock_item'],
|
||||||
quantity=allocations[item])
|
quantity=item['quantity'])
|
||||||
|
|
||||||
build_item.save()
|
build_item.save()
|
||||||
|
|
||||||
|
@ -18,7 +18,8 @@ InvenTree | Allocate Parts
|
|||||||
</div>
|
</div>
|
||||||
<div class='col-sm-6'>
|
<div class='col-sm-6'>
|
||||||
<div class='btn-group' style='float: right;'>
|
<div class='btn-group' style='float: right;'>
|
||||||
<button class='btn btn-warning' type='button' id='complete-build'>Complete Build</button>
|
<button class='btn btn-primary' type='button' title='Automatic allocation' id='auto-allocate-build'>Auto Allocate</button>
|
||||||
|
<button class='btn btn-warning' type='button' title='Complete build' id='complete-build'>Complete Build</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -64,4 +65,13 @@ InvenTree | Allocate Parts
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#auto-allocate-build").on('click', function() {
|
||||||
|
launchModalForm(
|
||||||
|
"{% url 'build-auto-allocate' build.id %}",
|
||||||
|
{
|
||||||
|
reload: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
43
InvenTree/build/templates/build/auto_allocate.html
Normal file
43
InvenTree/build/templates/build/auto_allocate.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{% extends "modal_form.html" %}
|
||||||
|
|
||||||
|
{% block pre_form_content %}
|
||||||
|
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
<b>Build: {{ build.title }}</b> - {{ build.quantity }} x {{ build.part.name }}
|
||||||
|
<br><br>
|
||||||
|
Automatically allocate stock to this build?
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
{% if allocations %}
|
||||||
|
|
||||||
|
<table class='table table-striped table-condensed'>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th>Part</th>
|
||||||
|
<th>Quantity</th>
|
||||||
|
<th>Location</th>
|
||||||
|
</tr>
|
||||||
|
{% for item in allocations %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a class='hover-icon'>
|
||||||
|
<img class='hover-img-thumb' src='{{ item.stock_item.part.image.url }}'>
|
||||||
|
<img class='hover-img-large' src='{{ item.stock_item.part.image.url }}'>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ item.stock_item.part.name }}<br>
|
||||||
|
<i>{{ item.stock_item.part.description }}</i>
|
||||||
|
</td>
|
||||||
|
<td>{{ item.quantity }}</td>
|
||||||
|
<td>{{ item.stock_item.location }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<i>No stock could be selected for automatic build allocation.</i>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -7,7 +7,7 @@ Are you sure you want to mark this build as complete?
|
|||||||
<hr>
|
<hr>
|
||||||
{% if taking %}
|
{% if taking %}
|
||||||
The following items will be removed from stock:
|
The following items will be removed from stock:
|
||||||
<ul>
|
<ul class='list-group'>
|
||||||
{% for item in taking %}
|
{% for item in taking %}
|
||||||
<li>{{ item.quantity }} x {{ item.stock_item.part.name }} from {{ item.stock_item.location }}</li>
|
<li>{{ item.quantity }} x {{ item.stock_item.part.name }} from {{ item.stock_item.location }}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -21,6 +21,7 @@ build_detail_urls = [
|
|||||||
url(r'^allocate/?', views.BuildAllocate.as_view(), name='build-allocate'),
|
url(r'^allocate/?', views.BuildAllocate.as_view(), name='build-allocate'),
|
||||||
url(r'^cancel/?', views.BuildCancel.as_view(), name='build-cancel'),
|
url(r'^cancel/?', views.BuildCancel.as_view(), name='build-cancel'),
|
||||||
url(r'^complete/?', views.BuildComplete.as_view(), name='build-complete'),
|
url(r'^complete/?', views.BuildComplete.as_view(), name='build-complete'),
|
||||||
|
url(r'^auto-allocate/?', views.BuildAutoAllocate.as_view(), name='build-auto-allocate'),
|
||||||
|
|
||||||
url(r'^.*$', views.BuildDetail.as_view(), name='build-detail'),
|
url(r'^.*$', views.BuildDetail.as_view(), name='build-detail'),
|
||||||
]
|
]
|
||||||
|
@ -12,7 +12,7 @@ from django.forms import HiddenInput
|
|||||||
|
|
||||||
from part.models import Part
|
from part.models import Part
|
||||||
from .models import Build, BuildItem
|
from .models import Build, BuildItem
|
||||||
from .forms import EditBuildForm, EditBuildItemForm, CompleteBuildForm
|
from .forms import EditBuildForm, EditBuildItemForm, CompleteBuildForm, AutoAllocateBuildForm
|
||||||
from stock.models import StockLocation, StockItem
|
from stock.models import StockLocation, StockItem
|
||||||
|
|
||||||
from InvenTree.views import AjaxView, AjaxUpdateView, AjaxCreateView, AjaxDeleteView
|
from InvenTree.views import AjaxView, AjaxUpdateView, AjaxCreateView, AjaxDeleteView
|
||||||
@ -67,6 +67,61 @@ class BuildCancel(AjaxView):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class BuildAutoAllocate(AjaxUpdateView):
|
||||||
|
""" View to auto-allocate parts for a build.
|
||||||
|
Follows a simple set of rules to automatically allocate StockItem objects.
|
||||||
|
|
||||||
|
Ref: build.models.Build.getAutoAllocations()
|
||||||
|
"""
|
||||||
|
|
||||||
|
model = Build
|
||||||
|
form_class = AutoAllocateBuildForm
|
||||||
|
context_object_name = 'build'
|
||||||
|
ajax_form_title = 'Allocate Stock'
|
||||||
|
ajax_template_name = 'build/auto_allocate.html'
|
||||||
|
|
||||||
|
def get_context_data(self, *args, **kwargs):
|
||||||
|
""" Get the context data for form rendering. """
|
||||||
|
|
||||||
|
context = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
build = Build.objects.get(id=self.kwargs['pk'])
|
||||||
|
context['build'] = build
|
||||||
|
context['allocations'] = build.getAutoAllocations()
|
||||||
|
except Build.DoesNotExist:
|
||||||
|
context['error'] = 'No matching buidl found'
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
""" Handle POST request. Perform auto allocations.
|
||||||
|
|
||||||
|
- If the form validation passes, perform allocations
|
||||||
|
- Otherwise, the form is passed back to the client
|
||||||
|
"""
|
||||||
|
|
||||||
|
build = self.get_object()
|
||||||
|
form = self.get_form()
|
||||||
|
|
||||||
|
confirm = request.POST.get('confirm', False)
|
||||||
|
|
||||||
|
valid = False
|
||||||
|
|
||||||
|
if confirm is False:
|
||||||
|
form.errors['confirm'] = ['Confirm stock allocation']
|
||||||
|
form.non_field_errors = 'Check the confirmation box at the bottom of the list'
|
||||||
|
else:
|
||||||
|
build.autoAllocate()
|
||||||
|
valid = True
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'form_valid': valid,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.renderJsonResponse(request, form, data, context=self.get_context_data())
|
||||||
|
|
||||||
|
|
||||||
class BuildComplete(AjaxUpdateView):
|
class BuildComplete(AjaxUpdateView):
|
||||||
""" View to mark a build as Complete.
|
""" View to mark a build as Complete.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user