Bugzilla – Attachment 39299 Details for
Bug 12768
Replacement cost and processing fee management
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 12768 - Replacement cost and processing fee management
Bug-12768---Replacement-cost-and-processing-fee-ma.patch (text/plain), 19.94 KB, created by
Mark Tompsett
on 2015-05-19 13:41:54 UTC
(
hide
)
Description:
Bug 12768 - Replacement cost and processing fee management
Filename:
MIME Type:
Creator:
Mark Tompsett
Created:
2015-05-19 13:41:54 UTC
Size:
19.94 KB
patch
obsolete
>From 211a026271704746f393bc5cc036d76eec568626 Mon Sep 17 00:00:00 2001 >From: charles <charles@inlibro.com> >Date: Wed, 22 Apr 2015 15:54:04 -0400 >Subject: [PATCH] Bug 12768 - Replacement cost and processing fee management > >--- > C4/Accounts.pm | 72 ++++++++--------- > C4/Circulation.pm | 5 +- > admin/itemtypes.pl | 16 +++- > ...-replacement_cost_processing_fee_management.sql | 2 + > installer/data/mysql/sysprefs.sql | 2 + > .../intranet-tmpl/prog/en/css/staff-global.css | 4 + > .../prog/en/modules/admin/itemtypes.tt | 16 +++- > .../en/modules/admin/preferences/circulation.pref | 12 +++ > t/db_dependent/Circulation/Chargelostitem.t | 89 ++++++++++++++++++++++ > 9 files changed, 172 insertions(+), 46 deletions(-) > create mode 100644 installer/data/mysql/atomicupdate/bug_12768-replacement_cost_processing_fee_management.sql > create mode 100644 t/db_dependent/Circulation/Chargelostitem.t > >diff --git a/C4/Accounts.pm b/C4/Accounts.pm >index d0709d0..614bf8e 100644 >--- a/C4/Accounts.pm >+++ b/C4/Accounts.pm >@@ -353,42 +353,35 @@ sub chargelostitem{ > # a charge has been added > # FIXME : if no replacement price, borrower just doesn't get charged? > my $dbh = C4::Context->dbh(); >- my ($borrowernumber, $itemnumber, $amount, $description) = @_; >- >+ my ($issues, $description) = @_; >+ my $borrowernumber = $issues->{'borrowernumber'}; >+ my $itemnumber = $issues->{'itemnumber'}; >+ my $replacementprice = $issues->{'replacementprice'}; >+ my $defaultreplacecost = $issues->{'defaultreplacecost'}; >+ my $processfee = $issues->{'processfee'}; >+ my $usedefaultreplacementcost = C4::Context->preference("useDefaultReplacementCost"); >+ my $processingfeenote = C4::Context->preference("ProcessingFeeNote"); >+ >+ if ($usedefaultreplacementcost && $replacementprice == 0){ >+ $replacementprice = $defaultreplacecost; >+ } > # first make sure the borrower hasn't already been charged for this item > my $sth1=$dbh->prepare("SELECT * from accountlines > WHERE borrowernumber=? AND itemnumber=? and accounttype='L'"); > $sth1->execute($borrowernumber,$itemnumber); > my $existing_charge_hashref=$sth1->fetchrow_hashref(); >- > # OK, they haven't >+ my $accountline; > unless ($existing_charge_hashref) { >- my $manager_id = 0; >- $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; >- # This item is on issue ... add replacement cost to the borrower's record and mark it returned >- # Note that we add this to the account even if there's no replacement price, allowing some other >- # process (or person) to update it, since we don't handle any defaults for replacement prices. >- my $accountno = getnextacctno($borrowernumber); >- my $sth2=$dbh->prepare("INSERT INTO accountlines >- (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding,itemnumber,manager_id) >- VALUES (?,?,now(),?,?,'L',?,?,?)"); >- $sth2->execute($borrowernumber,$accountno,$amount, >- $description,$amount,$itemnumber,$manager_id); > >- if ( C4::Context->preference("FinesLog") ) { >- logaction("FINES", 'CREATE', $borrowernumber, Dumper({ >- action => 'create_fee', >- borrowernumber => $borrowernumber, >- accountno => $accountno, >- amount => $amount, >- amountoutstanding => $amount, >- description => $description, >- accounttype => 'L', >- itemnumber => $itemnumber, >- manager_id => $manager_id, >- })); >+ #add processing fee >+ if ($processfee > 0){ >+ manualinvoice($borrowernumber, $itemnumber, $description, 'PF', $processfee, $processingfeenote, 1); >+ } >+ #add replace cost >+ if ($replacementprice > 0){ >+ manualinvoice($borrowernumber, $itemnumber, $description, 'L', $replacementprice, undef, 1); > } >- > } > } > >@@ -408,18 +401,19 @@ should be the empty string. > > #' > # FIXME: In Koha 3.0 , the only account adjustment 'types' passed to this function >-# are : >-# 'C' = CREDIT >-# 'FOR' = FORGIVEN (Formerly 'F', but 'F' is taken to mean 'FINE' elsewhere) >-# 'N' = New Card fee >-# 'F' = Fine >-# 'A' = Account Management fee >-# 'M' = Sundry >-# 'L' = Lost Item >+# are : >+# 'C' = CREDIT >+# 'FOR' = FORGIVEN (Formerly 'F', but 'F' is taken to mean 'FINE' elsewhere) >+# 'N' = New Card fee >+# 'F' = Fine >+# 'A' = Account Management fee >+# 'PF' = Processing fee >+# 'M' = Sundry >+# 'L' = Lost Item > # > > sub manualinvoice { >- my ( $borrowernumber, $itemnum, $desc, $type, $amount, $note ) = @_; >+ my ( $borrowernumber, $itemnum, $desc, $type, $amount, $note, $skip_notify ) = @_; > my $manager_id = 0; > $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; > my $dbh = C4::Context->dbh; >@@ -427,6 +421,7 @@ sub manualinvoice { > my $insert; > my $accountno = getnextacctno($borrowernumber); > my $amountleft = $amount; >+ $skip_notify //= 0; > > if ( ( $type eq 'L' ) > or ( $type eq 'F' ) >@@ -434,7 +429,7 @@ sub manualinvoice { > or ( $type eq 'N' ) > or ( $type eq 'M' ) ) > { >- $notifyid = 1; >+ $notifyid = 1 unless $skip_notify; > } > > if ( $itemnum ) { >@@ -473,9 +468,8 @@ sub manualinvoice { > } > > sub getcharges { >- my ( $borrowerno, $timestamp, $accountno ) = @_; >+ my ( $borrowerno, $accountno ) = @_; > my $dbh = C4::Context->dbh; >- my $timestamp2 = $timestamp - 1; > my $query = ""; > my $sth = $dbh->prepare( > "SELECT * FROM accountlines WHERE borrowernumber=? AND accountno = ?" >diff --git a/C4/Circulation.pm b/C4/Circulation.pm >index f991680..62c13a4 100644 >--- a/C4/Circulation.pm >+++ b/C4/Circulation.pm >@@ -3629,10 +3629,11 @@ sub LostItem{ > my ($itemnumber, $mark_returned) = @_; > > my $dbh = C4::Context->dbh(); >- my $sth=$dbh->prepare("SELECT issues.*,items.*,biblio.title >+ my $sth=$dbh->prepare("SELECT issues.*,items.*,biblio.title,itemtypes.defaultreplacecost, itemtypes.processfee > FROM issues > JOIN items USING (itemnumber) > JOIN biblio USING (biblionumber) >+ JOIN itemtypes on items.itype = itemtypes.itemtype > WHERE issues.itemnumber=?"); > $sth->execute($itemnumber); > my $issues=$sth->fetchrow_hashref(); >@@ -3646,7 +3647,7 @@ sub LostItem{ > defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $itemnumber...) failed!"; # zero is OK, check defined > } > if (C4::Context->preference('WhenLostChargeReplacementFee')){ >- C4::Accounts::chargelostitem($borrowernumber, $itemnumber, $issues->{'replacementprice'}, "Lost Item $issues->{'title'} $issues->{'barcode'}"); >+ C4::Accounts::chargelostitem($issues, "Lost Item $issues->{'title'} $issues->{'barcode'}"); > #FIXME : Should probably have a way to distinguish this from an item that really was returned. > #warn " $issues->{'borrowernumber'} / $itemnumber "; > } >diff --git a/admin/itemtypes.pl b/admin/itemtypes.pl >index 9effa7e..69aeb5f 100755 >--- a/admin/itemtypes.pl >+++ b/admin/itemtypes.pl >@@ -116,6 +116,8 @@ if ( $op eq 'add_form' ) { > itemtype => $itemtype, > description => $data->{'description'}, > rentalcharge => sprintf( "%.2f", $data->{'rentalcharge'} ), >+ defaultreplacecost => sprintf( "%.2f", $data->{'defaultreplacecost'} ), >+ processfee => sprintf( "%.2f", $data->{'processfee'} ), > notforloan => $data->{'notforloan'}, > imageurl => $data->{'imageurl'}, > template => C4::Context->preference('template'), >@@ -144,6 +146,8 @@ elsif ( $op eq 'add_validate' ) { > UPDATE itemtypes > SET description = ? > , rentalcharge = ? >+ , defaultreplacecost = ? >+ , processfee = ? > , notforloan = ? > , imageurl = ? > , summary = ? >@@ -156,6 +160,8 @@ elsif ( $op eq 'add_validate' ) { > $sth->execute( > $input->param('description'), > $input->param('rentalcharge'), >+ $input->param('defaultreplacecost'), >+ $input->param('processfee'), > ( $input->param('notforloan') ? 1 : 0 ), > ( > $input->param('image') eq 'removeImage' ? '' : ( >@@ -168,15 +174,15 @@ elsif ( $op eq 'add_validate' ) { > $input->param('checkinmsg'), > $input->param('checkinmsgtype'), > $sip_media_type, >- $input->param('itemtype') >+ $input->param('itemtype'), > ); > } > else { # add a new itemtype & not modif an old > my $query = " > INSERT INTO itemtypes >- (itemtype,description,rentalcharge, notforloan, imageurl, summary, checkinmsg, checkinmsgtype, sip_media_type) >+ (itemtype,description, rentalcharge, defaultreplacecost, processfee, notforloan, imageurl, summary, checkinmsg, checkinmsgtype, sip_media_type) > VALUES >- (?,?,?,?,?,?,?,?,?); >+ (?,?,?,?,?,?,?,?,?,?,?); > "; > my $sth = $dbh->prepare($query); > my $image = $input->param('image'); >@@ -184,6 +190,8 @@ elsif ( $op eq 'add_validate' ) { > $input->param('itemtype'), > $input->param('description'), > $input->param('rentalcharge'), >+ $input->param('defaultreplacecost'), >+ $input->param('processfee'), > $input->param('notforloan') ? 1 : 0, > $image eq 'removeImage' ? '' : > $image eq 'remoteImage' ? $input->param('remoteImage') : >@@ -250,6 +258,8 @@ else { # DEFAULT > foreach my $itemtype ( @{$results} ) { > $itemtype->{imageurl} = getitemtypeimagelocation( 'intranet', $itemtype->{imageurl} ); > $itemtype->{rentalcharge} = sprintf( '%.2f', $itemtype->{rentalcharge} ); >+ $itemtype->{defaultreplacecost} = sprintf( '%.2f', $itemtype->{defaultreplacecost} ); >+ $itemtype->{processfee} = sprintf( '%.2f', $itemtype->{processfee} ); > push( @loop, $itemtype ); > } > >diff --git a/installer/data/mysql/atomicupdate/bug_12768-replacement_cost_processing_fee_management.sql b/installer/data/mysql/atomicupdate/bug_12768-replacement_cost_processing_fee_management.sql >new file mode 100644 >index 0000000..9b27966 >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/bug_12768-replacement_cost_processing_fee_management.sql >@@ -0,0 +1,2 @@ >+INSERT INTO systempreferences (variable,value,explanation,type) VALUES ('useDefaultReplacementCost',0,'default replacement cost defined in item type','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,type) VALUES ('ProcessingFeeNote','','Set the text to be recorded in the column note, table accountlines when the processing fee (defined in item type) is applied','textarea'); >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index f371193..43673ad 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -344,6 +344,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('previousIssuesDefaultSortOrder','asc','asc|desc','Specify the sort order of Previous Issues on the circulation page','Choice'), > ('printcirculationslips','1','','If ON, enable printing circulation receipts','YesNo'), > ('PrintNoticesMaxLines','0','','If greater than 0, sets the maximum number of lines an overdue notice will print. If the number of items is greater than this number, the notice will end with a warning asking the borrower to check their online account for a full list of overdue items.','Integer'), >+('ProcessingFeeNote', '', NULL, 'Set the text to be recorded in the column note, table accountlines when the processing fee (defined in item type) is applied', 'textarea'), > ('QueryAutoTruncate','1',NULL,'If ON, query truncation is enabled by default','YesNo'), > ('QueryFuzzy','1',NULL,'If ON, enables fuzzy option for searches','YesNo'), > ('QueryStemming','1',NULL,'If ON, enables query stemming','YesNo'), >@@ -461,6 +462,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('UseControlNumber','0','','If ON, record control number (w subfields) and control number (001) are used for linking of bibliographic records.','YesNo'), > ('UseCourseReserves','0',NULL,'Enable the course reserves feature.','YesNo'), > ('useDaysMode','Calendar','Calendar|Days|Datedue','Choose the method for calculating due date: select Calendar to use the holidays module, and Days to ignore the holidays module','Choice'), >+('useDefaultReplacementCost', '0', NULL, 'default replacement cost defined in item type', 'YesNo'), > ('useDischarge','','','Allows librarians to discharge borrowers and borrowers to request a discharge','YesNo'), > ('UseICU','0','1','Tell Koha if ICU indexing is in use for Zebra or not.','YesNo'), > ('UseKohaPlugins','0','','Enable or disable the ability to use Koha Plugins.','YesNo'), >diff --git a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css b/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css >index 2c4011f..09d69ad 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css >+++ b/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css >@@ -604,6 +604,10 @@ fieldset.rows fieldset { > width: 9em; > } > >+.yui-b fieldset.rows ol.oladditemtype label, .yui-b fieldset.rows ol.oladditemtype span.label { >+ width: 13em; >+} >+ > .yui-b fieldset.rows div.hint { > margin-left : 10.5em; > } >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt >index 2e61a16..f26a0c9 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt >@@ -162,7 +162,7 @@ Item types administration > </div> > </div> > [% END %] >-<ol> >+<ol class="oladditemtype"> > <li> > <label for="notforloan">Not for loan: </label> [% IF ( notforloan ) %] > <input type="checkbox" id="notforloan" name="notforloan" checked="checked" value="1" /> >@@ -175,7 +175,15 @@ Item types administration > <li> > <label for="rentalcharge">Rental charge: </label> > <input type="text" id="rentalcharge" name="rentalcharge" size="10" value="[% rentalcharge %]" /> >- </li> >+ </li> >+ <li> >+ <label for="defaultreplacecost">Default replacement cost: </label> >+ <input type="text" id="defaultreplacecost" name="defaultreplacecost" size="10" value="[% defaultreplacecost %]" /> >+ </li> >+ <li> >+ <label for="processfee">Processing fee (when lost): </label> >+ <input type="text" id="processfee" name="processfee" size="10" value="[% processfee %]" /> >+ </li> > <li> > <label for="checkinmsg">Checkin message: </label> > <textarea id="checkinmsg" name="checkinmsg" cols="55" rows="5">[% checkinmsg %]</textarea> >@@ -262,6 +270,8 @@ Item types administration > <th>Description</th> > <th>Not for loan</th> > <th>Charge</th> >+ <th>Default replacement cost</th> >+ <th>Processing fee (when lost)</th> > <th>Checkin message</th> > <th>Actions</th> > </thead> >@@ -280,6 +290,8 @@ Item types administration > [% loo.rentalcharge %] > [% END %] > </td> >+ <td>[% loo.defaultreplacecost %]</td> >+ <td>[% loo.processfee %]</td> > <td>[% loo.checkinmsg | html_line_break %]</td> > <td> > <a href="[% loo.script_name %]?op=add_form&itemtype=[% loo.itemtype |html %]">Edit</a> >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 a16f231..6d85069 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 >@@ -626,6 +626,18 @@ Circulation: > yes: Charge > no: "Don't Charge" > - the replacement price when a patron loses an item. >+ - >+ - pref: useDefaultReplacementCost >+ choices: >+ yes: use >+ no: "Don't use" >+ - the default replacement cost defined in item type. >+ - >+ - "Set the text to be recorded in the column 'note', table 'accountlines' when the processing fee (defined in item type) is applied." >+ - pref: ProcessingFeeNote >+ type: textarea >+ class: code >+ > Self Checkout: > - > - "Include the following JavaScript on all pages in the web-based self checkout:" >diff --git a/t/db_dependent/Circulation/Chargelostitem.t b/t/db_dependent/Circulation/Chargelostitem.t >new file mode 100644 >index 0000000..e9d9694 >--- /dev/null >+++ b/t/db_dependent/Circulation/Chargelostitem.t >@@ -0,0 +1,89 @@ >+#!/usr/bin/perl >+# >+# This Koha test module is a stub! >+# Add more tests here!!! >+ >+use strict; >+use warnings; >+use Modern::Perl; >+ >+use Test::MockModule; >+use C4::Biblio; >+use C4::Items; >+use C4::Members; >+use C4::Branch; >+use C4::Category; >+use C4::Circulation; >+use MARC::Record; >+use Test::More tests => 7; >+ >+BEGIN { >+ use_ok('C4::Accounts'); >+} >+ >+my $dbh = C4::Context->dbh; >+$dbh->{AutoCommit} = 0; >+$dbh->{RaiseError} = 1; >+$dbh->do(q|DELETE FROM accountlines|); >+ >+my $branchcode; >+my $branch_created; >+my @branches = keys %{ GetBranches() }; >+if (@branches) { >+ $branchcode = $branches[0]; >+} else { >+ $branchcode = 'B'; >+ ModBranch({ add => 1, branchcode => $branchcode, branchname => 'Branch' }); >+ $branch_created = 1; >+} >+ >+my %item_branch_infos = ( >+ homebranch => $branchcode, >+ holdingbranch => $branchcode, >+); >+ >+my ($biblionumber1) = AddBiblio(MARC::Record->new, ''); >+my $itemnumber1 = AddItem({ barcode => '0101', %item_branch_infos }, $biblionumber1); >+my $itemnumber2 = AddItem({ barcode => '0102', %item_branch_infos }, $biblionumber1); >+ >+my ($biblionumber2) = AddBiblio(MARC::Record->new, ''); >+my $itemnumber3 = AddItem({ barcode => '0203', %item_branch_infos }, $biblionumber2); >+ >+my $categorycode; >+my $category_created; >+my @categories = C4::Category->all; >+if (@categories) { >+ $categorycode = $categories[0]->{categorycode} >+} else { >+ $categorycode = 'C'; >+ C4::Context->dbh->do( >+ "INSERT INTO categories(categorycode) VALUES(?)", undef, $categorycode); >+ $category_created = 1; >+} >+ >+my $borrowernumber = AddMember(categorycode => $categorycode, branchcode => $branchcode); >+my $borrower = GetMember(borrowernumber => $borrowernumber); >+ >+# Need to mock userenv for AddIssue >+my $module = new Test::MockModule('C4::Context'); >+$module->mock('userenv', sub { { branch => $branchcode } }); >+AddIssue($borrower, '0101'); >+AddIssue($borrower, '0203'); >+ >+# Begin tests... >+my $processfee = 10; >+my $issues; >+$issues = C4::Circulation::GetIssues({biblionumber => $biblionumber1}); >+my $issue=$issues->[0]; >+$issue->{'processfee'} = $processfee; >+my $accountlineId = C4::Accounts::chargelostitem($issue, 'test'); >+ >+my @accountline = C4::Accounts::getcharges($borrowernumber, $accountlineId); >+ >+is( scalar(@accountline), 1, 'accountline should have 1 row' ); >+is( int($accountline[0]->{amount}), $processfee, "The accountline amount should be precessfee value " ); >+is( $accountline[0]->{accounttype}, 'PF', "The accountline accounttype should be PF " ); >+is( $accountline[0]->{borrowernumber}, $borrowernumber, "The accountline borrowernumber should be the exemple borrownumber" ); >+my $itemnumber = C4::Items::GetItemnumberFromBarcode('0101'); >+is( $accountline[0]->{itemnumber}, $itemnumber, "The accountline itemnumber should the linked with barcode '0101'" ); >+is( $accountline[0]->{description}, 'test', "The accountline description should be 'test'" ); >-- >2.1.4
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 12768
:
34333
|
34334
|
36350
|
36505
|
36506
|
36552
|
36553
|
36554
|
36555
|
38365
|
38367
|
38368
|
38375
|
39298
|
39299
|
39300
|
39999
|
40000
|
40001
|
40002
|
42157
|
42158
|
43181
|
43546
|
64775
|
64776
|
66760
|
66761
|
67875
|
67876
|
67877
|
67878
|
67891
|
67892
|
67893
|
67894
|
67895
|
67896
|
67897
|
68035
|
68036
|
68037
|
68038
|
68039
|
68040
|
68041
|
68042
|
68076
|
68264
|
68265
|
68266
|
68267
|
68268
|
68269
|
68270
|
68271
|
68272
|
68273
|
68274
|
68332
|
68415
|
68416
|
68417
|
68426
|
68427