From b23c905b266d21971dacd2149022a31f04ef7e33 Mon Sep 17 00:00:00 2001 From: Holger Frey Date: Fri, 17 Apr 2020 14:48:25 +0200 Subject: [PATCH] added reordering --- ordr3/schemas/orders.py | 28 ++++- ordr3/static/script.js | 39 +++--- ordr3/static/style.css | 1 + ordr3/templates/orders/edit.jinja2 | 2 +- ordr3/templates/orders/reorder.jinja2 | 16 +++ ordr3/views/orders.py | 173 ++++++++++++++++++-------- 6 files changed, 192 insertions(+), 67 deletions(-) create mode 100644 ordr3/templates/orders/reorder.jinja2 diff --git a/ordr3/schemas/orders.py b/ordr3/schemas/orders.py index 124ce81..4e25cc4 100644 --- a/ordr3/schemas/orders.py +++ b/ordr3/schemas/orders.py @@ -178,9 +178,11 @@ class EditOrderSchema(CSRFSchema): @classmethod def as_form(cls, request, **override): """ returns the schema as a form """ + vendor_autocorrect_url = override.pop("autocorrect_url") + settings = { "buttons": ("Save Changes", "Cancel"), - "css_class": "deform o3-col-form", + "css_class": "deform o3-col-form o3-order-form", } settings.update(override) form = super().as_form(request, **settings) @@ -194,6 +196,30 @@ class EditOrderSchema(CSRFSchema): css_class="col-sm-9", ) + # set the url for vendor check + vendor_widget = form["item"]["vendor"].widget + vendor_widget.attributes["data-url"] = vendor_autocorrect_url + + return form + + +class AddOrderSchema(CSRFSchema): + """ add an order """ + + item = OrderItem() + pricing = OrderPricing() + optional = OrderOptionals() + + @classmethod + def as_form(cls, request, **override): + """ returns the schema as a form """ + settings = { + "buttons": ("Place Order", "Cancel"), + "css_class": "deform o3-col-form o3-order-form", + } + settings.update(override) + form = super().as_form(request, **settings) + # set the url for vendor check vendor_url = request.resource_url(request.context.__parent__, "vendor") vendor_widget = form["item"]["vendor"].widget diff --git a/ordr3/static/script.js b/ordr3/static/script.js index d20bdde..2a967f1 100644 --- a/ordr3/static/script.js +++ b/ordr3/static/script.js @@ -178,6 +178,8 @@ $(function() { $("label.o3-form-copy").attr("title", "copy to clipboard"); + $(".o3-order-form .invalid-feedback").addClass("col-sm-9 offset-sm-3"); + $(".o3-vendor").on("blur", function(event) { // autocorrect vendor var target = $(event.delegateTarget); @@ -185,23 +187,28 @@ $(function() { var url = target.attr("data-url") $.post( url, { vendor: input_value }, function( data ) { var corrected_name = data["name"]; - if (data["found"] && (corrected_name != input_value)) { - info = $('.o3-vendor-cancel') - if( info.length) { - info.find("a").text('"' + input_value + '"') + if (data["found"]) { + if (corrected_name.toLowerCase() != input_value.toLowerCase()) { + info = $('.o3-vendor-cancel') + if( info.length) { + info.find("a").text('"' + input_value + '"') + } else { + info = $(''); + info.addClass("o3-vendor-cancel col-sm-9 offset-sm-3 small text-secondary"); + info.html('Use "' + input_value + '" instead.'); + target.parent().append(info); + link = info.find("a"); + link.on("click", function() { + var link_text = link.text(); + var vendor = link_text.substring(1, link_text.length-1); + target.val(vendor) + info.remove() + return false; + }); + } } else { - info = $(''); - info.addClass("o3-vendor-cancel col-sm-9 offset-sm-3 small text-secondary"); - info.html('Use "' + input_value + '" instead.'); - target.parent().append(info); - link = info.find("a"); - link.on("click", function() { - var link_text = link.text(); - var vendor = link_text.substring(1, link_text.length-1); - target.val(vendor) - info.remove() - return false; - }); + var info = $('.o3-vendor-cancel'); + info.remove(); } target.val(corrected_name); } else { diff --git a/ordr3/static/style.css b/ordr3/static/style.css index fe8dc02..9d1b617 100644 --- a/ordr3/static/style.css +++ b/ordr3/static/style.css @@ -244,3 +244,4 @@ label.o3-form-copy { label.o3-form-copy:hover { text-decoration:underline; } + diff --git a/ordr3/templates/orders/edit.jinja2 b/ordr3/templates/orders/edit.jinja2 index 85bc698..240f373 100644 --- a/ordr3/templates/orders/edit.jinja2 +++ b/ordr3/templates/orders/edit.jinja2 @@ -9,7 +9,7 @@ {{form.render()|safe}}

- {% if request.has_permission("add", context.__parent__) %} + {% if request.has_permission("reorder", context) %} Reorder Item {% endif %} {% if request.has_permission("delete", context) %} diff --git a/ordr3/templates/orders/reorder.jinja2 b/ordr3/templates/orders/reorder.jinja2 new file mode 100644 index 0000000..3de3c2d --- /dev/null +++ b/ordr3/templates/orders/reorder.jinja2 @@ -0,0 +1,16 @@ +{% extends "ordr3:templates/layout_full.jinja2" %} + +{% block subtitle %} Reorder {{ context.model.cas_description }} {% endblock subtitle %} + +{% block content %} + +

+

Reorder {{ context.model.cas_description }}

+ {{form.render()|safe}} +
+ +
+ +{% endblock content %} + + diff --git a/ordr3/views/orders.py b/ordr3/views/orders.py index a08ecc7..30347fe 100644 --- a/ordr3/views/orders.py +++ b/ordr3/views/orders.py @@ -29,6 +29,56 @@ def get_multiple_orders(context, request): ) +def get_form_data_from_order(order): + status = {"status": order.status.name} + item = { + "cas_description": order.cas_description, + "category": order.category.name, + "vendor": order.vendor, + "catalog_nr": order.catalog_nr, + "package_size": order.package_size, + } + pricing = { + "unit_price": { + "amount": "%.2f" % order.unit_price, + "currency": order.currency, + }, + "quantity": order.amount, + "total_price": { + "amount": "%.2f" % order.total_price, + "currency": order.currency, + }, + } + optional = {"account": order.account, "comment": order.comment} + + form_data = { + "status": status, + "item": item, + "pricing": pricing, + "optional": optional, + } + return form_data + + +def update_order_with_form_data(order, form_data): + form_item = form_data["item"] + form_pricing = form_data["pricing"] + form_optional = form_data["optional"] + + order.cas_description = form_item["cas_description"] + order.category = models.OrderCategory[form_item["category"]] + order.vendor = form_item["vendor"] + order.catalog_nr = form_item["catalog_nr"] + order.package_size = form_item["package_size"] + + order.unit_price = form_pricing["unit_price"]["amount"] + order.currency = form_pricing["unit_price"]["currency"] + order.amount = form_pricing["quantity"] + + order.account = form_optional["account"] + order.comment = form_optional["comment"] + + @view_config( context="ordr3:resources.OrderList", permission="view", @@ -272,36 +322,14 @@ def view_order(context, request): renderer="ordr3:templates/orders/edit.jinja2", ) def edit_order(context, request): - form = orders.EditOrderSchema.as_form(request) - order = context.model - status = {"status": order.status.name} - item = { - "cas_description": order.cas_description, - "category": order.category.name, - "vendor": order.vendor, - "catalog_nr": order.catalog_nr, - "package_size": order.package_size, - } - pricing = { - "unit_price": { - "amount": "%.2f" % order.unit_price, - "currency": order.currency, - }, - "quantity": order.amount, - "total_price": { - "amount": "%.2f" % order.total_price, - "currency": order.currency, - }, - } - optional = {"account": order.account, "comment": order.comment} + autocorrect_url = request.resource_url(context.__parent__, "vendor") + form = orders.EditOrderSchema.as_form( + request, autocorrect_url=autocorrect_url + ) - form_data = { - "status": status, - "item": item, - "pricing": pricing, - "optional": optional, - } + form_data = get_form_data_from_order(context.model) form.set_appstruct(form_data) + return {"form": form} @@ -314,9 +342,10 @@ def edit_order(context, request): ) def do_edit_order(context, request): """ process the edit order form """ - print(request.POST) - - form = orders.EditOrderSchema.as_form(request) + autocorrect_url = request.resource_url(context.__parent__, "vendor") + form = orders.EditOrderSchema.as_form( + request, autocorrect_url=autocorrect_url + ) if "Save_Changes" not in request.POST: return HTTPFound(request.resource_url(context.__parent__)) @@ -330,25 +359,10 @@ def do_edit_order(context, request): # form validation sucessful, change order order = context.model - form_status = appstruct["status"] - form_item = appstruct["item"] - form_pricing = appstruct["pricing"] - form_optional = appstruct["optional"] - - order.cas_description = form_item["cas_description"] - order.category = models.OrderCategory[form_item["category"]] - order.vendor = form_item["vendor"] - order.catalog_nr = form_item["catalog_nr"] - order.package_size = form_item["package_size"] - - order.unit_price = form_pricing["unit_price"]["amount"] - order.currency = form_pricing["unit_price"]["currency"] - order.amount = form_pricing["quantity"] - - order.account = form_optional["account"] - order.comment = form_optional["comment"] + update_order_with_form_data(order, appstruct) + form_status_section = appstruct["status"] - status = models.OrderStatus[form_status["status"]] + status = models.OrderStatus[form_status_section["status"]] is_noteworthy = services.create_log_entry(order, status, request.user) if is_noteworthy: @@ -364,6 +378,67 @@ def do_edit_order(context, request): return HTTPFound(request.resource_url(context.__parent__)) +@view_config( + context="ordr3:resources.Order", + name="reorder", + permission="reorder", + request_method="GET", + renderer="ordr3:templates/orders/reorder.jinja2", +) +def reorder(context, request): + autocorrect_url = request.resource_url(context.__parent__, "vendor") + form = orders.AddOrderSchema.as_form( + request, autocorrect_url=autocorrect_url + ) + + form_data = get_form_data_from_order(context.model) + form.set_appstruct(form_data) + + return {"form": form} + + +@view_config( + context="ordr3:resources.Order", + name="reorder", + permission="reorder", + request_method="POST", + renderer="ordr3:templates/orders/reorder.jinja2", +) +def place_reorder(context, request): + """ process the reorder form """ + autocorrect_url = request.resource_url(context.__parent__, "vendor") + form = orders.AddOrderSchema.as_form( + request, autocorrect_url=autocorrect_url + ) + + if "Place_Order" not in request.POST: + return HTTPFound(request.resource_url(context.__parent__)) + + data = request.POST.items() + + try: + appstruct = form.validate(data) + except deform.ValidationFailure: + return {"form": form} + + # form validation sucessful, change order + default = [None] * 8 + order = models.OrderItem(*default) + update_order_with_form_data(order, appstruct) + + services.create_log_entry(order, models.OrderStatus.OPEN, request.user) + + request.repo.add_order(order) + + request.emit( + events.FlashMessage.info( + f"The order {order.cas_description} has been placed." + ) + ) + + return HTTPFound(request.resource_url(context.__parent__)) + + @view_config( context="ordr3:resources.Order", name="delete",