From 2d4de1440f22bf0cf73965c0c3a4ebd34793b101 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi <tomascohen@theke.io> Date: Fri, 17 Jan 2020 13:07:34 -0300 Subject: [PATCH] [WIP] Bug 20212: Use the API to render orders --- api/v1/swagger/definitions/order.json | 4 +- api/v1/swagger/paths/acquisitions_orders.json | 16 +- .../prog/en/modules/acqui/histsearch.tt | 229 ++++++++++++++++ .../prog/en/modules/acqui/parcel.tt | 255 +++++++++++++++++- 4 files changed, 485 insertions(+), 19 deletions(-) diff --git a/api/v1/swagger/definitions/order.json b/api/v1/swagger/definitions/order.json index 0432f6dda3..df89fea079 100644 --- a/api/v1/swagger/definitions/order.json +++ b/api/v1/swagger/definitions/order.json @@ -302,9 +302,9 @@ "null" ] }, - "holds_count": { + "current_holds_count": { "type": "integer", - "description": "Holds count for associated items" + "description": "Current holds count for associated items" }, "fund": { "type": [ diff --git a/api/v1/swagger/paths/acquisitions_orders.json b/api/v1/swagger/paths/acquisitions_orders.json index 7b350a49c8..66c685bcda 100644 --- a/api/v1/swagger/paths/acquisitions_orders.json +++ b/api/v1/swagger/paths/acquisitions_orders.json @@ -103,12 +103,12 @@ "basket.basket_group", "basket.creator", "biblio", - "biblio.active_orders_count", - "biblio.holds_count", - "biblio.items_count", + "biblio.active_orders+count", + "biblio.holds+count", + "biblio.items+count", "biblio.suggestions.suggester", "fund", - "holds_count", + "current_holds+count", "invoice", "items", "subscription" @@ -250,12 +250,12 @@ "basket.basket_group", "basket.creator", "biblio", - "biblio.active_orders_count", - "biblio.holds_count", - "biblio.items_count", + "biblio.active_orders+count", + "biblio.holds+count", + "biblio.items+count", "biblio.suggestions.suggester", "fund", - "holds_count", + "current_holds+count", "invoice", "items", "subscription" diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/histsearch.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/histsearch.tt index 805a6d2c1d..f25c42b8cf 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/histsearch.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/histsearch.tt @@ -29,6 +29,29 @@ [% PROCESS filter_form context => "main" %] [% END %] + <div id="acqui_histsearch_api"> + <table id="histsearcht_api"> + <thead> + <tr> + <th>Order line (parent)</th> + <th>Status</th> + <th>Basket</th> + <th>Basket creator</th> + <th>Basket group</th> + <th>Managing library</th> + <th>Invoice number</th> + <th class="anti-the">Summary</th> + <th>Vendor</th> + <th class="title-string">Placed on</th> + <th class="title-string">Received on</th> + <th>Quantity received</th> + <th>Pending order</th> + <th>Unit cost</th> + <th>Fund</th> + </tr> + </thead> + </table> + </div> [% IF ( order_loop ) %]<h1>Search results</h1> <div id="acqui_histsearch"> @@ -145,6 +168,212 @@ patron_input_name: 'created_by', field_to_retrieve: 'borrowernumber' }); + + var pendig_orders_tb = $("#histsearcht_api").api({ + "ajax": { + "url": "/api/v1/acquisitions/orders" + }, + "embed": [ + "basket.basket_group", + "biblio.active_orders_count", + "biblio.holds_count", + "biblio.items_count", + "biblio.suggestions.suggester", + "fund", + "holds_count", + "items" + ], + 'dom': 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>', + "columnDefs": [ + { "targets": [ "nosort" ],"sortable": false,"searchable": false }, + { "type": "anti-the", "targets" : [ "anti-the" ] }, + { "type": "title-string", "targets" : [ "title-string" ] } + ], + "columns": [ + { "data": "order_id" }, + { "data": "status" }, + { "data": "basket_id", + "render": function(data, type, row, meta) { + if (type != 'display') return data; + return "<a href=\"/cgi-bin/koha/acqui/basket.pl?basketno=" + data + "\">" + row.basket.name + " (" + data + ")</a>"; + } + }, + { "data": function(row, type, val, meta) { + if ( type != 'display' ) return row.basket.basket_group_id; + if ( row.basket.basket_group_id == null ) { + return _("No basket group"); + } + else { + return "<a href=\"/cgi-bin/koha/acqui/basketgroup.pl?op=add&booksellerid=" + + row.basket.vendor_id + "&basketgroupid=" + + row.basket.basket_group_id + "\">" + + row.basket.basket_group.name + " (" + row.basket.basket_group_id + ")</a>"; + } + } + }, + { "data": "order_id", + "render": function(data, type, row, meta) { + if (type != 'display') return data; + return "<a href=\"neworderempty.pl?ordernumber="+data+"&booksellerid="+row.basket.vendor_id+"\">"+data+"</a>"; + } + }, + { "data": function(row, type, val, meta) { + var result = "<a href=\"opac-detail.pl?biblionumber="+row.biblio_id+"\">"+row.biblio.title+"</a>"; + if ( row.biblio.author != null ) + result += _(" by ") + row.biblio.author; + if ( row.biblio.isbn != null ) + result += " – " + row.biblio.isbn; + if ( row.biblio.publisher != null ) { + result += "<br/>" + _("Publisher: ") + row.biblio.publisher; + if ( row.biblio.publication_year != null ) { + result += ", " + row.biblio.publication_year; + } + else if ( row.biblio.copyright_date != null ) { + result += row.biblio.copyright_date; + } + } + var suggestions = row.biblio.suggestions; + if ( suggestions != null && suggestions.length > 0 ) { + var suggestion = suggestions[0]; + if ( suggestion.suggestor != null ) { + var suggestor = suggestion.suggestor; + var suggested_by = []; + if ( suggestor.surname != null ) { + suggested_by.push(suggestor.surname); + } + if ( suggestor.firstname != null ) { + suggested_by.push(suggestor.firstname); + } + + result += "<br/>" + _("Suggested by: ") + + '<a href="/cgi-bin/koha/suggestion/suggestion.pl?suggestionid=' + + suggestion.suggestionid + + '&op=show">' + + suggested_by.join(", ") + + " (#" + suggestions[0].suggestionid + ")</a>"; + } + } + + var internal_note = row.internal_note; + if ( internal_note != '' ) { + result += '<p class="ordernote"><strong>' + + _("Internal note: ") + + '</strong>' + internal_note + + ' [<a href="/cgi-bin/koha/acqui/modordernotes.pl?ordernumber=' + + row.order_id + '&referrer=/cgi-bin/koha/acqui/parcel.pl%3Finvoiceid=[% invoiceid | uri %]' + + '&type=internal">' + _("Change internal note") + '</a>]</p>'; + } + else { + result += ' [<a href="/cgi-bin/koha/acqui/modordernotes.pl?ordernumber=' + + row.order_id + '&referrer=/cgi-bin/koha/acqui/parcel.pl%3Finvoiceid=[% invoiceid | uri %]' + + '&type=internal">' + _("Add internal note") + '</a>]'; + } + + var vendor_note = row.vendor_note; + if ( vendor_note != '' ) { + result += '<p class="ordernote"><strong>' + + _("Vendor note: ") + + '</strong>' + vendor_note + '</p>'; + } + else { + result += ' [<a href="/cgi-bin/koha/acqui/modordernotes.pl?ordernumber=' + + row.order_id + '&referrer=/cgi-bin/koha/acqui/parcel.pl%3Finvoiceid=[% invoiceid | uri %]' + + '&type=vendor">' + _("Add vendor note") + '</a>]'; + } + + return result; + } + }, + { "data": function( row, type, val, meta) { + if (type != 'display') return data; + var result = '<a href="/cgi-bin/koha/acqui/showorder.pl?ordernumber=' + row.order_id + '" class="previewData">' + _('Order') + '</a><br>' + + '<a href="/cgi-bin/koha/catalogue/showmarc.pl?id=' + row.biblio_id + '" class="previewData">' + _("MARC") + '</a><br>' + + '<a href="/cgi-bin/koha/catalogue/showmarc.pl?viewas=card&id=' + row.biblio_id + '" class="previewData">' + _("Card") + '</a>'; + return result; + } + }, + { "data": "replacement_price" }, + { "data": "quantity" }, + { "data": "ecost" }, + { "data": function ( row, type, val, meta ) { + return row.quantity * row.ecost; + } + }, + { "data": "fund_id", + "render": function(data, type, row, meta) { + if (type != 'display') return data; + return row.fund.name; + } + }, + { + "data": function( row, type, val, meta ) { + return '<a href="orderreceive.pl?ordernumber=' + + row.order_id + '&invoiceid=[% invoiceid | uri %]' + '">' + + _("Receive") + '</a><br/>' + + '<a href="#" onclick="transfer_order_popup(' + row.order_id + '); return false;">' + + _("Transfer") + '</a>'; + } + }, + { + "data": function( row, type, val, meta ) { + var result = ""; + + if ( row.holds_count > 0 ) { + result += '<span class="button" title="' + + _("Can't cancel order, (%s) holds are linked with this order. Cancel holds first").format( row.holds_count ) + '">' + + _("Can't cancel order") + '</span><br/>'; + } + else { + result += '<a href="/cgi-bin/koha/acqui/cancelorder.pl?ordernumber=' + + row.order_id + + '&biblionumber=' + row.biblio_id + + '&referrer=/cgi-bin/koha/acqui/parcel.pl?invoiceid=[% invoiceid | uri %]">' + + _("Cancel order") + '</a><br/>'; + } + + if ( row.items.length > 0 || + row.biblio.active_orders_count > 1 || + row.biblio.subscriptions_count > 0 || + row.bibio.holds_count > 0 ) { // biblio can be deleted + result += '<span class="button" title="' + + _("Can't delete catalog record, see constraints below") + '">' + + _("Can't cancel order and delete catalog record") + '</span><br>'; + } + else { + result += '<a href="/cgi-bin/koha/acqui/cancelorder.pl?ordernumber=' + + row.order_id + '&biblionumber=' + row.biblio_id + + '&del_biblio=1&referrer="/cgi-bin/koha/acqui/parcel.pl?invoiceid=[$ invoiceid | uri ]">' + + _("Cancel order and catalog record") + '</a><br/>'; + } + + if ( row.items.length > 0 ) { + result += '<b title="' + + _("Can't delete catalog record, because of %s existing item(s)").format(row.items.length) + +'">' + (row.biblio.items_count - row.items.length) + _(" item(s) left") + '</b><br/>'; + } + + if ( row.biblio.active_orders_count > 1 ) { + result += '<b title="' + + _("Can't delete catalog record, delete other orders linked to it first") + '">' + + (row.biblio.active_orders_count - 1) + _(" order(s) left") + '</b><br/>'; + } + + if ( row.biblio.subscriptions_count > 0 ) { + result += '<b title="' + _("Can't delete catalog record, delete subscriptions first") + '">' + + _("%s subscription(s) left").format(row.biblio.subscriptions_count) + + '</b><br>'; + } + + if ( row.biblio.holds_count > 0 ) { + result += '<b title="' + _("Can't delete catalog record or order, cancel holds first") + '">' + + _("%s hold(s) left").format(row.bibio.holds_count) + '</b>'; + } + + return result; + } + } + ] + }); }); </script> [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt index 414844397c..f4a4e0c49d 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt @@ -3,6 +3,7 @@ [% USE Koha %] [% USE KohaDates %] [% USE Price %] +[% USE Currencies %] [% USE currency = format('%.2f') -%] [% PROCESS 'i18n.inc' %] [% SET footerjs = 1 %] @@ -87,6 +88,26 @@ </div> [% END %] +<h3>Pending orders (api)</h3> +<table id="pending_orders" class="table table-bordered table-striped"> + <thead> + <tr> + <th>Basket</th> + <th>Basket group</th> + <th>Order line</th> + <th>Summary</th> + <th>More</th> + <th>Replacement price</th> + <th>Quantity</th> + <th>Unit cost</th> + <th>Order cost</th> + <th>Fund</th> + <th> </th> + <th> </th> + </tr> + </thead> +</table> + [% UNLESS no_orders_to_display %] <div id="acqui_receive_summary"> <p><strong>Invoice number:</strong> [% invoice | html %] <strong>Received by:</strong> [% logged_in_user.userid | html %] <strong>On:</strong> [% datereceived | $KohaDates %]</p> @@ -181,26 +202,26 @@ <a href="#" onclick="transfer_order_popup([% loop_order.ordernumber | html %]); return false;">Transfer</a> </td> <td> - [% IF ( loop_order.left_holds_on_order ) %] + [% IF ( loop_order.left_holds_on_order ) %] [%# DONE %] <span class="button" title="Can't cancel order, ([% loop_order.holds_on_order | html %]) holds are linked with this order. Cancel holds first">Can't cancel order</span><br> - [% ELSE %] + [% ELSE %] [%# DONE %] <a href="/cgi-bin/koha/acqui/cancelorder.pl?ordernumber=[% loop_order.ordernumber | uri %]&biblionumber=[% loop_order.biblionumber | uri %]&referrer=[% "/cgi-bin/koha/acqui/parcel.pl?invoiceid=$invoiceid" | uri %]">Cancel order</a><br /> - [% END %] - [% IF ( loop_order.can_del_bib ) %] + [% END %] [%# DONE %] + [% IF ( loop_order.can_del_bib ) %] [%# DONE %] <a href="/cgi-bin/koha/acqui/cancelorder.pl?ordernumber=[% loop_order.ordernumber | uri %]&biblionumber=[% loop_order.biblionumber | uri %]&del_biblio=1&referrer=[% "/cgi-bin/koha/acqui/parcel.pl?invoiceid=$invoiceid" | uri %]">Cancel order and catalog record</a><br /> - [% ELSE %] + [% ELSE %] [%# DONE %] <span class="button" title="Can't delete catalog record, see constraints below">Can't cancel order and delete catalog record</span><br> [% END %] - [% IF ( loop_order.left_item ) %] + [% IF ( loop_order.left_item ) %] [%# DONE %] <b title="Can't delete catalog record, because of [% loop_order.items | html %] existing item(s)" >[% loop_order.items | html %] item(s) left</b><br> [% END %] - [% IF ( loop_order.left_biblio ) %] + [% IF ( loop_order.left_biblio ) %] [%# DONE %] <b title="Can't delete catalog record, delete other orders linked to it first">[% loop_order.biblios | html %] order(s) left</b><br> [% END %] - [% IF ( loop_order.left_subscription ) %] + [% IF ( loop_order.left_subscription ) %] [%# DONE %] <b title="Can't delete catalog record, delete subscriptions first">[% loop_order.subscriptions | html %] subscription(s) left</b><br> [% END %] - [% IF ( loop_order.left_holds ) %] + [% IF ( loop_order.left_holds ) %] [%# DONE %] <b title="Can't delete catalog record or order, cancel holds first">[% loop_order.holds | html %] hold(s) left</b> [% END %] </td> @@ -452,6 +473,7 @@ [% MACRO jsinclude BLOCK %] [% Asset.js("js/acquisitions-menu.js") | $raw %] [% INCLUDE 'datatables.inc' %] + [% INCLUDE 'currency.inc' %] [% Asset.js("lib/jquery/plugins/jquery.dataTables.columnFilter.js") | $raw %] [% Asset.js("lib/jquery/plugins/jquery.cookie.min.js") | $raw %] <style>#dataPreview { width : 80%; } @media (max-width: 767px) { #dataPreview { margin: 0; width : auto; } }</style> @@ -533,6 +555,221 @@ })); } + var pendig_orders_tb = $("#pending_orders").api({ + "ajax": { + "url": "/api/v1/acquisitions/orders" + }, + "embed": [ + "basket.basket_group", + "biblio.active_orders+count", + "biblio.holds+count", + "biblio.items+count", + "biblio.suggestions.suggester", + "fund", + "current_holds+count", + "items" + ], + 'dom': 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>', + "columns": [ + { "data": "basket_id", + "orderable": true, + "render": function(data, type, row, meta) { + if (type != 'display') return data; + return "<a href=\"/cgi-bin/koha/acqui/basket.pl?basketno=" + data + "\">" + row.basket.name + " (" + data + ")</a>"; + } + }, + { "data": function(row, type, val, meta) { + if ( type != 'display' ) return row.basket.basket_group_id; + if ( row.basket.basket_group_id == null ) { + return _("No basket group"); + } + else { + return "<a href=\"/cgi-bin/koha/acqui/basketgroup.pl?op=add&booksellerid=" + + row.basket.vendor_id + "&basketgroupid=" + + row.basket.basket_group_id + "\">" + + row.basket.basket_group.name + " (" + row.basket.basket_group_id + ")</a>"; + } + }, + "orderable": false // FIXME + }, + { "data": "order_id", + "render": function(data, type, row, meta) { + if (type != 'display') return data; + return "<a href=\"neworderempty.pl?ordernumber="+data+"&booksellerid="+row.basket.vendor_id+"\">"+data+"</a>"; + } + }, + { "data": function(row, type, val, meta) { + var result = "<a href=\"opac-detail.pl?biblionumber="+row.biblio_id+"\">"+row.biblio.title+"</a>"; + if ( row.biblio.author != null ) + result += _(" by ") + row.biblio.author; + if ( row.biblio.isbn != null ) + result += " – " + row.biblio.isbn; + if ( row.biblio.publisher != null ) { + result += "<br/>" + _("Publisher: ") + row.biblio.publisher; + if ( row.biblio.publication_year != null ) { + result += ", " + row.biblio.publication_year; + } + else if ( row.biblio.copyright_date != null ) { + result += row.biblio.copyright_date; + } + } + var suggestions = row.biblio.suggestions; + if ( suggestions != null && suggestions.length > 0 ) { + var suggestion = suggestions[0]; + if ( suggestion.suggester != null ) { + var suggester = suggestion.suggester; + var suggested_by = []; + if ( suggester.surname != null ) { + suggested_by.push(suggester.surname); + } + if ( suggester.firstname != null ) { + suggested_by.push(suggester.firstname); + } + + result += "<br/>" + _("Suggested by: ") + + '<a href="/cgi-bin/koha/suggestion/suggestion.pl?suggestionid=' + + suggestion.suggestionid + + '&op=show">' + + suggested_by.join(", ") + + " (#" + suggestions[0].suggestionid + ")</a>"; + } + } + + var internal_note = row.internal_note; + if ( internal_note != '' ) { + result += '<p class="ordernote"><strong>' + + _("Internal note: ") + + '</strong>' + internal_note + + ' [<a href="/cgi-bin/koha/acqui/modordernotes.pl?ordernumber=' + + row.order_id + '&referrer=/cgi-bin/koha/acqui/parcel.pl%3Finvoiceid=[% invoiceid | uri %]' + + '&type=internal">' + _("Change internal note") + '</a>]</p>'; + } + else { + result += ' [<a href="/cgi-bin/koha/acqui/modordernotes.pl?ordernumber=' + + row.order_id + '&referrer=/cgi-bin/koha/acqui/parcel.pl%3Finvoiceid=[% invoiceid | uri %]' + + '&type=internal">' + _("Add internal note") + '</a>]'; + } + + var vendor_note = row.vendor_note; + if ( vendor_note != '' ) { + result += '<p class="ordernote"><strong>' + + _("Vendor note: ") + + '</strong>' + vendor_note + '</p>'; + } + else { + result += ' [<a href="/cgi-bin/koha/acqui/modordernotes.pl?ordernumber=' + + row.order_id + '&referrer=/cgi-bin/koha/acqui/parcel.pl%3Finvoiceid=[% invoiceid | uri %]' + + '&type=vendor">' + _("Add vendor note") + '</a>]'; + } + + return result; + }, + "orderable": false // FIXME + }, + { "data": function( row, type, val, meta) { + var result = '<a href="/cgi-bin/koha/acqui/showorder.pl?ordernumber=' + row.order_id + '" class="previewData">' + _('Order') + '</a><br>' + + '<a href="/cgi-bin/koha/catalogue/showmarc.pl?id=' + row.biblio_id + '" class="previewData">' + _("MARC") + '</a><br>' + + '<a href="/cgi-bin/koha/catalogue/showmarc.pl?viewas=card&id=' + row.biblio_id + '" class="previewData">' + _("Card") + '</a>'; + return result; + }, + "orderable": false + }, + { "data": "replacement_price", + "render": function(data, type, val, meta) { + if (type != 'display') return data; + return data.format_price(); + } + }, + { "data": "quantity" }, + { "data": "ecost", + "render": function(data, type, val, meta) { + if (type != 'display') return data; + return data.format_price(); + } + }, + { "data": function ( row, type, val, meta ) { + return (row.quantity * row.ecost).format_price(); + } + }, + { "data": "fund_id", + "render": function(data, type, row, meta) { + if (type != 'display') return data; + return row.fund.name; + } + }, + { + "data": function( row, type, val, meta ) { + return '<a href="orderreceive.pl?ordernumber=' + + row.order_id + '&invoiceid=[% invoiceid | uri %]' + '">' + + _("Receive") + '</a><br/>' + + '<a href="#" onclick="transfer_order_popup(' + row.order_id + '); return false;">' + + _("Transfer") + '</a>'; + }, + "orderable": false + }, + { + "data": function( row, type, val, meta ) { + var result = ""; + + if ( row.current_holds_count > 0 ) { + result += '<span class="button" title="' + + _("Can't cancel order, (%s) holds are linked with this order. Cancel holds first").format( row.holds_count ) + '">' + + _("Can't cancel order") + '</span><br/>'; + } + else { + result += '<a href="/cgi-bin/koha/acqui/cancelorder.pl?ordernumber=' + + row.order_id + + '&biblionumber=' + row.biblio_id + + '&referrer=/cgi-bin/koha/acqui/parcel.pl?invoiceid=[% invoiceid | uri %]">' + + _("Cancel order") + '</a><br/>'; + } + + if ( row.items.length > 0 || + row.biblio.active_orders_count > 1 || + row.biblio.subscriptions_count > 0 || + row.bibio.holds_count > 0 ) { // biblio can be deleted + result += '<span class="button" title="' + + _("Can't delete catalog record, see constraints below") + '">' + + _("Can't cancel order and delete catalog record") + '</span><br>'; + } + else { + result += '<a href="/cgi-bin/koha/acqui/cancelorder.pl?ordernumber=' + + row.order_id + '&biblionumber=' + row.biblio_id + + '&del_biblio=1&referrer="/cgi-bin/koha/acqui/parcel.pl?invoiceid=[$ invoiceid | uri ]">' + + _("Cancel order and catalog record") + '</a><br/>'; + } + + if ( row.biblio.items_count - row.items.length > 0 ) { + result += '<b title="' + + _("Can't delete catalog record, because of %s existing item(s)").format(row.items.length) + +'">' + (row.biblio.items_count - row.items.length) + _(" item(s) left") + '</b><br/>'; + } + + if ( row.biblio.active_orders_count > 1 ) { + result += '<b title="' + + _("Can't delete catalog record, delete other orders linked to it first") + '">' + + (row.biblio.active_orders_count - 1) + _(" order(s) left") + '</b><br/>'; + } + + if ( row.biblio.subscriptions_count > 0 ) { + result += '<b title="' + _("Can't delete catalog record, delete subscriptions first") + '">' + + _("%s subscription(s) left").format(row.biblio.subscriptions_count) + + '</b><br>'; + } + + if ( row.biblio.holds_count > 0 ) { + result += '<b title="' + _("Can't delete catalog record or order, cancel holds first") + '">' + + _("%s hold(s) left").format(row.bibio.holds_count) + '</b>'; + } + + return result; + }, + "orderable": false + } + ] + }); + + // Keep filters from finishreceive.pl to parcel.pl $.cookie("filter_parcel_summary", $("#summaryfilter").val()); $.cookie("filter_parcel_basketname", $("#basketfilter").val()); -- 2.25.0