where one or more test report templates exist for a part,

provide a button for all stock-items of that part,
allowing the user to generate and download a test repotr
This commit is contained in:
Oliver Walters 2020-05-22 22:25:05 +10:00
parent 71681bfda1
commit e6f56cb056
7 changed files with 141 additions and 24 deletions

View File

@ -166,6 +166,9 @@ class AjaxMixin(object):
except AttributeError: except AttributeError:
context = {} context = {}
if form is None:
form = self.get_form()
if form: if form:
context['form'] = form context['form'] = form
else: else:

View File

@ -100,7 +100,7 @@ class ReportTemplateBase(models.Model):
""" """
def __str__(self): def __str__(self):
return os.path.basename(self.template.name) return "{n} - {d}".format(n=self.name, d=self.description)
def getSubdir(self): def getSubdir(self):
return '' return ''
@ -218,7 +218,8 @@ class TestReport(ReportTemplateBase, PartFilterMixin):
def get_context_data(self, request): def get_context_data(self, request):
return { return {
'stock_item': self.stock_item, 'stock_item': self.stock_item,
'results': self.stock_item.testResultMap() 'results': self.stock_item.testResultMap(),
'result_list': self.stock_item.testResultList()
} }

View File

@ -142,6 +142,35 @@ class SerializeStockForm(HelperForm):
] ]
class TestReportFormatForm(HelperForm):
""" Form for selection a test report template """
class Meta:
model = StockItem
fields = [
'template',
]
def __init__(self, stock_item, *args, **kwargs):
self.stock_item = stock_item
super().__init__(*args, **kwargs)
self.fields['template'].choices = self.get_template_choices()
def get_template_choices(self):
""" Available choices """
choices = []
for report in self.stock_item.part.get_test_report_templates():
choices.append((report.pk, report))
return choices
template = forms.ChoiceField(label=_('Template'), help_text=_('Select test report template'))
class ExportOptionsForm(HelperForm): class ExportOptionsForm(HelperForm):
""" Form for selecting stock export options """ """ Form for selecting stock export options """

View File

@ -963,6 +963,13 @@ class StockItem(MPTTModel):
return result_map return result_map
def testResultList(self, **kwargs):
"""
Return a list of test-result objects for this StockItem
"""
return self.testResultMap(**kwargs).values()
def requiredTestStatus(self): def requiredTestStatus(self):
""" """
Return the status of the tests required for this StockItem. Return the status of the tests required for this StockItem.

View File

@ -269,6 +269,17 @@ $("#stock-serialize").click(function() {
); );
}); });
{% if item.part.has_test_report_templates %}
$("#stock-test-report").click(function() {
launchModalForm(
"{% url 'stock-item-test-report-select' item.id %}",
{
follow: true,
}
);
});
{% endif %}
$("#stock-duplicate").click(function() { $("#stock-duplicate").click(function() {
launchModalForm( launchModalForm(
"{% url 'stock-item-create' %}", "{% url 'stock-item-create' %}",

View File

@ -25,6 +25,8 @@ stock_item_detail_urls = [
url(r'^add_tracking/', views.StockItemTrackingCreate.as_view(), name='stock-tracking-create'), url(r'^add_tracking/', views.StockItemTrackingCreate.as_view(), name='stock-tracking-create'),
url(r'^test-report-select/', views.StockItemTestReportSelect.as_view(), name='stock-item-test-report-select'),
url(r'^test/', views.StockItemDetail.as_view(template_name='stock/item_tests.html'), name='stock-item-test-results'), url(r'^test/', views.StockItemDetail.as_view(template_name='stock/item_tests.html'), name='stock-item-test-results'),
url(r'^children/', views.StockItemDetail.as_view(template_name='stock/item_childs.html'), name='stock-item-children'), url(r'^children/', views.StockItemDetail.as_view(template_name='stock/item_childs.html'), name='stock-item-children'),
url(r'^attachments/', views.StockItemDetail.as_view(template_name='stock/item_attachments.html'), name='stock-item-attachments'), url(r'^attachments/', views.StockItemDetail.as_view(template_name='stock/item_attachments.html'), name='stock-item-attachments'),
@ -53,6 +55,8 @@ stock_urls = [
url(r'^item/new/?', views.StockItemCreate.as_view(), name='stock-item-create'), url(r'^item/new/?', views.StockItemCreate.as_view(), name='stock-item-create'),
url(r'^item/test-report-download/', views.StockItemTestReportDownload.as_view(), name='stock-item-test-report-download'),
# URLs for StockItem attachments # URLs for StockItem attachments
url(r'^item/attachment/', include([ url(r'^item/attachment/', include([
url(r'^new/', views.StockItemAttachmentCreate.as_view(), name='stock-item-attachment-create'), url(r'^new/', views.StockItemAttachmentCreate.as_view(), name='stock-item-attachment-create'),

View File

@ -27,19 +27,12 @@ from datetime import datetime
from company.models import Company, SupplierPart from company.models import Company, SupplierPart
from part.models import Part from part.models import Part
from report.models import TestReport
from .models import StockItem, StockLocation, StockItemTracking, StockItemAttachment, StockItemTestResult from .models import StockItem, StockLocation, StockItemTracking, StockItemAttachment, StockItemTestResult
from .admin import StockItemResource from .admin import StockItemResource
from .forms import EditStockLocationForm from . import forms as StockForms
from .forms import CreateStockItemForm
from .forms import EditStockItemForm
from .forms import AdjustStockForm
from .forms import TrackingEntryForm
from .forms import SerializeStockForm
from .forms import ExportOptionsForm
from .forms import EditStockItemAttachmentForm
from .forms import EditStockItemTestResultForm
class StockIndex(ListView): class StockIndex(ListView):
@ -114,7 +107,7 @@ class StockLocationEdit(AjaxUpdateView):
""" """
model = StockLocation model = StockLocation
form_class = EditStockLocationForm form_class = StockForms.EditStockLocationForm
context_object_name = 'location' context_object_name = 'location'
ajax_template_name = 'modal_form.html' ajax_template_name = 'modal_form.html'
ajax_form_title = _('Edit Stock Location') ajax_form_title = _('Edit Stock Location')
@ -158,7 +151,7 @@ class StockItemAttachmentCreate(AjaxCreateView):
""" """
model = StockItemAttachment model = StockItemAttachment
form_class = EditStockItemAttachmentForm form_class = StockForms.EditStockItemAttachmentForm
ajax_form_title = _("Add Stock Item Attachment") ajax_form_title = _("Add Stock Item Attachment")
ajax_template_name = "modal_form.html" ajax_template_name = "modal_form.html"
@ -203,7 +196,7 @@ class StockItemAttachmentEdit(AjaxUpdateView):
""" """
model = StockItemAttachment model = StockItemAttachment
form_class = EditStockItemAttachmentForm form_class = StockForms.EditStockItemAttachmentForm
ajax_form_title = _("Edit Stock Item Attachment") ajax_form_title = _("Edit Stock Item Attachment")
def get_form(self): def get_form(self):
@ -271,7 +264,7 @@ class StockItemTestResultCreate(AjaxCreateView):
""" """
model = StockItemTestResult model = StockItemTestResult
form_class = EditStockItemTestResultForm form_class = StockForms.EditStockItemTestResultForm
ajax_form_title = _("Add Test Result") ajax_form_title = _("Add Test Result")
def post_save(self, **kwargs): def post_save(self, **kwargs):
@ -319,7 +312,7 @@ class StockItemTestResultEdit(AjaxUpdateView):
""" """
model = StockItemTestResult model = StockItemTestResult
form_class = EditStockItemTestResultForm form_class = StockForms.EditStockItemTestResultForm
ajax_form_title = _("Edit Test Result") ajax_form_title = _("Edit Test Result")
def get_form(self): def get_form(self):
@ -343,12 +336,81 @@ class StockItemTestResultDelete(AjaxDeleteView):
context_object_name = "result" context_object_name = "result"
class StockItemTestReportSelect(AjaxView):
"""
View for selecting a TestReport template,
and generating a TestReport as a PDF.
"""
model = StockItem
ajax_form_title = _("Select Test Report Template")
def get_form(self):
stock_item = StockItem.objects.get(pk=self.kwargs['pk'])
return StockForms.TestReportFormatForm(stock_item)
def post(self, request, *args, **kwargs):
template_id = request.POST.get('template', None)
try:
template = TestReport.objects.get(pk=template_id)
except (ValueError, TestReport.DoesNoteExist):
raise ValidationError({'template': _("Select valid template")})
stock_item = StockItem.objects.get(pk=self.kwargs['pk'])
url = reverse('stock-item-test-report-download')
url += '?stock_item={id}'.format(id=stock_item.pk)
url += '&template={id}'.format(id=template.pk)
data = {
'form_valid': True,
'url': url,
}
return self.renderJsonResponse(request, self.get_form(), data=data)
class StockItemTestReportDownload(AjaxView):
"""
Download a TestReport against a StockItem.
Requires the following arguments to be passed as URL params:
stock_item - Valid PK of a StockItem object
template - Valid PK of a TestReport template object
"""
def get(self, request, *args, **kwargs):
template = request.GET.get('template', None)
stock_item = request.GET.get('stock_item', None)
try:
template = TestReport.objects.get(pk=template)
except (ValueError, TestReport.DoesNotExist):
raise ValidationError({'template': 'Invalid template ID'})
try:
stock_item = StockItem.objects.get(pk=stock_item)
except (ValueError, StockItem.DoesNotExist):
raise ValidationError({'stock_item': 'Invalid StockItem ID'})
template.stock_item = stock_item
return template.render(request)
class StockExportOptions(AjaxView): class StockExportOptions(AjaxView):
""" Form for selecting StockExport options """ """ Form for selecting StockExport options """
model = StockLocation model = StockLocation
ajax_form_title = _('Stock Export Options') ajax_form_title = _('Stock Export Options')
form_class = ExportOptionsForm form_class = StockForms.ExportOptionsForm
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
@ -491,7 +553,7 @@ class StockAdjust(AjaxView, FormMixin):
ajax_template_name = 'stock/stock_adjust.html' ajax_template_name = 'stock/stock_adjust.html'
ajax_form_title = _('Adjust Stock') ajax_form_title = _('Adjust Stock')
form_class = AdjustStockForm form_class = StockForms.AdjustStockForm
stock_items = [] stock_items = []
def get_GET_items(self): def get_GET_items(self):
@ -809,7 +871,7 @@ class StockItemEdit(AjaxUpdateView):
""" """
model = StockItem model = StockItem
form_class = EditStockItemForm form_class = StockForms.EditStockItemForm
context_object_name = 'item' context_object_name = 'item'
ajax_template_name = 'modal_form.html' ajax_template_name = 'modal_form.html'
ajax_form_title = _('Edit Stock Item') ajax_form_title = _('Edit Stock Item')
@ -845,7 +907,7 @@ class StockLocationCreate(AjaxCreateView):
""" """
model = StockLocation model = StockLocation
form_class = EditStockLocationForm form_class = StockForms.EditStockLocationForm
context_object_name = 'location' context_object_name = 'location'
ajax_template_name = 'modal_form.html' ajax_template_name = 'modal_form.html'
ajax_form_title = _('Create new Stock Location') ajax_form_title = _('Create new Stock Location')
@ -870,7 +932,7 @@ class StockItemSerialize(AjaxUpdateView):
model = StockItem model = StockItem
ajax_template_name = 'stock/item_serialize.html' ajax_template_name = 'stock/item_serialize.html'
ajax_form_title = _('Serialize Stock') ajax_form_title = _('Serialize Stock')
form_class = SerializeStockForm form_class = StockForms.SerializeStockForm
def get_form(self): def get_form(self):
@ -958,7 +1020,7 @@ class StockItemCreate(AjaxCreateView):
""" """
model = StockItem model = StockItem
form_class = CreateStockItemForm form_class = StockForms.CreateStockItemForm
context_object_name = 'item' context_object_name = 'item'
ajax_template_name = 'modal_form.html' ajax_template_name = 'modal_form.html'
ajax_form_title = _('Create new Stock Item') ajax_form_title = _('Create new Stock Item')
@ -1265,7 +1327,7 @@ class StockItemTrackingEdit(AjaxUpdateView):
model = StockItemTracking model = StockItemTracking
ajax_form_title = _('Edit Stock Tracking Entry') ajax_form_title = _('Edit Stock Tracking Entry')
form_class = TrackingEntryForm form_class = StockForms.TrackingEntryForm
class StockItemTrackingCreate(AjaxCreateView): class StockItemTrackingCreate(AjaxCreateView):
@ -1274,7 +1336,7 @@ class StockItemTrackingCreate(AjaxCreateView):
model = StockItemTracking model = StockItemTracking
ajax_form_title = _("Add Stock Tracking Entry") ajax_form_title = _("Add Stock Tracking Entry")
form_class = TrackingEntryForm form_class = StockForms.TrackingEntryForm
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):