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)

Signed-off-by: sonia BOUIS <sonia.bouis@univ-lyon3.fr>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
This commit is contained in:
Nick Clemens 2015-12-24 14:53:16 +00:00 committed by Kyle M Hall
parent 75c61b94f3
commit bdcbada8b8
4 changed files with 106 additions and 5 deletions

View File

@ -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);
}

View File

@ -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");

View File

@ -1,5 +1,6 @@
[% USE KohaDates %]
[% INCLUDE 'doc-head-open.inc' %]
[% USE Koha %]
<title>Koha &rsaquo; Acquisitions &rsaquo; Basket [% basketno %] &rsaquo; [% 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">

View File

@ -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);
}
});