Bugzilla – Attachment 109287 Details for
Bug 24023
Add ability to create bundles of items
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 24023: Add ability to create bundles of items
Bug-24023-Add-ability-to-create-bundles-of-items.patch (text/plain), 49.66 KB, created by
Julian Maurice
on 2020-08-28 14:41:31 UTC
(
hide
)
Description:
Bug 24023: Add ability to create bundles of items
Filename:
MIME Type:
Creator:
Julian Maurice
Created:
2020-08-28 14:41:31 UTC
Size:
49.66 KB
patch
obsolete
>From efdf365858454a58e95254d842c35919685f3c96 Mon Sep 17 00:00:00 2001 >From: Julian Maurice <julian.maurice@biblibre.com> >Date: Tue, 12 Nov 2019 15:21:15 +0100 >Subject: [PATCH] Bug 24023: Add ability to create bundles of items >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >This patch adds the ability to link items to a biblio to create bundles >of items that can be reserved and checked out like a regular item. >A withdrawn status will be set to linked items so that they can't be >checked out while they are part of a bundle. >When returning a bundle, the list of items that are part of this bundle >will be displayed, allowing the librarian to verify that all items are >there. >Bundles can also be used in the inventory tool as a filter. > >Test plan: >0. Apply the patch, run updatedatabase + update_dbix_class_files >1. Create a biblio record with at least a title. Create an item for this > biblio record >2. In the biblio 'Edit' menu you have a new option: 'Link elements'. > Click on it >3. Enter a list of valid and invalid barcodes in the textarea, select a > withdrawn status and click on 'Continue' >4. Verify that new fields have been added to the MARC record (462 for > UNIMARC, 774 otherwise) >5. Verify that the withdrawn status has been correctly set for the items > you have linked >6. Verify that, for item created at step 1, items.materials has been > updated with the number of items contained in the bundle >7. Edit the biblio record and remove one of the 462/774 fields >8. Verify that the corresponding item's withdrawn status has been reset >9. Checkout and checkin the item created at step 1 >10. You should see the list of items contained in the bundle. Click on > 'Confirm checkin without verifying'. Verify that the item has been > returned >11. Checkout and checkin the item created at step 1 again >12. Now click on 'Verify items bundle contents'. A textarea lets you > enter barcodes. Enter some (but not all) barcodes that are in the > bundle. Select a 'lost' status and click on 'Confirm checkin and > mark missing items as lost' >13. Verify that the items corresponding to barcodes you did not type in > the textarea are now marked as lost with the lost status you chose >14. Go to the inventory tool, use the bundle filter and verify that it > works > >Sponsored-by: Bibliothèque Départementale de l'Yonne >--- > C4/Biblio.pm | 45 ++++++ > C4/Items.pm | 6 + > Koha/Template/Plugin/Biblio.pm | 9 ++ > admin/columns_settings.yml | 10 ++ > catalogue/detail.pl | 10 ++ > catalogue/items-bundle-contents.pl | 53 +++++++ > cataloguing/linkelements.pl | 144 ++++++++++++++++++ > circ/returns.pl | 31 ++++ > .../atomicupdate/bug-24023-items-bundles.perl | 37 +++++ > installer/data/mysql/kohastructure.sql | 38 +++++ > .../prog/en/includes/biblio-view-menu.inc | 7 + > .../prog/en/includes/cat-toolbar.inc | 1 + > .../prog/en/includes/item-status.inc | 84 ++++++++++ > .../prog/en/modules/catalogue/detail.tt | 9 ++ > .../catalogue/items-bundle-contents.tt | 79 ++++++++++ > .../en/modules/cataloguing/linkelements.tt | 91 +++++++++++ > .../prog/en/modules/circ/returns.tt | 92 +++++++++++ > .../prog/en/modules/tools/inventory.tt | 20 ++- > tools/inventory.pl | 10 ++ > 19 files changed, 775 insertions(+), 1 deletion(-) > create mode 100644 catalogue/items-bundle-contents.pl > create mode 100755 cataloguing/linkelements.pl > create mode 100644 installer/data/mysql/atomicupdate/bug-24023-items-bundles.perl > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/item-status.inc > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/items-bundle-contents.tt > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/linkelements.tt > >diff --git a/C4/Biblio.pm b/C4/Biblio.pm >index da86e62fdd..06e473de7b 100644 >--- a/C4/Biblio.pm >+++ b/C4/Biblio.pm >@@ -3148,6 +3148,8 @@ sub ModBiblioMarc { > $m_rs->metadata( $record->as_xml_record($encoding) ); > $m_rs->store; > >+ UpdateItemsBundles($biblionumber, $record); >+ > ModZebra( $biblionumber, "specialUpdate", "biblioserver" ); > > return $biblionumber; >@@ -3383,6 +3385,49 @@ sub RemoveAllNsb { > return $record; > } > >+=head2 UpdateItemsBundles >+ >+Remove from items bundle the items that were removed from the MARC record (keep >+the table in sync with the MARC record) >+ >+This is called by ModBiblio >+ >+ UpdateItemsBundles($biblionumber, $record) >+ >+=cut >+ >+sub UpdateItemsBundles { >+ my ($biblionumber, $record) = @_; >+ >+ my $schema = Koha::Database->new()->schema(); >+ my $items_bundle_rs = $schema->resultset('ItemsBundle'); >+ my $items_rs = $schema->resultset('Item'); >+ my $items_bundle = $items_bundle_rs->find({ biblionumber => $biblionumber }); >+ return unless $items_bundle; >+ >+ my $tag = C4::Context->preference('marcflavour') eq 'UNIMARC' ? '462' : '774'; >+ my @fields = $record->field($tag); >+ my %fields_by_itemnumber = map { (scalar $_->subfield('9')) // '' => $_ } @fields; >+ >+ foreach my $items_bundle_item ($items_bundle->items_bundle_items) { >+ my $itemnumber = $items_bundle_item->get_column('itemnumber'); >+ if (not exists $fields_by_itemnumber{$itemnumber}) { >+ $items_bundle_item->itemnumber->update({ withdrawn => 0 }); >+ $items_bundle_item->delete(); >+ } >+ } >+ >+ my $items_count = $items_bundle->items_bundle_items->count(); >+ # If bundle is empty, delete it >+ if ($items_count == 0) { >+ $items_bundle->delete(); >+ } >+ >+ my $materials = $items_count || undef; >+ $items_rs->search({ biblionumber => $biblionumber }) >+ ->update_all({ materials => $materials }); >+} >+ > 1; > > >diff --git a/C4/Items.pm b/C4/Items.pm >index 22ac2de12c..4507cd5822 100644 >--- a/C4/Items.pm >+++ b/C4/Items.pm >@@ -492,6 +492,7 @@ sub GetItemsForInventory { > my $minlocation = $parameters->{'minlocation'} // ''; > my $maxlocation = $parameters->{'maxlocation'} // ''; > my $class_source = $parameters->{'class_source'} // C4::Context->preference('DefaultClassificationSource'); >+ my $items_bundle = $parameters->{'items_bundle'} // ''; > my $location = $parameters->{'location'} // ''; > my $itemtype = $parameters->{'itemtype'} // ''; > my $ignoreissued = $parameters->{'ignoreissued'} // ''; >@@ -537,6 +538,11 @@ sub GetItemsForInventory { > push @bind_params, $max_cnsort; > } > >+ if ($items_bundle) { >+ push @where_strings, 'items.itemnumber IN (SELECT itemnumber FROM items_bundle_item WHERE items_bundle_id = ?)'; >+ push @bind_params, $items_bundle; >+ } >+ > if ($datelastseen) { > $datelastseen = output_pref({ str => $datelastseen, dateformat => 'iso', dateonly => 1 }); > push @where_strings, '(datelastseen < ? OR datelastseen IS NULL)'; >diff --git a/Koha/Template/Plugin/Biblio.pm b/Koha/Template/Plugin/Biblio.pm >index e9d7a73009..df3da0b0cf 100644 >--- a/Koha/Template/Plugin/Biblio.pm >+++ b/Koha/Template/Plugin/Biblio.pm >@@ -63,4 +63,13 @@ sub CanArticleRequest { > return $biblio ? $biblio->can_article_request( $borrower ) : 0; > } > >+sub IsItemsBundle { >+ my ($self, $biblionumber) = @_; >+ >+ my $items_bundle_rs = Koha::Database->new()->schema()->resultset('ItemsBundle'); >+ my $count = $items_bundle_rs->search({ biblionumber => $biblionumber })->count; >+ >+ return $count > 0; >+} >+ > 1; >diff --git a/admin/columns_settings.yml b/admin/columns_settings.yml >index 96b3a31a68..e008749054 100644 >--- a/admin/columns_settings.yml >+++ b/admin/columns_settings.yml >@@ -422,6 +422,16 @@ modules: > - > columnname: checkin_on > >+ items-bundle-contents: >+ items-bundle-contents-table: >+ - columnname: title >+ - columnname: author >+ - columnname: ccode >+ - columnname: itemtype >+ - columnname: callnumber >+ - columnname: barcode >+ - columnname: status >+ > cataloguing: > additem: > itemst: >diff --git a/catalogue/detail.pl b/catalogue/detail.pl >index f865ddb28d..d279d36505 100755 >--- a/catalogue/detail.pl >+++ b/catalogue/detail.pl >@@ -44,12 +44,15 @@ use C4::Acquisition qw(GetOrdersByBiblionumber); > use Koha::AuthorisedValues; > use Koha::Biblios; > use Koha::Illrequests; >+use Koha::Database; > use Koha::Items; > use Koha::ItemTypes; > use Koha::Patrons; > use Koha::Virtualshelves; > use Koha::Plugins; > >+my $schema = Koha::Database->new()->schema(); >+ > my $query = CGI->new(); > > my $analyze = $query->param('analyze'); >@@ -386,6 +389,12 @@ foreach my $item (@items) { > } > } > >+ my $items_bundle_item = $schema->resultset('ItemsBundleItem')->find({ itemnumber => $item->{itemnumber} }); >+ if ($items_bundle_item) { >+ $itemfields{items_bundle} = 1; >+ $item->{items_bundle} = $items_bundle_item->items_bundle; >+ } >+ > if ($currentbranch and C4::Context->preference('SeparateHoldings')) { > if ($itembranchcode and $itembranchcode eq $currentbranch) { > push @itemloop, $item; >@@ -415,6 +424,7 @@ $template->param( > itemdata_publisheddate => $itemfields{publisheddate}, > volinfo => $itemfields{enumchron}, > itemdata_itemnotes => $itemfields{itemnotes}, >+ itemdata_items_bundle => $itemfields{items_bundle}, > itemdata_nonpublicnotes => $itemfields{itemnotes_nonpublic}, > z3950_search_params => C4::Search::z3950_search_args($dat), > hostrecords => $hostrecords, >diff --git a/catalogue/items-bundle-contents.pl b/catalogue/items-bundle-contents.pl >new file mode 100644 >index 0000000000..6969a64014 >--- /dev/null >+++ b/catalogue/items-bundle-contents.pl >@@ -0,0 +1,53 @@ >+#!/usr/bin/perl >+ >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use CGI qw(-utf8); >+use C4::Auth; >+use C4::Output; >+ >+use Koha::Database; >+use Koha::Biblios; >+use Koha::Items; >+ >+my $schema = Koha::Database->new()->schema(); >+ >+my $cgi = CGI->new(); >+ >+my ($template, $borrowernumber, $cookie) = get_template_and_user({ >+ template_name => 'catalogue/items-bundle-contents.tt', >+ query => $cgi, >+ type => 'intranet', >+ authnotrequired => 0, >+ flagsrequired => { catalogue => 1 }, >+}); >+ >+my $biblionumber = $cgi->param('biblionumber'); >+my $biblio = Koha::Biblios->find($biblionumber); >+ >+my $items_bundle_rs = $schema->resultset('ItemsBundle'); >+my $items_bundle = $items_bundle_rs->find({ biblionumber => $biblionumber }); >+my @items = map { scalar Koha::Items->find($_->get_column('itemnumber')) } $items_bundle->items_bundle_items; >+ >+$template->param( >+ biblionumber => $biblionumber, >+ biblio => $biblio, >+ items => \@items, >+); >+ >+output_html_with_http_headers $cgi, $cookie, $template->output; >diff --git a/cataloguing/linkelements.pl b/cataloguing/linkelements.pl >new file mode 100755 >index 0000000000..320886b255 >--- /dev/null >+++ b/cataloguing/linkelements.pl >@@ -0,0 +1,144 @@ >+#!/usr/bin/perl >+ >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use CGI qw ( -utf8 ); >+use Encode; >+use List::MoreUtils qw/uniq/; >+use MARC::Record; >+ >+use Koha::Biblios; >+use Koha::Items; >+use Koha::Database; >+ >+use C4::Auth; >+use C4::Output; >+use C4::Biblio; >+use C4::Context; >+use C4::Items; >+ >+my $cgi = new CGI; >+ >+my ($template, $loggedinuser, $cookie) = get_template_and_user({ >+ template_name => 'cataloguing/linkelements.tt', >+ query => $cgi, >+ type => 'intranet', >+ authnotrequired => 0, >+ flagsrequired => { editcatalogue => 'edit_catalogue' }, >+}); >+ >+my $biblionumber = $cgi->param('biblionumber'); >+my $sessionId = $cgi->cookie('CGISESSID'); >+my $session = C4::Auth::get_session($sessionId); >+my $schema = Koha::Database->new()->schema(); >+my $items_bundle_rs = $schema->resultset('ItemsBundle'); >+my $items_bundle_item_rs = $schema->resultset('ItemsBundleItem'); >+ >+if ($cgi->request_method() eq 'POST') { >+ my $barcodelist = $cgi->param('barcodelist'); >+ my $withdrawn = $cgi->param('withdrawn'); >+ my @barcodes = uniq( split(/\s*\n\s*/, $barcodelist) ); >+ my @items; >+ my @notfound_barcodes; >+ my @found_barcodes; >+ my @alreadylinked_barcodes; >+ foreach my $barcode (@barcodes) { >+ my $item = Koha::Items->find( { barcode => $barcode } ); >+ if ($item) { >+ my $items_bundle_item = $items_bundle_item_rs->find({ itemnumber => $item->itemnumber }); >+ if ($items_bundle_item && $items_bundle_item->items_bundle->get_column('biblionumber') ne $biblionumber) { >+ # This item is already linked to another biblio >+ push @alreadylinked_barcodes, $barcode >+ } else { >+ push @items, $item; >+ push @found_barcodes, $barcode; >+ } >+ } else { >+ push @notfound_barcodes, $barcode; >+ } >+ } >+ >+ if (@items) { >+ my $biblio = Koha::Biblios->find($biblionumber); >+ my $record = GetMarcBiblio({ biblionumber => $biblionumber }); >+ my $tag = C4::Context->preference('marcflavour') eq 'UNIMARC' ? '462' : '774'; >+ foreach my $item (@items) { >+ # Remove fields that references the same itemnumber >+ # to avoid duplicates >+ my @fields = $record->field($tag); >+ my @duplicate_fields = grep { >+ $_->subfield('9') eq $item->itemnumber; >+ } @fields; >+ $record->delete_fields(@duplicate_fields); >+ >+ my $field = MARC::Field->new($tag, '', '', >+ 't' => $item->biblio->title, >+ '0' => $item->biblionumber, >+ '9' => $item->itemnumber); >+ $record->insert_fields_ordered($field); >+ >+ my $items_bundle = $items_bundle_rs->find_or_create({ biblionumber => $biblionumber }); >+ $items_bundle_item_rs->find_or_create({ >+ items_bundle_id => $items_bundle->items_bundle_id, >+ itemnumber => $item->itemnumber, >+ }); >+ >+ if (defined $withdrawn and $withdrawn ne '') { >+ $item->withdrawn($withdrawn)->store(); >+ } >+ } >+ ModBiblio($record, $biblionumber, $biblio->frameworkcode); >+ } >+ >+ # Store barcodes in the session to display messages after the redirect >+ $session->param('linkelements_notfound_barcodes', \@notfound_barcodes); >+ $session->param('linkelements_found_barcodes', \@found_barcodes); >+ $session->param('linkelements_alreadylinked_barcodes', \@alreadylinked_barcodes); >+ $session->flush(); >+ >+ print $cgi->redirect('/cgi-bin/koha/cataloguing/linkelements.pl?biblionumber=' . $biblionumber); >+ exit; >+} >+ >+my @notfound_barcodes = map { >+ Encode::is_utf8($_) ? $_ : Encode::decode('UTF-8', $_) >+} @{ $session->param('linkelements_notfound_barcodes') // [] }; >+ >+my @found_barcodes = map { >+ Encode::is_utf8($_) ? $_ : Encode::decode('UTF-8', $_) >+} @{ $session->param('linkelements_found_barcodes') // [] }; >+ >+my @alreadylinked_barcodes = map { >+ Encode::is_utf8($_) ? $_ : Encode::decode('UTF-8', $_) >+} @{ $session->param('linkelements_alreadylinked_barcodes') // [] }; >+ >+$session->clear([ >+ 'linkelements_notfound_barcodes', >+ 'linkelements_found_barcodes', >+ 'linkelements_alreadylinked_barcodes', >+]); >+$session->flush(); >+ >+$template->param( >+ biblionumber => $biblionumber, >+ notfound_barcodes => \@notfound_barcodes, >+ found_barcodes => \@found_barcodes, >+ alreadylinked_barcodes => \@alreadylinked_barcodes, >+); >+ >+output_html_with_http_headers $cgi, $cookie, $template->output; >diff --git a/circ/returns.pl b/circ/returns.pl >index e1bce3c3f1..9996396b17 100755 >--- a/circ/returns.pl >+++ b/circ/returns.pl >@@ -285,6 +285,37 @@ if ($barcode) { > additional_materials => $materials, > issue => $checkout, > ); >+ >+ my $items_bundle_rs = Koha::Database->new->schema->resultset('ItemsBundle'); >+ my $items_bundle = $items_bundle_rs->find({ biblionumber => $biblio->biblionumber }); >+ if ($items_bundle) { >+ my @items_bundle_items = map { >+ scalar Koha::Items->find($_->get_column('itemnumber')) >+ } $items_bundle->items_bundle_items; >+ >+ my $confirm = $query->param('confirm_items_bundle_return'); >+ unless ($confirm) { >+ $template->param( >+ items_bundle_return_confirmation => 1, >+ items_bundle_items => \@items_bundle_items, >+ ); >+ >+ output_html_with_http_headers $query, $cookie, $template->output; >+ exit; >+ } >+ >+ my $mark_missing_items_as_lost = $query->param('confirm_items_bundle_mark_missing_items_as_lost'); >+ if ($mark_missing_items_as_lost) { >+ my $barcodes = $query->param('verify-items-bundle-contents-barcodes'); >+ my $lost = $query->param('verify-items-bundle-contents-lost'); >+ my @barcodes = map { s/^\s+|\s+$//gr } (split /\n/, $barcodes); >+ foreach my $item (@items_bundle_items) { >+ unless (grep { $_ eq $item->barcode } @barcodes) { >+ $item->itemlost($lost)->store(); >+ } >+ } >+ } >+ } > } # FIXME else we should not call AddReturn but set BadBarcode directly instead > > my %input = ( >diff --git a/installer/data/mysql/atomicupdate/bug-24023-items-bundles.perl b/installer/data/mysql/atomicupdate/bug-24023-items-bundles.perl >new file mode 100644 >index 0000000000..2e6b7dc431 >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/bug-24023-items-bundles.perl >@@ -0,0 +1,37 @@ >+$DBversion = 'XXX'; >+if( CheckVersion( $DBversion ) ) { >+ $dbh->do(q{ >+ CREATE TABLE IF NOT EXISTS items_bundle ( >+ items_bundle_id SERIAL, >+ biblionumber INT NOT NULL, >+ CONSTRAINT pk_items_bundle_items_bundle_id >+ PRIMARY KEY (items_bundle_id), >+ CONSTRAINT fk_items_bundle_biblio_biblionumber >+ FOREIGN KEY (biblionumber) REFERENCES biblio (biblionumber) >+ ON DELETE CASCADE ON UPDATE CASCADE, >+ CONSTRAINT uniq_items_bundle_biblionumber >+ UNIQUE KEY (biblionumber) >+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci >+ }); >+ >+ $dbh->do(q{ >+ CREATE TABLE IF NOT EXISTS items_bundle_item ( >+ items_bundle_item_id SERIAL, >+ items_bundle_id BIGINT UNSIGNED NOT NULL, >+ itemnumber INT NOT NULL, >+ CONSTRAINT pk_items_bundle_item_items_bundle_item_id >+ PRIMARY KEY (items_bundle_item_id), >+ CONSTRAINT fk_items_bundle_item_itemnumber >+ FOREIGN KEY (itemnumber) REFERENCES items (itemnumber) >+ ON DELETE CASCADE ON UPDATE CASCADE, >+ CONSTRAINT fk_items_bundle_item_items_bundle_id >+ FOREIGN KEY (items_bundle_id) REFERENCES items_bundle (items_bundle_id) >+ ON DELETE CASCADE ON UPDATE CASCADE, >+ CONSTRAINT uniq_items_bundle_item_itemnumber >+ UNIQUE KEY (itemnumber) >+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci >+ }); >+ >+ SetVersion( $DBversion ); >+ print "Upgrade to $DBversion done (Bug 24023 - Items bundles)\n"; >+} >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index 9700ee04ab..5e3809ed0e 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -4576,6 +4576,44 @@ CREATE TABLE advanced_editor_macros ( > CONSTRAINT borrower_macro_fk FOREIGN KEY ( borrowernumber ) REFERENCES borrowers ( borrowernumber ) ON UPDATE CASCADE ON DELETE CASCADE > ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; > >+-- >+-- Table structure for table items_bundle >+-- >+ >+DROP TABLE IF EXISTS items_bundle; >+CREATE TABLE items_bundle ( >+ items_bundle_id SERIAL, >+ biblionumber INT NOT NULL, >+ CONSTRAINT pk_items_bundle_items_bundle_id >+ PRIMARY KEY (items_bundle_id), >+ CONSTRAINT fk_items_bundle_biblio_biblionumber >+ FOREIGN KEY (biblionumber) REFERENCES biblio (biblionumber) >+ ON DELETE CASCADE ON UPDATE CASCADE, >+ CONSTRAINT uniq_items_bundle_biblionumber >+ UNIQUE KEY (biblionumber) >+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; >+ >+-- >+-- Table structure for table items_bundle_item >+-- >+ >+DROP TABLE IF EXISTS items_bundle_item; >+CREATE TABLE items_bundle_item ( >+ items_bundle_item_id SERIAL, >+ items_bundle_id BIGINT UNSIGNED NOT NULL, >+ itemnumber INT NOT NULL, >+ CONSTRAINT pk_items_bundle_item_items_bundle_item_id >+ PRIMARY KEY (items_bundle_item_id), >+ CONSTRAINT fk_items_bundle_item_itemnumber >+ FOREIGN KEY (itemnumber) REFERENCES items (itemnumber) >+ ON DELETE CASCADE ON UPDATE CASCADE, >+ CONSTRAINT fk_items_bundle_item_items_bundle_id >+ FOREIGN KEY (items_bundle_id) REFERENCES items_bundle (items_bundle_id) >+ ON DELETE CASCADE ON UPDATE CASCADE, >+ CONSTRAINT uniq_items_bundle_item_itemnumber >+ UNIQUE KEY (itemnumber) >+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; >+ > /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; > /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; > /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/biblio-view-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/biblio-view-menu.inc >index 2080b07707..62a3f5bf20 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/biblio-view-menu.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/biblio-view-menu.inc >@@ -1,5 +1,6 @@ > [% USE Koha %] > [% USE Biblio %] >+[% PROCESS 'i18n.inc' %] > [% SET biblio_object_id = object || biblionumber || biblio.biblionumber %] > > <div id="menu"> >@@ -41,5 +42,11 @@ > <a href="/cgi-bin/koha/catalogue/issuehistory.pl?biblionumber=[% biblio_object_id | url %]" >Checkout history</a></li> > [% IF ( CAN_user_tools_view_system_logs ) %][% IF ( logview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/tools/viewlog.pl?do_it=1&modules=CATALOGUING&action=MODIFY&object=[% biblio_object_id | url %]&object_type=biblio">Modification log</a> </li>[% END %] > [% IF ( CAN_user_stockrotation_manage_rota_items && Koha.Preference('StockRotation') ) %][% IF ( stockrotationview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/catalogue/stockrotation.pl?biblionumber=[% biblio_object_id | uri %]">Rota</a> </li>[% END %] >+ >+[% IF Biblio.IsItemsBundle(biblio_object_id) %] >+ [% IF items_bundle_contents_view %]<li class="active">[% ELSE %]<li>[% END %] >+ <a href="/cgi-bin/koha/catalogue/items-bundle-contents.pl?biblionumber=[% biblio_object_id | uri %]">[% t('Item bundle contents') | html %]</a> >+ </li> >+[% END %] > </ul> > </div> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc >index 4d07b26ce6..a85c75e235 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc >@@ -63,6 +63,7 @@ CAN_user_serials_create_subscription ) %] > > [% IF ( CAN_user_editcatalogue_edit_catalogue ) %] > <li><a id="duplicatebiblio" href="/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=[% biblionumber | html %]&op=duplicate">Edit as new (duplicate)</a></li> >+ <li><a id="linkelements" href="/cgi-bin/koha/cataloguing/linkelements.pl?biblionumber=[% biblionumber | html %]&frameworkcode=[% current_framework | html %]">Link elements</a></li> > <li><a href="#" id="z3950copy">Replace record via Z39.50/SRU</a></li> > [% END %] > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/item-status.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/item-status.inc >new file mode 100644 >index 0000000000..ca6dc1d1ff >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/item-status.inc >@@ -0,0 +1,84 @@ >+[% USE AuthorisedValues %] >+[% USE Branches %] >+[% USE Koha %] >+[% USE KohaDates %] >+[% PROCESS 'i18n.inc' %] >+[% transfer = item.get_transfer() %] >+[% IF item.checkout %] >+ <span class="datedue"> >+ [% IF item.checkout.onsite_checkout %] >+ [% t('Currently in local use by') | html %] >+ [% ELSE %] >+ [% t('Checked out to') | html %] >+ [% END %] >+ [% INCLUDE 'patron-title.inc' patron=item.checkout.patron hide_patron_infos_if_needed=1 %] >+ : [% tx('due {date_due}', { date_due = item.checkout.date_due }) | html %] >+ </span> >+[% ELSIF transfer %] >+ [% datesent = BLOCK %][% transfer.datesent | $KohaDates %][% END %] >+ <span class="intransit">[% tx('In transit from {frombranch} to {tobranch} since {datesent}', { frombranch = Branches.GetName(transfer.frombranch), tobranch = Branches.GetName(transfer.tobranch), datesent = datesent }) %]</span> >+[% END %] >+ >+[% IF item.itemlost %] >+ [% itemlost_description = AuthorisedValues.GetDescriptionByKohaField({ kohafield = 'items.itemlost', authorised_value = item.itemlost }) %] >+ [% IF itemlost_description %] >+ <span class="lost">[% itemlost_description | html %]</span> >+ [% ELSE %] >+ <span class="lost">[% t('Unavailable (lost or missing)') | html %]</span> >+ [% END %] >+[% END %] >+ >+[% IF item.withdrawn %] >+ [% withdrawn_description = AuthorisedValues.GetDescriptionByKohaField({ kohafield = 'items.withdrawn', authorised_value = item.withdrawn }) %] >+ [% IF withdrawn_description %] >+ <span class="wdn">[% withdrawn_description | html %]</span> >+ [% ELSE %] >+ <span class="wdn">[% t('Withdrawn') | html %]</span> >+ [% END %] >+[% END %] >+ >+[% IF item.damaged %] >+ [% damaged_description = AuthorisedValues.GetDescriptionByKohaField({ kohafield = 'items.damaged', authorised_value = item.damaged }) %] >+ [% IF damaged_description %] >+ <span class="dmg">[% damaged_description | html %]</span> >+ [% ELSE %] >+ <span class="dmg">[% t('Damaged') | html %]</span> >+ [% END %] >+[% END %] >+ >+[% IF item.notforloan || item.effective_itemtype.notforloan %] >+ <span> >+ [% t('Not for loan') | html %] >+ [% notforloan_description = AuthorisedValues.GetDescriptionByKohaField({ kohafield = 'items.notforloan', authorised_value = item.notforloan }) %] >+ [% IF notforloan_description %] >+ ([% notforloan_description | html %]) >+ [% END %] >+ </span> >+[% END %] >+ >+[% hold = item.holds.next %] >+[% IF hold %] >+ <span> >+ [% IF hold.waitingdate %] >+ Waiting at [% Branches.GetName(hold.get_column('branchcode')) | html %] since [% hold.waitingdate | $KohaDates %]. >+ [% ELSE %] >+ Item-level hold (placed [% hold.reservedate | $KohaDates %]) for delivery at [% Branches.GetName(hold.get_column('branchcode')) | html %]. >+ [% END %] >+ [% IF Koha.Preference('canreservefromotherbranches') %] >+ [% t('Hold for:') | html %] >+ [% INCLUDE 'patron-title.inc' patron=hold.borrower hide_patron_infos_if_needed=1 %] >+ [% END %] >+ </span> >+[% END %] >+[% UNLESS item.notforloan || item.effective_itemtype.notforloan || item.onloan || item.itemlost || item.withdrawn || item.damaged || transfer || hold %] >+ <span>[% t('Available') | html %]</span> >+[% END %] >+ >+[% IF ( item.restricted ) %] >+ [% restricted_description = AuthorisedValues.GetDescriptionByKohaField({ kohafield = 'items.restricted', authorised_value = item.restricted }) %] >+ [% IF restricted_description %] >+ <span class="restricted">([% restricted_description | html %])</span> >+ [% ELSE %] >+ <span class="restricted">[% t('Restricted') | html %]</span> >+ [% END %] >+[% END %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >index db2462723b..500b7316d2 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >@@ -311,6 +311,7 @@ > [% IF ( hostrecords ) %]<th id="[% tab | html %]_hostrecord" data-colname="[% tab | html %]_hostrecord">Host records</th>[% END %] > [% IF ( analyze ) %]<th id="[% tab | html %]_usedin" data-colname="[% tab | html %]_usedin">Used in</th><th></th>[% END %] > [% IF ( ShowCourseReserves ) %]<th id="[% tab | html %]_course_reserves" data-colname="[% tab | html %]_course_reserves">Course reserves</th>[% END %] >+ [% IF itemdata_items_bundle %]<th id="[% tab | html %]_items_bundle" data-colname="[% tab | html %]_items_bundle">Items bundle</th>[% END %] > [% IF ( SpineLabelShowPrintOnBibDetails ) %]<th id="[% tab | html %]_spinelabel" data-colname="[% tab | html %]_spinelabel" class="NoSort">Spine label</th>[% END %] > [% IF ( CAN_user_editcatalogue_edit_items ) %]<th id="[% tab | html %]_actions" data-colname="[% tab | html %]_actions"class="NoSort"> </th>[% END %] > </tr> >@@ -526,6 +527,14 @@ Note that permanent location is a code, and location may be an authval. > </td> > [% END %] > >+ [% IF itemdata_items_bundle %] >+ <td> >+ [% INCLUDE 'biblio-default-view.inc' biblionumber = item.items_bundle.biblionumber.biblionumber %] >+ [% item.items_bundle.biblionumber.title | html %] >+ </a> >+ </td> >+ [% END %] >+ > [% IF ( SpineLabelShowPrintOnBibDetails ) %] > <td><a class="btn btn-default btn-xs print-label" href="/cgi-bin/koha/labels/spinelabel-print.pl?barcode=[% item.barcode | uri %]"><i class="fa fa-print"></i> Print label</a></td> > [% END %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/items-bundle-contents.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/items-bundle-contents.tt >new file mode 100644 >index 0000000000..aa1fe3fdec >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/items-bundle-contents.tt >@@ -0,0 +1,79 @@ >+[% USE raw %] >+[% USE Asset %] >+[% USE AuthorisedValues %] >+[% USE ItemTypes %] >+[% USE ColumnsSettings %] >+ >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Catalog › Items bundle contents for [% INCLUDE 'biblio-title-head.inc' %]</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+ >+<body id="catalog_items_bundle_contents" class="catalog"> >+ >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/catalogue/search.pl">Catalog</a> › Items bundle contents for <i>[% INCLUDE 'biblio-title.inc' %]</i></div> >+ >+<div class="main container-fluid"> >+ <div class="row"> >+ <div class="col-sm-10 col-sm-push-2"> >+ [% INCLUDE 'cat-toolbar.inc' %] >+ >+ <h1>Items bundle contents for [% INCLUDE 'biblio-title.inc' %]</h1> >+ >+ <main> >+ <table id="items-bundle-contents-table"> >+ <thead> >+ <tr> >+ <th>Title</th> >+ <th>Author</th> >+ <th>Collection code</th> >+ <th>Item type</th> >+ <th>Callnumber</th> >+ <th>Barcode</th> >+ <th>Status</th> >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH item IN items %] >+ <tr> >+ <td>[% INCLUDE 'biblio-default-view.inc' biblionumber=item.biblionumber %][% INCLUDE 'biblio-title.inc' biblio=item.biblio %]</a></td> >+ <td>[% item.biblio.author | html %]</td> >+ <td>[% AuthorisedValues.GetByCode('CCODE', item.ccode) | html %]</td> >+ <td>[% ItemTypes.GetDescription(item.itype) | html %]</td> >+ <td>[% item.itemcallnumber | html %]</td> >+ <td>[% item.barcode | html %]</td> >+ <td>[% INCLUDE 'item-status.inc' item=item %]</td> >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+ </main> >+ </div> >+ >+ <div class="col-sm-2 col-sm-pull-10"> >+ <aside> >+ [% INCLUDE 'biblio-view-menu.inc' items_bundle_contents_view = 1 %] >+ </aside> >+ </div> >+ </div> >+ >+ [% Asset.js('js/table_filters.js') | $raw %] >+ [% Asset.js('lib/jquery/plugins/jquery.dataTables.columnFilter.js') | $raw %] >+ [% INCLUDE 'datatables.inc' %] >+ [% INCLUDE 'columns_settings.inc' %] >+ <script> >+ $(document).ready(function () { >+ var columns_settings = [% ColumnsSettings.GetColumns('catalogue', 'items-bundle-contents', 'items-bundle-contents-table', 'json') | $raw %]; >+ KohaTable('items-bundle-contents-table', { >+ dom: '<"pager"<"table_entries"ilp><"table_controls"B>>tr', >+ pagingType: 'full', >+ autoWidth: false, >+ }, columns_settings, true); >+ activate_filters('items-bundle-contents-table'); >+ }); >+ </script> >+ >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/linkelements.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/linkelements.tt >new file mode 100644 >index 0000000000..cf5cb0a7d0 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/linkelements.tt >@@ -0,0 +1,91 @@ >+[% USE AuthorisedValues %] >+[% PROCESS 'i18n.inc' %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Link elements together</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+<body id="tools_batchMod" class="tools"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+<div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">[% t('Home') | html %]</a> › >+ <a href="/cgi-bin/koha/cataloguing/addbooks.pl">[% t('Cataloguing') | html %]</a> › >+ [% t('Link elements to the biblio') | html %] >+</div> >+ >+[% BLOCK barcodes_table %] >+ <table> >+ <thead> >+ <tr> >+ <th>[% t('Barcode') | html %]</th> >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH barcode IN barcodes %] >+ <tr> >+ <td>[% barcode | html %]</td> >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+[% END %] >+ >+<div class="main container-fluid"> >+ <div class="row"> >+ <div class="col-sm-10 col-sm-push-2"> >+ <main> >+ <h1>[% t('Link elements to the biblio') | html %]</h1> >+ >+ [% IF ( notfound_barcodes ) %] >+ <div class="dialog alert"> >+ <p>[% t('Warning: the following barcodes were not found:') | html %]</p> >+ [% PROCESS barcodes_table barcodes = notfound_barcodes %] >+ </div> >+ [% END %] >+ >+ [% IF ( alreadylinked_barcodes ) %] >+ <div class="dialog alert"> >+ <p>[% t('Warning: the following barcodes are already linked to another biblio') | html %]</p> >+ [% PROCESS barcodes_table barcodes = alreadylinked_barcodes %] >+ </div> >+ [% END %] >+ >+ [% IF found_barcodes %] >+ <div class="dialog message"> >+ <p>[% t('The following barcodes were linked:') | html %]</p> >+ >+ [% PROCESS barcodes_table barcodes = found_barcodes %] >+ </div> >+ [% END %] >+ >+ <form method="post" action="/cgi-bin/koha/cataloguing/linkelements.pl"> >+ <fieldset class="rows"> >+ <legend>[% t('Items') | html %]</legend> >+ <ol> >+ <li> >+ <label for="barcodelist">[% t('Barcode list (one barcode per line):') | html %] </label> >+ <textarea rows="10" cols="30" id="barcodelist" name="barcodelist"></textarea> >+ </li> >+ <li> >+ <label for="withdrawn">[% t('Change withdrawn status to') | html %]</label> >+ <select id="withdrawn" name="withdrawn"> >+ <option value=""></option> >+ [% FOREACH av IN AuthorisedValues.Get('WITHDRAWN') %] >+ <option value="[% av.authorised_value | html %]">[% av.lib | html %]</option> >+ [% END %] >+ </select> >+ </li> >+ </ol> >+ <input type="hidden" name="biblionumber" value="[% biblionumber | html %]" /> >+ </fieldset> >+ >+ <fieldset class="action"> >+ <input type="submit" value="Continue" class="button" /> >+ <a class="cancel" href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblionumber | url %]">Cancel</a> >+ </fieldset> >+ </form> >+ </main> >+ </div> >+ </div> >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt >index 0647470a5e..28fa36b085 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt >@@ -6,6 +6,7 @@ > [% USE ItemTypes %] > [% USE AuthorisedValues %] > [% USE TablesSettings %] >+[% PROCESS 'i18n.inc' %] > [% PROCESS 'member-display-address-style.inc' %] > [% SET footerjs = 1 %] > [% BLOCK display_bormessagepref %] >@@ -659,6 +660,72 @@ > [% INCLUDE all_checkin_messages %] > </div> > >+ [% IF items_bundle_return_confirmation %] >+ <div class="dialog alert">[% t('The returned item is an items bundle and needs confirmation') | html %]</div> >+ >+ <table class="table table-condensed table-bordered" id="items-bundle-contents-table"> >+ <thead> >+ <tr> >+ <th>[% t('Title') | html %]</th> >+ <th>[% t('Author') | html %]</th> >+ <th>[% t('Collection code') | html %]</th> >+ <th>[% t('Item type') | html %]</th> >+ <th>[% t('Callnumber') | html %]</th> >+ <th>[% t('Barcode') | html %]</th> >+ <th>[% t('Status') | html %]</th> >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH item IN items_bundle_items %] >+ <tr data-barcode="[% item.barcode | html %]"> >+ <td>[% INCLUDE 'biblio-default-view.inc' biblionumber=item.biblionumber %][% INCLUDE 'biblio-title.inc' biblio=item.biblio %]</a></td> >+ <td>[% item.biblio.author | html %]</td> >+ <td>[% AuthorisedValues.GetByCode('CCODE', item.ccode) | html %]</td> >+ <td>[% ItemTypes.GetDescription(item.itype) | html %]</td> >+ <td>[% item.itemcallnumber | html %]</td> >+ <td>[% item.barcode | html %]</td> >+ <td>[% INCLUDE 'item-status.inc' item=item %]</td> >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+ >+ <div id="items-bundle-confirmation-action"> >+ <form method="post"> >+ <input type="hidden" name="barcode" value="[% itembarcode | html %]"> >+ <input type="hidden" name="confirm_items_bundle_return" value="1"> >+ <button class="btn btn-default" type="submit"><i class="fa fa-check"></i> [% t('Confirm checkin without verifying') | html %]</button> >+ </form> >+ >+ <button id="verify-items-bundle-contents-button" class="btn btn-default">[% t('Verify items bundle contents') | html %]</button> >+ </div> >+ >+ <div id="verify-items-bundle-contents-form-wrapper"> >+ <form method="post"> >+ <div class="form-group"> >+ <label for="verify-items-bundle-contents-barcodes">Barcodes</label> >+ <textarea autocomplete="off" id="verify-items-bundle-contents-barcodes" name="verify-items-bundle-contents-barcodes" class="form-control"></textarea> >+ <div class="help-block">[% t('Scan barcodes found in the items bundle and compare it to the table above') | html %]</div> >+ </div> >+ >+ <div class="form-group"> >+ <label for="verify-items-bundle-contents-lost">[% t('Lost status') | html %]</label> >+ <select id="verify-items-bundle-contents-lost" name="verify-items-bundle-contents-lost" class="form-control"> >+ [% FOREACH av IN AuthorisedValues.Get('LOST') %] >+ <option value="[% av.authorised_value | html %]">[% av.lib | html %]</option> >+ [% END %] >+ </select> >+ <div class="help-block">[% t('If some items are missing, they will be marked as lost with this status') | html %]</div> >+ </div> >+ <input type="hidden" name="barcode" value="[% itembarcode | html %]"> >+ <input type="hidden" name="confirm_items_bundle_return" value="1"> >+ <input type="hidden" name="confirm_items_bundle_mark_missing_items_as_lost" value="1"> >+ <button type="submit" class="btn btn-default"><i class="fa fa-check"></i> [% t('Confirm checkin and mark missing items as lost') | html %]</button> >+ <button type="button" class="btn btn-default" id="verify-items-bundle-contents-cancel-button"><i class="fa fa-close"></i> [% t('Cancel') | html %]</button> >+ </form> >+ </div> >+ [% END %] >+ > <form id="checkin-form" method="post" action="/cgi-bin/koha/circ/returns.pl" autocomplete="off" > > <fieldset id="circ_returns_checkin"> > <div class="show_checkin_dialog" style="float:right;display:none"><button type="button" class="btn btn-default btn-sm" data-toggle="tooltip" title="Show the last checkin message"><i class="fa fa-info"></i></button></div> >@@ -1073,6 +1140,31 @@ > $('[data-toggle="tooltip"]').tooltip(); > }); > </script> >+ >+ <script> >+ $(document).ready(function () { >+ $('#verify-items-bundle-contents-form-wrapper').hide(); >+ $('#verify-items-bundle-contents-button').on('click', function () { >+ $('#verify-items-bundle-contents-form-wrapper').show(); >+ $('#items-bundle-confirmation-action').hide(); >+ }); >+ $('#verify-items-bundle-contents-cancel-button').on('click', function () { >+ $('#verify-items-bundle-contents-form-wrapper').hide(); >+ $('#items-bundle-confirmation-action').show(); >+ }); >+ $('#verify-items-bundle-contents-barcodes').on('input', function (ev) { >+ const barcodes = ev.target.value.split('\n').map(function(s) { return s.trim() }); >+ $('#items-bundle-contents-table tr').each(function () { >+ const barcode = this.getAttribute('data-barcode'); >+ if (barcodes.includes(barcode)) { >+ this.classList.add('ok'); >+ } else { >+ this.classList.remove('ok'); >+ } >+ }) >+ }); >+ }); >+ </script> > [% END %] > > [% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt >index 2db78af6bd..68d538d424 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/inventory.tt >@@ -93,6 +93,17 @@ > [% END %] > </select> > </li> >+ [% IF items_bundles.size > 0 %] >+ <li> >+ <label for="items_bundle">Items bundle:</label> >+ <select id="items_bundle" name="items_bundle"> >+ <option value=""></option> >+ [% FOREACH items_bundle IN items_bundles %] >+ <option value="[% items_bundle.items_bundle_id | html %]">[% items_bundle.biblionumber.title | html %]</option> >+ [% END %] >+ </select> >+ </li> >+ [% END %] > </ol> > </fieldset> > >@@ -282,7 +293,8 @@ > $('#locationloop').val() || > $('#minlocation').val() || > $('#maxlocation').val() || >- $('#statuses input:checked').length >+ $('#statuses input:checked').length || >+ $('#items_bundle').val() > ) ) { > return confirm( > _("You have not selected any catalog filters and are about to compare a file of barcodes to your entire catalog.") + "\n\n" + >@@ -405,6 +417,12 @@ > }); > }); > </script> >+ [% INCLUDE 'select2.inc' %] >+ <script> >+ $(document).ready(function () { >+ $('#items_bundle').select2(); >+ }); >+ </script> > [% END %] > > [% INCLUDE 'intranet-bottom.inc' %] >diff --git a/tools/inventory.pl b/tools/inventory.pl >index 13b7a538a5..cbf0efcb57 100755 >--- a/tools/inventory.pl >+++ b/tools/inventory.pl >@@ -47,6 +47,7 @@ my $minlocation=$input->param('minlocation') || ''; > my $maxlocation=$input->param('maxlocation'); > my $class_source=$input->param('class_source'); > $maxlocation=$minlocation.'Z' unless ( $maxlocation || ! $minlocation ); >+my $items_bundle = $input->param('items_bundle'); > my $location=$input->param('location') || ''; > my $ignoreissued=$input->param('ignoreissued'); > my $ignore_waiting_holds = $input->param('ignore_waiting_holds'); >@@ -68,6 +69,12 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( > } > ); > >+my $schema = Koha::Database->new()->schema(); >+my $items_bundle_rs = $schema->resultset('ItemsBundle'); >+my @items_bundles = $items_bundle_rs->search(undef, { >+ order_by => { -asc => ['biblionumber.title'] }, >+ join => ['biblionumber'], >+}); > my @authorised_value_list; > my $authorisedvalue_categories = ''; > >@@ -125,6 +132,7 @@ my $pref_class = C4::Context->preference("DefaultClassificationSource"); > > $template->param( > authorised_values => \@authorised_value_list, >+ items_bundles => \@items_bundles, > today => dt_from_string, > minlocation => $minlocation, > maxlocation => $maxlocation, >@@ -234,6 +242,7 @@ if ( $op && ( !$uploadbarcodes || $compareinv2barcd )) { > minlocation => $minlocation, > maxlocation => $maxlocation, > class_source => $class_source, >+ items_bundle => $items_bundle, > location => $location, > ignoreissued => $ignoreissued, > datelastseen => $datelastseen, >@@ -251,6 +260,7 @@ if( @scanned_items ) { > maxlocation => $maxlocation, > class_source => $class_source, > location => $location, >+ items_bundle => $items_bundle, > ignoreissued => undef, > datelastseen => undef, > branchcode => $branchcode, >-- >2.20.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 24023
:
95331
|
101555
|
109287
|
112275
|
114855
|
119094
|
119554