View | Details | Raw Unified | Return to bug 12769
Collapse All | Expand All

(-)a/installer/data/mysql/kohastructure.sql (+1 lines)
Lines 1388-1393 CREATE TABLE `letter` ( -- table for all notice templates in Koha Link Here
1388
  `title` varchar(200) NOT NULL default '', -- subject line of the notice
1388
  `title` varchar(200) NOT NULL default '', -- subject line of the notice
1389
  `content` text, -- body text for the notice or slip
1389
  `content` text, -- body text for the notice or slip
1390
  `message_transport_type` varchar(20) NOT NULL DEFAULT 'email', -- transport type for this notice
1390
  `message_transport_type` varchar(20) NOT NULL DEFAULT 'email', -- transport type for this notice
1391
  `fee` decimal(10,2) DEFAULT NULL, -- set up the cost of sending a notice
1391
  PRIMARY KEY  (`module`,`code`, `branchcode`, `message_transport_type`),
1392
  PRIMARY KEY  (`module`,`code`, `branchcode`, `message_transport_type`),
1392
  CONSTRAINT `message_transport_type_fk` FOREIGN KEY (`message_transport_type`)
1393
  CONSTRAINT `message_transport_type_fk` FOREIGN KEY (`message_transport_type`)
1393
  REFERENCES `message_transport_types` (`message_transport_type`) ON DELETE CASCADE ON UPDATE CASCADE
1394
  REFERENCES `message_transport_types` (`message_transport_type`) ON DELETE CASCADE ON UPDATE CASCADE
(-)a/installer/data/mysql/sysprefs.sql (+2 lines)
Lines 100-105 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
100
('DefaultLongOverdueChargeValue', NULL, NULL, "Charge a lost item to the borrower's account when the LOST value of the item changes to n.", 'integer'),
100
('DefaultLongOverdueChargeValue', NULL, NULL, "Charge a lost item to the borrower's account when the LOST value of the item changes to n.", 'integer'),
101
('DefaultLongOverdueDays', NULL, NULL, "Set the LOST value of an item when the item has been overdue for more than n days.", 'integer'),
101
('DefaultLongOverdueDays', NULL, NULL, "Set the LOST value of an item when the item has been overdue for more than n days.", 'integer'),
102
('DefaultLongOverdueLostValue', NULL, NULL, "Set the LOST value of an item to n when the item has been overdue for more than defaultlongoverduedays days.", 'integer'),
102
('DefaultLongOverdueLostValue', NULL, NULL, "Set the LOST value of an item to n when the item has been overdue for more than defaultlongoverduedays days.", 'integer'),
103
('defaultnoticefee','0',NULL,' set up how much cost the sending of a notice',NULL),
103
('defaultSortField','relevance','relevance|popularity|call_number|pubdate|acqdate|title|author','Specify the default field used for sorting','Choice'),
104
('defaultSortField','relevance','relevance|popularity|call_number|pubdate|acqdate|title|author','Specify the default field used for sorting','Choice'),
104
('defaultSortOrder','dsc','asc|dsc|az|za','Specify the default sort order','Choice'),
105
('defaultSortOrder','dsc','asc|dsc|az|za','Specify the default sort order','Choice'),
105
('delimiter',';',';|tabulation|,|/|\\|#||','Define the default separator character for exporting reports','Choice'),
106
('delimiter',';',';|tabulation|,|/|\\|#||','Define the default separator character for exporting reports','Choice'),
Lines 216-221 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
216
('NotesBlacklist','',NULL,'List of notes fields that should not appear in the title notes/description separator of details','free'),
217
('NotesBlacklist','',NULL,'List of notes fields that should not appear in the title notes/description separator of details','free'),
217
('NotHighlightedWords','and|or|not',NULL,'List of words to NOT highlight when OpacHitHighlight is enabled','free'),
218
('NotHighlightedWords','and|or|not',NULL,'List of words to NOT highlight when OpacHitHighlight is enabled','free'),
218
('NoticeCSS','',NULL,'Notices CSS url.','free'),
219
('NoticeCSS','',NULL,'Notices CSS url.','free'),
220
('noticefeenote', '', NULL, 'Set up the notice fee note in the "accountlines" table', NULL),
219
('NotifyBorrowerDeparture','30',NULL,'Define number of days before expiry where circulation is warned about patron account expiry','Integer'),
221
('NotifyBorrowerDeparture','30',NULL,'Define number of days before expiry where circulation is warned about patron account expiry','Integer'),
220
('NovelistSelectEnabled','0',NULL,'Enable Novelist Select content.  Requires Novelist Profile and Password','YesNo'),
222
('NovelistSelectEnabled','0',NULL,'Enable Novelist Select content.  Requires Novelist Profile and Password','YesNo'),
221
('NovelistSelectPassword',NULL,NULL,'Enable Novelist user Profile','free'),
223
('NovelistSelectPassword',NULL,NULL,'Enable Novelist user Profile','free'),
(-)a/installer/data/mysql/updatedatabase.pl (+10 lines)
Lines 9793-9798 if(CheckVersion($DBversion)) { Link Here
9793
    SetVersion($DBversion);
9793
    SetVersion($DBversion);
9794
}
9794
}
9795
9795
9796
$DBversion = "XXX";
9797
if ( CheckVersion($DBversion) ) {
9798
    $dbh->do("ALTER TABLE  `letter` add  `fee` decimal(10,2) DEFAULT NULL");
9799
    $dbh->do("INSERT INTO `systempreferences` (variable,value,options,explanation,type)
9800
       VALUES ('defaultnoticefee','0',NULL,' set up how much cost the sending of a notice',NULL),
9801
       ('noticefeenote', '', NULL, 'Set up the notice fee note in the accountlines table', NULL)");
9802
    print "Upgrade to $DBversion done (Bug 12769 - Notice fee management)\n";
9803
    SetVersion ($DBversion);
9804
}
9805
9796
=head1 FUNCTIONS
9806
=head1 FUNCTIONS
9797
9807
9798
=head2 TableExists($table)
9808
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (+8 lines)
Lines 632-637 Circulation: Link Here
632
                  yes: Charge
632
                  yes: Charge
633
                  no: "Don't Charge"
633
                  no: "Don't Charge"
634
            - the replacement price when a patron loses an item.
634
            - the replacement price when a patron loses an item.
635
        -
636
            - Set up how much cost the sending of a notice to
637
            - pref: DefaultNoticeFee
638
              class: integer
639
        -
640
            - Set up the notice fee note in the "accountlines" table to
641
            - pref: NoticeFeeNote
642
635
    Self Checkout:
643
    Self Checkout:
636
        -
644
        -
637
            - "Include the following JavaScript on all pages in the web-based self checkout:"
645
            - "Include the following JavaScript on all pages in the web-based self checkout:"
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt (+6 lines)
Lines 331-336 $(document).ready(function() { Link Here
331
                                    [% END %]
331
                                    [% END %]
332
                </select>
332
                </select>
333
            </li>
333
            </li>
334
            [% IF (module == "circulation") %]
335
            <li>
336
              <label for="code" >Notice fee:</label>
337
              <input type="text" id="fee" name="fee" size="7" maxlength="7" value="[% IF ( modify ) %][% fee %][% END %]"/>
338
            </li>
339
            [% END %]
334
            <li>
340
            <li>
335
              [% IF adding %]
341
              [% IF adding %]
336
                  <label for="code" class="required">Code:</label>
342
                  <label for="code" class="required">Code:</label>
(-)a/misc/cronjobs/advance_notices.pl (-10 / +47 lines)
Lines 240-247 UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) { Link Here
240
        
240
        
241
        if ( $borrower_preferences->{'wants_digest'} ) {
241
        if ( $borrower_preferences->{'wants_digest'} ) {
242
            # cache this one to process after we've run through all of the items.
242
            # cache this one to process after we've run through all of the items.
243
            $due_digest->{ $upcoming->{borrowernumber} }->{email} = $from_address;
243
            my $digest = $due_digest->{$upcoming->{'borrowernumber'}} ||= {};
244
            $due_digest->{ $upcoming->{borrowernumber} }->{count}++;
244
            $digest->{email} ||= $from_address;
245
            $digest->{count}++;
246
            $digest->{itemnumber} = $upcoming->{'itemnumber'};
245
        } else {
247
        } else {
246
            my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} );
248
            my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} );
247
            my $letter_type = 'DUE';
249
            my $letter_type = 'DUE';
Lines 263-269 UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) { Link Here
263
                                      message_transport_type => $transport,
265
                                      message_transport_type => $transport,
264
                                    } )
266
                                    } )
265
                    or warn "no letter of type '$letter_type' found. Please see sample_notices.sql";
267
                    or warn "no letter of type '$letter_type' found. Please see sample_notices.sql";
266
                push @letters, $letter if $letter;
268
                push @letters, $letter;
269
                if ($letter){
270
                    noticefine($upcoming->{'borrowernumber'}, $upcoming->{'itemnumber'}, $letter_type, $upcoming->{'branchcode'}, $transport, $letter );
271
                }
267
            }
272
            }
268
        }
273
        }
269
    } else {
274
    } else {
Lines 274-281 UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) { Link Here
274
279
275
        if ( $borrower_preferences->{'wants_digest'} ) {
280
        if ( $borrower_preferences->{'wants_digest'} ) {
276
            # cache this one to process after we've run through all of the items.
281
            # cache this one to process after we've run through all of the items.
277
            $upcoming_digest->{ $upcoming->{borrowernumber} }->{email} = $from_address;
282
            my $digest = $upcoming_digest->{$upcoming->{'borrowernumber'}} ||= {};
278
            $upcoming_digest->{ $upcoming->{borrowernumber} }->{count}++;
283
            $digest->{email} ||= $from_address;
284
            $digest->{count}++;
285
            $digest->{itemnumber} = $upcoming->{'itemnumber'};
279
        } else {
286
        } else {
280
            my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} );
287
            my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} );
281
            my $letter_type = 'PREDUE';
288
            my $letter_type = 'PREDUE';
Lines 297-303 UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) { Link Here
297
                                      message_transport_type => $transport,
304
                                      message_transport_type => $transport,
298
                                    } )
305
                                    } )
299
                    or warn "no letter of type '$letter_type' found. Please see sample_notices.sql";
306
                    or warn "no letter of type '$letter_type' found. Please see sample_notices.sql";
300
                push @letters, $letter if $letter;
307
                push @letters, $letter;
308
                if ($letter){
309
                    noticefine($upcoming->{'borrowernumber'}, $upcoming->{'itemnumber'}, $letter_type, $upcoming->{'branchcode'}, $transport, $letter );
310
                }
301
            }
311
            }
302
        }
312
        }
303
    }
313
    }
Lines 337-342 PATRON: while ( my ( $borrowernumber, $digest ) = each %$upcoming_digest ) { Link Here
337
    @letters = ();
347
    @letters = ();
338
    my $count = $digest->{count};
348
    my $count = $digest->{count};
339
    my $from_address = $digest->{email};
349
    my $from_address = $digest->{email};
350
    my $itemnumber = $digest->{itemnumber};
340
351
341
    my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber,
352
    my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber,
342
                                                                                  message_name   => 'advance_notice' } );
353
                                                                                  message_name   => 'advance_notice' } );
Lines 369-376 PATRON: while ( my ( $borrowernumber, $digest ) = each %$upcoming_digest ) { Link Here
369
                message_transport_type => $transport,
380
                message_transport_type => $transport,
370
            }
381
            }
371
          )
382
          )
372
          or warn "no letter of type '$letter_type' found. Please see sample_notices.sql";
383
          or die "no letter of type '$letter_type' found. Please see sample_notices.sql";
373
        push @letters, $letter if $letter;
384
        push @letters, $letter;
385
        if ($letter){
386
            noticefine($borrowernumber, $itemnumber, $letter_type, $branch_info{"branches.branchcode"}, $transport, $letter );
387
        }
374
    }
388
    }
375
389
376
    if ( @letters ) {
390
    if ( @letters ) {
Lines 396-401 PATRON: while ( my ( $borrowernumber, $digest ) = each %$due_digest ) { Link Here
396
    @letters = ();
410
    @letters = ();
397
    my $count = $digest->{count};
411
    my $count = $digest->{count};
398
    my $from_address = $digest->{email};
412
    my $from_address = $digest->{email};
413
    my $itemnumber = $digest->{itemnumber};
399
414
400
    my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber,
415
    my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber,
401
                                                                                  message_name   => 'item_due' } );
416
                                                                                  message_name   => 'item_due' } );
Lines 426-433 PATRON: while ( my ( $borrowernumber, $digest ) = each %$due_digest ) { Link Here
426
                message_transport_type => $transport,
441
                message_transport_type => $transport,
427
            }
442
            }
428
          )
443
          )
429
          or warn "no letter of type '$letter_type' found. Please see sample_notices.sql";
444
          or die "no letter of type '$letter_type' found. Please see sample_notices.sql";
430
        push @letters, $letter if $letter;
445
        push @letters, $letter;
446
        if ($letter){
447
            noticefine($borrowernumber, $itemnumber, $letter_type, $branch_info{"branches.branchcode"}, $transport, $letter );
448
        }
431
    }
449
    }
432
450
433
    if ( @letters ) {
451
    if ( @letters ) {
Lines 491-496 sub format_date { Link Here
491
    return output_pref($dt);
509
    return output_pref($dt);
492
}
510
}
493
511
512
sub noticefine {
513
    my ($borrowernumber, $itemnumber, $code, $branchcode, $message_transport_type, $letter ) = @_;
514
515
    my $letterFee = C4::Letters::getletter( 'circulation', $code, $branchcode, $message_transport_type);
516
517
    if ($letterFee) {
518
        my $sendfee;
519
        if ($letter->{'fee'}){
520
            $sendfee = $letter->{'fee'};
521
        } else {
522
            $sendfee = C4::Context->preference('DefaultNoticeFee');
523
        }
524
525
        if ($sendfee > 0){
526
            C4::Accounts::manualinvoice($borrowernumber, "", "", "F", $sendfee, C4::Context->preference('NoticeFeeNote'));
527
        }
528
    }
529
}
530
494
=head2 get_branch_info
531
=head2 get_branch_info
495
532
496
=cut
533
=cut
(-)a/misc/cronjobs/overdue_notices.pl (-2 / +13 lines)
Lines 486-492 END_SQL Link Here
486
            # <date> <itemcount> <firstname> <lastname> <address1> <address2> <address3> <city> <postcode> <country>
486
            # <date> <itemcount> <firstname> <lastname> <address1> <address2> <address3> <city> <postcode> <country>
487
487
488
            my $borrower_sql = <<'END_SQL';
488
            my $borrower_sql = <<'END_SQL';
489
SELECT issues.borrowernumber, firstname, surname, address, address2, city, zipcode, country, email, emailpro, B_email, smsalertnumber, phone, cardnumber,
489
SELECT issues.borrowernumber, issues.itemnumber, firstname, surname, address, address2, city, zipcode, country, email, emailpro, B_email, smsalertnumber, phone, cardnumber,
490
TO_DAYS(?)-TO_DAYS(date_due) as difference, date_due
490
TO_DAYS(?)-TO_DAYS(date_due) as difference, date_due
491
FROM   issues,borrowers,categories
491
FROM   issues,borrowers,categories
492
WHERE  issues.borrowernumber=borrowers.borrowernumber
492
WHERE  issues.borrowernumber=borrowers.borrowernumber
Lines 570-575 END_SQL Link Here
570
570
571
                my $letter = C4::Letters::getletter( 'circulation', $overdue_rules->{"letter$i"}, $branchcode );
571
                my $letter = C4::Letters::getletter( 'circulation', $overdue_rules->{"letter$i"}, $branchcode );
572
572
573
573
                unless ($letter) {
574
                unless ($letter) {
574
                    $verbose and warn "Message '$overdue_rules->{letter$i}' content not found";
575
                    $verbose and warn "Message '$overdue_rules->{letter$i}' content not found";
575
576
Lines 577-583 END_SQL Link Here
577
                    # FIXME : Does this mean a letter must be defined in order to trigger a debar ?
578
                    # FIXME : Does this mean a letter must be defined in order to trigger a debar ?
578
                    next PERIOD;
579
                    next PERIOD;
579
                }
580
                }
580
    
581
                my $sendfee;
582
                if ($letter->{'fee'}){
583
                    $sendfee = $letter->{'fee'};
584
                } else {
585
                    $sendfee = C4::Context->preference('DefaultNoticeFee');
586
                }
587
588
                if ($sendfee > 0){
589
                    C4::Accounts::manualinvoice($borrowernumber, "", "", "F", $sendfee, C4::Context->preference('NoticeFeeNote'));
590
                }
591
581
                if ( $overdue_rules->{"debarred$i"} ) {
592
                if ( $overdue_rules->{"debarred$i"} ) {
582
    
593
    
583
                    #action taken is debarring
594
                    #action taken is debarring
(-)a/tools/letter.pl (-20 / +34 lines)
Lines 159-168 sub add_form { Link Here
159
        # So we can only sent the first one to the template.
159
        # So we can only sent the first one to the template.
160
        for my $mtt ( @$message_transport_types ) {
160
        for my $mtt ( @$message_transport_types ) {
161
            # The letter_name
161
            # The letter_name
162
            if ( $first_flag and $letters->{$mtt}{name} ) {
162
            if ( $first_flag) {
163
                $template->param(
163
                if ($letters->{$mtt}{name}) {
164
                    letter_name=> $letters->{$mtt}{name},
164
                    $template->param(
165
                );
165
                        letter_name=> $letters->{$mtt}{name},
166
                    );
167
                }
168
                if ($letters->{$mtt}{fee}) {
169
                    $template->param(
170
                        fee => $letters->{$mtt}{fee},
171
                    );
172
                }
166
                $first_flag = 0;
173
                $first_flag = 0;
167
            }
174
            }
168
175
Lines 246-254 sub add_validate { Link Here
246
    my $oldmodule     = $input->param('oldmodule');
253
    my $oldmodule     = $input->param('oldmodule');
247
    my $code          = $input->param('code');
254
    my $code          = $input->param('code');
248
    my $name          = $input->param('name');
255
    my $name          = $input->param('name');
256
    my $fee           = $input->param('fee');
249
    my @mtt           = $input->param('message_transport_type');
257
    my @mtt           = $input->param('message_transport_type');
250
    my @title         = $input->param('title');
258
    my @title         = $input->param('title');
251
    my @content       = $input->param('content');
259
    my @content       = $input->param('content');
260
261
    my $insertfee = $fee;
262
    if (defined($fee) and $fee eq ''){
263
        $insertfee = undef;
264
    }
265
252
    for my $mtt ( @mtt ) {
266
    for my $mtt ( @mtt ) {
253
        my $is_html = $input->param("is_html_$mtt");
267
        my $is_html = $input->param("is_html_$mtt");
254
        my $title   = shift @title;
268
        my $title   = shift @title;
Lines 266-287 sub add_validate { Link Here
266
            next;
280
            next;
267
        }
281
        }
268
        elsif ( $letter and $letter->{message_transport_type} eq $mtt ) {
282
        elsif ( $letter and $letter->{message_transport_type} eq $mtt ) {
269
            $dbh->do(
283
            if (defined($fee)){
270
                q{
284
                $dbh->do(q{UPDATE letter SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ?, fee = ?
271
                    UPDATE letter
285
                    WHERE branchcode = ? AND module = ? AND code = ? AND message_transport_type = ?}, undef,
272
                    SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ?
286
                    $branchcode, $module, $name, $is_html || 0, $title, $content, $insertfee, $branchcode, $oldmodule, $code, $mtt);
273
                    WHERE branchcode = ? AND module = ? AND code = ? AND message_transport_type = ?
287
            } else {
274
                },
288
                $dbh->do(q{UPDATE letter SET branchcode = ?, module = ?, name = ?, is_html = ?, title = ?, content = ?
275
                undef,
289
                    WHERE branchcode = ? AND module = ? AND code = ? AND message_transport_type = ?}, undef,
276
                $branchcode, $module, $name, $is_html || 0, $title, $content,
290
                    $branchcode, $module, $name, $is_html || 0, $title, $content, $branchcode, $oldmodule, $code, $mtt);
277
                $branchcode, $oldmodule, $code, $mtt
291
            }
278
            );
279
        } else {
292
        } else {
280
            $dbh->do(
293
            if (defined($fee) and $fee != ''){
281
                q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content,message_transport_type) VALUES (?,?,?,?,?,?,?,?)},
294
                $dbh->do(q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content,message_transport_type, fee) VALUES (?,?,?,?,?,?,?,?,?)},undef,
282
                undef,
295
                    $branchcode, $module, $code, $name, $is_html || 0, $title, $content, $mtt, $fee);
283
                $branchcode, $module, $code, $name, $is_html || 0, $title, $content, $mtt
296
            } else {
284
            );
297
                $dbh->do(q{INSERT INTO letter (branchcode,module,code,name,is_html,title,content,message_transport_type) VALUES (?,?,?,?,?,?,?,?)},undef,
298
                    $branchcode, $module, $code, $name, $is_html || 0, $title, $content, $mtt);
299
            }
285
        }
300
        }
286
    }
301
    }
287
    # set up default display
302
    # set up default display
288
- 

Return to bug 12769