Markdownify the notes field for PurchaseOrder

- Update model field
- Create tab view for PO page
- Add 'notes' tab
This commit is contained in:
Oliver Walters 2020-02-02 11:44:44 +11:00
parent a7846940c4
commit 7ec194a14a
8 changed files with 254 additions and 120 deletions

View 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'),
),
]

View File

@ -12,6 +12,8 @@ from django.contrib.auth.models import User
from django.urls import reverse
from django.utils.translation import ugettext as _
from markdownx.models import MarkdownxField
from datetime import datetime
from stock.models import StockItem
@ -81,7 +83,7 @@ class Order(models.Model):
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):
""" Marks the order as PLACED. Order must be currently PENDING. """

View 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 %}

View 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 %}

View File

@ -1,104 +1,22 @@
{% extends "base.html" %}
{% extends "order/order_base.html" %}
{% load inventree_extras %}
{% load i18n %}
{% load static %}
{% load inventree_extras %}
{% block page_title %}
InvenTree | {{ order }}
{% endblock %}
{% block details %}
{% 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>
{% include 'order/tabs.html' with tab='details' %}
<hr>
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
{% 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 %}
</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'>
<thead>
@ -162,40 +80,11 @@ InvenTree | {{ order }}
</tbody>
</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 %}
{% block js_ready %}
{% 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,
});
});
{{ block.super }}
$("#po-lines-table").on('click', ".line-receive", function() {

View 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>

View File

@ -19,6 +19,8 @@ purchase_order_detail_urls = [
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'),
]

View File

@ -7,8 +7,9 @@ from __future__ import unicode_literals
from django.db import transaction
from django.shortcuts import get_object_or_404
from django.urls import reverse
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
import logging
@ -69,6 +70,28 @@ class PurchaseOrderDetail(DetailView):
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):
""" View for creating a new PurchaseOrder object using a modal form """