mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Markdownify the notes field for PurchaseOrder
- Update model field - Create tab view for PO page - Add 'notes' tab
This commit is contained in:
parent
a7846940c4
commit
7ec194a14a
19
InvenTree/order/migrations/0015_auto_20200201_2346.py
Normal file
19
InvenTree/order/migrations/0015_auto_20200201_2346.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 2.2.9 on 2020-02-01 23:46
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
import markdownx.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('order', '0014_auto_20191118_2328'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='purchaseorder',
|
||||||
|
name='notes',
|
||||||
|
field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes'),
|
||||||
|
),
|
||||||
|
]
|
@ -12,6 +12,8 @@ from django.contrib.auth.models import User
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
from markdownx.models import MarkdownxField
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from stock.models import StockItem
|
from stock.models import StockItem
|
||||||
@ -81,7 +83,7 @@ class Order(models.Model):
|
|||||||
|
|
||||||
complete_date = models.DateField(blank=True, null=True)
|
complete_date = models.DateField(blank=True, null=True)
|
||||||
|
|
||||||
notes = models.TextField(blank=True, help_text=_('Order notes'))
|
notes = MarkdownxField(blank=True, help_text=_('Order notes'))
|
||||||
|
|
||||||
def place_order(self):
|
def place_order(self):
|
||||||
""" Marks the order as PLACED. Order must be currently PENDING. """
|
""" Marks the order as PLACED. Order must be currently PENDING. """
|
||||||
|
132
InvenTree/order/templates/order/order_base.html
Normal file
132
InvenTree/order/templates/order/order_base.html
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% load i18n %}
|
||||||
|
{% load static %}
|
||||||
|
{% load inventree_extras %}
|
||||||
|
|
||||||
|
{% block page_title %}
|
||||||
|
InvenTree | {{ order }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class='row'>
|
||||||
|
<div class='col-sm-6'>
|
||||||
|
<div class='media'>
|
||||||
|
<div class='media-left'>
|
||||||
|
<img class='part-thumb'
|
||||||
|
{% if order.supplier.image %}
|
||||||
|
src="{{ order.supplier.image.url }}"
|
||||||
|
{% else %}
|
||||||
|
src="{% static 'img/blank_image.png' %}"
|
||||||
|
{% endif %}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class='media-body'>
|
||||||
|
<h4>{{ order }}</h4>
|
||||||
|
<p>{{ order.description }}</p>
|
||||||
|
{% if order.URL %}
|
||||||
|
<a href="{{ order.URL }}">{{ order.URL }}</a>
|
||||||
|
{% endif %}
|
||||||
|
<p>
|
||||||
|
<div class='btn-row'>
|
||||||
|
<div class='btn-group'>
|
||||||
|
<button type='button' class='btn btn-default btn-glyph' id='edit-order' title='Edit order information'>
|
||||||
|
<span class='glyphicon glyphicon-edit'></span>
|
||||||
|
</button>
|
||||||
|
<button type='button' class='btn btn-default btn-glyph' id='export-order' title='Export order to file'>
|
||||||
|
<span class='glyphicon glyphicon-download-alt'></span>
|
||||||
|
</button>
|
||||||
|
{% if order.status == OrderStatus.PENDING and order.lines.count > 0 %}
|
||||||
|
<button type='button' class='btn btn-default btn-glyph' id='place-order' title='Place order'>
|
||||||
|
<span class='glyphicon glyphicon-send'></span>
|
||||||
|
</button>
|
||||||
|
{% elif order.status == OrderStatus.PLACED %}
|
||||||
|
<button type='button' class='btn btn-default btn-glyph' id='receive-order' title='Receive items'>
|
||||||
|
<span class='glyphicon glyphicon-check'></span>
|
||||||
|
</button>
|
||||||
|
<button type='button' class='btn btn-default btn-glyph' id='complete-order' title='Mark order as complete'>
|
||||||
|
<span class='glyphicon glyphicon-ok'></span>
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
{% if order.status == OrderStatus.PENDING or order.status == OrderStatus.PLACED %}
|
||||||
|
<button type='button' class='btn btn-default btn-glyph' id='cancel-order' title='Cancel order'>
|
||||||
|
<span class='glyphicon glyphicon-remove'></span>
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='col-sm-6'>
|
||||||
|
<h4>{% trans "Purchase Order Details" %}</h4>
|
||||||
|
<table class='table'>
|
||||||
|
<tr>
|
||||||
|
<td>{% trans "Supplier" %}</td>
|
||||||
|
<td><a href="{% url 'company-detail' order.supplier.id %}">{{ order.supplier }}</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{% trans "Status" %}</td>
|
||||||
|
<td>{% include "order/order_status.html" %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{% trans "Created" %}</td>
|
||||||
|
<td>{{ order.creation_date }}<span class='badge'>{{ order.created_by }}</span></td>
|
||||||
|
</tr>
|
||||||
|
{% if order.issue_date %}
|
||||||
|
<tr>
|
||||||
|
<td>{% trans "Issued" %}</td>
|
||||||
|
<td>{{ order.issue_date }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% if order.status == OrderStatus.COMPLETE %}
|
||||||
|
<tr>
|
||||||
|
<td>{% trans "Received" %}</td>
|
||||||
|
<td>{{ order.complete_date }}<span class='badge'>{{ order.received_by }}</span></td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<div class='container-fluid'>
|
||||||
|
{% block details %}
|
||||||
|
|
||||||
|
<!-- Specific order details to go here -->
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js_ready %}
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
{% if order.status == OrderStatus.PENDING and order.lines.count > 0 %}
|
||||||
|
$("#place-order").click(function() {
|
||||||
|
launchModalForm("{% url 'purchase-order-issue' order.id %}",
|
||||||
|
{
|
||||||
|
reload: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
$("#edit-order").click(function() {
|
||||||
|
launchModalForm("{% url 'purchase-order-edit' order.id %}",
|
||||||
|
{
|
||||||
|
reload: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#cancel-order").click(function() {
|
||||||
|
launchModalForm("{% url 'purchase-order-cancel' order.id %}", {
|
||||||
|
reload: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
57
InvenTree/order/templates/order/order_notes.html
Normal file
57
InvenTree/order/templates/order/order_notes.html
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
{% extends "order/order_base.html" %}
|
||||||
|
|
||||||
|
{% load inventree_extras %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load static %}
|
||||||
|
{% load markdownify %}
|
||||||
|
|
||||||
|
{% block details %}
|
||||||
|
|
||||||
|
{% include 'order/tabs.html' with tab='notes' %}
|
||||||
|
|
||||||
|
{% if editing %}
|
||||||
|
<h4>{% trans "Order Notes" %}</h4>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<form method='POST'>
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
{{ form }}
|
||||||
|
<hr>
|
||||||
|
<input type='submit' value='{% trans "Save" %}'/>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{{ form.media }}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<div class='row'>
|
||||||
|
<div class='col-sm-6'>
|
||||||
|
<h4>{% trans "Order Notes" %}</h4>
|
||||||
|
</div>
|
||||||
|
<div class='col-sm-6'>
|
||||||
|
<button title='{% trans "Edit notes" %}' class='btn btn-default btn-glyph float-right' id='edit-notes'><span class='glyphicon glyphicon-edit'></span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class='panel panel-default'>
|
||||||
|
<div class='panel-content'>
|
||||||
|
{{ order.notes | markdownify }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js_ready %}
|
||||||
|
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
{% if editing %}
|
||||||
|
{% else %}
|
||||||
|
$("#edit-notes").click(function() {
|
||||||
|
location.href = "{% url 'purchase-order-notes' order.id %}?edit=1";
|
||||||
|
});
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -1,104 +1,22 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "order/order_base.html" %}
|
||||||
|
|
||||||
|
{% load inventree_extras %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load inventree_extras %}
|
|
||||||
|
|
||||||
{% block page_title %}
|
{% block details %}
|
||||||
InvenTree | {{ order }}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% include 'order/tabs.html' with tab='details' %}
|
||||||
<div class='row'>
|
|
||||||
<div class='col-sm-6'>
|
|
||||||
<div class='media'>
|
|
||||||
<div class='media-left'>
|
|
||||||
<img class='part-thumb'
|
|
||||||
{% if order.supplier.image %}
|
|
||||||
src="{{ order.supplier.image.url }}"
|
|
||||||
{% else %}
|
|
||||||
src="{% static 'img/blank_image.png' %}"
|
|
||||||
{% endif %}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class='media-body'>
|
|
||||||
<h4>{{ order }}</h4>
|
|
||||||
<p>{{ order.description }}</p>
|
|
||||||
{% if order.URL %}
|
|
||||||
<a href="{{ order.URL }}">{{ order.URL }}</a>
|
|
||||||
{% endif %}
|
|
||||||
<p>
|
|
||||||
<div class='btn-row'>
|
|
||||||
<div class='btn-group'>
|
|
||||||
<button type='button' class='btn btn-default btn-glyph' id='edit-order' title='Edit order information'>
|
|
||||||
<span class='glyphicon glyphicon-edit'></span>
|
|
||||||
</button>
|
|
||||||
<button type='button' class='btn btn-default btn-glyph' id='export-order' title='Export order to file'>
|
|
||||||
<span class='glyphicon glyphicon-download-alt'></span>
|
|
||||||
</button>
|
|
||||||
{% if order.status == OrderStatus.PENDING and order.lines.count > 0 %}
|
|
||||||
<button type='button' class='btn btn-default btn-glyph' id='place-order' title='Place order'>
|
|
||||||
<span class='glyphicon glyphicon-send'></span>
|
|
||||||
</button>
|
|
||||||
{% elif order.status == OrderStatus.PLACED %}
|
|
||||||
<button type='button' class='btn btn-default btn-glyph' id='receive-order' title='Receive items'>
|
|
||||||
<span class='glyphicon glyphicon-check'></span>
|
|
||||||
</button>
|
|
||||||
<button type='button' class='btn btn-default btn-glyph' id='complete-order' title='Mark order as complete'>
|
|
||||||
<span class='glyphicon glyphicon-ok'></span>
|
|
||||||
</button>
|
|
||||||
{% endif %}
|
|
||||||
{% if order.status == OrderStatus.PENDING or order.status == OrderStatus.PLACED %}
|
|
||||||
<button type='button' class='btn btn-default btn-glyph' id='cancel-order' title='Cancel order'>
|
|
||||||
<span class='glyphicon glyphicon-remove'></span>
|
|
||||||
</button>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='col-sm-6'>
|
|
||||||
<h4>{% trans "Purchase Order Details" %}</h4>
|
|
||||||
<table class='table'>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans "Supplier" %}</td>
|
|
||||||
<td><a href="{% url 'company-detail' order.supplier.id %}">{{ order.supplier }}</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans "Status" %}</td>
|
|
||||||
<td>{% include "order/order_status.html" %}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans "Created" %}</td>
|
|
||||||
<td>{{ order.creation_date }}<span class='badge'>{{ order.created_by }}</span></td>
|
|
||||||
</tr>
|
|
||||||
{% if order.issue_date %}
|
|
||||||
<tr>
|
|
||||||
<td>{% trans "Issued" %}</td>
|
|
||||||
<td>{{ order.issue_date }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% if order.status == OrderStatus.COMPLETE %}
|
|
||||||
<tr>
|
|
||||||
<td>{% trans "Received" %}</td>
|
|
||||||
<td>{{ order.complete_date }}<span class='badge'>{{ order.received_by }}</span></td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
|
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
|
||||||
{% if order.status == OrderStatus.PENDING %}
|
{% if order.status == OrderStatus.PENDING %}
|
||||||
<button type='button' class='btn btn-default' id='new-po-line'>Add Line Item</button>
|
<button type='button' class='btn btn-default' id='new-po-line'>{% trans "Add Line Item" %}</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h4>Order Items</h4>
|
<h4>{% trans "Order Items" %}</h4>
|
||||||
|
|
||||||
<table class='table table-striped table-condensed' id='po-lines-table' data-toolbar='#order-toolbar-buttons'>
|
<table class='table table-striped table-condensed' id='po-lines-table' data-toolbar='#order-toolbar-buttons'>
|
||||||
<thead>
|
<thead>
|
||||||
@ -162,40 +80,11 @@ InvenTree | {{ order }}
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
{% if order.notes %}
|
|
||||||
<hr>
|
|
||||||
<div class='panel panel-default'>
|
|
||||||
<div class='panel-heading'><b>{% trans "Notes" %}</b></div>
|
|
||||||
<div class='panel-body'>{{ order.notes }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block js_ready %}
|
{% block js_ready %}
|
||||||
|
|
||||||
{% if order.status == OrderStatus.PENDING and order.lines.count > 0 %}
|
{{ block.super }}
|
||||||
$("#place-order").click(function() {
|
|
||||||
launchModalForm("{% url 'purchase-order-issue' order.id %}",
|
|
||||||
{
|
|
||||||
reload: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
$("#edit-order").click(function() {
|
|
||||||
launchModalForm("{% url 'purchase-order-edit' order.id %}",
|
|
||||||
{
|
|
||||||
reload: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#cancel-order").click(function() {
|
|
||||||
launchModalForm("{% url 'purchase-order-cancel' order.id %}", {
|
|
||||||
reload: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#po-lines-table").on('click', ".line-receive", function() {
|
$("#po-lines-table").on('click', ".line-receive", function() {
|
||||||
|
|
||||||
|
10
InvenTree/order/templates/order/tabs.html
Normal file
10
InvenTree/order/templates/order/tabs.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
<ul class='nav nav-tabs'>
|
||||||
|
<li{% ifequal tab 'details' %} class='active'{% endifequal %}>
|
||||||
|
<a href="{% url 'purchase-order-detail' order.id %}">{% trans "Items" %}</a>
|
||||||
|
</li>
|
||||||
|
<li{% ifequal tab 'notes' %} class='active'{% endifequal %}>
|
||||||
|
<a href="{% url 'purchase-order-notes' order.id %}">{% trans "Notes" %}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
@ -19,6 +19,8 @@ purchase_order_detail_urls = [
|
|||||||
|
|
||||||
url(r'^export/?', views.PurchaseOrderExport.as_view(), name='purchase-order-export'),
|
url(r'^export/?', views.PurchaseOrderExport.as_view(), name='purchase-order-export'),
|
||||||
|
|
||||||
|
url(r'^notes/', views.PurchaseOrderNotes.as_view(), name='purchase-order-notes'),
|
||||||
|
|
||||||
url(r'^.*$', views.PurchaseOrderDetail.as_view(), name='purchase-order-detail'),
|
url(r'^.*$', views.PurchaseOrderDetail.as_view(), name='purchase-order-detail'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -7,8 +7,9 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
|
from django.urls import reverse
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.views.generic import DetailView, ListView
|
from django.views.generic import DetailView, ListView, UpdateView
|
||||||
from django.forms import HiddenInput
|
from django.forms import HiddenInput
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@ -69,6 +70,28 @@ class PurchaseOrderDetail(DetailView):
|
|||||||
return ctx
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
|
class PurchaseOrderNotes(UpdateView):
|
||||||
|
""" View for updating the 'notes' field of a PurchaseOrder """
|
||||||
|
|
||||||
|
context_object_name = 'order'
|
||||||
|
template_name = 'order/order_notes.html'
|
||||||
|
model = PurchaseOrder
|
||||||
|
|
||||||
|
fields = ['notes']
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
|
||||||
|
return reverse('purchase-order-notes', kwargs={'pk': self.get_object().id})
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
|
||||||
|
ctx = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
ctx['editing'] = str2bool(self.request.GET.get('edit', ''))
|
||||||
|
|
||||||
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
class PurchaseOrderCreate(AjaxCreateView):
|
class PurchaseOrderCreate(AjaxCreateView):
|
||||||
""" View for creating a new PurchaseOrder object using a modal form """
|
""" View for creating a new PurchaseOrder object using a modal form """
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user