Bugzilla – Attachment 136912 Details for
Bug 28854
Add ability to create bundles of items for circulation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 28854: Record and display who lost the item
Bug-28854-Record-and-display-who-lost-the-item.patch (text/plain), 16.74 KB, created by
Katrin Fischer
on 2022-07-01 13:50:51 UTC
(
hide
)
Description:
Bug 28854: Record and display who lost the item
Filename:
MIME Type:
Creator:
Katrin Fischer
Created:
2022-07-01 13:50:51 UTC
Size:
16.74 KB
patch
obsolete
>From 7081629240597b14a779bbdb0bf571b26eed407b Mon Sep 17 00:00:00 2001 >From: Martin Renvoize <martin.renvoize@ptfs-europe.com> >Date: Thu, 23 Sep 2021 13:58:50 +0100 >Subject: [PATCH] Bug 28854: Record and display who lost the item > >This patch records the bundle issue from which an item is marked as lost >so that we may use that to infer who lost the item (for later charges >and display). > >Test plan >0) Apply all patches up to this point >1) Checkout a bundle to a user >2) Checkin the bundle and do not scan one of the barcodes at > confirmation > * Note that the item not scanned is marked as lost >3) Navigate to the biblio for the lost item and note that it is marked > as lost. >4) Navigate to the biblio for the collection and expand the collection > item that contains the lost item. Note the item is marked as lost and > checkout details are listed. >5) Checkin the lost item > * The item should be marked as found and the return_claims line should > be marked as resolved. > >Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de> >--- > C4/Accounts.pm | 7 +- > Koha/Item.pm | 16 ++- > circ/returns.pl | 109 ++++++++++++------ > .../prog/en/includes/html_helpers.inc | 2 + > .../prog/en/modules/catalogue/detail.tt | 7 +- > .../prog/en/modules/circ/returns.tt | 19 +++ > 6 files changed, 118 insertions(+), 42 deletions(-) > >diff --git a/C4/Accounts.pm b/C4/Accounts.pm >index ad0d34f184..84ebbcd225 100644 >--- a/C4/Accounts.pm >+++ b/C4/Accounts.pm >@@ -70,7 +70,8 @@ FIXME : if no replacement price, borrower just doesn't get charged? > sub chargelostitem { > my $dbh = C4::Context->dbh(); > my ($borrowernumber, $itemnumber, $amount, $description) = @_; >- my $itype = Koha::ItemTypes->find({ itemtype => Koha::Items->find($itemnumber)->effective_itemtype() }); >+ my $item = Koha::Items->find($itemnumber); >+ my $itype = Koha::ItemTypes->find({ itemtype => $item->effective_itemtype() }); > my $replacementprice = $amount; > my $defaultreplacecost = $itype->defaultreplacecost; > my $processfee = $itype->processfee; >@@ -80,6 +81,10 @@ sub chargelostitem { > $replacementprice = $defaultreplacecost; > } > my $checkout = Koha::Checkouts->find({ itemnumber => $itemnumber }); >+ if ( !$checkout && $item->in_bundle ) { >+ my $host = $item->bundle_host; >+ $checkout = $host->checkout; >+ } > my $issue_id = $checkout ? $checkout->issue_id : undef; > > my $account = Koha::Account->new({ patron_id => $borrowernumber }); >diff --git a/Koha/Item.pm b/Koha/Item.pm >index 134def36a2..9c64709b57 100644 >--- a/Koha/Item.pm >+++ b/Koha/Item.pm >@@ -417,6 +417,20 @@ sub checkout { > return Koha::Checkout->_new_from_dbic( $checkout_rs ); > } > >+=head3 return_claims >+ >+ my $return_claims = $item->return_claims; >+ >+Return any return_claims associated with this item >+ >+=cut >+ >+sub return_claims { >+ my ( $self, $params, $attrs ) = @_; >+ my $claims_rs = $self->_result->return_claims->search($params, $attrs); >+ return Koha::Checkouts::ReturnClaims->_new_from_dbic( $claims_rs ); >+} >+ > =head3 holds > > my $holds = $item->holds(); >@@ -1090,7 +1104,7 @@ Internal function, not exported, called only by Koha::Item->store. > sub _set_found_trigger { > my ( $self, $pre_mod_item ) = @_; > >- ## If item was lost, it has now been found, reverse any list item charges if necessary. >+ # Reverse any lost item charges if necessary. > my $no_refund_after_days = > C4::Context->preference('NoRefundOnLostReturnedItemsAge'); > if ($no_refund_after_days) { >diff --git a/circ/returns.pl b/circ/returns.pl >index 52df948d14..545de9b502 100755 >--- a/circ/returns.pl >+++ b/circ/returns.pl >@@ -391,43 +391,6 @@ if ($barcode) { > } > } > >- # Mark missing bundle items as lost and report unexpected items >- if ( $item->is_bundle ) { >- my $BundleLostValue = C4::Context->preference('BundleLostValue'); >- my $barcodes = $query->param('verify-items-bundle-contents-barcodes'); >- my @barcodes = map { s/^\s+|\s+$//gr } ( split /\n/, $barcodes ); >- my $expected_items = { map { $_->barcode => $_ } $item->bundle_items->as_list }; >- my $verify_items = Koha::Items->search( { barcode => { 'in' => \@barcodes } } ); >- my @unexpected_items; >- my @missing_items; >- my @bundle_items; >- while ( my $verify_item = $verify_items->next ) { >- # Fix and lost statuses >- $verify_item->itemlost(0); >- >- # Expected item, remove from lookup table >- if ( delete $expected_items->{$verify_item->barcode} ) { >- push @bundle_items, $verify_item; >- } >- # Unexpected item, warn and remove from bundle >- else { >- $verify_item->remove_from_bundle; >- push @unexpected_items, $verify_item; >- } >- # Store results >- $verify_item->store(); >- } >- for my $missing_item ( keys %{$expected_items} ) { >- my $bundle_item = $expected_items->{$missing_item}; >- $bundle_item->itemlost($BundleLostValue)->store(); >- push @missing_items, $bundle_item; >- } >- $template->param( >- unexpected_items => \@unexpected_items, >- missing_items => \@missing_items, >- bundle_items => \@bundle_items >- ); >- } > } elsif ( C4::Context->preference('ShowAllCheckins') and !$messages->{'BadBarcode'} and !$needs_confirm and !$bundle_confirm ) { > $input{duedate} = 0; > $returneditems{0} = $barcode; >@@ -445,6 +408,78 @@ if ($barcode) { > items_bundle_return_confirmation => 1, > ); > } >+ >+ # Mark missing bundle items as lost and report unexpected items >+ if ( $item->is_bundle && $query->param('confirm_items_bundle_return') ) { >+ my $BundleLostValue = C4::Context->preference('BundleLostValue'); >+ my $barcodes = $query->param('verify-items-bundle-contents-barcodes'); >+ my @barcodes = map { s/^\s+|\s+$//gr } ( split /\n/, $barcodes ); >+ my $expected_items = { map { $_->barcode => $_ } $item->bundle_items->as_list }; >+ my $verify_items = Koha::Items->search( { barcode => { 'in' => \@barcodes } } ); >+ my @unexpected_items; >+ my @missing_items; >+ my @bundle_items; >+ while ( my $verify_item = $verify_items->next ) { >+ # Fix and lost statuses >+ $verify_item->itemlost(0); >+ >+ # Update last_seen >+ $verify_item->datelastseen( dt_from_string()->ymd() ); >+ >+ # Update last_borrowed if actual checkin >+ $verify_item->datelastborrowed( dt_from_string()->ymd() ) if $issue; >+ >+ # Expected item, remove from lookup table >+ if ( delete $expected_items->{$verify_item->barcode} ) { >+ push @bundle_items, $verify_item; >+ } >+ # Unexpected item, warn and remove from bundle >+ else { >+ $verify_item->remove_from_bundle; >+ push @unexpected_items, $verify_item; >+ } >+ >+ # Store results >+ $verify_item->store(); >+ } >+ for my $missing_item ( keys %{$expected_items} ) { >+ my $bundle_item = $expected_items->{$missing_item}; >+ $bundle_item->itemlost($BundleLostValue)->store(); >+ # Add return_claim record if this is an actual checkin >+ if ($issue) { >+ $bundle_item->_result->create_related( >+ 'return_claims', >+ { >+ issue_id => $issue->issue_id, >+ itemnumber => $bundle_item->itemnumber, >+ borrowernumber => $issue->borrowernumber, >+ created_by => C4::Context->userenv()->{number}, >+ created_on => dt_from_string >+ } >+ ); >+ } >+ push @missing_items, $bundle_item; >+ # NOTE: We cannot use C4::LostItem here because the item itself doesn't have a checkout >+ # and thus would not get charged.. it's checked out as part of the bundle. >+ if ( C4::Context->preference('WhenLostChargeReplacementFee') && $issue ) { >+ C4::Accounts::chargelostitem( >+ $issue->borrowernumber, >+ $bundle_item->itemnumber, >+ $bundle_item->replacementprice, >+ sprintf( "%s %s %s", >+ $bundle_item->biblio->title || q{}, >+ $bundle_item->barcode || q{}, >+ $bundle_item->itemcallnumber || q{}, >+ ), >+ ); >+ } >+ } >+ $template->param( >+ unexpected_items => \@unexpected_items, >+ missing_items => \@missing_items, >+ bundle_items => \@bundle_items >+ ); >+ } > } > $template->param( inputloop => \@inputloop ); > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc >index a991f0ce50..ea799da114 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc >@@ -115,6 +115,8 @@ > [% ELSE %] > [% IF subfield.IS_LOST_AV && Koha.Preference("ClaimReturnedLostValue") && aval == Koha.Preference("ClaimReturnedLostValue") %] > <option disabled="disabled" value="[%- aval | html -%]" title="Return claims must be processed from the patron details page">[%- mv.labels.$aval | html -%]</option> >+ [% ELSIF subfield.IS_LOST_AV && Koha.Preference("BundleLostValue") && aval == Koha.Preference("BundleLostValue") %] >+ <option disabled="disabled" value="[%- aval | html -%]" title="Bundle losses are set at checkin automatically">[%- mv.labels.$aval | html -%]</option> > [% ELSE %] > <option value="[%- aval | html -%]">[%- mv.labels.$aval | html -%]</option> > [% END %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >index b658c475d6..d054714c61 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >@@ -1414,6 +1414,7 @@ Note that permanent location is a code, and location may be an authval. > > [% IF bundlesEnabled %] > var bundle_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail','bundle_tables','json') | $raw %]; >+ var bundle_lost_value = [% Koha.Preference('BundleLostValue') %]; > [% END %] > $(document).ready(function() { > >@@ -1505,10 +1506,10 @@ Note that permanent location is a code, and location may be an authval. > "searchable": false, > "orderable": true, > "render": function(data, type, row, meta) { >- if ( row.lost_status ) { >- return "Lost: " + row.lost_status; >+ if ( row.lost_status == bundle_lost_value ) { >+ return "Last seen: " + row.last_seen_date; > } >- return ""; >+ return "Present"; > } > }, > { >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt >index d71b326eb8..1a4e0b7809 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt >@@ -429,11 +429,14 @@ > <th>[% t('Author') | html %]</th> > <th>[% t('Item type') | html %]</th> > <th>[% t('Barcode') | html %]</th> >+ [% IF !item.onloan %] > <th>[% t('Status') | html %]</th> >+ [% END %] > </tr> > </thead> > <tbody> > [% FOREACH bundle_item IN item.bundle_items %] >+ [% IF !item.onloan %] > <tr data-barcode="[% bundle_item.barcode | html %]"> > <td>[% INCLUDE 'biblio-title.inc' biblio=bundle_item.biblio link = 1 %]</td> > <td>[% bundle_item.biblio.author | html %]</td> >@@ -441,6 +444,14 @@ > <td>[% bundle_item.barcode | html %]</td> > <td>[% INCLUDE 'item-status.inc' item=bundle_item %]</td> > </tr> >+ [% ELSIF !bundle_item.itemlost %] >+ <tr data-barcode="[% bundle_item.barcode | html %]"> >+ <td>[% INCLUDE 'biblio-title.inc' biblio=bundle_item.biblio link = 1 %]</td> >+ <td>[% bundle_item.biblio.author | html %]</td> >+ <td>[% ItemTypes.GetDescription(bundle_item.itype) | html %]</td> >+ <td>[% bundle_item.barcode | html %]</td> >+ </tr> >+ [% END %] > [% END %] > </tbody> > </table> >@@ -448,7 +459,11 @@ > <div class="form-group"> > <label for="verify-items-bundle-contents-barcodes">Barcodes</label> > <textarea autocomplete="off" id="verify-items-bundle-contents-barcodes" name="verify-items-bundle-contents-barcodes" class="form-control"></textarea> >+ [% IF item.onloan %] > <div class="help-block">[% t('Scan all barcodes of items found in the items bundle. If any items are missing, they will be marked as lost') | html %]</div> >+ [% ELSE %] >+ <div class="help-block">[% t('Optionally scan all barcodes of items found in the items bundle to perform an inventory check. If any items are missing, they will be marked as lost') | html %]</div> >+ [% END %] > </div> > > </div> >@@ -460,7 +475,11 @@ > <input type="hidden" name="dd-[% inputloo.counter | html %]" value="[% inputloo.duedate | html %]" /> > <input type="hidden" name="bn-[% inputloo.counter | html %]" value="[% inputloo.borrowernumber | html %]" /> > [% END %] >+ [% IF item.onloan %] > <button type="submit" class="btn btn-default"><i class="fa fa-check"></i> [% t('Confirm checkin and mark missing items as lost') | html %]</button> >+ [% ELSE %] >+ <button type="submit" class="btn btn-default"><i class="fa fa-check"></i> [% t('Confirm inventory check and mark items as lost') | html %]</button> >+ [% END %] > <button type="button" data-dismiss="modal" class="btn btn-default"><i class="fa fa-close"></i> [% t('Cancel') | html %]</button> > </div> > </form> >-- >2.30.2
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 28854
:
124319
|
124498
|
124616
|
125200
|
125201
|
125202
|
125203
|
125204
|
125205
|
125206
|
126103
|
126104
|
126105
|
126106
|
126107
|
126108
|
126109
|
126110
|
126148
|
126149
|
126150
|
126151
|
126152
|
126153
|
126154
|
126155
|
126166
|
126167
|
126168
|
126169
|
126170
|
126171
|
126172
|
126173
|
127498
|
127499
|
127500
|
127501
|
127502
|
127503
|
127504
|
127505
|
127659
|
127660
|
127661
|
127662
|
127663
|
127664
|
127665
|
127666
|
127829
|
127830
|
127831
|
127832
|
127833
|
127834
|
127835
|
127836
|
127837
|
127838
|
130313
|
130314
|
130315
|
130316
|
130317
|
130318
|
130319
|
130320
|
130321
|
130322
|
130323
|
130324
|
130325
|
130326
|
130327
|
130328
|
130329
|
130330
|
130331
|
130332
|
130456
|
132703
|
132704
|
132705
|
132706
|
132707
|
132708
|
132709
|
132710
|
132711
|
132712
|
132713
|
132714
|
132715
|
132716
|
132717
|
132718
|
132719
|
132720
|
132721
|
132722
|
132723
|
135019
|
135020
|
135021
|
135022
|
135023
|
135024
|
135025
|
135026
|
135027
|
135028
|
135029
|
135030
|
135031
|
135032
|
135033
|
135034
|
135035
|
135036
|
135037
|
136226
|
136227
|
136228
|
136229
|
136230
|
136231
|
136232
|
136233
|
136234
|
136235
|
136236
|
136237
|
136238
|
136239
|
136240
|
136241
|
136242
|
136243
|
136244
|
136249
|
136253
|
136254
|
136264
|
136265
|
136266
|
136267
|
136268
|
136269
|
136270
|
136271
|
136272
|
136273
|
136274
|
136275
|
136276
|
136277
|
136278
|
136279
|
136280
|
136281
|
136282
|
136283
|
136284
|
136285
|
136287
|
136340
|
136341
|
136342
|
136343
|
136344
|
136345
|
136346
|
136347
|
136348
|
136349
|
136350
|
136351
|
136352
|
136353
|
136354
|
136355
|
136356
|
136357
|
136358
|
136359
|
136360
|
136361
|
136362
|
136363
|
136364
|
136365
|
136366
|
136367
|
136368
|
136369
|
136370
|
136371
|
136498
|
136529
|
136530
|
136613
|
136614
|
136615
|
136616
|
136617
|
136618
|
136619
|
136620
|
136621
|
136622
|
136623
|
136624
|
136625
|
136626
|
136627
|
136628
|
136629
|
136630
|
136631
|
136632
|
136633
|
136634
|
136635
|
136636
|
136637
|
136638
|
136639
|
136640
|
136641
|
136642
|
136643
|
136644
|
136645
|
136646
|
136647
|
136648
|
136649
|
136650
|
136651
|
136652
|
136654
|
136655
|
136806
|
136809
|
136811
|
136814
|
136817
|
136821
|
136824
|
136826
|
136829
|
136832
|
136835
|
136838
|
136841
|
136843
|
136846
|
136849
|
136850
|
136851
|
136852
|
136853
|
136854
|
136855
|
136856
|
136857
|
136858
|
136859
|
136860
|
136861
|
136862
|
136863
|
136864
|
136865
|
136866
|
136867
|
136868
|
136869
|
136870
|
136871
|
136872
|
136873
|
136874
|
136875
|
136876
|
136877
|
136905
|
136906
|
136907
|
136908
|
136909
|
136910
|
136911
|
136912
|
136913
|
136914
|
136915
|
136916
|
136917
|
136918
|
136919
|
136920
|
136921
|
136922
|
136923
|
136924
|
136925
|
136926
|
136927
|
136928
|
136929
|
136930
|
136931
|
136932
|
136933
|
136934
|
136935
|
136936
|
136937
|
136938
|
136939
|
136940
|
136941
|
136942
|
136943
|
136944
|
136945
|
136946
|
136947
|
136949
|
136978
|
136979
|
136980
|
136981
|
136982
|
136985
|
136988
|
136989
|
136990
|
136991
|
136992
|
136993
|
136994
|
136995
|
136996
|
136997
|
136998
|
136999
|
137000
|
137001
|
137002
|
137003
|
137004
|
137005
|
137006
|
137007
|
137008
|
137009
|
137010
|
137011
|
137012
|
137013
|
137014
|
137015
|
137016
|
137017
|
137018
|
137019
|
137020
|
137021
|
137022
|
137461
|
137462
|
137463
|
137464
|
137465
|
137466
|
137467
|
137468
|
137469
|
137470
|
137471
|
137472
|
137473
|
137474
|
137475
|
137476
|
137477
|
137478
|
137479
|
137480
|
137481
|
137482
|
137483
|
137484
|
137485
|
137486
|
137487
|
137488
|
137489
|
137490
|
137491
|
137492
|
137493
|
137494
|
137495
|
137496
|
137497
|
137498
|
137499
|
137500
|
137501
|
137503
|
137506
|
137524
|
137525
|
137527
|
137528
|
137529
|
137530
|
137531
|
137532
|
137533
|
137534
|
137535
|
137536
|
137537
|
137538
|
137540
|
137541
|
137542
|
137543
|
137544
|
137545
|
137546
|
137547
|
137548
|
137549
|
137550
|
137551
|
137552
|
137553
|
137554
|
137555
|
137556
|
137557
|
137558
|
137559
|
137560
|
137561
|
137562
|
137563
|
137564
|
137565
|
137566
|
137567
|
137568
|
137569
|
137570
|
137571
|
137684
|
137685
|
139347