From 76f10d3c861496cf784a271272e23cd04ace7e26 Mon Sep 17 00:00:00 2001 From: Nick Clemens <nick@bywatersolutions.com> Date: Thu, 24 Dec 2015 14:53:16 +0000 Subject: [PATCH] Bug 14752 - Add multiple copies to a basket at once This patch add an 'Add multiple copies' button on the new order page in acquisitions. While processing the multiple copies a modal is displayed. To test: 1 - Add an order to an acquisitions basket 2 - Choose to add multiple items 3 - A modal shouold warn about ignoring UniqueItemFields from syspref 4 - When submitting the modal should popup until all items are processed. 5 - The modal should disappear after items are added. 6 - Items should be cloned, minus unique fields 7 - Enable autoBarcode for various formats, ensure you are warned that barcodes will be generated, and ensure they are generated correctly Sponsored by: Middletown Township Public Library (http://www.mtpl.org) --- acqui/addorder.pl | 18 ++++++- .../intranet-tmpl/prog/en/includes/additem.js.inc | 3 ++ .../prog/en/modules/acqui/neworderempty.tt | 33 +++++++++++++ koha-tmpl/intranet-tmpl/prog/js/additem.js | 57 ++++++++++++++++++++-- 4 files changed, 106 insertions(+), 5 deletions(-) diff --git a/acqui/addorder.pl b/acqui/addorder.pl index 70cb36c..80f01c6 100755 --- a/acqui/addorder.pl +++ b/acqui/addorder.pl @@ -130,6 +130,7 @@ use C4::Budgets; use C4::Items; use C4::Output; use Koha::Acquisition::Currencies; +use C4::Barcodes; ### "-------------------- addorder.pl ----------" @@ -307,7 +308,6 @@ if ( $basket->{is_standing} || $orderinfo->{quantity} ne '0' ) { push @{$itemhash{$itemid[$i]}->{'indicator'}},$indicator[$i]; } foreach my $item (keys %itemhash){ - my $xml = TransformHtmlToXml( $itemhash{$item}->{'tags'}, $itemhash{$item}->{'subfields'}, $itemhash{$item}->{'field_values'}, @@ -315,6 +315,22 @@ if ( $basket->{is_standing} || $orderinfo->{quantity} ne '0' ) { $itemhash{$item}->{'ind_tag'}, 'ITEM'); my $record=MARC::Record::new_from_xml($xml, 'UTF-8'); + my ($barcodefield,$barcodesubfield) = GetMarcFromKohaField('items.barcode'); + my $barcode = $record->subfield($barcodefield,$barcodesubfield); + my $aBpref = C4::Context->preference('autoBarcode'); + if( $barcode eq '' && $aBpref ne 'OFF'){ + my $barcodeobj; + if ( $aBpref eq 'hbyymmincr'){ + my ($homebranchfield,$homebranchsubfield) = GetMarcFromKohaField('items.homebranch'); + my $homebranch = $record->subfield($homebranchfield,$homebranchsubfield); + $barcodeobj = C4::Barcodes->new($aBpref, $homebranch); + } else { + $barcodeobj = C4::Barcodes->new($aBpref); + } + $barcode = $barcodeobj->value(); + $record->field($barcodefield)->delete_subfield( code => $barcodesubfield); + $record->field($barcodefield)->add_subfields($barcodesubfield => $barcode); + } my ($biblionumber,$bibitemnum,$itemnumber) = AddItemFromMarc($record,$$orderinfo{biblionumber}); $order->add_item($itemnumber); } diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/additem.js.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/additem.js.inc index 28d39e4..1ecee30 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/additem.js.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/additem.js.inc @@ -1,6 +1,9 @@ <script type="text/javascript"> //<![CDATA[ var MSG_ADDITEM_JS_ADDITEM = _("Add item"); +var MSG_ADDITEM_JS_ADDMULTI = _("Add multiple items"); +var MSG_ADDITEM_JS_MULTIVAL = _("Number of items to add"); +var MSG_ADDITEM_JS_SUBMITMULTI = _("Add"); var MSG_ADDITEM_JS_UPDATEITEM = _("Update item"); var MSG_ADDITEM_JS_EDIT = _("Edit"); var MSG_ADDITEM_JS_DELETE = _("Delete"); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt index 805b1a6..fe659a6 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt @@ -1,5 +1,6 @@ [% USE KohaDates %] [% INCLUDE 'doc-head-open.inc' %] +[% USE Koha %] <title>Koha › Acquisitions › Basket [% basketno %] › [% IF ( ordernumber ) %]Modify order details (line #[% ordernumber %])[% ELSE %]New order[% END %]</title> [% INCLUDE 'doc-head-close.inc' %] @@ -451,6 +452,10 @@ $(document).ready(function() <div class="dialog message">No ACQ framework, using default. You should create a framework with code ACQ, the items framework would be used</div> [% END %] + [% UNLESS Koha.Preference('autoBarcode') == 'OFF' %] + <div class="dialog message">The autoBarcode system preference is set to [% Koha.Preference('autoBarcode') %] and items with blank barcodes will have barcodes generated upon save to database</div> + [% END %] + <div id="outeritemblock"></div> </fieldset> @@ -646,6 +651,34 @@ $(document).ready(function() [% END %] </fieldset> </form> + +<div id="procModal" data-backdrop="static" class="modal hide fade" aria-labelledby="procModal" aria-hidden="true"> + <div class="modal-body"> + <h3>Processing multiple items</h3> + </div> +</div> + +[% IF UniqueItemFields %] +<div id="uniqueFieldsModal" class="modal hide fade" aria-labelledby="uniqueFieldsModal" aria-hidden="true"> + <div class="modal-body"> + <h3>The following fields are listed in the UniqueItemFields system preference and will not be copied</h3> + <ul id="uniqueItemFields"> + [% FOREACH uniqueField IN UniqueItemFields.split(" ") %] + <li>[% uniqueField %]</li> + [% END %] + </ul> + [% UNLESS Koha.Preference('autoBarcode') == 'OFF' %] + <h3>If barcode is blank and/or listed in UniqueItemFields barcodes will be generate using the autoBarcode preference setting ([% Koha.Preference('autoBarcode') %]) when saved</h3> + [% END %] + </div> +</div> +[% END %] + +<div id="multiCountModal" class="modal hide fade" aria-labelledby="multiCountModal" aria-hidden="true"> + <h3>Invalid number of copies</h3> + <p>Please enter a <b>number</b>, greater than or equal to 1</p> +</div> + </div> </div> <div class="yui-b"> diff --git a/koha-tmpl/intranet-tmpl/prog/js/additem.js b/koha-tmpl/intranet-tmpl/prog/js/additem.js index 4a9de09..3cbd66d 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/additem.js +++ b/koha-tmpl/intranet-tmpl/prog/js/additem.js @@ -12,7 +12,9 @@ function addItem( node, unique_item_fields ) { if ( current_qty < max_qty - 1 ) cloneItemBlock(index, unique_item_fields); addItemInList(index, unique_item_fields); - $("#" + index).find("input[name='buttonPlus']").val( (window.MSG_ADDITEM_JS_UPDATEITEM || "Update item") ); + $("#" + index).find("input[name='buttonPlus']").val( (window.MSG_ADDITEM_JS_UPDATEITEM ) ); + $("#"+ index).find("input[name='buttonPlusMulti']").remove(); + $("#" + index).find("input[name='multiValue']").remove(); $("#quantity").val(current_qty + 1).change(); } else if ( current_qty >= max_qty ) { alert(window.MSG_ADDITEM_JS_CANT_RECEIVE_MORE_ITEMS @@ -27,6 +29,44 @@ function addItem( node, unique_item_fields ) { $("#" + index).hide(); } +function addMulti( count, node, unique_item_fields){ + var index = $(node).closest("div").attr('id'); + var countItemsBefore = $("#items_list tbody tr").length; + var current_qty = parseInt( $('#quantity').val(), 10 ); + $("#procModal").modal('show'); + $("#" + index).hide(); + for(var i=0;i<count;i++){ + cloneItemBlock(index, unique_item_fields, function(cloneIndex){ + addItemInList(cloneIndex,unique_item_fields, function(){ + if( ($("#items_list tbody tr").length-countItemsBefore)==(count)){ + $("#multiValue").val(''); + $('#'+index).appendTo('#outeritemblock'); + $('#'+index).show(); + $('#'+index + ' #add_multiple_copies' ).css("visibility","hidden"); + $("#procModal").modal('hide'); + } + }); + $("#" + cloneIndex).find("input[name='buttonPlus']").val( (window.MSG_ADDITEM_JS_UPDATEITEM ) ); + $("#" + cloneIndex).find("input[name='buttonPlusMulti']").remove(); + $("#" + cloneIndex).find("input[name='multiValue']").remove(); + $("#" + cloneIndex).hide(); + current_qty++; + $('#quantity').val( current_qty ); + }); + } +} + + +function checkCount(node, unique_item_fields){ + var count = parseInt( $("#multiValue").val(), 10 ); + if ( isNaN( count ) || count <=0) { + $("#multiCountModal").modal('show'); + } + else{ + addMulti( count, node, unique_item_fields); + } +} + function showItem(index) { $("#outeritemblock").children("div").each(function(){ if ( $(this).attr('id') == index ) { @@ -75,10 +115,13 @@ function constructTrNode(index, unique_item_fields) { return result; } -function addItemInList(index, unique_item_fields) { +function addItemInList(index, unique_item_fields, callback) { $("#items_list").show(); var tr = constructTrNode(index, unique_item_fields); $("#items_list table tbody").append(tr); + if (typeof callback === "function"){ + callback(); + } } function deleteItemBlock(node_a, index, unique_item_fields) { @@ -105,7 +148,7 @@ function deleteItemBlock(node_a, index, unique_item_fields) { } } -function cloneItemBlock(index, unique_item_fields) { +function cloneItemBlock(index, unique_item_fields, callback) { var original; if(index) { original = $("#" + index); //original <div> @@ -136,7 +179,9 @@ function cloneItemBlock(index, unique_item_fields) { /* Add buttons + and Clear */ var buttonPlus = "<fieldset class=\"action\">"; buttonPlus += '<input type="button" class="addItemControl" name="buttonPlus" style="cursor:pointer; margin:0 1em;" onclick="addItem(this,\'' + unique_item_fields + '\')" value="' + (window.MSG_ADDITEM_JS_ADDITEM || 'Add item')+ '" />'; - buttonPlus += '<a class="addItemControl cancel" name="buttonClear" style="cursor:pointer;" onclick="clearItemBlock(this)">' + (window.MSG_ADDITEM_JS_CLEAR || 'Clear') + '</a>'; + buttonPlus += '<input type="button" class="addItemControl cancel" name="buttonClear" style="cursor:pointer;" onclick="clearItemBlock(this)" value="' + (window.MSG_ADDITEM_JS_CLEAR || 'Clear')+ '" />'; + buttonPlus += '<input type="button" class="addItemControl" name="buttonPlusMulti" data-toggle="modal" data-target="#uniqueFieldsModal" onclick="javascript:this.nextSibling.style.visibility=\'visible\'; return false;" style="cursor:pointer; margin:0 1em;" value="' + (window.MSG_ADDITEM_JS_ADDMULTI || 'Add multiple items')+ '" />'; + buttonPlus +='<span id="add_multiple_copies" style="visibility:hidden"><input type="number" class="addItemControl" id="multiValue" name="multiValue" placeholder="'+window.MSG_ADDITEM_JS_MULTIVAL+'" /><input type="button" class="addItemControl" name=buttonAddMulti" style="cursor:pointer; margin:0 1em;" onclick="checkCount( this ,\'' + unique_item_fields + '\')" value="' + (window.MSG_ADDITEM_JS_SUBMITMULTI || 'Add') + '" /></span>'; buttonPlus += "</fieldset>"; $(clone).append(buttonPlus); /* Copy values from the original block (input) */ @@ -161,6 +206,10 @@ function cloneItemBlock(index, unique_item_fields) { }); $("#outeritemblock").append(clone); + if (typeof callback === "function"){ + var cloneIndex = "itemblock"+random; + callback(cloneIndex); + } BindPluginEvents(data); } }); -- 2.1.4