mirror of
https://github.com/inventree/InvenTree.git
synced 2025-07-01 03:00:54 +00:00
Merge branch 'warning-mesages'
This commit is contained in:
@ -28,4 +28,41 @@
|
||||
test: "Temperature Test"
|
||||
result: True
|
||||
date: 2020-05-17
|
||||
notes: 'Passed temperature test by making it cooler'
|
||||
notes: 'Passed temperature test by making it cooler'
|
||||
|
||||
- model: stock.stockitemtestresult
|
||||
fields:
|
||||
stock_item: 522
|
||||
test: 'applypaint'
|
||||
result: True
|
||||
date: 2020-05-17
|
||||
|
||||
- model: stock.stockitemtestresult
|
||||
fields:
|
||||
stock_item: 522
|
||||
test: 'applypaint'
|
||||
result: False
|
||||
date: 2020-05-18
|
||||
|
||||
- model: stock.stockitemtestresult
|
||||
fields:
|
||||
stock_item: 522
|
||||
test: 'Attach Legs'
|
||||
result: True
|
||||
date: 2020-05-17
|
||||
|
||||
- model: stock.stockitemtestresult
|
||||
fields:
|
||||
stock_item: 522
|
||||
test: 'Check that chair is GreEn '
|
||||
result: True
|
||||
date: 2020-05-17
|
||||
|
||||
- model: stock.stockitemtestresult
|
||||
pk: 12345
|
||||
fields:
|
||||
stock_item: 522
|
||||
test: 'test strength of chair'
|
||||
result: False
|
||||
value: 100kg
|
||||
date: 2020-05-17
|
@ -46,6 +46,7 @@ class EditStockItemTestResultForm(HelperForm):
|
||||
'test',
|
||||
'result',
|
||||
'value',
|
||||
'attachment',
|
||||
'notes',
|
||||
]
|
||||
|
||||
|
@ -276,10 +276,6 @@ class StockItem(MPTTModel):
|
||||
# Serial numbered items cannot be deleted on depletion
|
||||
self.delete_on_deplete = False
|
||||
|
||||
# A template part cannot be instantiated as a StockItem
|
||||
if self.part.is_template:
|
||||
raise ValidationError({'part': _('Stock item cannot be created for a template Part')})
|
||||
|
||||
except PartModels.Part.DoesNotExist:
|
||||
# This gets thrown if self.supplier_part is null
|
||||
# TODO - Find a test than can be perfomed...
|
||||
@ -962,10 +958,57 @@ class StockItem(MPTTModel):
|
||||
result_map = {}
|
||||
|
||||
for result in results:
|
||||
result_map[result.test] = result
|
||||
key = helpers.generateTestKey(result.test)
|
||||
result_map[key] = result
|
||||
|
||||
return result_map
|
||||
|
||||
def requiredTestStatus(self):
|
||||
"""
|
||||
Return the status of the tests required for this StockItem.
|
||||
|
||||
return:
|
||||
A dict containing the following items:
|
||||
- total: Number of required tests
|
||||
- passed: Number of tests that have passed
|
||||
- failed: Number of tests that have failed
|
||||
"""
|
||||
|
||||
# All the tests required by the part object
|
||||
required = self.part.getRequiredTests()
|
||||
|
||||
results = self.testResultMap()
|
||||
|
||||
total = len(required)
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
for test in required:
|
||||
key = helpers.generateTestKey(test.test_name)
|
||||
|
||||
if key in results:
|
||||
result = results[key]
|
||||
|
||||
if result.result:
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
return {
|
||||
'total': total,
|
||||
'passed': passed,
|
||||
'failed': failed,
|
||||
}
|
||||
|
||||
def hasRequiredTests(self):
|
||||
return self.part.getRequiredTests().count() > 0
|
||||
|
||||
def passedAllRequiredTests(self):
|
||||
|
||||
status = self.requiredTestStatus()
|
||||
|
||||
return status['passed'] >= status['total']
|
||||
|
||||
|
||||
@receiver(pre_delete, sender=StockItem, dispatch_uid='stock_item_pre_delete_log')
|
||||
def before_delete_stock_item(sender, instance, using, **kwargs):
|
||||
|
@ -15,6 +15,12 @@ InvenTree | {% trans "Stock Item" %} - {{ item }}
|
||||
{% block pre_content %}
|
||||
{% include 'stock/loc_link.html' with location=item.location %}
|
||||
|
||||
{% if item.hasRequiredTests and not item.passedAllRequiredTests %}
|
||||
<div class='alert alert-block alert-danger'>
|
||||
{% trans "This stock item has not passed all required tests" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% for allocation in item.sales_order_allocations.all %}
|
||||
<div class='alert alert-block alert-info'>
|
||||
{% trans "This stock item is allocated to Sales Order" %} <a href="{% url 'so-detail' allocation.line.order.id %}"><b>#{{ allocation.line.order.reference }}</b></a> ({% trans "Quantity" %}: {% decimal allocation.quantity %})
|
||||
@ -221,6 +227,13 @@ InvenTree | {% trans "Stock Item" %} - {{ item }}
|
||||
<td>{% trans "Status" %}</td>
|
||||
<td>{% stock_status_label item.status %}</td>
|
||||
</tr>
|
||||
{% if item.hasRequiredTests %}
|
||||
<tr>
|
||||
<td><span class='fas fa-vial'></span></td>
|
||||
<td>{% trans "Tests" %}</td>
|
||||
<td>{{ item.requiredTestStatus.passed }} / {{ item.requiredTestStatus.total }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
|
@ -7,21 +7,21 @@
|
||||
|
||||
{% include "stock/tabs.html" with tab='tests' %}
|
||||
|
||||
<h4>{% trans "Test Results" %}</h4>
|
||||
<h4>{% trans "Test Data" %}</h4>
|
||||
<hr>
|
||||
|
||||
<div id='button-toolbar'>
|
||||
<div class='button-toolbar container-fluid' style="float: right;">
|
||||
<div class='btn-group' role='group'>
|
||||
<button type='button' class='btn btn-success' id='add-test-result'>{% trans "Add Test Result" %}</button>
|
||||
<button type='button' class='btn btn-success' id='add-test-result'>{% trans "Add Test Data" %}</button>
|
||||
</div>
|
||||
<div class='filter-list' id='filter-list-stocktests'>
|
||||
<!-- Empty div -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' data-toolbar='#button-toolbar' id='test-result-table'></table>
|
||||
|
||||
<table class='table table-striped table-condensed' data-toolbar='#button-toolbar' id='test-result-table'></table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@ -30,16 +30,14 @@
|
||||
|
||||
loadStockTestResultsTable(
|
||||
$("#test-result-table"), {
|
||||
params: {
|
||||
stock_item: {{ item.id }},
|
||||
user_detail: true,
|
||||
attachment_detail: true,
|
||||
},
|
||||
part: {{ item.part.id }},
|
||||
stock_item: {{ item.id }},
|
||||
}
|
||||
);
|
||||
|
||||
function reloadTable() {
|
||||
$("#test-result-table").bootstrapTable("refresh");
|
||||
location.reload();
|
||||
//$("#test-result-table").bootstrapTable("refresh");
|
||||
}
|
||||
|
||||
$("#add-test-result").click(function() {
|
||||
@ -53,6 +51,22 @@ $("#add-test-result").click(function() {
|
||||
);
|
||||
});
|
||||
|
||||
$("#test-result-table").on('click', '.button-test-add', function() {
|
||||
var button = $(this);
|
||||
|
||||
var test_name = button.attr('pk');
|
||||
|
||||
launchModalForm(
|
||||
"{% url 'stock-item-test-create' %}", {
|
||||
data: {
|
||||
stock_item: {{ item.id }},
|
||||
test: test_name
|
||||
},
|
||||
success: reloadTable,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$("#test-result-table").on('click', '.button-test-edit', function() {
|
||||
var button = $(this);
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
{% if item.part.trackable %}
|
||||
<li{% if tab == 'tests' %} class='active'{% endif %}>
|
||||
<a href="{% url 'stock-item-test-results' item.id %}">
|
||||
{% trans "Test Results" %}
|
||||
{% trans "Test Data" %}
|
||||
{% if item.test_results.count > 0 %}<span class='badge'>{{ item.test_results.count }}</span>{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
|
@ -4,6 +4,7 @@ from django.contrib.auth import get_user_model
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from .models import StockLocation, StockItem, StockItemTracking
|
||||
from .models import StockItemTestResult
|
||||
from part.models import Part
|
||||
|
||||
|
||||
@ -15,6 +16,7 @@ class StockTest(TestCase):
|
||||
fixtures = [
|
||||
'category',
|
||||
'part',
|
||||
'test_templates',
|
||||
'location',
|
||||
'stock',
|
||||
'stock_tests',
|
||||
@ -429,5 +431,30 @@ class TestResultTest(StockTest):
|
||||
|
||||
self.assertEqual(len(result_map), 3)
|
||||
|
||||
for test in ['Firmware Version', 'Settings Checksum', 'Temperature Test']:
|
||||
# Keys are all lower-case and do not contain spaces
|
||||
for test in ['firmwareversion', 'settingschecksum', 'temperaturetest']:
|
||||
self.assertIn(test, result_map.keys())
|
||||
|
||||
def test_test_results(self):
|
||||
item = StockItem.objects.get(pk=522)
|
||||
|
||||
status = item.requiredTestStatus()
|
||||
|
||||
self.assertEqual(status['total'], 5)
|
||||
self.assertEqual(status['passed'], 3)
|
||||
self.assertEqual(status['failed'], 1)
|
||||
|
||||
self.assertFalse(item.passedAllRequiredTests())
|
||||
|
||||
# Add some new test results to make it pass!
|
||||
test = StockItemTestResult.objects.get(pk=12345)
|
||||
test.result = True
|
||||
test.save()
|
||||
|
||||
StockItemTestResult.objects.create(
|
||||
stock_item=item,
|
||||
test='sew cushion',
|
||||
result=True
|
||||
)
|
||||
|
||||
self.assertTrue(item.passedAllRequiredTests())
|
||||
|
@ -254,6 +254,8 @@ class StockItemTestResultCreate(AjaxCreateView):
|
||||
except (ValueError, StockItem.DoesNotExist):
|
||||
pass
|
||||
|
||||
initials['test'] = self.request.GET.get('test', '')
|
||||
|
||||
return initials
|
||||
|
||||
def get_form(self):
|
||||
@ -261,6 +263,17 @@ class StockItemTestResultCreate(AjaxCreateView):
|
||||
form = super().get_form()
|
||||
form.fields['stock_item'].widget = HiddenInput()
|
||||
|
||||
# Extract the StockItem object
|
||||
item_id = form['stock_item'].value()
|
||||
|
||||
# Limit the options for the file attachments
|
||||
try:
|
||||
stock_item = StockItem.objects.get(pk=item_id)
|
||||
form.fields['attachment'].queryset = stock_item.attachments.all()
|
||||
except (ValueError, StockItem.DoesNotExist):
|
||||
# Hide the attachments field
|
||||
form.fields['attachment'].widget = HiddenInput()
|
||||
|
||||
return form
|
||||
|
||||
|
||||
@ -278,6 +291,8 @@ class StockItemTestResultEdit(AjaxUpdateView):
|
||||
form = super().get_form()
|
||||
|
||||
form.fields['stock_item'].widget = HiddenInput()
|
||||
|
||||
form.fields['attachment'].queryset = self.object.stock_item.attachments.all()
|
||||
|
||||
return form
|
||||
|
||||
|
Reference in New Issue
Block a user