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

(-)a/C4/Letters.pm (-2 / +3 lines)
Lines 496-502 sub SendAlerts { Link Here
496
                    ? C4::Context->preference('SerialsDefaultEmailAddress')
496
                    ? C4::Context->preference('SerialsDefaultEmailAddress')
497
                    : C4::Context->preference('AcquisitionsDefaultEmailAddress')
497
                    : C4::Context->preference('AcquisitionsDefaultEmailAddress')
498
                    )
498
                    )
499
                    || $library->branchemail
499
                    || ( $library ? $library->branchemail : undef )
500
                    || C4::Context->preference('KohaAdminEmailAddress'),
500
                    || C4::Context->preference('KohaAdminEmailAddress'),
501
                (
501
                (
502
                    $type eq 'claimissues' && C4::Context->preference('SerialsDefaultReplyTo')
502
                    $type eq 'claimissues' && C4::Context->preference('SerialsDefaultReplyTo')
Lines 520-526 sub SendAlerts { Link Here
520
        }
520
        }
521
521
522
        my $success = try {
522
        my $success = try {
523
            $mail->send_or_die( { transport => $library->smtp_server->transport } );
523
            my $smtp_server = $library ? $library->smtp_server : Koha::SMTP::Servers->get_default;
524
            $mail->send_or_die( { transport => $smtp_server->transport } );
524
        } catch {
525
        } catch {
525
526
526
            # We expect ref($_) eq 'Email::Sender::Failure'
527
            # We expect ref($_) eq 'Email::Sender::Failure'
(-)a/C4/Serials.pm (-10 / +13 lines)
Lines 1347-1353 sub ModSubscription { Link Here
1347
        $biblionumber,  $callnumber,       $notes,             $letter,        $manualhistory,
1347
        $biblionumber,  $callnumber,       $notes,             $letter,        $manualhistory,
1348
        $internalnotes, $serialsadditems,  $staffdisplaycount, $opacdisplaycount,
1348
        $internalnotes, $serialsadditems,  $staffdisplaycount, $opacdisplaycount,
1349
        $graceperiod,   $location,         $enddate,           $subscriptionid, $skip_serialseq,
1349
        $graceperiod,   $location,         $enddate,           $subscriptionid, $skip_serialseq,
1350
        $itemtype,      $previousitemtype, $mana_id,           $ccode,          $published_on_template
1350
        $itemtype,      $previousitemtype, $mana_id,           $ccode,          $published_on_template,
1351
        $auto_claim_enabled
1351
    ) = @_;
1352
    ) = @_;
1352
1353
1353
    my $subscription = Koha::Subscriptions->find($subscriptionid);
1354
    my $subscription = Koha::Subscriptions->find($subscriptionid);
Lines 1392-1397 sub ModSubscription { Link Here
1392
            mana_id               => $mana_id,
1393
            mana_id               => $mana_id,
1393
            ccode                 => $ccode,
1394
            ccode                 => $ccode,
1394
            published_on_template => $published_on_template,
1395
            published_on_template => $published_on_template,
1396
            auto_claim_enabled    => $auto_claim_enabled // 0,
1395
        }
1397
        }
1396
    )->store;
1398
    )->store;
1397
1399
Lines 1424-1437 the id of this new subscription Link Here
1424
1426
1425
sub NewSubscription {
1427
sub NewSubscription {
1426
    my (
1428
    my (
1427
        $auser,           $branchcode,        $aqbooksellerid,   $cost,          $aqbudgetid, $biblionumber,
1429
        $auser,                 $branchcode,        $aqbooksellerid,   $cost,          $aqbudgetid, $biblionumber,
1428
        $startdate,       $periodicity,       $numberlength,     $weeklength,    $monthlength,
1430
        $startdate,             $periodicity,       $numberlength,     $weeklength,    $monthlength,
1429
        $lastvalue1,      $innerloop1,        $lastvalue2,       $innerloop2,    $lastvalue3,
1431
        $lastvalue1,            $innerloop1,        $lastvalue2,       $innerloop2,    $lastvalue3,
1430
        $innerloop3,      $status,            $notes,            $letter,        $firstacquidate, $irregularity,
1432
        $innerloop3,            $status,            $notes,            $letter,        $firstacquidate, $irregularity,
1431
        $numberpattern,   $locale,            $callnumber,       $manualhistory, $internalnotes,
1433
        $numberpattern,         $locale,            $callnumber,       $manualhistory, $internalnotes,
1432
        $serialsadditems, $staffdisplaycount, $opacdisplaycount, $graceperiod,
1434
        $serialsadditems,       $staffdisplaycount, $opacdisplaycount, $graceperiod,
1433
        $location,        $enddate,           $skip_serialseq,   $itemtype, $previousitemtype, $mana_id, $ccode,
1435
        $location,              $enddate,           $skip_serialseq,   $itemtype, $previousitemtype, $mana_id, $ccode,
1434
        $published_on_template,
1436
        $published_on_template, $auto_claim_enabled
1435
    ) = @_;
1437
    ) = @_;
1436
    my $dbh = C4::Context->dbh;
1438
    my $dbh = C4::Context->dbh;
1437
1439
Lines 1476-1481 sub NewSubscription { Link Here
1476
            mana_id               => $mana_id,
1478
            mana_id               => $mana_id,
1477
            ccode                 => $ccode,
1479
            ccode                 => $ccode,
1478
            published_on_template => $published_on_template,
1480
            published_on_template => $published_on_template,
1481
            auto_claim_enabled    => $auto_claim_enabled // 0,
1479
        }
1482
        }
1480
    )->store;
1483
    )->store;
1481
    $subscription->discard_changes;
1484
    $subscription->discard_changes;
Lines 1935-1941 sub GetLateOrMissingIssues { Link Here
1935
    if ($supplierid) {
1938
    if ($supplierid) {
1936
        $sth = $dbh->prepare(
1939
        $sth = $dbh->prepare(
1937
            "SELECT
1940
            "SELECT
1938
                serialid,      aqbooksellerid,        name,
1941
                serialid,      serial.aqbooksellerid,        name,
1939
                biblio.title,  biblioitems.issn,      planneddate,    serialseq,
1942
                biblio.title,  biblioitems.issn,      planneddate,    serialseq,
1940
                serial.status, serial.subscriptionid, claimdate, serial.notes AS notes, claims_count,
1943
                serial.status, serial.subscriptionid, claimdate, serial.notes AS notes, claims_count,
1941
                subscription.branchcode, serial.publisheddate
1944
                subscription.branchcode, serial.publisheddate
(-)a/installer/data/mysql/atomicupdate/bug-18783.pl (+23 lines)
Line 0 Link Here
1
use Modern::Perl;
2
3
return {
4
    bug_number  => "18783",
5
    description => "Automatic claims for serials",
6
    up          => sub {
7
        my ($args) = @_;
8
        my ( $dbh, $out ) = @$args{qw(dbh out)};
9
10
        unless ( column_exists( 'subscription', 'auto_claim_enabled' ) ) {
11
            $dbh->do(
12
                q{
13
                ALTER TABLE subscription
14
                ADD COLUMN auto_claim_enabled tinyint NOT NULL DEFAULT 0 COMMENT 'enable automatic claiming' AFTER published_on_template
15
            }
16
            );
17
18
            say $out "Added column subscription.auto_claim_enabled";
19
        } else {
20
            say $out "Column subscription.auto_claim_enabled already exists";
21
        }
22
    },
23
};
(-)a/installer/data/mysql/kohastructure.sql (-1 / +2 lines)
Lines 6187-6192 CREATE TABLE `subscription` ( Link Here
6187
  `mana_id` int(11) DEFAULT NULL,
6187
  `mana_id` int(11) DEFAULT NULL,
6188
  `ccode` varchar(80) DEFAULT NULL COMMENT 'collection code to assign to serial items',
6188
  `ccode` varchar(80) DEFAULT NULL COMMENT 'collection code to assign to serial items',
6189
  `published_on_template` text DEFAULT NULL COMMENT 'Template Toolkit syntax to generate the default "Published on (text)" field when receiving an issue this serial',
6189
  `published_on_template` text DEFAULT NULL COMMENT 'Template Toolkit syntax to generate the default "Published on (text)" field when receiving an issue this serial',
6190
  `auto_claim_enabled` tinyint NOT NULL DEFAULT 0 COMMENT 'enable automatic claiming',
6190
  PRIMARY KEY (`subscriptionid`),
6191
  PRIMARY KEY (`subscriptionid`),
6191
  KEY `subscription_ibfk_1` (`periodicity`),
6192
  KEY `subscription_ibfk_1` (`periodicity`),
6192
  KEY `subscription_ibfk_2` (`numberpattern`),
6193
  KEY `subscription_ibfk_2` (`numberpattern`),
Lines 6798-6801 CREATE TABLE `zebraqueue` ( Link Here
6798
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
6799
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
6799
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
6800
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
6800
6801
6801
-- Dump completed on 2025-05-26 13:26:31
6802
-- Dump completed on 2024-11-25 12:13:27
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt (+8 lines)
Lines 262-267 Link Here
262
                            <label for="graceperiod">Grace period:</label>
262
                            <label for="graceperiod">Grace period:</label>
263
                            <input type="text" name="graceperiod" id="graceperiod" value="[% graceperiod | html %]" size="5" /> day(s)
263
                            <input type="text" name="graceperiod" id="graceperiod" value="[% graceperiod | html %]" size="5" /> day(s)
264
                        </li>
264
                        </li>
265
                        <li>
266
                            <label for="auto_claim_enabled">Enable automatic claims</label>
267
                            [% IF auto_claim_enabled %]
268
                                <input type="checkbox" name="auto_claim_enabled" id="auto_claim_enabled" value="1" checked />
269
                            [% ELSE %]
270
                                <input type="checkbox" name="auto_claim_enabled" id="auto_claim_enabled" value="1" />
271
                            [% END %]
272
                        </li>
265
                        <li>
273
                        <li>
266
                            <label class="widelabel" for="staffdisplaycount">Number of issues to display to staff: </label>
274
                            <label class="widelabel" for="staffdisplaycount">Number of issues to display to staff: </label>
267
                            <input type="text" name="staffdisplaycount" id="staffdisplaycount" value="[% staffdisplaycount | html %]" inputmode="numeric" pattern="[0-9]*" size="4" />
275
                            <input type="text" name="staffdisplaycount" id="staffdisplaycount" value="[% staffdisplaycount | html %]" inputmode="numeric" pattern="[0-9]*" size="4" />
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-detail.tt (+1 lines)
Lines 138-143 Link Here
138
                                    [% END %]
138
                                    [% END %]
139
                                </li>
139
                                </li>
140
                                <li><span class="label">Grace period:</span> [% graceperiod | html %]</li>
140
                                <li><span class="label">Grace period:</span> [% graceperiod | html %]</li>
141
                                <li><span class="label">Automatic claims:</span> [% IF auto_claim_enabled %]Enabled[% ELSE %]Disabled[% END %]</li>
141
                            </ol>
142
                            </ol>
142
                        </div>
143
                        </div>
143
                        <!-- /.rows -->
144
                        <!-- /.rows -->
(-)a/misc/cronjobs/serialsClaim.pl (+127 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2017 Biblibre
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
=head1 NAME
21
22
serialsClaims.pl - Send claim notice to suppliers that have late or missing issues
23
24
=head1 SYNOPSIS
25
26
serialsClaims.pl --letter-code LETTER_CODE [--max-claims MAX_CLAIMS]
27
28
Options:
29
    --letter-code LETTER_CODE   Mandatory. Use letter LETTER_CODE.
30
    --max-claims MAX_CLAIMS     Send up to MAX_CLAIMS notices
31
32
=cut
33
34
use Modern::Perl;
35
36
use Koha::Script -cron;
37
38
use Koha::Acquisition::Booksellers;
39
use Koha::DateUtils qw( dt_from_string );
40
use Koha::Subscriptions;
41
42
use C4::Context;
43
use C4::Letters;
44
use C4::Serials;
45
46
use Getopt::Long qw( GetOptions );
47
48
sub usage {
49
    return <<EOT;
50
Usage: $0 --letter-code LETTER_CODE [--max-claims MAX_CLAIMS]
51
EOT
52
}
53
54
my $command_line_options = join( " ", @ARGV );
55
56
my ( $help, $letter_code, $max_claims );
57
GetOptions(
58
    'help'          => \$help,
59
    'letter-code=s' => \$letter_code,
60
    'max-claims=i'  => \$max_claims,
61
) or die usage();
62
63
if ($help) {
64
    say usage();
65
    exit;
66
}
67
68
die usage() unless $letter_code;
69
70
cronlogaction( { info => $command_line_options } );
71
72
my $suppliers = C4::Serials::GetSuppliersWithLateIssues();
73
foreach my $supplier (@$suppliers) {
74
    my $bookseller   = Koha::Acquisition::Booksellers->find( $supplier->{id} );
75
    my $supplierinfo = $bookseller->name . ' (' . $bookseller->id . ')';
76
77
    my $deliverytime = $bookseller->deliverytime;
78
    unless ($deliverytime) {
79
        say STDERR
80
            "Warning: There is no delivery time set for supplier $supplierinfo. Automatic claiming is disabled for this supplier.";
81
        next;
82
    }
83
84
    my @serials = C4::Serials::GetLateOrMissingIssues( $bookseller->id );
85
    my @serialids;
86
    foreach my $serial (@serials) {
87
        if ( $max_claims && $serial->{claims_count} >= $max_claims ) {
88
            say "Maximum claims count reached for serial " . $serial->{serialid};
89
            next;
90
        }
91
92
        my $subscription = Koha::Subscriptions->find( $serial->{subscriptionid} );
93
        next unless $subscription->auto_claim_enabled;
94
95
        my $claims_count = $serial->{claims_count};
96
        my $date         = $serial->{claimdate} ? $serial->{claimdate} : $serial->{planneddate};
97
        my $newclaimdate = dt_from_string($date)->add( days => $deliverytime );
98
        my $now          = dt_from_string;
99
100
        if ( $newclaimdate <= $now ) {
101
            push @serialids, $serial->{serialid};
102
        }
103
    }
104
105
    if (@serialids) {
106
        my $err;
107
        eval {
108
            $err = C4::Letters::SendAlerts( 'claimissues', \@serialids, $letter_code );
109
            if ( not ref $err or not exists $err->{error} ) {
110
                C4::Serials::updateClaim( \@serialids );
111
            }
112
        };
113
        if ($@) {
114
            say STDERR "Error: $@ while claiming serials " . join( ',', @serialids );
115
        } elsif ( ref $err and exists $err->{error} ) {
116
            if ( $err->{error} eq "no_email" ) {
117
                say STDERR "Error: Supplier $supplierinfo has no email";
118
            } elsif ( $err->{error} =~ m|Bad or missing From address| ) {
119
                say STDERR "Error: Supplier $supplierinfo has no email";
120
            } else {
121
                say STDERR "Error: " . $err->{error};
122
            }
123
        } else {
124
            say "Claim sent to $supplierinfo for serials " . join( ',', @serialids );
125
        }
126
    }
127
}
(-)a/serials/subscription-add.pl (-8 / +9 lines)
Lines 349-354 sub redirect_add_subscription { Link Here
349
    my $skip_serialseq        = $query->param('skip_serialseq');
349
    my $skip_serialseq        = $query->param('skip_serialseq');
350
    my $ccode                 = $query->param('ccode');
350
    my $ccode                 = $query->param('ccode');
351
    my $published_on_template = $query->param('published_on_template');
351
    my $published_on_template = $query->param('published_on_template');
352
    my $auto_claim_enabled    = $query->param('auto_claim_enabled');
352
353
353
    my $mana_id;
354
    my $mana_id;
354
    if ( $query->param('mana_id') ne "" ) {
355
    if ( $query->param('mana_id') ne "" ) {
Lines 376-382 sub redirect_add_subscription { Link Here
376
        join( ";", @irregularity ), $numberpattern,    $locale,         $callnumber,
377
        join( ";", @irregularity ), $numberpattern,    $locale,         $callnumber,
377
        $manualhistory,             $internalnotes,    $serialsadditems,
378
        $manualhistory,             $internalnotes,    $serialsadditems,
378
        $staffdisplaycount,         $opacdisplaycount, $graceperiod, $location, $enddate,
379
        $staffdisplaycount,         $opacdisplaycount, $graceperiod, $location, $enddate,
379
        $skip_serialseq,            $itemtype,         $previousitemtype, $mana_id, $ccode, $published_on_template
380
        $skip_serialseq, $itemtype, $previousitemtype, $mana_id, $ccode, $published_on_template, $auto_claim_enabled
380
    );
381
    );
381
    if (    ( C4::Context->preference('Mana') == 1 )
382
    if (    ( C4::Context->preference('Mana') == 1 )
382
        and ( grep { $_ eq "subscription" } split( /,/, C4::Context->preference('AutoShareWithMana') ) ) )
383
        and ( grep { $_ eq "subscription" } split( /,/, C4::Context->preference('AutoShareWithMana') ) ) )
Lines 458-463 sub redirect_mod_subscription { Link Here
458
    my $skip_serialseq        = $query->param('skip_serialseq');
459
    my $skip_serialseq        = $query->param('skip_serialseq');
459
    my $ccode                 = $query->param('ccode');
460
    my $ccode                 = $query->param('ccode');
460
    my $published_on_template = $query->param('published_on_template');
461
    my $published_on_template = $query->param('published_on_template');
462
    my $auto_claim_enabled    = $query->param('auto_claim_enabled');
461
463
462
    my $mana_id;
464
    my $mana_id;
463
    if ( $query->param('mana_id') ne "" ) {
465
    if ( $query->param('mana_id') ne "" ) {
Lines 489-500 sub redirect_mod_subscription { Link Here
489
    ModSubscription(
491
    ModSubscription(
490
        $auser,            $branchcode,     $aqbooksellerid, $cost, $aqbudgetid, $startdate,
492
        $auser,            $branchcode,     $aqbooksellerid, $cost, $aqbudgetid, $startdate,
491
        $periodicity,      $firstacquidate, join( ";", @irregularity ),
493
        $periodicity,      $firstacquidate, join( ";", @irregularity ),
492
        $numberpattern,    $locale,         $numberlength,     $weeklength, $monthlength, $lastvalue1,
494
        $numberpattern,    $locale,         $numberlength,    $weeklength, $monthlength, $lastvalue1,
493
        $innerloop1,       $lastvalue2,     $innerloop2,       $lastvalue3, $innerloop3,
495
        $innerloop1,       $lastvalue2,     $innerloop2,      $lastvalue3, $innerloop3,
494
        $status,           $biblionumber,   $callnumber,       $notes,      $letter,
496
        $status,           $biblionumber,   $callnumber,      $notes,      $letter,
495
        $manualhistory,    $internalnotes,  $serialsadditems,  $staffdisplaycount,
497
        $manualhistory,    $internalnotes,  $serialsadditems, $staffdisplaycount,
496
        $opacdisplaycount, $graceperiod,    $location,         $enddate, $subscriptionid,
498
        $opacdisplaycount, $graceperiod,    $location,        $enddate, $subscriptionid,
497
        $skip_serialseq,   $itemtype,       $previousitemtype, $mana_id, $ccode, $published_on_template
499
        $skip_serialseq,   $itemtype, $previousitemtype, $mana_id, $ccode, $published_on_template, $auto_claim_enabled
498
    );
500
    );
499
501
500
    my @additional_fields =
502
    my @additional_fields =
501
- 

Return to bug 18783