From a661d7e1a62520a7fb4adb59e4b761c1ad2a2b04 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 22 Mar 2020 17:59:23 +1100 Subject: [PATCH 01/12] Abstract the PartAttachment class Now "Attachments" are much easier to implement for different models --- InvenTree/InvenTree/models.py | 48 +++++++++++++++++++ .../migrations/0032_auto_20200322_0453.py | 19 ++++++++ InvenTree/part/models.py | 24 ++-------- 3 files changed, 72 insertions(+), 19 deletions(-) create mode 100644 InvenTree/part/migrations/0032_auto_20200322_0453.py diff --git a/InvenTree/InvenTree/models.py b/InvenTree/InvenTree/models.py index a60935b4b6..d2a5c5daa6 100644 --- a/InvenTree/InvenTree/models.py +++ b/InvenTree/InvenTree/models.py @@ -4,8 +4,11 @@ Generic models which provide extra functionality over base Django model types. from __future__ import unicode_literals +import os + from django.db import models from django.contrib.contenttypes.models import ContentType +from django.utils.translation import gettext_lazy as _ from django.db.models.signals import pre_delete from django.dispatch import receiver @@ -15,6 +18,51 @@ from mptt.models import MPTTModel, TreeForeignKey from .validators import validate_tree_name +def rename_attachment(instance, filename): + """ + Function for renaming an attachment file. + The subdirectory for the uploaded file is determined by the implementing class. + + Args: + instance: Instance of a PartAttachment object + filename: name of uploaded file + + Returns: + path to store file, format: '//filename' + """ + + # Construct a path to store a file attachment for a given model type + return os.path.join(instance.getSubdir(), filename) + + +class InvenTreeAttachment(models.Model): + """ Provides an abstracted class for managing file attachments. + + Attributes: + attachment: File + comment: String descriptor for the attachment + """ + def getSubdir(self): + """ + Return the subdirectory under which attachments should be stored. + Note: Re-implement this for each subclass of InvenTreeAttachment + """ + + return "attachments" + + attachment = models.FileField(upload_to=rename_attachment, + help_text=_('Select file to attach')) + + comment = models.CharField(max_length=100, help_text=_('File comment')) + + @property + def basename(self): + return os.path.basename(self.attachment.name) + + class Meta: + abstract = True + + class InvenTreeTree(MPTTModel): """ Provides an abstracted self-referencing tree model for data categories. diff --git a/InvenTree/part/migrations/0032_auto_20200322_0453.py b/InvenTree/part/migrations/0032_auto_20200322_0453.py new file mode 100644 index 0000000000..29fb25f1e7 --- /dev/null +++ b/InvenTree/part/migrations/0032_auto_20200322_0453.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.9 on 2020-03-22 04:53 + +import InvenTree.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('part', '0031_auto_20200318_1044'), + ] + + operations = [ + migrations.AlterField( + model_name='partattachment', + name='attachment', + field=models.FileField(help_text='Select file to attach', upload_to=InvenTree.models.rename_attachment), + ), + ] diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index d8cb8b07e0..427cf4dcea 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -34,7 +34,7 @@ import hashlib from InvenTree import helpers from InvenTree import validators -from InvenTree.models import InvenTreeTree +from InvenTree.models import InvenTreeTree, InvenTreeAttachment from InvenTree.fields import InvenTreeURLField from InvenTree.helpers import decimal2string @@ -941,28 +941,14 @@ def attach_file(instance, filename): return os.path.join('part_files', str(instance.part.id), filename) -class PartAttachment(models.Model): - """ A PartAttachment links a file to a part - Parts can have multiple files such as datasheets, etc - - Attributes: - part: Link to a Part object - attachment: File - comment: String descriptor for the attachment - """ +class PartAttachment(InvenTreeAttachment): + + def getSubdir(self): + return os.path.join("part_files", str(self.part.id)) part = models.ForeignKey(Part, on_delete=models.CASCADE, related_name='attachments') - attachment = models.FileField(upload_to=attach_file, - help_text=_('Select file to attach')) - - comment = models.CharField(max_length=100, help_text=_('File comment')) - - @property - def basename(self): - return os.path.basename(self.attachment.name) - class PartStar(models.Model): """ A PartStar object creates a relationship between a User and a Part. From cc41752f9f6d339f86efe6f14e7e05be2e657978 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 22 Mar 2020 18:02:53 +1100 Subject: [PATCH 02/12] Add PurchaseOrderAttachment model - File attachment against PurchaseOrder --- .../0016_purchaseorderattachment.py | 27 +++++++++++++++++++ InvenTree/order/models.py | 13 +++++++++ 2 files changed, 40 insertions(+) create mode 100644 InvenTree/order/migrations/0016_purchaseorderattachment.py diff --git a/InvenTree/order/migrations/0016_purchaseorderattachment.py b/InvenTree/order/migrations/0016_purchaseorderattachment.py new file mode 100644 index 0000000000..25b43e222d --- /dev/null +++ b/InvenTree/order/migrations/0016_purchaseorderattachment.py @@ -0,0 +1,27 @@ +# Generated by Django 2.2.9 on 2020-03-22 07:01 + +import InvenTree.models +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0015_auto_20200201_2346'), + ] + + operations = [ + migrations.CreateModel( + name='PurchaseOrderAttachment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('attachment', models.FileField(help_text='Select file to attach', upload_to=InvenTree.models.rename_attachment)), + ('comment', models.CharField(help_text='File comment', max_length=100)), + ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='order.PurchaseOrder')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index b5538c6040..9479dda191 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -14,6 +14,7 @@ from django.utils.translation import ugettext as _ from markdownx.models import MarkdownxField +import os from datetime import datetime from stock.models import StockItem @@ -21,6 +22,7 @@ from company.models import Company, SupplierPart from InvenTree.helpers import decimal2string from InvenTree.status_codes import OrderStatus +from InvenTree.models import InvenTreeAttachment class Order(models.Model): @@ -239,6 +241,17 @@ class PurchaseOrder(Order): self.complete_order() # This will save the model +class PurchaseOrderAttachment(InvenTreeAttachment): + """ + Model for storing file attachments against a PurchaseOrder object + """ + + def getSubdir(self): + return os.path.join("po_files", str(self.order.id)) + + order = models.ForeignKey(PurchaseOrder, on_delete=models.CASCADE, related_name="attachments") + + class OrderLineItem(models.Model): """ Abstract model for an order line item From 56a69434381ef5a992c59d106b952b6311c665e9 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 22 Mar 2020 18:13:34 +1100 Subject: [PATCH 03/12] Add an 'attachment' page for the PurchaseOrder view --- .../order/templates/order/po_attachments.html | 73 +++++++++++++++++++ InvenTree/order/templates/order/tabs.html | 3 + InvenTree/order/urls.py | 1 + InvenTree/part/models.py | 3 + 4 files changed, 80 insertions(+) create mode 100644 InvenTree/order/templates/order/po_attachments.html diff --git a/InvenTree/order/templates/order/po_attachments.html b/InvenTree/order/templates/order/po_attachments.html new file mode 100644 index 0000000000..2e2e696833 --- /dev/null +++ b/InvenTree/order/templates/order/po_attachments.html @@ -0,0 +1,73 @@ +{% extends "order/order_base.html" %} + +{% load inventree_extras %} +{% load i18n %} +{% load static %} + +{% block details %} + +{% include 'order/tabs.html' with tab='attachments' %} + +

{% trans "Purchase Order Attachments" %} + +
+ +
+
+ +
+
+ + + + + + + + + + + {% for attachment in order.attachments.all %} + + + + + + {% endfor %} + +
{% trans "File" %}{% trans "Comment" %}
{{ attachment.basename }}{{ attachment.comment }} +
+ + +
+
+ +{% endblock %} + +{% block js_ready %} +{{ block.super }} + +$("#new-attachment").click(function() { + +}); + +$("#attachment-table").on('click', '.attachment-edit-button', function() { + var button = $(this); + + // TODO +}); + +$("#attachment-table").on('click', '.attachment-delete-button', function() { + var button = $(this); + + // TODO +}); + +$("#attachment-table").inventreeTable({ +}); + +{% endblock %} \ No newline at end of file diff --git a/InvenTree/order/templates/order/tabs.html b/InvenTree/order/templates/order/tabs.html index e673a3271e..f98822c769 100644 --- a/InvenTree/order/templates/order/tabs.html +++ b/InvenTree/order/templates/order/tabs.html @@ -4,6 +4,9 @@ {% trans "Items" %} + + {% trans "Attachments" %} + {% trans "Notes" %}{% if order.notes %} {% endif %} diff --git a/InvenTree/order/urls.py b/InvenTree/order/urls.py index d1d7d7f5f7..e663dacba8 100644 --- a/InvenTree/order/urls.py +++ b/InvenTree/order/urls.py @@ -21,6 +21,7 @@ purchase_order_detail_urls = [ url(r'^notes/', views.PurchaseOrderNotes.as_view(), name='purchase-order-notes'), + url(r'^attachments/', views.PurchaseOrderDetail.as_view(template_name='order/po_attachments.html'), name='purchase-order-attachments'), url(r'^.*$', views.PurchaseOrderDetail.as_view(), name='purchase-order-detail'), ] diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 427cf4dcea..4e579ea44c 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -942,6 +942,9 @@ def attach_file(instance, filename): class PartAttachment(InvenTreeAttachment): + """ + Model for storing file attachments against a Part object + """ def getSubdir(self): return os.path.join("part_files", str(self.part.id)) From 834f80698bb59beb212ac338837a2e1a7643148c Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 22 Mar 2020 18:41:41 +1100 Subject: [PATCH 04/12] Create a new attachment against a PurchaseOrder --- InvenTree/order/forms.py | 14 +++++- .../order/templates/order/po_attachments.html | 6 ++- InvenTree/order/urls.py | 6 +++ InvenTree/order/views.py | 45 ++++++++++++++++++- InvenTree/part/urls.py | 14 +++--- 5 files changed, 75 insertions(+), 10 deletions(-) diff --git a/InvenTree/order/forms.py b/InvenTree/order/forms.py index 97e0f0bdd9..fead5d0496 100644 --- a/InvenTree/order/forms.py +++ b/InvenTree/order/forms.py @@ -13,7 +13,7 @@ from mptt.fields import TreeNodeChoiceField from InvenTree.forms import HelperForm from stock.models import StockLocation -from .models import PurchaseOrder, PurchaseOrderLineItem +from .models import PurchaseOrder, PurchaseOrderLineItem, PurchaseOrderAttachment class IssuePurchaseOrderForm(HelperForm): @@ -74,6 +74,18 @@ class EditPurchaseOrderForm(HelperForm): ] +class EditPurchaseOrderAttachmentForm(HelperForm): + """ Form for editing a PurchaseOrderAttachment object """ + + class Meta: + model = PurchaseOrderAttachment + fields = [ + 'order', + 'attachment', + 'comment' + ] + + class EditPurchaseOrderLineItemForm(HelperForm): """ Form for editing a PurchaseOrderLineItem object """ diff --git a/InvenTree/order/templates/order/po_attachments.html b/InvenTree/order/templates/order/po_attachments.html index 2e2e696833..13dad066df 100644 --- a/InvenTree/order/templates/order/po_attachments.html +++ b/InvenTree/order/templates/order/po_attachments.html @@ -52,7 +52,11 @@ {{ block.super }} $("#new-attachment").click(function() { - + launchModalForm("{% url 'purchase-order-attachment-create' %}?order={{ order.id }}", + { + reload: true, + } + ); }); $("#attachment-table").on('click', '.attachment-edit-button', function() { diff --git a/InvenTree/order/urls.py b/InvenTree/order/urls.py index e663dacba8..8a6613b563 100644 --- a/InvenTree/order/urls.py +++ b/InvenTree/order/urls.py @@ -9,6 +9,10 @@ from django.conf.urls import url, include from . import views +purchase_order_attachment_urls = [ + url(r'^new/', views.PurchaseOrderAttachmentCreate.as_view(), name='purchase-order-attachment-create'), +] + purchase_order_detail_urls = [ url(r'^cancel/?', views.PurchaseOrderCancel.as_view(), name='purchase-order-cancel'), @@ -49,6 +53,8 @@ purchase_order_urls = [ url(r'^line/', include(po_line_urls)), + url(r'^attachments/', include(purchase_order_attachment_urls)), + # Display complete list of purchase orders url(r'^.*$', views.PurchaseOrderIndex.as_view(), name='purchase-order-index'), ] diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index 2b31740bd2..09866f91dc 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -15,7 +15,7 @@ from django.forms import HiddenInput import logging from decimal import Decimal, InvalidOperation -from .models import PurchaseOrder, PurchaseOrderLineItem +from .models import PurchaseOrder, PurchaseOrderLineItem, PurchaseOrderAttachment from .admin import POLineItemResource from build.models import Build from company.models import Company, SupplierPart @@ -70,6 +70,49 @@ class PurchaseOrderDetail(DetailView): return ctx +class PurchaseOrderAttachmentCreate(AjaxCreateView): + """ + View for creating a new PurchaseOrderAtt + """ + + model = PurchaseOrderAttachment + form_class = order_forms.EditPurchaseOrderAttachmentForm + ajax_form_title = _("Add Purchase Order Attachment") + ajax_template_name = "modal_form.html" + + def get_data(self): + return { + "success": _("Added attachment") + } + + def get_initial(self): + """ + Get initial data for creating a new PurchaseOrderAttachment object. + + - Client must request this form with a parent PurchaseOrder in midn. + - e.g. ?order= + """ + + initials = super(AjaxCreateView, self).get_initial() + + initials["order"] = PurchaseOrder.objects.get(id=self.request.GET.get('order', -1)) + + return initials + + def get_form(self): + """ + Create a form to upload a new PurchaseOrderAttachment + + - Hide the 'order' field + """ + + form = super(AjaxCreateView, self).get_form() + + form.fields['order'].widget = HiddenInput() + + return form + + class PurchaseOrderNotes(UpdateView): """ View for updating the 'notes' field of a PurchaseOrder """ diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index 36be170bcb..0d376f8e5b 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -13,20 +13,20 @@ from django.conf.urls import url, include from . import views part_attachment_urls = [ - url('^new/?', views.PartAttachmentCreate.as_view(), name='part-attachment-create'), + url(r'^new/?', views.PartAttachmentCreate.as_view(), name='part-attachment-create'), url(r'^(?P\d+)/edit/?', views.PartAttachmentEdit.as_view(), name='part-attachment-edit'), url(r'^(?P\d+)/delete/?', views.PartAttachmentDelete.as_view(), name='part-attachment-delete'), ] part_parameter_urls = [ - url('^template/new/', views.PartParameterTemplateCreate.as_view(), name='part-param-template-create'), - url('^template/(?P\d+)/edit/', views.PartParameterTemplateEdit.as_view(), name='part-param-template-edit'), - url('^template/(?P\d+)/delete/', views.PartParameterTemplateDelete.as_view(), name='part-param-template-edit'), + url(r'^template/new/', views.PartParameterTemplateCreate.as_view(), name='part-param-template-create'), + url(r'^template/(?P\d+)/edit/', views.PartParameterTemplateEdit.as_view(), name='part-param-template-edit'), + url(r'^template/(?P\d+)/delete/', views.PartParameterTemplateDelete.as_view(), name='part-param-template-edit'), - url('^new/', views.PartParameterCreate.as_view(), name='part-param-create'), - url('^(?P\d+)/edit/', views.PartParameterEdit.as_view(), name='part-param-edit'), - url('^(?P\d+)/delete/', views.PartParameterDelete.as_view(), name='part-param-delete'), + url(r'^new/', views.PartParameterCreate.as_view(), name='part-param-create'), + url(r'^(?P\d+)/edit/', views.PartParameterEdit.as_view(), name='part-param-edit'), + url(r'^(?P\d+)/delete/', views.PartParameterDelete.as_view(), name='part-param-delete'), ] From 5af2fae1207770223e47e67b558c47e5d07590e0 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 22 Mar 2020 19:47:08 +1100 Subject: [PATCH 05/12] Simplify URLs for purchase orders --- .../templates/company/company_base.html | 2 +- .../company/detail_purchase_orders.html | 2 +- .../order/templates/order/order_base.html | 6 ++--- .../order/templates/order/order_notes.html | 2 +- .../order/templates/order/po_attachments.html | 2 +- InvenTree/order/templates/order/po_table.html | 2 +- .../order/purchase_order_detail.html | 8 +++--- .../templates/order/purchase_orders.html | 4 +-- InvenTree/order/templates/order/tabs.html | 6 ++--- InvenTree/order/urls.py | 25 ++++++++++--------- .../stock/templates/stock/item_base.html | 2 +- InvenTree/templates/navbar.html | 2 +- 12 files changed, 32 insertions(+), 31 deletions(-) diff --git a/InvenTree/company/templates/company/company_base.html b/InvenTree/company/templates/company/company_base.html index 1080f01445..9e849e5a47 100644 --- a/InvenTree/company/templates/company/company_base.html +++ b/InvenTree/company/templates/company/company_base.html @@ -100,7 +100,7 @@ InvenTree | {% trans "Company" %} - {{ company.name }} }); $("#company-order-2").click(function() { - launchModalForm("{% url 'purchase-order-create' %}", + launchModalForm("{% url 'po-create' %}", { data: { supplier: {{ company.id }}, diff --git a/InvenTree/company/templates/company/detail_purchase_orders.html b/InvenTree/company/templates/company/detail_purchase_orders.html index fcba26e2af..c3878eec6d 100644 --- a/InvenTree/company/templates/company/detail_purchase_orders.html +++ b/InvenTree/company/templates/company/detail_purchase_orders.html @@ -28,7 +28,7 @@ function newOrder() { - launchModalForm("{% url 'purchase-order-create' %}", + launchModalForm("{% url 'po-create' %}", { data: { supplier: {{ company.id }}, diff --git a/InvenTree/order/templates/order/order_base.html b/InvenTree/order/templates/order/order_base.html index 2cefeb6465..80a33fbfa8 100644 --- a/InvenTree/order/templates/order/order_base.html +++ b/InvenTree/order/templates/order/order_base.html @@ -107,7 +107,7 @@ InvenTree | {{ order }} {% if order.status == OrderStatus.PENDING and order.lines.count > 0 %} $("#place-order").click(function() { - launchModalForm("{% url 'purchase-order-issue' order.id %}", + launchModalForm("{% url 'po-issue' order.id %}", { reload: true, }); @@ -115,7 +115,7 @@ $("#place-order").click(function() { {% endif %} $("#edit-order").click(function() { - launchModalForm("{% url 'purchase-order-edit' order.id %}", + launchModalForm("{% url 'po-edit' order.id %}", { reload: true, } @@ -123,7 +123,7 @@ $("#edit-order").click(function() { }); $("#cancel-order").click(function() { - launchModalForm("{% url 'purchase-order-cancel' order.id %}", { + launchModalForm("{% url 'po-cancel' order.id %}", { reload: true, }); }); diff --git a/InvenTree/order/templates/order/order_notes.html b/InvenTree/order/templates/order/order_notes.html index 9077108510..de4f18ba6b 100644 --- a/InvenTree/order/templates/order/order_notes.html +++ b/InvenTree/order/templates/order/order_notes.html @@ -50,7 +50,7 @@ {% if editing %} {% else %} $("#edit-notes").click(function() { - location.href = "{% url 'purchase-order-notes' order.id %}?edit=1"; + location.href = "{% url 'po-notes' order.id %}?edit=1"; }); {% endif %} diff --git a/InvenTree/order/templates/order/po_attachments.html b/InvenTree/order/templates/order/po_attachments.html index 13dad066df..4ba54a9c91 100644 --- a/InvenTree/order/templates/order/po_attachments.html +++ b/InvenTree/order/templates/order/po_attachments.html @@ -52,7 +52,7 @@ {{ block.super }} $("#new-attachment").click(function() { - launchModalForm("{% url 'purchase-order-attachment-create' %}?order={{ order.id }}", + launchModalForm("{% url 'po-attachment-create' %}?order={{ order.id }}", { reload: true, } diff --git a/InvenTree/order/templates/order/po_table.html b/InvenTree/order/templates/order/po_table.html index 0fe41e8efa..712553e866 100644 --- a/InvenTree/order/templates/order/po_table.html +++ b/InvenTree/order/templates/order/po_table.html @@ -12,7 +12,7 @@ {% for order in orders %} {% include "hover_image.html" with image=order.supplier.image hover=True %}{{ order.supplier.name }} - {{ order }} + {{ order }} {{ order.description }} {% include "order/order_status.html" %} {{ order.lines.count }} diff --git a/InvenTree/order/templates/order/purchase_order_detail.html b/InvenTree/order/templates/order/purchase_order_detail.html index 15bc55a3d8..d2930cb8d1 100644 --- a/InvenTree/order/templates/order/purchase_order_detail.html +++ b/InvenTree/order/templates/order/purchase_order_detail.html @@ -92,7 +92,7 @@ $("#po-lines-table").on('click', ".line-receive", function() { console.log('clicked! ' + button.attr('pk')); - launchModalForm("{% url 'purchase-order-receive' order.id %}", { + launchModalForm("{% url 'po-receive' order.id %}", { reload: true, data: { line: button.attr('pk') @@ -109,7 +109,7 @@ $("#po-lines-table").on('click', ".line-receive", function() { }); $("#receive-order").click(function() { - launchModalForm("{% url 'purchase-order-receive' order.id %}", { + launchModalForm("{% url 'po-receive' order.id %}", { reload: true, secondary: [ { @@ -123,13 +123,13 @@ $("#receive-order").click(function() { }); $("#complete-order").click(function() { - launchModalForm("{% url 'purchase-order-complete' order.id %}", { + launchModalForm("{% url 'po-complete' order.id %}", { reload: true, }); }); $("#export-order").click(function() { - location.href = "{% url 'purchase-order-export' order.id %}"; + location.href = "{% url 'po-export' order.id %}"; }); {% if order.status == OrderStatus.PENDING %} diff --git a/InvenTree/order/templates/order/purchase_orders.html b/InvenTree/order/templates/order/purchase_orders.html index 17f3115c75..644e6418fa 100644 --- a/InvenTree/order/templates/order/purchase_orders.html +++ b/InvenTree/order/templates/order/purchase_orders.html @@ -18,7 +18,7 @@ InvenTree | Purchase Orders - +
{% endblock %} @@ -27,7 +27,7 @@ InvenTree | Purchase Orders {{ block.super }} $("#po-create").click(function() { - launchModalForm("{% url 'purchase-order-create' %}", + launchModalForm("{% url 'po-create' %}", { follow: true, } diff --git a/InvenTree/order/templates/order/tabs.html b/InvenTree/order/templates/order/tabs.html index f98822c769..f15acdd2b0 100644 --- a/InvenTree/order/templates/order/tabs.html +++ b/InvenTree/order/templates/order/tabs.html @@ -2,12 +2,12 @@ diff --git a/InvenTree/order/urls.py b/InvenTree/order/urls.py index 8a6613b563..c7fbc1e890 100644 --- a/InvenTree/order/urls.py +++ b/InvenTree/order/urls.py @@ -10,23 +10,24 @@ from django.conf.urls import url, include from . import views purchase_order_attachment_urls = [ - url(r'^new/', views.PurchaseOrderAttachmentCreate.as_view(), name='purchase-order-attachment-create'), + url(r'^new/', views.PurchaseOrderAttachmentCreate.as_view(), name='po-attachment-create'), + #url(r'^(?P\d+)/edit/', views.PurchaseOrderAttachmentEdit.as_view(), name='po-attachment-edit'), ] purchase_order_detail_urls = [ - url(r'^cancel/?', views.PurchaseOrderCancel.as_view(), name='purchase-order-cancel'), - url(r'^edit/?', views.PurchaseOrderEdit.as_view(), name='purchase-order-edit'), - url(r'^issue/?', views.PurchaseOrderIssue.as_view(), name='purchase-order-issue'), - url(r'^receive/?', views.PurchaseOrderReceive.as_view(), name='purchase-order-receive'), - url(r'^complete/?', views.PurchaseOrderComplete.as_view(), name='purchase-order-complete'), + url(r'^cancel/?', views.PurchaseOrderCancel.as_view(), name='po-cancel'), + url(r'^edit/?', views.PurchaseOrderEdit.as_view(), name='po-edit'), + url(r'^issue/?', views.PurchaseOrderIssue.as_view(), name='po-issue'), + url(r'^receive/?', views.PurchaseOrderReceive.as_view(), name='po-receive'), + url(r'^complete/?', views.PurchaseOrderComplete.as_view(), name='po-complete'), - url(r'^export/?', views.PurchaseOrderExport.as_view(), name='purchase-order-export'), + url(r'^export/?', views.PurchaseOrderExport.as_view(), name='po-export'), - url(r'^notes/', views.PurchaseOrderNotes.as_view(), name='purchase-order-notes'), + url(r'^notes/', views.PurchaseOrderNotes.as_view(), name='po-notes'), - url(r'^attachments/', views.PurchaseOrderDetail.as_view(template_name='order/po_attachments.html'), name='purchase-order-attachments'), - url(r'^.*$', views.PurchaseOrderDetail.as_view(), name='purchase-order-detail'), + url(r'^attachments/', views.PurchaseOrderDetail.as_view(template_name='order/po_attachments.html'), name='po-attachments'), + url(r'^.*$', views.PurchaseOrderDetail.as_view(), name='po-detail'), ] po_line_item_detail_urls = [ @@ -44,7 +45,7 @@ po_line_urls = [ purchase_order_urls = [ - url(r'^new/', views.PurchaseOrderCreate.as_view(), name='purchase-order-create'), + url(r'^new/', views.PurchaseOrderCreate.as_view(), name='po-create'), url(r'^order-parts/', views.OrderParts.as_view(), name='order-parts'), @@ -56,7 +57,7 @@ purchase_order_urls = [ url(r'^attachments/', include(purchase_order_attachment_urls)), # Display complete list of purchase orders - url(r'^.*$', views.PurchaseOrderIndex.as_view(), name='purchase-order-index'), + url(r'^.*$', views.PurchaseOrderIndex.as_view(), name='po-index'), ] order_urls = [ diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index 3e398ba16a..3f5fdca9ad 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -117,7 +117,7 @@ {% if item.purchase_order %} {% trans "Purchase Order" %} - {{ item.purchase_order }} + {{ item.purchase_order }} {% endif %} {% if item.customer %} diff --git a/InvenTree/templates/navbar.html b/InvenTree/templates/navbar.html index 691b73f982..c7e5a574e3 100644 --- a/InvenTree/templates/navbar.html +++ b/InvenTree/templates/navbar.html @@ -11,7 +11,7 @@
  • {% trans "Stock" %}
  • {% trans "Build" %}
  • {% trans "Suppliers" %}
  • -
  • {% trans "Orders" %}
  • +
  • {% trans "Orders" %}