mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +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):
|
||||
""" 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)
|
||||
|
||||
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():
|
||||
|
||||
@ -151,12 +151,17 @@ class Build(models.Model):
|
||||
|
||||
# Are there any parts available?
|
||||
if stock_item.quantity > 0:
|
||||
|
||||
# Only take as many as are available
|
||||
if stock_item.quantity < q_required:
|
||||
q_required = stock_item.quantity
|
||||
|
||||
# Add the item to the allocations list
|
||||
allocations[stock_item] = q_required
|
||||
allocation = {
|
||||
'stock_item': stock_item,
|
||||
'quantity': q_required,
|
||||
}
|
||||
|
||||
allocations.append(allocation)
|
||||
|
||||
return allocations
|
||||
|
||||
@ -164,6 +169,13 @@ class Build(models.Model):
|
||||
def autoAllocate(self):
|
||||
""" 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()
|
||||
"""
|
||||
|
||||
@ -173,8 +185,8 @@ class Build(models.Model):
|
||||
# Create a new allocation
|
||||
build_item = BuildItem(
|
||||
build=self,
|
||||
stock_item=item,
|
||||
quantity=allocations[item])
|
||||
stock_item=item['stock_item'],
|
||||
quantity=item['quantity'])
|
||||
|
||||
build_item.save()
|
||||
|
||||
|
@ -18,7 +18,8 @@ InvenTree | Allocate Parts
|
||||
</div>
|
||||
<div class='col-sm-6'>
|
||||
<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>
|
||||
@ -64,4 +65,13 @@ InvenTree | Allocate Parts
|
||||
);
|
||||
});
|
||||
|
||||
$("#auto-allocate-build").on('click', function() {
|
||||
launchModalForm(
|
||||
"{% url 'build-auto-allocate' build.id %}",
|
||||
{
|
||||
reload: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
{% 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>
|
||||
{% if taking %}
|
||||
The following items will be removed from stock:
|
||||
<ul>
|
||||
<ul class='list-group'>
|
||||
{% for item in taking %}
|
||||
<li>{{ item.quantity }} x {{ item.stock_item.part.name }} from {{ item.stock_item.location }}</li>
|
||||
{% endfor %}
|
||||
|
@ -21,6 +21,7 @@ build_detail_urls = [
|
||||
url(r'^allocate/?', views.BuildAllocate.as_view(), name='build-allocate'),
|
||||
url(r'^cancel/?', views.BuildCancel.as_view(), name='build-cancel'),
|
||||
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'),
|
||||
]
|
||||
|
@ -12,7 +12,7 @@ from django.forms import HiddenInput
|
||||
|
||||
from part.models import Part
|
||||
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 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):
|
||||
""" View to mark a build as Complete.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user