@@ -, +, @@ --- installer/data/mysql/kohastructure.sql | 1 + installer/data/mysql/sysprefs.sql | 2 + installer/data/mysql/updatedatabase.pl | 10 ++++ .../en/modules/admin/preferences/circulation.pref | 8 +++ .../intranet-tmpl/prog/en/modules/tools/letter.tt | 6 +++ misc/cronjobs/advance_notices.pl | 57 ++++++++++++++++++---- misc/cronjobs/overdue_notices.pl | 15 +++++- tools/letter.pl | 53 ++++++++++++-------- 8 files changed, 121 insertions(+), 31 deletions(-) --- a/installer/data/mysql/kohastructure.sql +++ a/installer/data/mysql/kohastructure.sql @@ -1388,6 +1388,7 @@ CREATE TABLE `letter` ( -- table for all notice templates in Koha `title` varchar(200) NOT NULL default '', -- subject line of the notice `content` text, -- body text for the notice or slip `message_transport_type` varchar(20) NOT NULL DEFAULT 'email', -- transport type for this notice + `fee` decimal(10,2) DEFAULT NULL, -- set up the cost of sending a notice PRIMARY KEY (`module`,`code`, `branchcode`, `message_transport_type`), CONSTRAINT `message_transport_type_fk` FOREIGN KEY (`message_transport_type`) REFERENCES `message_transport_types` (`message_transport_type`) ON DELETE CASCADE ON UPDATE CASCADE --- a/installer/data/mysql/sysprefs.sql +++ a/installer/data/mysql/sysprefs.sql @@ -100,6 +100,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('DefaultLongOverdueChargeValue', NULL, NULL, "Charge a lost item to the borrower's account when the LOST value of the item changes to n.", 'integer'), ('DefaultLongOverdueDays', NULL, NULL, "Set the LOST value of an item when the item has been overdue for more than n days.", 'integer'), ('DefaultLongOverdueLostValue', NULL, NULL, "Set the LOST value of an item to n when the item has been overdue for more than defaultlongoverduedays days.", 'integer'), +('defaultnoticefee','0',NULL,' set up how much cost the sending of a notice',NULL), ('defaultSortField','relevance','relevance|popularity|call_number|pubdate|acqdate|title|author','Specify the default field used for sorting','Choice'), ('defaultSortOrder','dsc','asc|dsc|az|za','Specify the default sort order','Choice'), ('delimiter',';',';|tabulation|,|/|\\|#||','Define the default separator character for exporting reports','Choice'), @@ -216,6 +217,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('NotesBlacklist','',NULL,'List of notes fields that should not appear in the title notes/description separator of details','free'), ('NotHighlightedWords','and|or|not',NULL,'List of words to NOT highlight when OpacHitHighlight is enabled','free'), ('NoticeCSS','',NULL,'Notices CSS url.','free'), +('noticefeenote', '', NULL, 'Set up the notice fee note in the "accountlines" table', NULL), ('NotifyBorrowerDeparture','30',NULL,'Define number of days before expiry where circulation is warned about patron account expiry','Integer'), ('NovelistSelectEnabled','0',NULL,'Enable Novelist Select content. Requires Novelist Profile and Password','YesNo'), ('NovelistSelectPassword',NULL,NULL,'Enable Novelist user Profile','free'), --- a/installer/data/mysql/updatedatabase.pl +++ a/installer/data/mysql/updatedatabase.pl @@ -9779,6 +9779,16 @@ if ( CheckVersion($DBversion) ) { SetVersion ($DBversion); } +$DBversion = "XXX"; +if ( CheckVersion($DBversion) ) { + $dbh->do("ALTER TABLE `letter` add `fee` decimal(10,2) DEFAULT NULL"); + $dbh->do("INSERT INTO `systempreferences` (variable,value,options,explanation,type) + VALUES ('defaultnoticefee','0',NULL,' set up how much cost the sending of a notice',NULL), + ('noticefeenote', '', NULL, 'Set up the notice fee note in the accountlines table', NULL)"); + print "Upgrade to $DBversion done (Bug 12769 - Notice fee management)\n"; + SetVersion ($DBversion); +} + =head1 FUNCTIONS =head2 TableExists($table) --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -632,6 +632,14 @@ Circulation: yes: Charge no: "Don't Charge" - the replacement price when a patron loses an item. + - + - Set up how much cost the sending of a notice to + - pref: DefaultNoticeFee + class: integer + - + - Set up the notice fee note in the "accountlines" table to + - pref: NoticeFeeNote + Self Checkout: - - "Include the following JavaScript on all pages in the web-based self checkout:" --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt @@ -331,6 +331,12 @@ $(document).ready(function() { [% END %] + [% IF (module == "circulation") %] +
  • + + +
  • + [% END %]
  • [% IF adding %] --- a/misc/cronjobs/advance_notices.pl +++ a/misc/cronjobs/advance_notices.pl @@ -240,8 +240,10 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) { if ( $borrower_preferences->{'wants_digest'} ) { # cache this one to process after we've run through all of the items. - $due_digest->{ $upcoming->{borrowernumber} }->{email} = $from_address; - $due_digest->{ $upcoming->{borrowernumber} }->{count}++; + my $digest = $due_digest->{$upcoming->{'borrowernumber'}} ||= {}; + $digest->{email} ||= $from_address; + $digest->{count}++; + $digest->{itemnumber} = $upcoming->{'itemnumber'}; } else { my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} ); my $letter_type = 'DUE'; @@ -263,7 +265,10 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) { message_transport_type => $transport, } ) or warn "no letter of type '$letter_type' found. Please see sample_notices.sql"; - push @letters, $letter if $letter; + push @letters, $letter; + if ($letter){ + noticefine($upcoming->{'borrowernumber'}, $upcoming->{'itemnumber'}, $letter_type, $upcoming->{'branchcode'}, $transport, $letter ); + } } } } else { @@ -274,8 +279,10 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) { if ( $borrower_preferences->{'wants_digest'} ) { # cache this one to process after we've run through all of the items. - $upcoming_digest->{ $upcoming->{borrowernumber} }->{email} = $from_address; - $upcoming_digest->{ $upcoming->{borrowernumber} }->{count}++; + my $digest = $upcoming_digest->{$upcoming->{'borrowernumber'}} ||= {}; + $digest->{email} ||= $from_address; + $digest->{count}++; + $digest->{itemnumber} = $upcoming->{'itemnumber'}; } else { my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} ); my $letter_type = 'PREDUE'; @@ -297,7 +304,10 @@ UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) { message_transport_type => $transport, } ) or warn "no letter of type '$letter_type' found. Please see sample_notices.sql"; - push @letters, $letter if $letter; + push @letters, $letter; + if ($letter){ + noticefine($upcoming->{'borrowernumber'}, $upcoming->{'itemnumber'}, $letter_type, $upcoming->{'branchcode'}, $transport, $letter ); + } } } } @@ -337,6 +347,7 @@ PATRON: while ( my ( $borrowernumber, $digest ) = each %$upcoming_digest ) { @letters = (); my $count = $digest->{count}; my $from_address = $digest->{email}; + my $itemnumber = $digest->{itemnumber}; my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber, message_name => 'advance_notice' } ); @@ -369,8 +380,11 @@ PATRON: while ( my ( $borrowernumber, $digest ) = each %$upcoming_digest ) { message_transport_type => $transport, } ) - or warn "no letter of type '$letter_type' found. Please see sample_notices.sql"; - push @letters, $letter if $letter; + or die "no letter of type '$letter_type' found. Please see sample_notices.sql"; + push @letters, $letter; + if ($letter){ + noticefine($borrowernumber, $itemnumber, $letter_type, $branch_info{"branches.branchcode"}, $transport, $letter ); + } } if ( @letters ) { @@ -396,6 +410,7 @@ PATRON: while ( my ( $borrowernumber, $digest ) = each %$due_digest ) { @letters = (); my $count = $digest->{count}; my $from_address = $digest->{email}; + my $itemnumber = $digest->{itemnumber}; my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber, message_name => 'item_due' } ); @@ -426,8 +441,11 @@ PATRON: while ( my ( $borrowernumber, $digest ) = each %$due_digest ) { message_transport_type => $transport, } ) - or warn "no letter of type '$letter_type' found. Please see sample_notices.sql"; - push @letters, $letter if $letter; + or die "no letter of type '$letter_type' found. Please see sample_notices.sql"; + push @letters, $letter; + if ($letter){ + noticefine($borrowernumber, $itemnumber, $letter_type, $branch_info{"branches.branchcode"}, $transport, $letter ); + } } if ( @letters ) { @@ -491,6 +509,25 @@ sub format_date { return output_pref($dt); } +sub noticefine { + my ($borrowernumber, $itemnumber, $code, $branchcode, $message_transport_type, $letter ) = @_; + + my $letterFee = C4::Letters::getletter( 'circulation', $code, $branchcode, $message_transport_type); + + if ($letterFee) { + my $sendfee; + if ($letter->{'fee'}){ + $sendfee = $letter->{'fee'}; + } else { + $sendfee = C4::Context->preference('DefaultNoticeFee'); + } + + if ($sendfee > 0){ + C4::Accounts::manualinvoice($borrowernumber, "", "", "F", $sendfee, C4::Context->preference('NoticeFeeNote')); + } + } +} + =head2 get_branch_info =cut --- a/misc/cronjobs/overdue_notices.pl +++ a/misc/cronjobs/overdue_notices.pl @@ -486,7 +486,7 @@ END_SQL # my $borrower_sql = <<'END_SQL'; -SELECT issues.borrowernumber, firstname, surname, address, address2, city, zipcode, country, email, emailpro, B_email, smsalertnumber, phone, cardnumber, +SELECT issues.borrowernumber, issues.itemnumber, firstname, surname, address, address2, city, zipcode, country, email, emailpro, B_email, smsalertnumber, phone, cardnumber, TO_DAYS(?)-TO_DAYS(date_due) as difference, date_due FROM issues,borrowers,categories WHERE issues.borrowernumber=borrowers.borrowernumber @@ -570,6 +570,7 @@ END_SQL my $letter = C4::Letters::getletter( 'circulation', $overdue_rules->{"letter$i"}, $branchcode ); + unless ($letter) { $verbose and warn "Message '$overdue_rules->{letter$i}' content not found"; @@ -577,7 +578,17 @@ END_SQL # FIXME : Does this mean a letter must be defined in order to trigger a debar ? next PERIOD; } - + my $sendfee; + if ($letter->{'fee'}){ + $sendfee = $letter->{'fee'}; + } else { + $sendfee = C4::Context->preference('DefaultNoticeFee'); + } + + if ($sendfee > 0){ + C4::Accounts::manualinvoice($borrowernumber, "", "", "F", $sendfee, C4::Context->preference('NoticeFeeNote')); + } + if ( $overdue_rules->{"debarred$i"} ) { #action taken is debarring --- a/tools/letter.pl +++ a/tools/letter.pl @@ -159,10 +159,17 @@ sub add_form { # So we can only sent the first one to the template. for my $mtt ( @$message_transport_types ) { # The letter_name - if ( $first_flag and $letters->{$mtt}{name} ) { - $template->param( - letter_name=> $letters->{$mtt}{name}, - ); + if ( $first_flag) { + if ($letters->{$mtt}{name}) { + $template->param( + letter_name=> $letters->{$mtt}{name}, + ); + } + if ($letters->{$mtt}{fee}) { + $template->param( + fee => $letters->{$mtt}{fee}, + ); + } $first_flag = 0; } @@ -246,9 +253,16 @@ sub add_validate { my $oldmodule = $input->param('oldmodule'); my $code = $input->param('code'); my $name = $input->param('name'); + my $fee = $input->param('fee'); my @mtt = $input->param('message_transport_type'); my @title = $input->param('title'); my @content = $input->param('content'); + + my $insertfee = $fee; + if (defined($fee) and $fee eq ''){ + $insertfee = undef; + } + for my $mtt ( @mtt ) { my $is_html = $input->param("is_html_$mtt"); my $title = shift @title; @@ -266,22 +280,23 @@ sub add_validate { next; } elsif ( $letter and $letter->{message_transport_type} eq $mtt ) { - $dbh->do( - q{ - UPDATE letter - SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ? - WHERE branchcode = ? AND module = ? AND code = ? AND message_transport_type = ? - }, - undef, - $branchcode, $module, $name, $is_html || 0, $title, $content, - $branchcode, $oldmodule, $code, $mtt - ); + if (defined($fee)){ + $dbh->do(q{UPDATE letter SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ?, fee = ? + WHERE branchcode = ? AND module = ? AND code = ? AND message_transport_type = ?}, undef, + $branchcode, $module, $name, $is_html || 0, $title, $content, $insertfee, $branchcode, $oldmodule, $code, $mtt); + } else { + $dbh->do(q{UPDATE letter SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ? + WHERE branchcode = ? AND module = ? AND code = ? AND message_transport_type = ?}, undef, + $branchcode, $module, $name, $is_html || 0, $title, $content, $branchcode, $oldmodule, $code, $mtt); + } } else { - $dbh->do( - q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content,message_transport_type) VALUES (?,?,?,?,?,?,?,?)}, - undef, - $branchcode, $module, $code, $name, $is_html || 0, $title, $content, $mtt - ); + if (defined($fee) and $fee != ''){ + $dbh->do(q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content,message_transport_type, fee) VALUES (?,?,?,?,?,?,?,?,?)},undef, + $branchcode, $module, $code, $name, $is_html || 0, $title, $content, $mtt, $fee); + } else { + $dbh->do(q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content,message_transport_type) VALUES (?,?,?,?,?,?,?,?)},undef, + $branchcode, $module, $code, $name, $is_html || 0, $title, $content, $mtt); + } } } # set up default display --