Bugzilla – Attachment 124613 Details for
Bug 24857
Add ability to group items for records
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 24857: Adapt code to the volumes => item_groups change
Bug-24857-Adapt-code-to-the-volumes--itemgroups-ch.patch (text/plain), 114.62 KB, created by
Martin Renvoize (ashimema)
on 2021-09-07 14:12:31 UTC
(
hide
)
Description:
Bug 24857: Adapt code to the volumes => item_groups change
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2021-09-07 14:12:31 UTC
Size:
114.62 KB
patch
obsolete
>From 9d6f9a920d1b0e7b047d3e1d1bd6987f941410ff Mon Sep 17 00:00:00 2001 >From: Tomas Cohen Arazi <tomascohen@theke.io> >Date: Wed, 18 Aug 2021 11:15:41 -0300 >Subject: [PATCH] Bug 24857: Adapt code to the volumes => item_groups change > >This patch updates the code so all references to 'volumes' are >translated into 'item groups'. > >Relevant changes: >- API routes and specs >- Permission name is changed >- Syspref name changed > >Note: I removed a behavior that felt unnatural (at least in the place it >was put): deleting the item group if the linked item is deleted. It >feels like a controller thing, and also something that could be offered >to the staff on the UI on item deletion. To avoid blocking the feature, >I suggest this removal, and discuss it in its own context. > >To test: >1. Run: > $ reset_all >2. Apply this patchset >3. Run: > $ updatedatabase >=> SUCCESS: Update works >4. Repeat 1 (with the patches applied) >=> SUCCESS: Install works with this DB structure >5. Run all the tests: > $ kshell > k$ git diff origin/master --name-only | grep -e '\.t$' | xargs prove >=> SUCCESS: Tests pass! >6. Follow the original plan (with the Volume=>ItemGRoup change in mind) >=> SUCCESS: All good! >7. Sign off :-D > >Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com> >--- > Koha/Biblio.pm | 14 +- > Koha/Biblio/{Volume.pm => ItemGroup.pm} | 40 ++- > Koha/Biblio/{Volume => ItemGroup}/Item.pm | 8 +- > Koha/Biblio/{Volume => ItemGroup}/Items.pm | 10 +- > Koha/Biblio/{Volumes.pm => ItemGroups.pm} | 10 +- > Koha/Item.pm | 27 +- > .../V1/Biblios/{Volumes.pm => ItemGroups.pm} | 87 +++--- > .../Biblios/{Volumes => ItemGroups}/Items.pm | 44 +-- > Koha/Schema/Result/Biblio.pm | 4 - > Koha/Schema/Result/ItemGroup.pm | 19 +- > Koha/Schema/Result/ItemGroupItem.pm | 7 +- > api/v1/swagger/definitions.json | 6 +- > .../{volume.json => item_group.json} | 16 +- > api/v1/swagger/paths.json | 16 +- > ..._volumes.json => biblios_item_groups.json} | 138 +++++----- > catalogue/detail.pl | 37 ++- > cataloguing/additem.pl | 66 ++--- > .../prog/en/includes/permissions.inc | 6 +- > .../admin/preferences/circulation.pref | 4 +- > .../prog/en/modules/catalogue/detail.tt | 256 +++++++++--------- > .../prog/en/modules/cataloguing/additem.tt | 30 +- > .../prog/js/cataloging_additem.js | 24 +- > t/db_dependent/Koha/Biblio.t | 29 +- > t/db_dependent/Koha/Biblio/ItemGroups.t | 70 +++++ > t/db_dependent/Koha/Item.t | 27 +- > t/db_dependent/Koha/Volumes.t | 156 ----------- > .../api/v1/{volumes.t => item_groups.t} | 87 +++--- > 27 files changed, 592 insertions(+), 646 deletions(-) > rename Koha/Biblio/{Volume.pm => ItemGroup.pm} (70%) > rename Koha/Biblio/{Volume => ItemGroup}/Item.pm (82%) > rename Koha/Biblio/{Volume => ItemGroup}/Items.pm (79%) > rename Koha/Biblio/{Volumes.pm => ItemGroups.pm} (81%) > rename Koha/REST/V1/Biblios/{Volumes.pm => ItemGroups.pm} (53%) > rename Koha/REST/V1/Biblios/{Volumes => ItemGroups}/Items.pm (70%) > rename api/v1/swagger/definitions/{volume.json => item_group.json} (67%) > rename api/v1/swagger/paths/{biblios_volumes.json => biblios_item_groups.json} (83%) > create mode 100755 t/db_dependent/Koha/Biblio/ItemGroups.t > delete mode 100755 t/db_dependent/Koha/Volumes.t > rename t/db_dependent/api/v1/{volumes.t => item_groups.t} (73%) > >diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm >index eb0ce09d32..29a32142c6 100644 >--- a/Koha/Biblio.pm >+++ b/Koha/Biblio.pm >@@ -33,8 +33,8 @@ use base qw(Koha::Object); > use Koha::Acquisition::Orders; > use Koha::ArticleRequest::Status; > use Koha::ArticleRequests; >+use Koha::Biblio::ItemGroups; > use Koha::Biblio::Metadatas; >-use Koha::Biblio::Volumes; > use Koha::Biblioitems; > use Koha::CirculationRules; > use Koha::Item::Transfer::Limits; >@@ -113,19 +113,19 @@ sub active_orders { > return $self->orders->search({ datecancellationprinted => undef }); > } > >-=head3 volumes >+=head3 item_groups > >-my $volumes = $biblio->volumes(); >+my $item_groups = $biblio->item_groups(); > >-Returns a Koha::Biblio::Volumes object >+Returns a Koha::Biblio::ItemGroups object > > =cut > >-sub volumes { >+sub item_groups { > my ( $self ) = @_; > >- my $volumes = $self->_result->volumes; >- return Koha::Biblio::Volumes->_new_from_dbic($volumes); >+ my $item_groups = $self->_result->item_groups; >+ return Koha::Biblio::ItemGroups->_new_from_dbic($item_groups); > } > > =head3 can_article_request >diff --git a/Koha/Biblio/Volume.pm b/Koha/Biblio/ItemGroup.pm >similarity index 70% >rename from Koha/Biblio/Volume.pm >rename to Koha/Biblio/ItemGroup.pm >index a5eda853dc..8c4ba66db1 100644 >--- a/Koha/Biblio/Volume.pm >+++ b/Koha/Biblio/ItemGroup.pm >@@ -1,4 +1,4 @@ >-package Koha::Biblio::Volume; >+package Koha::Biblio::ItemGroup; > > # This file is part of Koha. > # >@@ -19,13 +19,13 @@ use Modern::Perl; > > use base qw(Koha::Object); > >-use Koha::Biblio::Volume::Items; >+use Koha::Biblio::ItemGroup::Items; > use Koha::Exceptions::Object; > use Koha::Items; > > =head1 NAME > >-Koha::Volume - Koha Volume Object class >+Koha::Biblio::ItemGroup - Koha ItemGroup Object class > > =head1 API > >@@ -33,7 +33,7 @@ Koha::Volume - Koha Volume Object class > > =head3 store > >- $volume->store; >+ $item_group->store; > > Overloaded I<store> method that takes care of creation date handling. > >@@ -56,24 +56,24 @@ sub store { > > =head3 items > >- my $items = $volume->items; >+ my $items = $item_group->items; > >-Returns all the items linked to the volume. >+Returns all the items linked to the item group. > > =cut > > sub items { > my ($self) = @_; > >- my $items_rs = $self->_result->volume_items; >- my @item_numbers = $items_rs->get_column('itemnumber')->all; >+ my $items_rs = $self->_result->item_group_items; >+ my @item_ids = $items_rs->get_column('item_id')->all; > >- return Koha::Items->new->empty unless @item_numbers; >+ return Koha::Items->new->empty unless @item_ids; > > return Koha::Items->search( > { > itemnumber => { >- -in => \@item_numbers >+ -in => \@item_ids > } > } > ); >@@ -81,7 +81,7 @@ sub items { > > =head3 add_item > >- $volume->add_item({ item_id => $item_id }); >+ $item_group->add_item({ item_id => $item_id }); > > =cut > >@@ -91,16 +91,16 @@ sub add_item { > my $item_id = $params->{item_id}; > > my $item = Koha::Items->find( $item_id ); >- unless ( $item->biblionumber == $self->biblionumber ) { >+ unless ( $item->biblionumber == $self->biblio_id ) { > Koha::Exceptions::Object::FKConstraint->throw( >- broken_fk => 'biblionumber' >+ broken_fk => 'biblio_id' > ); > } > >- Koha::Biblio::Volume::Item->new( >+ Koha::Biblio::ItemGroup::Item->new( > { >- itemnumber => $item_id, >- volume_id => $self->id >+ item_group_id => $self->id, >+ item_id => $item_id, > } > )->store; > >@@ -109,15 +109,13 @@ sub add_item { > > =head3 to_api_mapping > >-This method returns the mapping for representing a Koha::Biblio::Volume object >+This method returns the mapping for representing a Koha::Biblio::ItemGroup object > on the API. > > =cut > > sub to_api_mapping { > return { >- id => 'volume_id', >- biblionumber => 'biblio_id', > created_on => 'creation_date', > updated_on => 'modification_date' > }; >@@ -130,7 +128,7 @@ sub to_api_mapping { > =cut > > sub _type { >- return 'Volume'; >+ return 'ItemGroup'; > } > > =head3 object_class >@@ -138,7 +136,7 @@ sub _type { > =cut > > sub object_class { >- return 'Koha::Biblio::Volume'; >+ return 'Koha::Biblio::ItemGroup'; > } > > 1; >diff --git a/Koha/Biblio/Volume/Item.pm b/Koha/Biblio/ItemGroup/Item.pm >similarity index 82% >rename from Koha/Biblio/Volume/Item.pm >rename to Koha/Biblio/ItemGroup/Item.pm >index 9698f8fa65..17a175f302 100644 >--- a/Koha/Biblio/Volume/Item.pm >+++ b/Koha/Biblio/ItemGroup/Item.pm >@@ -1,4 +1,4 @@ >-package Koha::Biblio::Volume::Item; >+package Koha::Biblio::ItemGroup::Item; > > # This file is part of Koha. > # >@@ -21,7 +21,7 @@ use base qw(Koha::Object); > > =head1 NAME > >-Koha::Volume::Item - Koha Volume Item Object class >+Koha::Biblio::ItemGroup::Item - Koha ItemGroup Item Object class > > =head1 API > >@@ -32,7 +32,7 @@ Koha::Volume::Item - Koha Volume Item Object class > =cut > > sub _type { >- return 'VolumeItem'; >+ return 'ItemGroupItem'; > } > > =head3 object_class >@@ -40,7 +40,7 @@ sub _type { > =cut > > sub object_class { >- return 'Koha::Biblio::Volume::Item'; >+ return 'Koha::Biblio::ItemGroup::Item'; > } > > 1; >diff --git a/Koha/Biblio/Volume/Items.pm b/Koha/Biblio/ItemGroup/Items.pm >similarity index 79% >rename from Koha/Biblio/Volume/Items.pm >rename to Koha/Biblio/ItemGroup/Items.pm >index dc0ecf814d..9018c5e5fa 100644 >--- a/Koha/Biblio/Volume/Items.pm >+++ b/Koha/Biblio/ItemGroup/Items.pm >@@ -1,4 +1,4 @@ >-package Koha::Biblio::Volume::Items; >+package Koha::Biblio::ItemGroup::Items; > > # This file is part of Koha. > # >@@ -17,13 +17,13 @@ package Koha::Biblio::Volume::Items; > > use Modern::Perl; > >-use Koha::Biblio::Volume::Item; >+use Koha::Biblio::ItemGroup::Item; > > use base qw(Koha::Objects); > > =head1 NAME > >-Koha::Biblio::Volume::Items - Koha Volume Items Object set class >+Koha::Biblio::ItemGroup::Items - Koha ItemGroup Items Object set class > > =head1 API > >@@ -34,7 +34,7 @@ Koha::Biblio::Volume::Items - Koha Volume Items Object set class > =cut > > sub _type { >- return 'VolumeItem'; >+ return 'ItemGroupItem'; > } > > =head3 object_class >@@ -42,7 +42,7 @@ sub _type { > =cut > > sub object_class { >- return 'Koha::Biblio::Volume::Item'; >+ return 'Koha::Biblio::ItemGroup::Item'; > } > > 1; >diff --git a/Koha/Biblio/Volumes.pm b/Koha/Biblio/ItemGroups.pm >similarity index 81% >rename from Koha/Biblio/Volumes.pm >rename to Koha/Biblio/ItemGroups.pm >index 0729930fc5..78a6b337c6 100644 >--- a/Koha/Biblio/Volumes.pm >+++ b/Koha/Biblio/ItemGroups.pm >@@ -1,4 +1,4 @@ >-package Koha::Biblio::Volumes; >+package Koha::Biblio::ItemGroups; > > # This file is part of Koha. > # >@@ -17,13 +17,13 @@ package Koha::Biblio::Volumes; > > use Modern::Perl; > >-use Koha::Biblio::Volume; >+use Koha::Biblio::ItemGroup; > > use base qw(Koha::Objects); > > =head1 NAME > >-Koha::Biblio::Volumes - Koha Volume Object set class >+Koha::Biblio::ItemGroups - Koha ItemGroup Object set class > > =head1 API > >@@ -34,7 +34,7 @@ Koha::Biblio::Volumes - Koha Volume Object set class > =cut > > sub _type { >- return 'Volume'; >+ return 'ItemGroup'; > } > > =head3 object_class >@@ -42,7 +42,7 @@ sub _type { > =cut > > sub object_class { >- return 'Koha::Biblio::Volume'; >+ return 'Koha::Biblio::ItemGroup'; > } > > 1; >diff --git a/Koha/Item.pm b/Koha/Item.pm >index cd51bf85e7..50c156c0b4 100644 >--- a/Koha/Item.pm >+++ b/Koha/Item.pm >@@ -32,6 +32,7 @@ use C4::ClassSource qw( GetClassSort ); > use C4::Log qw( logaction ); > use C4::Reserves; > >+use Koha::Biblio::ItemGroups; > use Koha::Checkouts; > use Koha::CirculationRules; > use Koha::CoverImages; >@@ -224,14 +225,8 @@ sub delete { > # FIXME check the item has no current issues > # i.e. raise the appropriate exception > >- # Get the volume so we can delete it later if it has no items left >- my $volume = C4::Context->preference('EnableVolumes') ? $self->volume : undef; >- > my $result = $self->SUPER::delete; > >- # Delete the volume if it has no items left >- $volume->delete if ( $volume && $volume->items->count == 0 ); >- > my $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX }); > $indexer->index_records( $self->biblionumber, "specialUpdate", "biblioserver" ) > unless $params->{skip_record_index}; >@@ -401,25 +396,25 @@ sub checkout { > return Koha::Checkout->_new_from_dbic( $checkout_rs ); > } > >-=head3 volume >+=head3 item_group > >-my $volume = $item->volume; >+my $item_group = $item->item_group; > >-Return the volume for this item >+Return the item group for this item > > =cut > >-sub volume { >+sub item_group { > my ( $self ) = @_; > >- my $volume_item = $self->_result->volume_items->first; >- return unless $volume_item; >+ my $item_group_item = $self->_result->item_group_item; >+ return unless $item_group_item; > >- my $volume_rs = $volume_item->volume; >- return unless $volume_rs; >+ my $item_group_rs = $item_group_item->item_group; >+ return unless $item_group_rs; > >- my $volume = Koha::Biblio::Volume->_new_from_dbic( $volume_rs ); >- return $volume; >+ my $item_group = Koha::Biblio::ItemGroup->_new_from_dbic( $item_group_rs ); >+ return $item_group; > } > > =head3 holds >diff --git a/Koha/REST/V1/Biblios/Volumes.pm b/Koha/REST/V1/Biblios/ItemGroups.pm >similarity index 53% >rename from Koha/REST/V1/Biblios/Volumes.pm >rename to Koha/REST/V1/Biblios/ItemGroups.pm >index dedf26bdf4..f7784f4ba0 100644 >--- a/Koha/REST/V1/Biblios/Volumes.pm >+++ b/Koha/REST/V1/Biblios/ItemGroups.pm >@@ -1,4 +1,4 @@ >-package Koha::REST::V1::Biblios::Volumes; >+package Koha::REST::V1::Biblios::ItemGroups; > > # This file is part of Koha. > # >@@ -19,14 +19,14 @@ use Modern::Perl; > > use Mojo::Base 'Mojolicious::Controller'; > >-use Koha::Biblio::Volumes; >+use Koha::Biblio::ItemGroups; > > use Scalar::Util qw(blessed); > use Try::Tiny; > > =head1 NAME > >-Koha::REST::V1::Biblios::Volumes - Koha REST API for handling volumes (V1) >+Koha::REST::V1::Biblios::ItemGroups - Koha REST API for handling item groups (V1) > > =head1 API > >@@ -36,7 +36,7 @@ Koha::REST::V1::Biblios::Volumes - Koha REST API for handling volumes (V1) > > =head3 list > >-Controller function that handles listing Koha::Biblio::Volume objects >+Controller function that handles listing Koha::Biblio::ItemGroup objects > > =cut > >@@ -44,11 +44,11 @@ sub list { > my $c = shift->openapi->valid_input or return; > > return try { >- my $volumes_set = Koha::Biblio::Volumes->new; >- my $volumes = $c->objects->search( $volumes_set ); >+ my $item_groups_set = Koha::Biblio::ItemGroups->new; >+ my $item_groups = $c->objects->search( $item_groups_set ); > return $c->render( > status => 200, >- openapi => $volumes >+ openapi => $item_groups > ); > } > catch { >@@ -58,7 +58,7 @@ sub list { > > =head3 get > >-Controller function that handles retrieving a single Koha::Biblio::Volume >+Controller function that handles retrieving a single Koha::Biblio::ItemGroup > > =cut > >@@ -66,22 +66,22 @@ sub get { > my $c = shift->openapi->valid_input or return; > > try { >- my $volume_id = $c->validation->param('volume_id'); >+ my $item_group_id = $c->validation->param('item_group_id'); > my $biblio_id = $c->validation->param('biblio_id'); > >- my $volume = $c->objects->find( Koha::Biblio::Volumes->new, $volume_id ); >+ my $item_group = $c->objects->find( Koha::Biblio::ItemGroups->new, $item_group_id ); > >- if ( $volume && $volume->{biblio_id} eq $biblio_id ) { >+ if ( $item_group && $item_group->{biblio_id} eq $biblio_id ) { > return $c->render( > status => 200, >- openapi => $volume >+ openapi => $item_group > ); > } > else { > return $c->render( > status => 404, > openapi => { >- error => 'Volume not found' >+ error => 'Item group not found' > } > ); > } >@@ -93,7 +93,7 @@ sub get { > > =head3 add > >-Controller function to handle adding a Koha::Biblio::Volume object >+Controller function to handle adding a Koha::Biblio::ItemGroup object > > =cut > >@@ -101,26 +101,27 @@ sub add { > my $c = shift->openapi->valid_input or return; > > return try { >- my $volume_data = $c->validation->param('body'); >+ my $item_group_data = $c->validation->param('body'); > # biblio_id comes from the path >- $volume_data->{biblio_id} = $c->validation->param('biblio_id'); >+ $item_group_data->{biblio_id} = $c->validation->param('biblio_id'); > >- my $volume = Koha::Biblio::Volume->new_from_api($volume_data); >- $volume->store->discard_changes(); >+ my $item_group = Koha::Biblio::ItemGroup->new_from_api($item_group_data); >+ $item_group->store->discard_changes(); > >- $c->res->headers->location( $c->req->url->to_string . '/' . $volume->id ); >+ $c->res->headers->location( $c->req->url->to_string . '/' . $item_group->id ); > > return $c->render( > status => 201, >- openapi => $volume->to_api >+ openapi => $item_group->to_api > ); > } > catch { > if ( blessed($_) ) { >- my $to_api_mapping = Koha::Biblio::Volume->new->to_api_mapping; >+ my $to_api_mapping = Koha::Biblio::ItemGroup->new->to_api_mapping; > >- if ( $_->isa('Koha::Exceptions::Object::FKConstraint') and >- $to_api_mapping->{ $_->broken_fk } eq 'biblio_id') { >+ if ( $_->isa('Koha::Exceptions::Object::FKConstraint') >+ and $_->broken_fk eq 'biblio_id' ) >+ { > return $c->render( > status => 404, > openapi => { error => "Biblio not found" } >@@ -134,7 +135,7 @@ sub add { > > =head3 update > >-Controller function to handle updating a Koha::Biblio::Volume object >+Controller function to handle updating a Koha::Biblio::ItemGroup object > > =cut > >@@ -142,31 +143,31 @@ sub update { > my $c = shift->openapi->valid_input or return; > > return try { >- my $volume_id = $c->validation->param('volume_id'); >- my $biblio_id = $c->validation->param('biblio_id'); >+ my $item_group_id = $c->validation->param('item_group_id'); >+ my $biblio_id = $c->validation->param('biblio_id'); > >- my $volume = Koha::Biblio::Volumes->find( $volume_id ); >+ my $item_group = Koha::Biblio::ItemGroups->find( $item_group_id ); > >- unless ( $volume && $volume->biblionumber eq $biblio_id ) { >+ unless ( $item_group && $item_group->biblio_id eq $biblio_id ) { > return $c->render( > status => 404, > openapi => { >- error => 'Volume not found' >+ error => 'Item group not found' > } > ); > } > >- my $volume_data = $c->validation->param('body'); >- $volume->set_from_api( $volume_data )->store->discard_changes(); >+ my $item_group_data = $c->validation->param('body'); >+ $item_group->set_from_api( $item_group_data )->store->discard_changes(); > > return $c->render( > status => 200, >- openapi => $volume->to_api >+ openapi => $item_group->to_api > ); > } > catch { > if ( blessed($_) ) { >- my $to_api_mapping = Koha::Biblio::Volume->new->to_api_mapping; >+ my $to_api_mapping = Koha::Biblio::ItemGroup->new->to_api_mapping; > > if ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { > return $c->render( >@@ -184,7 +185,7 @@ sub update { > > =head3 delete > >-Controller function that handles deleting a Koha::Biblio::Volume object >+Controller function that handles deleting a Koha::Biblio::ItemGroup object > > =cut > >@@ -192,18 +193,22 @@ sub delete { > > my $c = shift->openapi->valid_input or return; > >- my $volume_id = $c->validation->param( 'volume_id' ); >- my $biblio_id = $c->validation->param( 'biblio_id' ); >+ my $item_group_id = $c->validation->param('item_group_id'); >+ my $biblio_id = $c->validation->param('biblio_id'); > >- my $volume = Koha::Biblio::Volumes->find({ id => $volume_id, biblionumber => $biblio_id }); >+ my $item_group = Koha::Biblio::ItemGroups->find( >+ { item_group_id => $item_group_id, biblio_id => $biblio_id } ); > >- if ( not defined $volume ) { >- return $c->render( status => 404, openapi => { error => "Volume not found" } ); >+ if ( not defined $item_group ) { >+ return $c->render( >+ status => 404, >+ openapi => { error => "Item group not found" } >+ ); > } > > return try { >- $volume->delete; >- return $c->render( status => 204, openapi => ''); >+ $item_group->delete; >+ return $c->render( status => 204, openapi => '' ); > } > catch { > $c->unhandled_exception($_); >diff --git a/Koha/REST/V1/Biblios/Volumes/Items.pm b/Koha/REST/V1/Biblios/ItemGroups/Items.pm >similarity index 70% >rename from Koha/REST/V1/Biblios/Volumes/Items.pm >rename to Koha/REST/V1/Biblios/ItemGroups/Items.pm >index fd6ad08882..a946e5fefc 100644 >--- a/Koha/REST/V1/Biblios/Volumes/Items.pm >+++ b/Koha/REST/V1/Biblios/ItemGroups/Items.pm >@@ -1,4 +1,4 @@ >-package Koha::REST::V1::Biblios::Volumes::Items; >+package Koha::REST::V1::Biblios::ItemGroups::Items; > > # This file is part of Koha. > # >@@ -19,14 +19,14 @@ use Modern::Perl; > > use Mojo::Base 'Mojolicious::Controller'; > >-use Koha::Biblio::Volume::Items; >+use Koha::Biblio::ItemGroup::Items; > > use Scalar::Util qw(blessed); > use Try::Tiny; > > =head1 NAME > >-Koha::REST::V1::Biblios::Volumes::Items - Koha REST API for handling volume items (V1) >+Koha::REST::V1::Biblios::ItemGroups::Items - Koha REST API for handling item group items (V1) > > =head1 API > >@@ -34,7 +34,7 @@ Koha::REST::V1::Biblios::Volumes::Items - Koha REST API for handling volume item > > =head3 add > >-Controller function to handle adding a Koha::Biblio::Volume object >+Controller function to handle linking an item to a Koha::Biblio::ItemGroup object > > =cut > >@@ -43,24 +43,24 @@ sub add { > > return try { > >- my $volume = Koha::Biblio::Volumes->find( >- $c->validation->param('volume_id') >+ my $item_group = Koha::Biblio::ItemGroups->find( >+ $c->validation->param('item_group_id') > ); > >- unless ( $volume ) { >+ unless ( $item_group ) { > return $c->render( > status => 404, > openapi => { >- error => 'Volume not found' >+ error => 'Item group not found' > } > ); > } > >- unless ( $volume->biblionumber eq $c->validation->param('biblio_id') ) { >+ unless ( $item_group->biblio_id eq $c->validation->param('biblio_id') ) { > return $c->render( > status => 409, > openapi => { >- error => 'Volume does not belong to passed biblio_id' >+ error => 'Item group does not belong to passed biblio_id' > } > ); > } >@@ -69,7 +69,7 @@ sub add { > my $body = $c->validation->param('body'); > my $item_id = $body->{item_id}; > >- $volume->add_item({ item_id => $item_id }); >+ $item_group->add_item({ item_id => $item_id }); > > $c->res->headers->location( $c->req->url->to_string . '/' . $item_id ); > >@@ -77,7 +77,7 @@ sub add { > > return $c->render( > status => 201, >- openapi => $volume->to_api({ embed => $embed }) >+ openapi => $item_group->to_api({ embed => $embed }) > ); > } > catch { >@@ -92,11 +92,11 @@ sub add { > } > ); > } >- elsif ( $_->broken_fk eq 'biblionumber' ) { >+ elsif ( $_->broken_fk eq 'biblio_id' ) { > return $c->render( > status => 409, > openapi => { >- error => "Given item_id does not belong to the volume's biblio" >+ error => "Given item_id does not belong to the item group's biblio" > } > ); > } >@@ -106,7 +106,7 @@ sub add { > return $c->render( > status => 409, > openapi => { >- error => "The given item_id is already linked to the volume" >+ error => "The given item_id is already linked to the item group" > } > ); > } >@@ -118,20 +118,20 @@ sub add { > > =head3 delete > >-Controller function that handles deleting a Koha::Biblio::Volume object >+Controller function that handles unlinking an item from a Koha::Biblio::ItemGroup object > > =cut > > sub delete { > my $c = shift->openapi->valid_input or return; > >- my $volume_id = $c->validation->param('volume_id'); >- my $item_id = $c->validation->param('item_id'); >+ my $item_group_id = $c->validation->param('item_group_id'); >+ my $item_id = $c->validation->param('item_id'); > >- my $item_link = Koha::Biblio::Volume::Items->find( >+ my $item_link = Koha::Biblio::ItemGroup::Items->find( > { >- itemnumber => $item_id, >- volume_id => $volume_id >+ item_id => $item_id, >+ item_group_id => $item_group_id > } > ); > >@@ -139,7 +139,7 @@ sub delete { > return $c->render( > status => 404, > openapi => { >- error => 'No such volume <-> item relationship' >+ error => 'No such item group <-> item relationship' > } > ); > } >diff --git a/Koha/Schema/Result/Biblio.pm b/Koha/Schema/Result/Biblio.pm >index 1dfbdff777..998314f555 100644 >--- a/Koha/Schema/Result/Biblio.pm >+++ b/Koha/Schema/Result/Biblio.pm >@@ -528,10 +528,6 @@ __PACKAGE__->has_many( > > # Created by DBIx::Class::Schema::Loader v0.07049 @ 2021-09-01 12:37:33 > # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:+wyHrHxnufn5n/hF2mfB6Q >-======= >-# Created by DBIx::Class::Schema::Loader v0.07049 @ 2021-08-18 14:00:35 >-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BILvOleQqOV6/Apcx7kXVg >->>>>>>> Bug 24857: Rename Volumes => Item groups (DB) > > __PACKAGE__->has_many( > "biblioitem", >diff --git a/Koha/Schema/Result/ItemGroup.pm b/Koha/Schema/Result/ItemGroup.pm >index ab34f0a15c..753f6e69be 100644 >--- a/Koha/Schema/Result/ItemGroup.pm >+++ b/Koha/Schema/Result/ItemGroup.pm >@@ -151,22 +151,11 @@ __PACKAGE__->has_many( > # Created by DBIx::Class::Schema::Loader v0.07049 @ 2021-09-01 12:37:33 > # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:uB7PHJt6WQHMv/saTCpkOw > >-=head2 koha_objects_class >- >-=cut >- >+sub koha_object_class { >+ 'Koha::Biblio::ItemGroup'; >+} > sub koha_objects_class { >- 'Koha::Biblio::Volumes'; >+ 'Koha::Biblio::ItemGroups'; > } > >-=head2 koha_object_class >- >-=cut >-======= >-# Created by DBIx::Class::Schema::Loader v0.07049 @ 2021-08-18 14:00:35 >-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:1WBTrtEB25MCOwR4nqPpVA >->>>>>>> Bug 24857: Rename Volumes => Item groups (DB):Koha/Schema/Result/ItemGroup.pm >- >- >-# You can replace this text with custom code or comments, and it will be preserved on regeneration > 1; >diff --git a/Koha/Schema/Result/ItemGroupItem.pm b/Koha/Schema/Result/ItemGroupItem.pm >index 847f957ed4..2ad0155f52 100644 >--- a/Koha/Schema/Result/ItemGroupItem.pm >+++ b/Koha/Schema/Result/ItemGroupItem.pm >@@ -150,6 +150,11 @@ sub koha_object_class { > # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:UkFl9MLWlH8wy3T/AaVIdQ > >>>>>>> Bug 24857: Rename Volumes => Item groups (DB):Koha/Schema/Result/ItemGroupItem.pm > >+sub koha_object_class { >+ 'Koha::Biblio::ItemGroup::Item'; >+} >+sub koha_objects_class { >+ 'Koha::Biblio::ItemGroup::Items'; >+} > >-# You can replace this text with custom code or comments, and it will be preserved on regeneration > 1; >diff --git a/api/v1/swagger/definitions.json b/api/v1/swagger/definitions.json >index 4bf37f177e..4a22a2d0fc 100644 >--- a/api/v1/swagger/definitions.json >+++ b/api/v1/swagger/definitions.json >@@ -26,6 +26,9 @@ > "invoice": { > "$ref": "definitions/invoice.json" > }, >+ "item_group": { >+ "$ref": "definitions/item_group.json" >+ }, > "checkouts": { > "$ref": "definitions/checkouts.json" > }, >@@ -83,9 +86,6 @@ > "vendor": { > "$ref": "definitions/vendor.json" > }, >- "volume": { >- "$ref": "definitions/volume.json" >- }, > "return_claim": { > "$ref": "definitions/return_claim.json" > }, >diff --git a/api/v1/swagger/definitions/volume.json b/api/v1/swagger/definitions/item_group.json >similarity index 67% >rename from api/v1/swagger/definitions/volume.json >rename to api/v1/swagger/definitions/item_group.json >index 884e3e5499..2357a7f818 100644 >--- a/api/v1/swagger/definitions/volume.json >+++ b/api/v1/swagger/definitions/item_group.json >@@ -1,10 +1,10 @@ > { > "type": "object", > "properties": { >- "volume_id": { >+ "item_group_id": { > "type": "integer", > "readOnly": true, >- "description": "Internal identifier for the volume" >+ "description": "Internal identifier for the item group" > }, > "biblio_id": { > "type": "integer", >@@ -13,23 +13,23 @@ > }, > "description": { > "type": "string", >- "description": "Volume description" >+ "description": "Item group description" > }, > "display_order": { > "type": "integer", >- "description": "Volume description" >+ "description": "Display order" > }, > "creation_date": { > "type": "string", > "format": "date-time", > "readOnly": true, >- "description": "Date and time the volume was created" >+ "description": "Date and time the item group was created" > }, > "modification_date": { > "type": "string", > "format": "date-time", > "readOnly": true, >- "description": "Date and time the volume was last modified" >+ "description": "Date and time the item group was last modified" > }, > "items": { > "type": [ >@@ -37,12 +37,12 @@ > "null" > ], > "readOnly": true, >- "description": "A list of items that belong to the volume (x-koha-embed)" >+ "description": "A list of items that belong to the item group (x-koha-embed)" > } > }, > "additionalProperties": false, > "required": [ >- "volume_id", >+ "item_group_id", > "biblio_id" > ] > } >diff --git a/api/v1/swagger/paths.json b/api/v1/swagger/paths.json >index d986a4414c..ced1747c06 100644 >--- a/api/v1/swagger/paths.json >+++ b/api/v1/swagger/paths.json >@@ -26,17 +26,17 @@ > "/biblios/{biblio_id}/pickup_locations": { > "$ref": "paths/biblios.json#/~1biblios~1{biblio_id}~1pickup_locations" > }, >- "/biblios/{biblio_id}/volumes": { >- "$ref": "paths/biblios_volumes.json#/~1biblios~1{biblio_id}~1volumes" >+ "/biblios/{biblio_id}/item_groups": { >+ "$ref": "paths/biblios_item_groups.json#/~1biblios~1{biblio_id}~1item_groups" > }, >- "/biblios/{biblio_id}/volumes/{volume_id}": { >- "$ref": "paths/biblios_volumes.json#/~1biblios~1{biblio_id}~1volumes~1{volume_id}" >+ "/biblios/{biblio_id}/item_groups/{item_group_id}": { >+ "$ref": "paths/biblios_item_groups.json#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}" > }, >- "/biblios/{biblio_id}/volumes/{volume_id}/items": { >- "$ref": "paths/biblios_volumes.json#/~1biblios~1{biblio_id}~1volumes~1{volume_id}~1items" >+ "/biblios/{biblio_id}/item_groups/{item_group_id}/items": { >+ "$ref": "paths/biblios_item_groups.json#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}~1items" > }, >- "/biblios/{biblio_id}/volumes/{volume_id}/items/{item_id}": { >- "$ref": "paths/biblios_volumes.json#/~1biblios~1{biblio_id}~1volumes~1{volume_id}~1items~1{item_id}" >+ "/biblios/{biblio_id}/item_groups/{item_group_id}/items/{item_id}": { >+ "$ref": "paths/biblios_item_groups.json#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}~1items~1{item_id}" > }, > "/cash_registers/{cash_register_id}/cashups": { > "$ref": "paths/cash_registers.json#/~1cash_registers~1{cash_register_id}~1cashups" >diff --git a/api/v1/swagger/paths/biblios_volumes.json b/api/v1/swagger/paths/biblios_item_groups.json >similarity index 83% >rename from api/v1/swagger/paths/biblios_volumes.json >rename to api/v1/swagger/paths/biblios_item_groups.json >index f547f30bcf..b3ca9868bb 100644 >--- a/api/v1/swagger/paths/biblios_volumes.json >+++ b/api/v1/swagger/paths/biblios_item_groups.json >@@ -1,10 +1,10 @@ > { >- "/biblios/{biblio_id}/volumes": { >+ "/biblios/{biblio_id}/item_groups": { > "get": { >- "x-mojo-to": "Biblios::Volumes#list", >- "operationId": "listVolumes", >- "tags": [ "volumes" ], >- "summary": "List volumes", >+ "x-mojo-to": "Biblios::ItemGroups#list", >+ "operationId": "listItemGroups", >+ "tags": [ "item_groups" ], >+ "summary": "List item groups", > "parameters": [ > { > "name": "biblio_id", >@@ -43,11 +43,11 @@ > ], > "responses": { > "200": { >- "description": "A list of volumes", >+ "description": "A list of item groups", > "schema": { > "type": "array", > "items": { >- "$ref": "../definitions.json#/volume" >+ "$ref": "../definitions.json#/item_group" > } > } > }, >@@ -78,7 +78,7 @@ > }, > "x-koha-authorization": { > "permissions": { >- "catalogue": "manage_volumes" >+ "catalogue": "manage_item_groups" > } > }, > "x-koha-embed": [ >@@ -86,10 +86,10 @@ > ] > }, > "post": { >- "x-mojo-to": "Biblios::Volumes#add", >- "operationId": "addVolume", >- "tags": [ "volumes" ], >- "summary": "Add volume", >+ "x-mojo-to": "Biblios::ItemGroups#add", >+ "operationId": "addItemGroup", >+ "tags": [ "item_groups" ], >+ "summary": "Add item group", > "parameters": [ > { > "name": "biblio_id", >@@ -101,18 +101,18 @@ > { > "name": "body", > "in": "body", >- "description": "A JSON object representing a volume", >+ "description": "A JSON object representing an item group", > "required": true, > "schema": { > "type": "object", > "properties": { > "description": { > "type": "string", >- "description": "Volume description" >+ "description": "Item group description" > }, > "display_order": { > "type": "integer", >- "description": "Position in waiting queue" >+ "description": "Display order" > } > } > } >@@ -126,9 +126,9 @@ > ], > "responses": { > "201": { >- "description": "A successfully created volume", >+ "description": "A successfully created item group", > "schema": { >- "$ref": "../definitions.json#/volume" >+ "$ref": "../definitions.json#/item_group" > } > }, > "400": { >@@ -176,17 +176,17 @@ > }, > "x-koha-authorization": { > "permissions": { >- "catalogue": "manage_volumes" >+ "catalogue": "manage_item_groups" > } > } > } > }, >- "/biblios/{biblio_id}/volumes/{volume_id}": { >+ "/biblios/{biblio_id}/item_groups/{item_group_id}": { > "get": { >- "x-mojo-to": "Biblios::Volumes#get", >- "operationId": "getVolume", >- "tags": [ "volumes" ], >- "summary": "Get volume", >+ "x-mojo-to": "Biblios::ItemGroups#get", >+ "operationId": "getItemGroup", >+ "tags": [ "item_groups" ], >+ "summary": "Get item group", > "parameters": [ > { > "name": "biblio_id", >@@ -196,9 +196,9 @@ > "type": "string" > }, > { >- "name": "volume_id", >+ "name": "item_group_id", > "in": "path", >- "description": "Internal identifier for the volume", >+ "description": "Internal identifier for the item group", > "required": true, > "type": "string" > } >@@ -211,9 +211,9 @@ > ], > "responses": { > "200": { >- "description": "A volume", >+ "description": "An item group", > "schema": { >- "$ref": "../definitions.json#/volume" >+ "$ref": "../definitions.json#/item_group" > } > }, > "400": { >@@ -223,7 +223,7 @@ > } > }, > "404": { >- "description": "Volume not found", >+ "description": "Item group not found", > "schema": { > "$ref": "../definitions.json#/error" > } >@@ -246,15 +246,15 @@ > ], > "x-koha-authorization": { > "permissions": { >- "catalogue": "manage_volumes" >+ "catalogue": "manage_item_groups" > } > } > }, > "put": { >- "x-mojo-to": "Biblios::Volumes#update", >- "operationId": "updateVolume", >- "tags": [ "volumes" ], >- "summary": "Update volume", >+ "x-mojo-to": "Biblios::ItemGroups#update", >+ "operationId": "updateItemGroup", >+ "tags": [ "item_groups" ], >+ "summary": "Update item group", > "parameters": [ > { > "name": "biblio_id", >@@ -264,23 +264,23 @@ > "type": "string" > }, > { >- "name": "volume_id", >+ "name": "item_group_id", > "in": "path", >- "description": "Internal identifier for the volume", >+ "description": "Internal identifier for the item group", > "required": true, > "type": "string" > }, > { > "name": "body", > "in": "body", >- "description": "A JSON object with the new values for the volume", >+ "description": "A JSON object with the new values for the item group", > "required": true, > "schema": { > "type": "object", > "properties": { > "description": { > "type": "string", >- "description": "Volume description" >+ "description": "Item group description" > }, > "display_order": { > "type": "integer", >@@ -298,9 +298,9 @@ > ], > "responses": { > "200": { >- "description": "The updated volume", >+ "description": "The updated item group", > "schema": { >- "$ref": "../definitions.json#/volume" >+ "$ref": "../definitions.json#/item_group" > } > }, > "400": { >@@ -322,7 +322,7 @@ > } > }, > "404": { >- "description": "Volume not found", >+ "description": "Item group not found", > "schema": { > "$ref": "../definitions.json#/error" > } >@@ -342,7 +342,7 @@ > }, > "x-koha-authorization": { > "permissions": { >- "catalogue": "manage_volumes" >+ "catalogue": "manage_item_groups" > } > }, > "x-koha-embed": [ >@@ -350,10 +350,10 @@ > ] > }, > "delete": { >- "x-mojo-to": "Biblios::Volumes#delete", >- "operationId": "deleteVolume", >- "tags": ["volumes"], >- "summary": "Delete volume", >+ "x-mojo-to": "Biblios::ItemGroups#delete", >+ "operationId": "deleteItemGroup", >+ "tags": ["item_groups"], >+ "summary": "Delete item group", > "parameters": [ > { > "name": "biblio_id", >@@ -363,9 +363,9 @@ > "type": "string" > }, > { >- "name": "volume_id", >+ "name": "item_group_id", > "in": "path", >- "description": "Internal identifier for the volume", >+ "description": "Internal identifier for the item group", > "required": true, > "type": "string" > } >@@ -375,7 +375,7 @@ > ], > "responses": { > "204": { >- "description": "Volume deleted", >+ "description": "Item group deleted", > "schema": { > "type": "string" > } >@@ -393,7 +393,7 @@ > } > }, > "404": { >- "description": "Volume not found", >+ "description": "Item group not found", > "schema": { > "$ref": "../definitions.json#/error" > } >@@ -413,17 +413,17 @@ > }, > "x-koha-authorization": { > "permissions": { >- "catalogue": "manage_volumes" >+ "catalogue": "manage_item_groups" > } > } > } > }, >- "/biblios/{biblio_id}/volumes/{volume_id}/items": { >+ "/biblios/{biblio_id}/item_groups/{item_group_id}/items": { > "post": { >- "x-mojo-to": "Biblios::Volumes::Items#add", >- "operationId": "addVolumeItem", >- "tags": [ "volumes" ], >- "summary": "Add item to volume", >+ "x-mojo-to": "Biblios::ItemGroups::Items#add", >+ "operationId": "addItemGroupItem", >+ "tags": [ "item_groups" ], >+ "summary": "Add item to item group", > "parameters": [ > { > "name": "biblio_id", >@@ -433,9 +433,9 @@ > "type": "string" > }, > { >- "name": "volume_id", >+ "name": "item_group_id", > "in": "path", >- "description": "Internal identifier for the volume", >+ "description": "Internal identifier for the item group", > "required": true, > "type": "string" > }, >@@ -463,7 +463,7 @@ > ], > "responses": { > "201": { >- "description": "Item linked to volume" >+ "description": "Item linked to item group" > }, > "400": { > "description": "Bad request", >@@ -504,7 +504,7 @@ > }, > "x-koha-authorization": { > "permissions": { >- "catalogue": "manage_volumes" >+ "catalogue": "manage_item_groups" > } > }, > "x-koha-embed": [ >@@ -512,12 +512,12 @@ > ] > } > }, >- "/biblios/{biblio_id}/volumes/{volume_id}/items/{item_id}": { >+ "/biblios/{biblio_id}/item_groups/{item_group_id}/items/{item_id}": { > "delete": { >- "x-mojo-to": "Biblios::Volumes::Items#delete", >- "operationId": "deleteVolumeItems", >- "tags": ["volumes"], >- "summary": "Delete item from volume", >+ "x-mojo-to": "Biblios::ItemGroups::Items#delete", >+ "operationId": "deleteItemGroupItems", >+ "tags": ["item_groups"], >+ "summary": "Delete item from item group", > "parameters": [ > { > "name": "biblio_id", >@@ -527,9 +527,9 @@ > "type": "string" > }, > { >- "name": "volume_id", >+ "name": "item_group_id", > "in": "path", >- "description": "Internal identifier for the volume", >+ "description": "Internal identifier for the item group", > "required": true, > "type": "string" > }, >@@ -549,7 +549,7 @@ > ], > "responses": { > "204": { >- "description": "Item unlinked from volume", >+ "description": "Item unlinked from item group", > "schema": { > "type": "string" > } >@@ -567,7 +567,7 @@ > } > }, > "404": { >- "description": "Item not linked to volume", >+ "description": "Item not linked to item group", > "schema": { > "$ref": "../definitions.json#/error" > } >@@ -587,7 +587,7 @@ > }, > "x-koha-authorization": { > "permissions": { >- "catalogue": "manage_volumes" >+ "catalogue": "manage_item_groups" > } > } > } >diff --git a/catalogue/detail.pl b/catalogue/detail.pl >index c5c9792a24..2167d1de5c 100755 >--- a/catalogue/detail.pl >+++ b/catalogue/detail.pl >@@ -46,8 +46,9 @@ use Koha::DateUtils qw( format_sqldatetime ); > use C4::HTML5Media; > use C4::CourseReserves qw( GetItemCourseReservesInfo ); > use Koha::AuthorisedValues; >-use Koha::Biblio::Volume::Items; > use Koha::Biblios; >+use Koha::Biblio::ItemGroup::Items; >+use Koha::Biblio::ItemGroups; > use Koha::CoverImages; > use Koha::DateUtils; > use Koha::Illrequests; >@@ -100,37 +101,35 @@ eval { $biblio->metadata->record }; > $template->param( decoding_error => $@ ); > > my $op = $query->param('op') || q{}; >-if ( $op eq 'set_volume' ) { >- my $volume_id = $query->param('volume_id'); >- my @itemnumbers = $query->multi_param('itemnumber'); >+if ( $op eq 'set_item_group' ) { >+ my $item_group_id = $query->param('item_group_id'); >+ my @itemnumbers = $query->multi_param('itemnumber'); > >- foreach my $itemnumber (@itemnumbers) { >- my $volume_item = >- Koha::Biblio::Volume::Items->find( { itemnumber => $itemnumber } ); >+ foreach my $item_id (@itemnumbers) { >+ my $item_group_item = Koha::Biblio::ItemGroup::Items->find( { item_id => $item_id } ); > >- if ($volume_item) { >- $volume_item->volume_id($volume_id); >+ if ($item_group_item) { >+ $item_group_item->item_group_id($item_group_id); > } > else { >- $volume_item = Koha::Biblio::Volume::Item->new( >+ $item_group_item = Koha::Biblio::ItemGroup::Item->new( > { >- itemnumber => $itemnumber, >- volume_id => $volume_id, >+ item_id => $item_id, >+ item_group_id => $item_group_id, > } > ); > } > >- $volume_item->store(); >+ $item_group_item->store(); > } > } >-elsif ( $op eq 'unset_volume' ) { >- my $volume_id = $query->param('volume_id'); >+elsif ( $op eq 'unset_item_group' ) { >+ my $item_group_id = $query->param('item_group_id'); > my @itemnumbers = $query->multi_param('itemnumber'); > >- foreach my $itemnumber (@itemnumbers) { >- my $volume_item = >- Koha::Biblio::Volume::Items->find( { itemnumber => $itemnumber } ); >- $volume_item->delete() if $volume_item; >+ foreach my $item_id (@itemnumbers) { >+ my $item_group_item = Koha::Biblio::ItemGroup::Items->find( { item_id => $item_id } ); >+ $item_group_item->delete() if $item_group_item; > } > } > >diff --git a/cataloguing/additem.pl b/cataloguing/additem.pl >index ede8ecb752..c0fc311d21 100755 >--- a/cataloguing/additem.pl >+++ b/cataloguing/additem.pl >@@ -40,6 +40,7 @@ use C4::Context; > use C4::Circulation qw( LostItem ); > use C4::Koha qw( GetAuthorisedValues ); > use C4::ClassSource qw( GetClassSources GetClassSource ); >+use Koha::Biblio::ItemGroups; > use Koha::DateUtils qw( dt_from_string ); > use Koha::Items; > use Koha::ItemTypes; >@@ -85,32 +86,25 @@ sub get_item_from_barcode { > return($result); > } > >-sub add_item_to_volume { >- my ( $biblionumber, $itemnumber, $volume, $volume_description ) = @_; >- >- return unless $volume; >- >- my $volume_id; >- if ( $volume eq 'create' ) { >- my $volume = Koha::Biblio::Volume->new( >- { >- biblionumber => $biblionumber, >- description => $volume_description, >- } >- )->store(); >- >- $volume_id = $volume->id; >- } >- else { >- $volume_id = $volume; >- } >- >- my $volume_item = Koha::Biblio::Volume::Item->new( >- { >- itemnumber => $itemnumber, >- volume_id => $volume_id, >+sub add_item_to_item_group { >+ my ( $biblio_id, $item_id, $item_group_param, $description ) = @_; >+ >+ if ( $item_group_param ) { >+ # item group passed, deal with it >+ my $item_group; >+ if ( $item_group_param eq 'create' ) { >+ $item_group = Koha::Biblio::ItemGroup->new( >+ { >+ biblio_id => $biblio_id, >+ description => $description, >+ } >+ ); >+ } >+ else { >+ $item_group = Koha::Biblio::ItemGroups->find( $item_group_param ); > } >- )->store(); >+ $item_group->add_item({ item_id => $item_id }); >+ } > } > > # NOTE: This code is subject to change in the future with the implemenation of ajax based autobarcode code >@@ -449,13 +443,13 @@ my $hostitemnumber = $input->param('hostitemnumber'); > my $marcflavour = C4::Context->preference("marcflavour"); > my $searchid = $input->param('searchid'); > # fast cataloguing datas >-my $fa_circborrowernumber = $input->param('circborrowernumber'); >-my $fa_barcode = $input->param('barcode'); >-my $fa_branch = $input->param('branch'); >-my $fa_stickyduedate = $input->param('stickyduedate'); >-my $fa_duedatespec = $input->param('duedatespec'); >-my $volume = $input->param('volume'); >-my $volume_description = $input->param('volume_description'); >+my $fa_circborrowernumber = $input->param('circborrowernumber'); >+my $fa_barcode = $input->param('barcode'); >+my $fa_branch = $input->param('branch'); >+my $fa_stickyduedate = $input->param('stickyduedate'); >+my $fa_duedatespec = $input->param('duedatespec'); >+my $item_group_param = $input->param('item_group_id'); >+my $item_group_description = $input->param('item_group_description'); > > my $frameworkcode = &GetFrameworkCode($biblionumber); > >@@ -562,8 +556,7 @@ if ($op eq "additem") { > # if barcode exists, don't create, but report The problem. > unless ($exist_itemnumber) { > my ( $oldbiblionumber, $oldbibnum, $oldbibitemnum ) = AddItemFromMarc( $record, $biblionumber ); >- add_item_to_volume( $oldbiblionumber, $oldbibitemnum, $volume, $volume_description ); >- >+ add_item_to_item_group( $oldbiblionumber, $oldbibitemnum, $item_group_param, $item_group_description ); > # Pushing the last created item cookie back > if ($prefillitem && defined $record) { > my $itemcookie = $input->cookie( >@@ -662,8 +655,7 @@ if ($op eq "additem") { > if (!$exist_itemnumber) { > my ( $oldbiblionumber, $oldbibnum, $oldbibitemnum ) = > AddItemFromMarc( $record, $biblionumber, { skip_record_index => 1 } ); >- add_item_to_volume( $oldbiblionumber, $oldbibitemnum, $volume, $volume_description ); >- >+ add_item_to_item_group( $oldbiblionumber, $oldbibitemnum, $item_group_param, $item_group_description ); > # We count the item only if it was really added > # That way, all items are added, even if there was some already existing barcodes > # FIXME : Please note that there is a risk of infinite loop here if we never find a suitable barcode >@@ -1033,7 +1025,7 @@ foreach my $tag ( keys %{$tagslib}){ > > # what's the next op ? it's what we are not in : an add if we're editing, otherwise, and edit. > $template->param( >- volumes => scalar Koha::Biblio::Volumes->search({ biblionumber => $biblionumber }), >+ item_groups => scalar Koha::Biblio::ItemGroups->search({ biblio_id => $biblionumber }), > biblionumber => $biblionumber, > title => $oldrecord->{title}, > author => $oldrecord->{author}, >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc >index 8e0b18383c..a62f89c225 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc >@@ -330,9 +330,9 @@ > Fast cataloging > </span> > <span class="permissioncode">([% name | html %])</span> >- [%- CASE 'manage_volumes' -%] >- <span class="sub_permission manage_volumes_subpermission"> >- Create, update and delete volumes, add or remove items from a volume >+ [%- CASE 'manage_item_groups' -%] >+ <span class="sub_permission manage_item_groups_subpermission"> >+ Create, update and delete item groups, add or remove items from an item group > </span> > <span class="permissioncode">([% name | html %])</span> > [%- CASE 'remaining_permissions' -%] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref >index 78752c3311..8875fc4d65 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref >@@ -660,11 +660,11 @@ Circulation: > - 'the last patron to return an item. This setting is independent of the <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=opacreadinghistory">opacreadinghistory</a> and <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=AnonymousPatron">AnonymousPatron</a> system preferences.' > Holds policy: > - >- - pref: EnableVolumes >+ - pref: EnableItemGroups > choices: > yes: Enable > no: "Don't enable" >- - volumes feature to allow collecting groups of items on a record into volumes. >+ - the item groups feature to allow collecting groups of items on a record together. > - > - In the staff client, split the holds queue into separate tables by > - pref: HoldsSplitQueue >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 7ee02ca7e8..0f7e6b628d 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >@@ -273,7 +273,7 @@ > <a href="#holdings">Holdings ([% itemloop.size() || 0 | html %])</a> > </li> > [% END %] >-[% IF Koha.Preference('EnableVolumes') %]<li><a href="#volumes">Volumes</a></li>[% END %] >+[% IF Koha.Preference('EnableItemGroups') %]<li><a href="#item_groups">Item groups</a></li>[% END %] > [% IF ( MARCNOTES || notes ) %]<li><a href="#description">Descriptions ([% ( MARCNOTES.size || 1 ) | html %])</a></li>[% END %] > [% IF ( subscriptionsnumber ) %]<li><a href="#subscriptions">Subscriptions</a></li>[% END %] > [% IF Koha.Preference('AcquisitionDetails') %]<li><a href="#acq_details">Acquisition details</a></li>[% END %] >@@ -310,9 +310,9 @@ > [% IF CAN_user_tools_items_batchmod %] > <a class="itemselection_action_modify"><i class="fa fa-pencil"></i> Modify selected items</a> > [% END %] >- [% IF CAN_user_editcatalogue_manage_volumes && biblio.volumes.count %] >- <a class="itemselection_action_volume_set" href="#"><i class="fa fa-book"></i> Add/move to volume</a> >- <a class="itemselection_action_volume_unset" href="#"><i class="fa fa-unlink"></i> Remove from volume</a> >+ [% IF CAN_user_editcatalogue_manage_item_groups && biblio.item_groups.count %] >+ <a class="itemselection_action_item_group_set" href="#"><i class="fa fa-book"></i> Add/move to item group</a> >+ <a class="itemselection_action_item_group_unset" href="#"><i class="fa fa-unlink"></i> Remove from item group</a> > [% END %] > </span> > [% END %] >@@ -328,8 +328,8 @@ > <th id="[% tab | html %]_holdingbranch" data-colname="[% tab | html %]_holdingbranch">Current library</th> > <th id="[% tab | html %]_homebranch" data-colname="[% tab | html %]_homebranch">Home library</th> > [% IF ( itemdata_ccode ) %]<th id="[% tab | html %]_ccode" data-colname="[% tab | html %]_ccode">Collection</th>[% END %] >- [% IF Koha.Preference('EnableVolumes') %] >- <th id="[% tab | html %]_volume" data-colname="[% tab | html %]_volume">Volume</th> >+ [% IF Koha.Preference('EnableItemGroups') %] >+ <th id="[% tab | html %]_item_group" data-colname="[% tab | html %]_item_group">Item group</th> > [% END %] > <th id="[% tab | html %]_itemcallnumber" data-colname="[% tab | html %]_itemcallnumber">Call number</th> > [% IF volinfo %] >@@ -405,7 +405,7 @@ Note that permanent location is a code, and location may be an authval. > </span> > </td> > [% IF ( itemdata_ccode ) %]<td>[% item.ccode | html %]</td>[% END %] >- [% IF Koha.Preference('EnableVolumes') %]<td class="volume">[% item.object.volume.description | html %]</td>[% END %] >+ [% IF Koha.Preference('EnableItemGroups') %]<td class="item_group">[% item.object.item_group.description | html %]</td>[% END %] > <td class="itemcallnumber">[% IF ( item.itemcallnumber ) %] [% item.itemcallnumber | html %][% END %]</td> > [% IF ( volinfo ) %] > [% IF itemdata_publisheddate #If there is at least one published date, use it for sorting %] >@@ -611,14 +611,14 @@ Note that permanent location is a code, and location may be an authval. > > [% END %][%# end of block items_table %] > >-[% IF Koha.Preference('EnableVolumes') %] >- <div id="volumes"> >- [% IF CAN_user_editcatalogue_manage_volumes %] >- <div class="volumes_table_table_controls"> >- <a href="#" class="volume-create btn btn-default btn-xs"><i class="fa fa-plus"></i> New volume</a> >+[% IF Koha.Preference('EnableItemGroups') %] >+ <div id="item_groups"> >+ [% IF CAN_user_editcatalogue_manage_item_groups %] >+ <div class="item_groups_table_table_controls"> >+ <a href="#" class="item-group-create btn btn-default btn-xs"><i class="fa fa-plus"></i> New item group</a> > </div> > [% END %] >- <table class="volumes-table" id="volumes-table"> >+ <table class="items-group-table" id="items-group-table"> > <thead> > <tr> > <td>Display Order</td> >@@ -1048,32 +1048,32 @@ Note that permanent location is a code, and location may be an authval. > > [% END %] > >-<div class="modal fade" id="modal-volume-create" tabindex="-1" role="dialog" aria-labelledby="modal-volume-create-label"> >+<div class="modal fade" id="modal-item-group-create" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-create-label"> > <div class="modal-dialog"> > <div class="modal-content"> > <div class="modal-header"> > <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">Ã</button> >- <h3 id="modal-volume-create-label"><i class="fa fa-plus"></i> Create a new volume</h3> >+ <h3 id="modal-item-group-create-label"><i class="fa fa-plus"></i> Create a new item group</h3> > </div> >- <form id="modal-volume-create-form" class="validated"> >+ <form id="modal-item-group-create-form" class="validated"> > <div class="modal-body"> > <fieldset> > <p> >- <label for="volume_description" class="required">Name: </label> >- <input name="description" id="modal-volume-create-form-description" type="text" size="30" required="required" class="required" /> >+ <label for="item_group_description" class="required">Name: </label> >+ <input name="description" id="modal-item-group-create-form-description" type="text" size="30" required="required" class="required" /> > <span class="required">Required</span> > </p> > <p> >- <label for="volume_display_order" class="required">Display order: </label> >- <input name="display_order" id="modal-volume-create-form-display_order" value="0" size="5" required="required" class="required" /> >+ <label for="item_group_display_order" class="required">Display order: </label> >+ <input name="display_order" id="modal-item-group-create-form-display_order" value="0" size="5" required="required" class="required" /> > <span class="required">Required</span> > <br/> >- <span class="hint">Numbers only, volumes will be displayed in counting order</span> >+ <span class="hint">Numbers only, item groups will be displayed in counting order</span> > </p> > </fieldset> > </div> > <div class="modal-footer"> >- <button id="modal-volume-create-submit" class="btn btn-default"><i class="fa fa-plus"></i> Submit</button> >+ <button id="modal-item-group-create-submit" class="btn btn-default"><i class="fa fa-plus"></i> Submit</button> > <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button> > </div> > </form> >@@ -1081,30 +1081,30 @@ Note that permanent location is a code, and location may be an authval. > </div> > </div> > >-<div class="modal fade" id="modal-volume-edit" tabindex="-1" role="dialog" aria-labelledby="modal-volume-edit-label"> >+<div class="modal fade" id="modal-item-group-edit" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-edit-label"> > <div class="modal-dialog"> > <div class="modal-content"> > <div class="modal-header"> > <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">Ã</button> >- <h3 id="modal-volume-edit-label"><i class='fa fa-edit'></i> Edit volume</h3> >+ <h3 id="modal-item-group-edit-label"><i class='fa fa-edit'></i> Edit item group</h3> > </div> >- <form id="modal-volume-edit-form" class="validated"> >+ <form id="modal-item-group-edit-form" class="validated"> > <div class="modal-body"> > <fieldset> > <p> >- <label for="volume_description" class="required">Name: </label> >- <input name="description" id="modal-volume-edit-form-description" type="text" size="30" required="required" class="required" /> >+ <label for="item_group_description" class="required">Name: </label> >+ <input name="description" id="modal-item-group-edit-form-description" type="text" size="30" required="required" class="required" /> > <span class="required">Required</span> > </p> > <p> >- <label for="volume_display_order" class="required">Sort order: </label> >- <input name="display_order" id="modal-volume-edit-form-display_order" size="5" /> >- <span class="hint">Numbers only, volumes will be displayed in counting order</span> >+ <label for="item_group_display_order" class="required">Sort order: </label> >+ <input name="display_order" id="modal-item-group-edit-form-display_order" size="5" /> >+ <span class="hint">Numbers only, item groups will be displayed in counting order</span> > </p> > </fieldset> > </div> > <div class="modal-footer"> >- <button id="modal-volume-edit-submit" class="btn btn-default"><i class='fa fa-edit'></i> Submit</button> >+ <button id="modal-item-group-edit-submit" class="btn btn-default"><i class='fa fa-edit'></i> Submit</button> > <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button> > </div> > </form> >@@ -1112,39 +1112,39 @@ Note that permanent location is a code, and location may be an authval. > </div> > </div> > >-<div class="modal fade" id="modal-volume-delete" tabindex="-1" role="dialog" aria-labelledby="modal-volume-delete-label"> >+<div class="modal fade" id="modal-item-group-delete" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-delete-label"> > <div class="modal-dialog"> > <div class="modal-content"> > <div class="modal-header"> > <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">Ã</button> >- <h3 id="modal-volume-delete-label"><i class='fa fa-trash'></i> Delete volume</h3> >+ <h3 id="modal-item-group-delete-label"><i class='fa fa-trash'></i> Delete item group</h3> > </div> > <div class="modal-body"> >- Are you sure you want to delete this volume? >+ Are you sure you want to delete this item group? > </div> > <div class="modal-footer"> >- <button id="modal-volume-delete-submit" class="btn btn-danger"><i class='fa fa-trash'></i> Delete</button> >+ <button id="modal-item-group-delete-submit" class="btn btn-danger"><i class='fa fa-trash'></i> Delete</button> > <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button> > </div> > </div> > </div> > </div> > >-<div class="modal fade" id="modal-volume-set" tabindex="-1" role="dialog" aria-labelledby="modal-volume-set-label"> >+<div class="modal fade" id="modal-item-group-set" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-set-label"> > <div class="modal-dialog"> > <div class="modal-content"> > <div class="modal-header"> > <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">Ã</button> >- <h3 id="modal-volume-set-label"><i class='fa fa-book'></i> Set volume for items</h3> >+ <h3 id="modal-item-group-set-label"><i class='fa fa-book'></i> Set item group for items</h3> > </div> >- <form id="modal-volume-set-form" class="validated"> >+ <form id="modal-item-group-set-form" class="validated"> > <div class="modal-body"> > <fieldset> > <p> >- <label for="volume" class="required">Volume: </label> >- <select name="volume" id="volume-add-form-select"> >- [% FOREACH v IN biblio.volumes %] >- <option value="[% v.id | html %]">[% v.description | html %]</option> >+ <label for="item_group" class="required">Item group: </label> >+ <select name="item_group" id="item-group-add-form-select"> >+ [% FOREACH ig IN biblio.item_groups %] >+ <option value="[% ig.id | html %]">[% ig.description | html %]</option> > [% END %] > </select> > <span class="required">Required</span> >@@ -1152,7 +1152,7 @@ Note that permanent location is a code, and location may be an authval. > </fieldset> > </div> > <div class="modal-footer"> >- <button id="modal-volume-set-submit" class="btn btn-default"><i class='fa fa-book'></i> Set volume</button> >+ <button id="modal-item-group-set-submit" class="btn btn-default"><i class='fa fa-book'></i> Set item group</button> > <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button> > </div> > </form> >@@ -1160,18 +1160,18 @@ Note that permanent location is a code, and location may be an authval. > </div> > </div> > >-<div class="modal fade" id="modal-volume-unset" tabindex="-1" role="dialog" aria-labelledby="modal-volume-unset-label"> >+<div class="modal fade" id="modal-item-group-unset" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-unset-label"> > <div class="modal-dialog"> > <div class="modal-content"> > <div class="modal-header"> > <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">Ã</button> >- <h3 id="modal-volume-unset-label"><i class='fa fa-unlink'></i> Remove item from volume</h3> >+ <h3 id="modal-item-group-unset-label"><i class='fa fa-unlink'></i> Remove item from item group</h3> > </div> > <div class="modal-body"> >- Are you sure you want to remove these item(s) from their volume(s)? >+ Are you sure you want to remove these item(s) from their item group(s)? > </div> > <div class="modal-footer"> >- <button id="modal-volume-unset-submit" class="btn btn-danger"><i class='fa fa-unlink'></i> Remove</button> >+ <button id="modal-item-group-unset-submit" class="btn btn-danger"><i class='fa fa-unlink'></i> Remove</button> > <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button> > </div> > </div> >@@ -1527,9 +1527,9 @@ Note that permanent location is a code, and location may be an authval. > if ( search_value ){ $('#cat-search-block #search-form').val(search_value)}; > }); > >- [% IF Koha.Preference('EnableVolumes') %] >- // Load volumes table >- var volumesTable = KohaTable("volumes-table", { >+ [% IF Koha.Preference('EnableItemGroups') %] >+ // Load item groups table >+ var itemGroupsTable = KohaTable("items-group-table", { > "bAutoWidth": false, > 'sDom': '<"top pager"ilp>t<"bottom pager"ip>r', > "aoColumns": [ >@@ -1545,12 +1545,12 @@ Note that permanent location is a code, and location may be an authval. > }, > { > "mDataProp": function( oObj ) { >- [% IF CAN_user_editcatalogue_manage_volumes %] >- return `<button class='volume-edit btn btn-default btn-xs' data-volume-id='${oObj.volume_id}'> >+ [% IF CAN_user_editcatalogue_manage_item_groups %] >+ return `<button class='item-group-edit btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'> > <i class='fa fa-edit'></i> ${_("Edit")} > </button>` > + ' ' >- + `<button class='volume-delete btn btn-default btn-xs' data-volume-id='${oObj.volume_id}'> >+ + `<button class='item-group-delete btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'> > <i class='fa fa-trash'></i> ${('Delete')} > </button>`; > [% ELSE %] >@@ -1562,7 +1562,7 @@ Note that permanent location is a code, and location may be an authval. > "bPaginate": false, > "bProcessing": true, > "bServerSide": false, >- "sAjaxSource": `/api/v1/biblios/${biblionumber}/volumes?_per_page=-1`, >+ "sAjaxSource": `/api/v1/biblios/${biblionumber}/item_groups?_per_page=-1`, > "sAjaxDataProp": "", > "fnServerData": function ( sSource, aoData, fnCallback ) { > $.getJSON( sSource, aoData, function (json) { >@@ -1571,49 +1571,49 @@ Note that permanent location is a code, and location may be an authval. > }, > }); > >- // Create new volumes >- $('.volume-create').on('click', function(){ >- $('#modal-volume-create-form-description').val(""); >- $('#modal-volume-create-submit').removeAttr('disabled'); >- $('#modal-volume-create').modal('show'); >+ // Create new item groups >+ $('.item-group-create').on('click', function(){ >+ $('#modal-item-group-create-form-description').val(""); >+ $('#modal-item-group-create-submit').removeAttr('disabled'); >+ $('#modal-item-group-create').modal('show'); > }); > >- $("#modal-volume-create-form").validate({ >+ $("#modal-item-group-create-form").validate({ > submitHandler: function(form) { > $.ajax({ >- url: `/api/v1/biblios/${biblionumber}/volumes`, >+ url: `/api/v1/biblios/${biblionumber}/item_groups`, > headers: { "x-koha-embed": "items" }, >- success: function(volumes){ >- $('#modal-volume-create-submit').attr('disabled', 'disabled'); >+ success: function(item_groups){ >+ $('#modal-item-group-create-submit').attr('disabled', 'disabled'); > > var settings = { >- "url": `/api/v1/biblios/${biblionumber}/volumes`, >+ "url": `/api/v1/biblios/${biblionumber}/item_groups`, > "method": "POST", > "headers": { > "Content-Type": "application/json" > }, > "data": JSON.stringify( > { >- "description": $("#modal-volume-create-form-description").val(), >- "display_order": $("#modal-volume-create-form-display_order").val(), >+ "description": $("#modal-item-group-create-form-description").val(), >+ "display_order": $("#modal-item-group-create-form-display_order").val(), > } > ), > }; > > $.ajax(settings) > .done(function (response) { >- $('#volume-add-form-select').append($('<option>', { >- value: response.volume_id, >+ $('#item-group-add-form-select').append($('<option>', { >+ value: response.item_group_id, > text: response.description > })); > >- $('#modal-volume-create').modal('hide'); >- if ( volumes.length == 0 ) { >- // This bib has no previous volumes, reload the page >+ $('#modal-item-group-create').modal('hide'); >+ if ( item_groups.length == 0 ) { >+ // This bib has no previous item groups, reload the page > window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`); > } else { >- // Has other volumes, just reload the table >- volumesTable.api().ajax.reload(); >+ // Has other item groups, just reload the table >+ itemGroupsTable.api().ajax.reload(); > } > }) > .fail(function(err) { >@@ -1625,29 +1625,29 @@ Note that permanent location is a code, and location may be an authval. > } > }); > >- $('#modal-volume-create').on('shown.bs.modal', function () { >- $('#modal-volume-create-form-description').focus(); >+ $('#modal-item-group-create').on('shown.bs.modal', function () { >+ $('#modal-item-group-create-form-description').focus(); > }) > >- // Edit existing volumes >- $('body').on( 'click', '.volume-edit', function(){ >- const volume_id = $(this).data('volume-id'); >- const url = `/api/v1/biblios/${biblionumber}/volumes/${volume_id}`; >+ // Edit existing item groups >+ $('body').on( 'click', '.item-group-edit', function(){ >+ const item_group_id = $(this).data('item-group-id'); >+ const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`; > $.get( url, function( data ) { >- $('#modal-volume-edit-form-description').val( data.description ); >- $('#modal-volume-edit-form-display_order').val( data.display_order ); >- $('#modal-volume-edit-submit').data('volume-id', volume_id ); >- $('#modal-volume-edit-submit').removeAttr('disabled'); >- $('#modal-volume-edit').modal('show'); >+ $('#modal-item-group-edit-form-description').val( data.description ); >+ $('#modal-item-group-edit-form-display_order').val( data.display_order ); >+ $('#modal-item-group-edit-submit').data('item-group-id', item_group_id ); >+ $('#modal-item-group-edit-submit').removeAttr('disabled'); >+ $('#modal-item-group-edit').modal('show'); > }); > }); > >- $("#modal-volume-edit-form").validate({ >+ $("#modal-item-group-edit-form").validate({ > submitHandler: function(form) { >- $('#modal-volume-edit-submit').attr('disabled', 'disabled'); >+ $('#modal-item-group-edit-submit').attr('disabled', 'disabled'); > >- const volume_id = $('#modal-volume-edit-submit').data('volume-id'); >- const url = `/api/v1/biblios/${biblionumber}/volumes/${volume_id}`; >+ const item_group_id = $('#modal-item-group-edit-submit').data('item-group-id'); >+ const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`; > > var settings = { > "url": url, >@@ -1657,16 +1657,16 @@ Note that permanent location is a code, and location may be an authval. > }, > "data": JSON.stringify( > { >- "description": $("#modal-volume-edit-form-description").val(), >- "display_order": $("#modal-volume-edit-form-display_order").val(), >+ "description": $("#modal-item-group-edit-form-description").val(), >+ "display_order": $("#modal-item-group-edit-form-display_order").val(), > } > ), > }; > > $.ajax(settings) > .done(function (response) { >- $('#modal-volume-edit').modal('hide'); >- volumesTable.api().ajax.reload(); >+ $('#modal-item-group-edit').modal('hide'); >+ itemGroupsTable.api().ajax.reload(); > }) > .fail(function(err) { > var message = err.responseJSON.error; >@@ -1675,37 +1675,37 @@ Note that permanent location is a code, and location may be an authval. > } > }); > >- $('#modal-volume-edit').on('shown.bs.modal', function () { >- $('#modal-volume-edit-form-description').focus(); >+ $('#modal-item-group-edit').on('shown.bs.modal', function () { >+ $('#modal-item-group-edit-form-description').focus(); > }) > >- // Delete existing volumes >- $('body').on( 'click', '.volume-delete', function(){ >- const volume_id = $(this).data('volume-id'); >- $('#modal-volume-delete-submit').data('volume-id', volume_id ); >- $('#modal-volume-delete-submit').removeAttr('disabled'); >- $('#modal-volume-delete').modal('show'); >+ // Delete existing item groups >+ $('body').on( 'click', '.item-group-delete', function(){ >+ const item_group_id = $(this).data('item-group-id'); >+ $('#modal-item-group-delete-submit').data('item-group-id', item_group_id ); >+ $('#modal-item-group-delete-submit').removeAttr('disabled'); >+ $('#modal-item-group-delete').modal('show'); > }); >- $("#modal-volume-delete-submit").on('click', function(){ >- $('#modal-volume-delete-submit').attr('disabled', 'disabled'); >- const volume_id = $("#modal-volume-delete-submit").data('volume-id'); >+ $("#modal-item-group-delete-submit").on('click', function(){ >+ $('#modal-item-group-delete-submit').attr('disabled', 'disabled'); >+ const item_group_id = $("#modal-item-group-delete-submit").data('item-group-id'); > > $.ajax({ >- url: `/api/v1/biblios/${biblionumber}/volumes/${volume_id}`, >+ url: `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`, > headers: { "x-koha-embed": "items" }, >- success: function(volume_data){ >+ success: function(item_group_data){ > $.ajax({ >- "url": `/api/v1/biblios/${biblionumber}/volumes/${volume_id}`, >+ "url": `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`, > "method": "DELETE", > }) > .done(function (response) { >- $('#modal-volume-delete').modal('hide'); >- $(`#volume-add-form-select option[value='${volume_id}']`).remove(); >- if ( volume_data.items === null ) { >- // No items for this volume, we can just refresh the table >- volumesTable.api().ajax.reload(); >+ $('#modal-item-group-delete').modal('hide'); >+ $(`#item-group-add-form-select option[value='${item_group_id}']`).remove(); >+ if ( item_group_data.items === null ) { >+ // No items for this item group, we can just refresh the table >+ itemGroupsTable.api().ajax.reload(); > } else { >- // This volume had items attached to it, we need to reload the page >+ // This item group had items attached to it, we need to reload the page > window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`); > } > }) >@@ -1717,16 +1717,16 @@ Note that permanent location is a code, and location may be an authval. > }); > }); > >- // Add item(s) to a volume >- $('.itemselection_action_volume_set').on('click', function(){ >- $('#modal-volume-set').modal('show'); >+ // Add item(s) to a item group >+ $('.itemselection_action_item_group_set').on('click', function(){ >+ $('#modal-item-group-set').modal('show'); > }); > >- $("#modal-volume-set-form").validate({ >+ $("#modal-item-group-set-form").validate({ > submitHandler: function(form) { >- $('#modal-volume-set-submit').attr('disabled', 'disabled'); >+ $('#modal-item-group-set-submit').attr('disabled', 'disabled'); > >- const volume_id = $('#volume-add-form-select').val(); >+ const item_group_id = $('#item-group-add-form-select').val(); > > let itemnumbers = new Array(); > $("input[name='itemnumber'][type='checkbox']:checked").each(function() { >@@ -1734,25 +1734,25 @@ Note that permanent location is a code, and location may be an authval. > itemnumbers.push( itemnumber ); > }); > if (itemnumbers.length > 0) { >- let url = '/cgi-bin/koha/catalogue/detail.pl?op=set_volume'; >+ let url = '/cgi-bin/koha/catalogue/detail.pl?op=set_item_group'; > url += '&itemnumber=' + itemnumbers.join('&itemnumber='); > url += '&biblionumber=[% biblionumber | uri %]'; >- url += `&volume_id=${volume_id}`; >+ url += `&item_group_id=${item_group_id}`; > > window.location.replace(url); > } > >- $('#modal-volume-set').modal('hide'); >+ $('#modal-item-group-set').modal('hide'); > } > }); > >- // Remove item(s) from a volume >- $('.itemselection_action_volume_unset').on('click', function(){ >- $('#modal-volume-unset').modal('show'); >+ // Remove item(s) from an item group >+ $('.itemselection_action_item_group_unset').on('click', function(){ >+ $('#modal-item-group-unset').modal('show'); > }); > >- $("#modal-volume-unset-submit").on('click', function(){ >- $('#modal-volume-unset-submit').attr('disabled', 'disabled'); >+ $("#modal-item-group-unset-submit").on('click', function(){ >+ $('#modal-item-group-unset-submit').attr('disabled', 'disabled'); > > let itemnumbers = new Array(); > $("input[name='itemnumber'][type='checkbox']:checked").each(function() { >@@ -1760,14 +1760,14 @@ Note that permanent location is a code, and location may be an authval. > itemnumbers.push( itemnumber ); > }); > if (itemnumbers.length > 0) { >- let url = '/cgi-bin/koha/catalogue/detail.pl?op=unset_volume'; >+ let url = '/cgi-bin/koha/catalogue/detail.pl?op=unset_item_group'; > url += '&itemnumber=' + itemnumbers.join('&itemnumber='); > url += '&biblionumber=[% biblionumber | uri %]'; > > window.location.replace(url); > } > >- $('#modal-volume-unset').modal('hide'); >+ $('#modal-item-group-unset').modal('hide'); > }); > [% END %] > </script> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt >index 1a06db08ca..2d0a55c3b3 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt >@@ -239,30 +239,30 @@ > <input type="hidden" name="indicator" value=" " /> > <input type="hidden" name="itemnumber" value="[% itemnumber | html %]" /> > >-[% IF volumes.count && op != 'saveitem' && CAN_user_editcatalogue_manage_volumes %] >+[% IF item_groups.count && op != 'saveitem' && CAN_user_editcatalogue_manage_item_groups %] > <fieldset class="rows"> >- <legend><i class="fa fa-plus"></i> Add to volume</legend> >- [% FOREACH v IN volumes %] >- <input type="hidden" id="volume-[% v.id | html %]" value="[% v.description | html %]" /> >+ <legend><i class="fa fa-plus"></i> Add to item group</legend> >+ [% FOREACH ig IN item_groups %] >+ <input type="hidden" id="item-group-[% ig.id | html %]" value="[% ig.description | html %]" /> > [% END %] > <p> >- <label for="select_volume">Options: </label> >- <select name="volume" id="volume-add-or-create-form-select"> >- <optgroup label="Use existing volume"> >- [% FOREACH v IN volumes %] >- <option value="[% v.id | html %]">Use: [% v.description | html %]</option> >+ <label for="select_item_group">Options: </label> >+ <select name="item_group" id="item-group-add-or-create-form-select"> >+ <optgroup label="Use existing item group"> >+ [% FOREACH ig IN item_groups %] >+ <option value="[% ig.id | html %]">Use: [% ig.description | html %]</option> > [% END %] > </optgroup> > <optgroup label="Other options"> >- <option id="volume-add-or-create-form-no-add" value="">Do not add to volume</option> >- <option value="create">Create new volume</option> >+ <option id="item-group-add-or-create-form-no-add" value="">Do not add to item group</option> >+ <option value="create">Create new item group</option> > </optgroup> > </select> > </p> > >- <p id="volume-add-or-create-form-description-block"> >- <label for="volume_description" class="required">Name: </label> >- <input name="volume_description" id="volume-add-or-create-form-description" type="text" size="30" class="required" /> >+ <p id="item-group-add-or-create-form-description-block"> >+ <label for="item_group_description" class="required">Name: </label> >+ <input name="item_group_description" id="item-group-add-or-create-form-description" type="text" size="30" class="required" /> > <span class="required">Required</span> > </p> > </fieldset> >@@ -319,7 +319,7 @@ > > [% MACRO jsinclude BLOCK %] > <script> >- var has_volumes = [% volumes.count | html %]; >+ var has_item_groups = [% item_groups.count | html %]; > </script> > [% END %] > >diff --git a/koha-tmpl/intranet-tmpl/prog/js/cataloging_additem.js b/koha-tmpl/intranet-tmpl/prog/js/cataloging_additem.js >index f5b0d3ab1f..ed51edf0b5 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/cataloging_additem.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/cataloging_additem.js >@@ -69,30 +69,30 @@ $(document).ready(function(){ > multiCopyControl.toggle(); > }); > >- // Add new item to volume >- if ( has_volumes ) { >- $('#volume-add-or-create-form-description-block').hide(); >- $('#volume-add-or-create-form-no-add').attr('selected', 'selected' ); >+ // Add new item to an item group >+ if ( has_item_groups ) { >+ $('#item-add-or-create-form-description-block').hide(); >+ $('#item-group-add-or-create-form-no-add').attr('selected', 'selected' ); > >- $('#volume-add-or-create-form-select').on('change', function(){ >+ $('#item-group-add-or-create-form-select').on('change', function(){ > if ( $(this).val() == 'create' ) { >- $('#volume-add-or-create-form-description') >+ $('#item-group-add-or-create-form-description') > .addClass('required') > .attr( 'required', 'required' ); >- $('#volume-add-or-create-form-description-block').show(); >+ $('#item-group-add-or-create-form-description-block').show(); > } else { >- $('#volume-add-or-create-form-description') >+ $('#item-group-add-or-create-form-description') > .removeClass('required') > .removeAttr('required'); >- $('#volume-add-or-create-form-description-block').hide(); >+ $('#item-group-add-or-create-form-description-block').hide(); > } > }); > } > >- $('#volume-add-or-create-form-select').on('change', function() { >+ $('#item-group-add-or-create-form-select').on('change', function() { > if ( ! $('input.items-enumchron').val() ) { >- let volume_selector = '#volume-' + $(this).val(); >- let enumchron = $(volume_selector).val(); >+ let item_group_selector = '#item-group-' + $(this).val(); >+ let enumchron = $(item_group_selector).val(); > $('input.items-enumchron').val( enumchron ); > } > }); >diff --git a/t/db_dependent/Koha/Biblio.t b/t/db_dependent/Koha/Biblio.t >index 83de0634c6..2cb6fa4d40 100755 >--- a/t/db_dependent/Koha/Biblio.t >+++ b/t/db_dependent/Koha/Biblio.t >@@ -17,7 +17,7 @@ > > use Modern::Perl; > >-use Test::More tests => 14; >+use Test::More tests => 15; > > use C4::Biblio qw( AddBiblio ModBiblio ); > use Koha::Database; >@@ -637,3 +637,30 @@ subtest 'get_marc_notes() UNIMARC tests' => sub { > > $schema->storage->txn_rollback; > }; >+ >+subtest 'item_groups() tests' => sub { >+ >+ plan tests => 6; >+ >+ $schema->storage->txn_begin; >+ >+ my $biblio = $builder->build_sample_biblio(); >+ >+ my @item_groups = $biblio->item_groups; >+ is( scalar(@item_groups), 0, 'Got zero item groups'); >+ >+ my $item_group_1 = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id } )->store(); >+ >+ @item_groups = $biblio->item_groups; >+ is( scalar(@item_groups), 1, 'Got one item group'); >+ is( $item_groups[0]->id, $item_group_1->id, 'Got correct item group'); >+ >+ my $item_group_2 = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id } )->store(); >+ >+ @item_groups = $biblio->item_groups; >+ is( scalar(@item_groups), 2, 'Got two item groups'); >+ is( $item_groups[0]->id, $item_group_1->id, 'Got correct item group 1'); >+ is( $item_groups[1]->id, $item_group_2->id, 'Got correct item group 2'); >+ >+ $schema->storage->txn_rollback; >+}; >diff --git a/t/db_dependent/Koha/Biblio/ItemGroups.t b/t/db_dependent/Koha/Biblio/ItemGroups.t >new file mode 100755 >index 0000000000..0336ace9aa >--- /dev/null >+++ b/t/db_dependent/Koha/Biblio/ItemGroups.t >@@ -0,0 +1,70 @@ >+#!/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 Test::More tests => 3; >+ >+use Koha::Database; >+ >+use t::lib::TestBuilder; >+use t::lib::Mocks; >+ >+BEGIN { >+ use_ok('Koha::Biblio::ItemGroup'); >+ use_ok('Koha::Biblio::ItemGroups'); >+} >+ >+my $schema = Koha::Database->new->schema; >+my $builder = t::lib::TestBuilder->new; >+ >+t::lib::Mocks::mock_preference('EnableItemGroups', 1); >+ >+subtest 'add_item() and items() tests' => sub { >+ >+ plan tests => 8; >+ >+ $schema->storage->txn_begin; >+ >+ my $biblio = $builder->build_sample_biblio(); >+ my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); >+ my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); >+ >+ my $item_group = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id } )->store(); >+ >+ my $items = $item_group->items; >+ is( $items->count, 0, 'Item group has no items'); >+ >+ $item_group->add_item({ item_id => $item_1->id }); >+ my @items = $item_group->items; >+ is( scalar(@items), 1, 'Item group has one item'); >+ is( $items[0]->id, $item_1->id, 'Item 1 is correct' ); >+ >+ $item_group->add_item({ item_id => $item_2->id }); >+ @items = $item_group->items; >+ is( scalar(@items), 2, 'Item group has two items'); >+ is( $items[0]->id, $item_1->id, 'Item 1 is correct' ); >+ is( $items[1]->id, $item_2->id, 'Item 2 is correct' ); >+ >+ # Remove an item >+ $item_1->delete; >+ @items = $item_group->items; >+ is( scalar(@items), 1, 'Item group now has only one item'); >+ is( $items[0]->id, $item_2->id, 'Item 2 is correct' ); >+ >+ $schema->storage->txn_rollback; >+}; >diff --git a/t/db_dependent/Koha/Item.t b/t/db_dependent/Koha/Item.t >index e9cc993cd7..d44ad076bd 100755 >--- a/t/db_dependent/Koha/Item.t >+++ b/t/db_dependent/Koha/Item.t >@@ -19,7 +19,7 @@ > > use Modern::Perl; > >-use Test::More tests => 12; >+use Test::More tests => 13; > use Test::Exception; > > use C4::Biblio qw( GetMarcSubfieldStructure ); >@@ -1050,3 +1050,28 @@ subtest 'move_to_biblio() tests' => sub { > > $schema->storage->txn_rollback; > }; >+ >+subtest 'item_group() tests' => sub { >+ >+ plan tests => 4; >+ >+ $schema->storage->txn_begin; >+ >+ my $biblio = $builder->build_sample_biblio(); >+ my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); >+ my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); >+ >+ is( $item_1->item_group, undef, 'Item 1 has no item group'); >+ is( $item_2->item_group, undef, 'Item 2 has no item group'); >+ >+ my $item_group_1 = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id } )->store(); >+ my $item_group_2 = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id } )->store(); >+ >+ $item_group_1->add_item({ item_id => $item_1->id }); >+ $item_group_2->add_item({ item_id => $item_2->id }); >+ >+ is( $item_1->item_group->id, $item_group_1->id, 'Got item group 1 correctly' ); >+ is( $item_2->item_group->id, $item_group_2->id, 'Got item group 2 correctly' ); >+ >+ $schema->storage->txn_rollback; >+}; >diff --git a/t/db_dependent/Koha/Volumes.t b/t/db_dependent/Koha/Volumes.t >deleted file mode 100755 >index 1d4b17f9d2..0000000000 >--- a/t/db_dependent/Koha/Volumes.t >+++ /dev/null >@@ -1,156 +0,0 @@ >-#!/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 Test::More tests => 6; >- >-use Koha::Database; >- >-use t::lib::TestBuilder; >-use t::lib::Mocks; >- >-BEGIN { >- use_ok('Koha::Biblio::Volume'); >- use_ok('Koha::Biblio::Volumes'); >-} >- >-my $schema = Koha::Database->new->schema; >-my $builder = t::lib::TestBuilder->new; >- >-t::lib::Mocks::mock_preference('EnableVolumes', 1); >- >-subtest 'Test Koha::Biblio::volumes' => sub { >- >- plan tests => 6; >- >- $schema->storage->txn_begin; >- >- my $biblio = $builder->build_sample_biblio(); >- >- my @volumes = $biblio->volumes->as_list; >- is( scalar(@volumes), 0, 'Got zero volumes'); >- >- my $volume_1 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id } )->store(); >- >- @volumes = $biblio->volumes->as_list; >- is( scalar(@volumes), 1, 'Got one volume'); >- is( $volumes[0]->id, $volume_1->id, 'Got correct volume'); >- >- my $volume_2 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id } )->store(); >- >- @volumes = $biblio->volumes->as_list; >- is( scalar(@volumes), 2, 'Got two volumes'); >- is( $volumes[0]->id, $volume_1->id, 'Got correct volume 1'); >- is( $volumes[1]->id, $volume_2->id, 'Got correct volume 2'); >- >- $schema->storage->txn_rollback; >-}; >- >-subtest 'Test Koha::Biblio::Volume::add_item & Koha::Biblio::Volume::items' => sub { >- >- plan tests => 6; >- >- $schema->storage->txn_begin; >- >- my $biblio = $builder->build_sample_biblio(); >- my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); >- my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); >- >- my $volume = Koha::Biblio::Volume->new( { biblionumber => $biblio->id } )->store(); >- >- my $items = $volume->items; >- is( $items->count, 0, 'Volume has no items'); >- >- $volume->add_item({ item_id => $item_1->id }); >- my @items = $volume->items->as_list; >- is( scalar(@items), 1, 'Volume has one item'); >- is( $items[0]->id, $item_1->id, 'Item 1 is correct' ); >- >- $volume->add_item({ item_id => $item_2->id }); >- @items = $volume->items->as_list; >- is( scalar(@items), 2, 'Volume has two items'); >- is( $items[0]->id, $item_1->id, 'Item 1 is correct' ); >- is( $items[1]->id, $item_2->id, 'Item 2 is correct' ); >- >- $schema->storage->txn_rollback; >-}; >- >-subtest 'Test Koha::Item::volume' => sub { >- >- plan tests => 4; >- >- $schema->storage->txn_begin; >- >- my $biblio = $builder->build_sample_biblio(); >- my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); >- my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); >- >- is( $item_1->volume, undef, 'Item 1 has no volume'); >- is( $item_2->volume, undef, 'Item 2 has no volume'); >- >- my $volume_1 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id } )->store(); >- my $volume_2 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id } )->store(); >- >- $volume_1->add_item({ item_id => $item_1->id }); >- $volume_2->add_item({ item_id => $item_2->id }); >- >- is( $item_1->volume->id, $volume_1->id, 'Got volume 1 correctly' ); >- is( $item_2->volume->id, $volume_2->id, 'Got volume 2 correctly' ); >- >- $schema->storage->txn_rollback; >-}; >- >-subtest 'Koha::Item::delete should delete volume if no other items are using the volume' => sub { >- >- plan tests => 11; >- >- $schema->storage->txn_begin; >- >- my $biblio = $builder->build_sample_biblio(); >- my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); >- my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); >- is( $biblio->items->count, 2, 'Bib has 2 items'); >- >- is( $item_1->volume, undef, 'Item 1 has no volume'); >- is( $item_2->volume, undef, 'Item 2 has no volume'); >- >- my $volume_1 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id } )->store(); >- >- $volume_1->add_item({ item_id => $item_1->id }); >- $volume_1->add_item({ item_id => $item_2->id }); >- >- my $volume = Koha::Biblio::Volumes->find( $volume_1->id ); >- is( $volume->id, $volume_1->id, 'Found the correct volume'); >- >- is( $item_1->volume->id, $volume_1->id, 'Item 1 has correct volume'); >- is( $item_2->volume->id, $volume_1->id, 'Item 2 has correct volume'); >- >- $item_1->delete(); >- is( $biblio->items->count, 1, 'Bib has 2 item'); >- $volume = Koha::Biblio::Volumes->find( $volume_1->id ); >- is( $volume->id, $volume_1->id, 'Volume still exists after deleting and item, but other items remain'); >- >- is( $item_2->volume->id, $volume_1->id, 'Item 2 still has correct volume'); >- >- $item_2->delete(); >- is( $biblio->items->count, 0, 'Bib has 0 items'); >- $volume = Koha::Biblio::Volumes->find( $volume_1->id ); >- is( $volume, undef, 'Volume was deleted when last item was deleted'); >- >- $schema->storage->txn_rollback; >-}; >diff --git a/t/db_dependent/api/v1/volumes.t b/t/db_dependent/api/v1/item_groups.t >similarity index 73% >rename from t/db_dependent/api/v1/volumes.t >rename to t/db_dependent/api/v1/item_groups.t >index 2bfe28adf3..eeaced7ac2 100755 >--- a/t/db_dependent/api/v1/volumes.t >+++ b/t/db_dependent/api/v1/item_groups.t >@@ -26,6 +26,7 @@ use t::lib::Mocks; > > use List::Util qw(min); > >+use Koha::Biblio::ItemGroups; > use Koha::Libraries; > use Koha::Database; > >@@ -33,11 +34,11 @@ my $schema = Koha::Database->new->schema; > my $builder = t::lib::TestBuilder->new; > > t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 ); >-t::lib::Mocks::mock_preference( 'EnableVolumes', 1 ); >+t::lib::Mocks::mock_preference( 'EnableItemGroups', 1 ); > > my $t = Test::Mojo->new('Koha::REST::V1'); > >-subtest 'volumes list() tests' => sub { >+subtest 'list() tests' => sub { > plan tests => 9; > > $schema->storage->txn_begin; >@@ -53,21 +54,21 @@ subtest 'volumes list() tests' => sub { > my $biblio = $builder->build_sample_biblio(); > my $biblio_id = $biblio->id; > >- $t->get_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/volumes" ) >+ $t->get_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/item_groups" ) > ->status_is( 200, 'SWAGGER3.2.2' ); > my $response_count = scalar @{ $t->tx->res->json }; > is( $response_count, 0, 'Results count is 2'); > >- my $volume_1 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id, display_order => 1, description => "Vol 1" } )->store(); >+ my $item_group_1 = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id, display_order => 1, description => "Vol 1" } )->store(); > >- $t->get_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/volumes" ) >+ $t->get_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/item_groups" ) > ->status_is( 200, 'SWAGGER3.2.2' ); > $response_count = scalar @{ $t->tx->res->json }; > is( $response_count, 1, 'Results count is 2'); > >- my $volume_2 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id, display_order => 2, description => "Vol 2" } )->store(); >+ my $item_group_2 = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id, display_order => 2, description => "Vol 2" } )->store(); > >- $t->get_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/volumes" ) >+ $t->get_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/item_groups" ) > ->status_is( 200, 'SWAGGER3.2.2' ); > > $response_count = scalar @{ $t->tx->res->json }; >@@ -76,7 +77,7 @@ subtest 'volumes list() tests' => sub { > $schema->storage->txn_rollback; > }; > >-subtest 'volumes add() tests' => sub { >+subtest 'add() tests' => sub { > > plan tests => 6; > >@@ -98,22 +99,22 @@ subtest 'volumes add() tests' => sub { > my $unauth_userid = $unauthorized_patron->userid; > > my $biblio = $builder->build_sample_biblio(); >- my $biblio_id = $biblio->id; >- my $volume = { description => 'Vol 1', display_order => 1 }; >+ my $biblio_id = $biblio->id; >+ my $item_group = { description => 'Vol 1', display_order => 1 }; > > # Unauthorized attempt >- $t->post_ok( "//$unauth_userid:$password@/api/v1/biblios/$biblio_id/volumes" => json => $volume ) >+ $t->post_ok( "//$unauth_userid:$password@/api/v1/biblios/$biblio_id/item_groups" => json => $item_group ) > ->status_is(403); > > # Authorized attempt >- $t->post_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/volumes" => json => $volume ) >+ $t->post_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/item_groups" => json => $item_group ) > ->status_is( 201, 'SWAGGER3.2.1' ); > > # Invalid biblio id > { # hide useless warnings > local *STDERR; > open STDERR, '>', '/dev/null'; >- $t->post_ok( "//$auth_userid:$password@/api/v1/biblios/XXX/volumes" => json => $volume ) >+ $t->post_ok( "//$auth_userid:$password@/api/v1/biblios/XXX/item_groups" => json => $item_group ) > ->status_is( 404 ); > close STDERR; > } >@@ -121,7 +122,7 @@ subtest 'volumes add() tests' => sub { > $schema->storage->txn_rollback; > }; > >-subtest 'volumes update() tests' => sub { >+subtest 'update() tests' => sub { > plan tests => 9; > > $schema->storage->txn_begin; >@@ -143,31 +144,31 @@ subtest 'volumes update() tests' => sub { > > my $biblio = $builder->build_sample_biblio(); > my $biblio_id = $biblio->id; >- my $volume = Koha::Biblio::Volume->new( { biblionumber => $biblio->id, display_order => 1, description => "Vol 1" } )->store(); >- my $volume_id = $volume->id; >+ my $item_group = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id, display_order => 1, description => "Vol 1" } )->store(); >+ my $item_group_id = $item_group->id; > > # Unauthorized attempt >- $t->put_ok( "//$unauth_userid:$password@/api/v1/biblios/$biblio_id/volumes/$volume_id" >+ $t->put_ok( "//$unauth_userid:$password@/api/v1/biblios/$biblio_id/item_groups/$item_group_id" > => json => { description => 'New unauthorized desc change' } ) > ->status_is(403); > > # Authorized attempt >- $t->put_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/volumes/$volume_id" => json => { description => "Vol A" } ) >+ $t->put_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/item_groups/$item_group_id" => json => { description => "Vol A" } ) > ->status_is(200, 'SWAGGER3.2.1') > ->json_has( '/description' => "Vol A", 'SWAGGER3.3.3' ); > > # Invalid biblio id >- $t->put_ok( "//$auth_userid:$password@/api/v1/biblios/XXX/volumes/$volume_id" => json => { description => "Vol A" } ) >+ $t->put_ok( "//$auth_userid:$password@/api/v1/biblios/XXX/item_groups/$item_group_id" => json => { description => "Vol A" } ) > ->status_is(404); > >- # Invalid volume id >- $t->put_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/volumes/XXX" => json => { description => "Vol A" } ) >+ # Invalid item group id >+ $t->put_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/item_groups/XXX" => json => { description => "Vol A" } ) > ->status_is(404); > > $schema->storage->txn_rollback; > }; > >-subtest 'volumes delete() tests' => sub { >+subtest 'delete() tests' => sub { > plan tests => 9; > > $schema->storage->txn_begin; >@@ -189,21 +190,21 @@ subtest 'volumes delete() tests' => sub { > > my $biblio = $builder->build_sample_biblio(); > my $biblio_id = $biblio->id; >- my $volume = Koha::Biblio::Volume->new( { biblionumber => $biblio->id, display_order => 1, description => "Vol 1" } )->store(); >- my $volume_id = $volume->id; >+ my $item_group = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id, display_order => 1, description => "Vol 1" } )->store(); >+ my $item_groupid = $item_group->id; > >- $t->delete_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/volumes/$volume_id" ) >+ $t->delete_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/item_groups/$item_groupid" ) > ->status_is(204, 'SWAGGER3.2.4') > ->content_is('', 'SWAGGER3.3.4'); > > # Unauthorized attempt to delete >- $t->delete_ok( "//$unauth_userid:$password@/api/v1/biblios/$biblio_id/volumes/$volume_id" ) >+ $t->delete_ok( "//$unauth_userid:$password@/api/v1/biblios/$biblio_id/item_groups/$item_groupid" ) > ->status_is(403); > >- $t->delete_ok( "//$auth_userid:$password@/api/v1/biblios/XXX/volumes/$volume_id" ) >+ $t->delete_ok( "//$auth_userid:$password@/api/v1/biblios/XXX/item_groups/$item_groupid" ) > ->status_is(404); > >- $t->delete_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/volumes/XXX" ) >+ $t->delete_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/item_groups/XXX" ) > ->status_is(404); > > $schema->storage->txn_rollback; >@@ -225,40 +226,40 @@ subtest 'volume items add() + delete() tests' => sub { > my $biblio = $builder->build_sample_biblio(); > my $biblio_id = $biblio->id; > >- my $volume = Koha::Biblio::Volume->new( { biblionumber => $biblio->id, display_order => 1, description => "Vol 1" } )->store(); >- my $volume_id = $volume->id; >+ my $item_group = Koha::Biblio::ItemGroup->new( { biblio_id => $biblio->id, display_order => 1, description => "Vol 1" } )->store(); >+ my $item_groupid = $item_group->id; > >- my @items = $volume->items; >- is( scalar(@items), 0, 'Volume has no items'); >+ my @items = $item_group->items; >+ is( scalar(@items), 0, 'Item group has no items'); > > my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); > my $item_1_id = $item_1->id; > >- $t->post_ok( "//$userid:$password@/api/v1/biblios/XXX/volumes/$volume_id/items" => json => { item_id => $item_1->id } ) >+ $t->post_ok( "//$userid:$password@/api/v1/biblios/XXX/item_groups/$item_groupid/items" => json => { item_id => $item_1->id } ) > ->status_is( 409 ) >- ->json_is( { error => 'Volume does not belong to passed biblio_id' } ); >+ ->json_is( { error => 'Item group does not belong to passed biblio_id' } ); > >- $t->post_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/volumes/$volume_id/items" => json => { item_id => $item_1->id } ) >+ $t->post_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/item_groups/$item_groupid/items" => json => { item_id => $item_1->id } ) > ->status_is( 201, 'SWAGGER3.2.1' ); > >- @items = $volume->items; >- is( scalar(@items), 1, 'Volume now has one item'); >+ @items = $item_group->items; >+ is( scalar(@items), 1, 'Item group now has one item'); > > my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); > my $item_2_id = $item_2->id; > >- $t->post_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/volumes/$volume_id/items" => json => { item_id => $item_2->id } ) >+ $t->post_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/item_groups/$item_groupid/items" => json => { item_id => $item_2->id } ) > ->status_is( 201, 'SWAGGER3.2.1' ); > >- @items = $volume->items; >- is( scalar(@items), 2, 'Volume now has two items'); >+ @items = $item_group->items; >+ is( scalar(@items), 2, 'Item group now has two items'); > >- $t->delete_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/volumes/$volume_id/items/$item_1_id" ) >+ $t->delete_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/item_groups/$item_groupid/items/$item_1_id" ) > ->status_is(204, 'SWAGGER3.2.4') > ->content_is('', 'SWAGGER3.3.4'); > >- @items = $volume->items; >- is( scalar(@items), 1, 'Volume now has one item'); >+ @items = $item_group->items; >+ is( scalar(@items), 1, 'Item group now has one item'); > > $schema->storage->txn_rollback; > }; >-- >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 24857
:
100652
|
100653
|
100654
|
100655
|
100656
|
100657
|
100658
|
100659
|
100660
|
100661
|
100662
|
101637
|
101638
|
101639
|
101640
|
101641
|
101642
|
101643
|
101644
|
101645
|
101646
|
101647
|
101648
|
101650
|
101651
|
101652
|
101653
|
101654
|
101655
|
101656
|
101657
|
101658
|
101659
|
101660
|
101661
|
101670
|
101671
|
101672
|
101673
|
101674
|
101675
|
101676
|
101677
|
101678
|
101679
|
101680
|
101681
|
101730
|
101731
|
101732
|
101733
|
101734
|
101735
|
101736
|
101737
|
101738
|
101739
|
101740
|
101741
|
101752
|
101753
|
101754
|
101755
|
101756
|
101757
|
101758
|
101759
|
101760
|
101761
|
101762
|
101763
|
104952
|
104953
|
104954
|
104955
|
104956
|
104957
|
104958
|
104959
|
104960
|
104961
|
104962
|
104963
|
104964
|
104966
|
106728
|
106729
|
106730
|
106731
|
106732
|
106733
|
106734
|
106735
|
106736
|
106737
|
106738
|
106739
|
106740
|
106741
|
108443
|
108444
|
108445
|
108446
|
108447
|
108448
|
108449
|
108450
|
108451
|
108452
|
108453
|
108454
|
108455
|
108456
|
108666
|
108667
|
108668
|
108669
|
108670
|
108671
|
108672
|
108673
|
108674
|
108675
|
108676
|
108677
|
108678
|
108679
|
108680
|
108681
|
108682
|
108683
|
108684
|
108685
|
108686
|
109074
|
109075
|
109076
|
109077
|
109078
|
109079
|
109080
|
109081
|
109082
|
109083
|
109084
|
109085
|
109086
|
109087
|
109088
|
109089
|
109090
|
109091
|
109092
|
109093
|
109094
|
109795
|
109796
|
109797
|
109798
|
109799
|
109800
|
109801
|
109802
|
109803
|
109804
|
109805
|
109806
|
109807
|
109808
|
109809
|
109810
|
109811
|
109812
|
109813
|
109814
|
109815
|
109894
|
109901
|
109902
|
109903
|
109904
|
109905
|
109906
|
109907
|
109908
|
109909
|
109910
|
109911
|
109912
|
109913
|
109914
|
109915
|
109916
|
109917
|
109918
|
109919
|
109920
|
109921
|
109922
|
109923
|
113136
|
113137
|
113138
|
113139
|
113140
|
113141
|
113142
|
113143
|
113144
|
113145
|
113146
|
113147
|
113148
|
113149
|
113150
|
113151
|
113152
|
113153
|
113154
|
113155
|
113156
|
113157
|
113158
|
113159
|
113160
|
113168
|
113169
|
113170
|
113171
|
113172
|
113173
|
113174
|
113175
|
113176
|
113177
|
113178
|
113179
|
113180
|
113181
|
113182
|
113183
|
113184
|
113185
|
113186
|
113187
|
113188
|
113189
|
113190
|
113191
|
120495
|
120496
|
120497
|
120498
|
120499
|
120500
|
120501
|
120502
|
120503
|
120504
|
120505
|
120506
|
120507
|
120508
|
120509
|
120510
|
120511
|
120512
|
120513
|
120514
|
120515
|
120516
|
120517
|
120518
|
122808
|
122809
|
122810
|
122811
|
122812
|
122813
|
122814
|
122815
|
122816
|
122817
|
122818
|
122819
|
122820
|
122821
|
122822
|
122823
|
122824
|
122825
|
122826
|
122827
|
122828
|
122829
|
122830
|
122831
|
123882
|
123883
|
123884
|
123885
|
123886
|
123887
|
123888
|
123889
|
123890
|
123891
|
123892
|
123893
|
123894
|
123895
|
123896
|
123897
|
123898
|
123899
|
123900
|
123901
|
123902
|
123903
|
123904
|
123905
|
123906
|
123907
|
123908
|
123909
|
123910
|
123912
|
124021
|
124022
|
124023
|
124024
|
124025
|
124026
|
124027
|
124028
|
124029
|
124030
|
124031
|
124032
|
124033
|
124034
|
124035
|
124036
|
124037
|
124038
|
124039
|
124040
|
124041
|
124042
|
124043
|
124044
|
124045
|
124046
|
124047
|
124048
|
124049
|
124050
|
124051
|
124052
|
124053
|
124331
|
124332
|
124333
|
124334
|
124335
|
124336
|
124337
|
124338
|
124339
|
124340
|
124341
|
124342
|
124343
|
124344
|
124345
|
124346
|
124347
|
124348
|
124349
|
124351
|
124352
|
124353
|
124354
|
124355
|
124356
|
124357
|
124358
|
124359
|
124360
|
124361
|
124362
|
124363
|
124421
|
124463
|
124583
|
124584
|
124585
|
124586
|
124587
|
124588
|
124589
|
124590
|
124591
|
124592
|
124593
|
124594
|
124595
|
124596
|
124597
|
124598
|
124599
|
124600
|
124601
|
124602
|
124603
|
124604
|
124605
|
124606
|
124607
|
124608
|
124609
|
124610
|
124611
|
124612
|
124613
|
124614
|
124615
|
131449
|
131450
|
131451
|
131452
|
131453
|
131454
|
131455
|
131456
|
134288
|
134289
|
134290
|
134291
|
134292
|
134293
|
134294
|
134295
|
134296
|
135590
|
135591
|
135592
|
135593
|
135594
|
135595
|
135596
|
135597
|
135598
|
135599
|
135600
|
135601
|
135602
|
135603
|
135604
|
135605
|
135606
|
135607
|
135608
|
135609
|
135610
|
135614
|
135615
|
135616
|
135617
|
135618
|
135619
|
135620
|
135621
|
135622
|
135623
|
135624
|
135625
|
135626
|
135627
|
135628
|
135629
|
137259
|
137260
|
137261
|
137262
|
137263
|
137264
|
137265
|
137266
|
137267
|
137268
|
137311
|
137314
|
137315
|
137316
|
137317
|
137318
|
137319
|
137320
|
137321
|
137322
|
137323
|
137441
|
137442
|
137443
|
137608
|
138933