diff --git a/InvenTree/InvenTree/status_codes.py b/InvenTree/InvenTree/status_codes.py new file mode 100644 index 0000000000..061d0da99e --- /dev/null +++ b/InvenTree/InvenTree/status_codes.py @@ -0,0 +1,28 @@ +from django.utils.translation import ugettext as _ + + +class StatusCode: + + @classmethod + def items(cls): + return cls.options.items() + + +class OrderStatus(StatusCode): + + # Order status codes + PENDING = 10 # Order is pending (not yet placed) + PLACED = 20 # Order has been placed + COMPLETE = 30 # Order has been completed + CANCELLED = 40 # Order was cancelled + LOST = 50 # Order was lost + RETURNED = 60 # Order was returned + + options = { + PENDING: _("Pending"), + PLACED: _("Placed"), + COMPLETE: _("Complete"), + CANCELLED: _("Cancelled"), + LOST: _("Lost"), + RETURNED: _("Returned"), + } diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index 245264900d..de8d2d0458 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -17,6 +17,8 @@ from django.urls import reverse from django.conf import settings from django.contrib.staticfiles.templatetags.staticfiles import static +from InvenTree.status_codes import OrderStatus + def rename_company_image(instance, filename): """ Function to rename a company image after upload @@ -128,6 +130,26 @@ class Company(models.Model): stock = apps.get_model('stock', 'StockItem') return stock.objects.filter(supplier_part__supplier=self.id).count() + def outstanding_purchase_orders(self): + """ Return purchase orders which are 'outstanding' """ + return self.purchase_orders.filter(status__in=[ + OrderStatus.PENDING, + OrderStatus.PLACED + ]) + + def complete_purchase_orders(self): + return self.purchase_orders.filter(status=OrderStatus.COMPLETE) + + def failed_purchase_orders(self): + """ Return any purchase orders which were not successful """ + + return self.purchase_orders.filter(status__in=[ + OrderStatus.CANCELLED, + OrderStatus.LOST, + OrderStatus.RETURNED + ]) + + class Contact(models.Model): """ A Contact represents a person who works at a particular company. diff --git a/InvenTree/company/templates/company/detail.html b/InvenTree/company/templates/company/detail.html index 8e26d85a89..fa40913f98 100644 --- a/InvenTree/company/templates/company/detail.html +++ b/InvenTree/company/templates/company/detail.html @@ -6,7 +6,7 @@
-

Company Details

+

Company Details

diff --git a/InvenTree/company/templates/company/detail_part.html b/InvenTree/company/templates/company/detail_part.html index ec6f80c652..5e0a28541c 100644 --- a/InvenTree/company/templates/company/detail_part.html +++ b/InvenTree/company/templates/company/detail_part.html @@ -4,7 +4,7 @@ {% include 'company/tabs.html' with tab='parts' %} -

Supplier Parts

+

Supplier Parts

diff --git a/InvenTree/company/templates/company/detail_purchase_orders.html b/InvenTree/company/templates/company/detail_purchase_orders.html index f7e3c6c5f9..28d7becd1a 100644 --- a/InvenTree/company/templates/company/detail_purchase_orders.html +++ b/InvenTree/company/templates/company/detail_purchase_orders.html @@ -4,4 +4,17 @@ {% include 'company/tabs.html' with tab='po' %} +

Purchase Orders

+ + + + + + + + {% include "company/po_list.html" with orders=company.outstanding_purchase_orders %} + {% include "company/po_list.html" with orders=company.complete_purchase_orders %} + {% include "company/po_list.html" with orders=company.failed_purchase_orders %} +
ReferenceDescriptionStatus
+ {% endblock %} \ No newline at end of file diff --git a/InvenTree/company/templates/company/detail_stock.html b/InvenTree/company/templates/company/detail_stock.html index b3682043dd..108342b2b1 100644 --- a/InvenTree/company/templates/company/detail_stock.html +++ b/InvenTree/company/templates/company/detail_stock.html @@ -5,7 +5,7 @@ {% include "company/tabs.html" with tab='stock' %} -

Supplier Stock

+

Supplier Stock

{% include "stock_table.html" %} diff --git a/InvenTree/company/templates/company/po_list.html b/InvenTree/company/templates/company/po_list.html new file mode 100644 index 0000000000..8b4204996f --- /dev/null +++ b/InvenTree/company/templates/company/po_list.html @@ -0,0 +1,7 @@ +{% for order in orders %} + + {{ order }} + {{ order.description }} + {% include "order/order_status.html" with order=order %} + +{% endfor %} \ No newline at end of file diff --git a/InvenTree/order/admin.py b/InvenTree/order/admin.py index 18f1dd32f8..0ea5e8c599 100644 --- a/InvenTree/order/admin.py +++ b/InvenTree/order/admin.py @@ -12,6 +12,7 @@ class PurchaseOrderAdmin(admin.ModelAdmin): list_display = ( 'reference', 'supplier', + 'status', 'description', 'creation_date' ) diff --git a/InvenTree/order/migrations/0004_purchaseorder_status.py b/InvenTree/order/migrations/0004_purchaseorder_status.py new file mode 100644 index 0000000000..d1ad90eb38 --- /dev/null +++ b/InvenTree/order/migrations/0004_purchaseorder_status.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2 on 2019-06-04 12:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0003_auto_20190604_2226'), + ] + + operations = [ + migrations.AddField( + model_name='purchaseorder', + name='status', + field=models.PositiveIntegerField(choices=[(10, 'Pending'), (20, 'Placed'), (30, 'Complete'), (40, 'Cancelled'), (50, 'Lost'), (60, 'Returned')], default=10, help_text='Order status'), + ), + ] diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index d4bc6627b1..4679f02eea 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -8,6 +8,8 @@ from part.models import Part from company.models import Company from stock.models import StockItem +from InvenTree.status_codes import OrderStatus + class Order(models.Model): """ Abstract model for an order. @@ -26,13 +28,17 @@ class Order(models.Model): """ - # Order status codes - PENDING = 10 # Order is pending (not yet placed) - PLACED = 20 # Order has been placed - RECEIVED = 30 # Order has been received - CANCELLED = 40 # Order was cancelled - LOST = 50 # Order was lost - RETURNED = 60 # Order was returned + ORDER_PREFIX = "" + + def __str__(self): + el = [] + + if self.ORDER_PREFIX: + el.append(self.ORDER_PREFIX) + + el.append(self.reference) + + return " ".join(el) class Meta: abstract = True @@ -45,6 +51,9 @@ class Order(models.Model): creation_date = models.DateField(auto_now=True, editable=False) + status = models.PositiveIntegerField(default=OrderStatus.PENDING, choices=OrderStatus.items(), + help_text='Order status') + created_by = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True, @@ -64,6 +73,8 @@ class PurchaseOrder(Order): """ + ORDER_PREFIX = "PO" + supplier = models.ForeignKey(Company, on_delete=models.CASCADE, limit_choices_to={ 'is_supplier': True, diff --git a/InvenTree/company/templates/company/order_status.html b/InvenTree/order/templates/order/order_status.html similarity index 70% rename from InvenTree/company/templates/company/order_status.html rename to InvenTree/order/templates/order/order_status.html index 49ccc7f170..46359e562d 100644 --- a/InvenTree/company/templates/company/order_status.html +++ b/InvenTree/order/templates/order/order_status.html @@ -2,9 +2,9 @@ {% elif order.status == order.PLACED %} -{% elif order.status == order.RECEIVED %} +{% elif order.status == order.COMPLETE %} -{% elif order.status == order.CANCELLED %} +{% elif order.status == order.CANCELLED or order.status == order.RETURNED %} {% else %}