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

(-)a/C4/Letters.pm (-2 / +7 lines)
Lines 479-485 sub SendAlerts { Link Here
479
        $letter->{content} =~ s/<order>(.*?)<\/order>/$1/gxms;
479
        $letter->{content} =~ s/<order>(.*?)<\/order>/$1/gxms;
480
480
481
        # ... then send mail
481
        # ... then send mail
482
        my $from;
482
        my $library = Koha::Libraries->find( $userenv->{branch} );
483
        my $library = Koha::Libraries->find( $userenv->{branch} );
484
        if ($library and $library->branchemail) {
485
            $from = $library->branchemail;
486
        } else {
487
            $from = C4::Context->preference('KohaAdminEmailAddress');
488
        }
483
        my $email = Koha::Email->new();
489
        my $email = Koha::Email->new();
484
        my %mail = $email->create_message_headers(
490
        my %mail = $email->create_message_headers(
485
            {
491
            {
Lines 493-500 sub SendAlerts { Link Here
493
                    ) ? ( bcc => $userenv->{emailaddress} )
499
                    ) ? ( bcc => $userenv->{emailaddress} )
494
                    : ()
500
                    : ()
495
                ),
501
                ),
496
                from => $library->branchemail
502
                from => $from,
497
                  || C4::Context->preference('KohaAdminEmailAddress'),
498
                subject => Encode::encode( "UTF-8", "" . $letter->{title} ),
503
                subject => Encode::encode( "UTF-8", "" . $letter->{title} ),
499
                message => $letter->{'is_html'} ? _wrap_html(
504
                message => $letter->{'is_html'} ? _wrap_html(
500
                    Encode::encode( "UTF-8", $letter->{'content'} ),
505
                    Encode::encode( "UTF-8", $letter->{'content'} ),
(-)a/C4/Serials.pm (-9 / +16 lines)
Lines 323-329 sub GetFullSubscription { Link Here
323
    my $sth = $dbh->prepare($query);
323
    my $sth = $dbh->prepare($query);
324
    $sth->execute($subscriptionid);
324
    $sth->execute($subscriptionid);
325
    my $subscriptions = $sth->fetchall_arrayref( {} );
325
    my $subscriptions = $sth->fetchall_arrayref( {} );
326
    my $cannotedit = not can_edit_subscription( $subscriptions->[0] ) if scalar @$subscriptions;
326
    my $cannotedit;
327
    $cannotedit = not can_edit_subscription( $subscriptions->[0] ) if scalar @$subscriptions;
327
    for my $subscription ( @$subscriptions ) {
328
    for my $subscription ( @$subscriptions ) {
328
        $subscription->{cannotedit} = $cannotedit;
329
        $subscription->{cannotedit} = $cannotedit;
329
    }
330
    }
Lines 346-354 sub PrepareSerialsData { Link Here
346
    my $year;
347
    my $year;
347
    my @res;
348
    my @res;
348
    my $startdate;
349
    my $startdate;
349
    my $aqbooksellername;
350
    my $bibliotitle;
351
    my @loopissues;
352
    my $first;
350
    my $first;
353
    my $previousnote = "";
351
    my $previousnote = "";
354
352
Lines 481-487 sub GetFullSubscriptionsFromBiblionumber { Link Here
481
    my $sth = $dbh->prepare($query);
479
    my $sth = $dbh->prepare($query);
482
    $sth->execute($biblionumber);
480
    $sth->execute($biblionumber);
483
    my $subscriptions = $sth->fetchall_arrayref( {} );
481
    my $subscriptions = $sth->fetchall_arrayref( {} );
484
    my $cannotedit = not can_edit_subscription( $subscriptions->[0] ) if scalar @$subscriptions;
482
    my $cannotedit;
483
    $cannotedit = not can_edit_subscription( $subscriptions->[0] ) if scalar @$subscriptions;
485
    for my $subscription ( @$subscriptions ) {
484
    for my $subscription ( @$subscriptions ) {
486
        $subscription->{cannotedit} = $cannotedit;
485
        $subscription->{cannotedit} = $cannotedit;
487
    }
486
    }
Lines 1301-1309 sub ModSubscription { Link Here
1301
    $biblionumber, $callnumber, $notes, $letter, $manualhistory,
1300
    $biblionumber, $callnumber, $notes, $letter, $manualhistory,
1302
    $internalnotes, $serialsadditems, $staffdisplaycount, $opacdisplaycount,
1301
    $internalnotes, $serialsadditems, $staffdisplaycount, $opacdisplaycount,
1303
    $graceperiod, $location, $enddate, $subscriptionid, $skip_serialseq,
1302
    $graceperiod, $location, $enddate, $subscriptionid, $skip_serialseq,
1304
    $itemtype, $previousitemtype, $mana_id
1303
    $itemtype, $previousitemtype, $mana_id, $auto_claim_enabled
1305
    ) = @_;
1304
    ) = @_;
1306
1305
1306
    $auto_claim_enabled //= 0;
1307
1307
    my $dbh   = C4::Context->dbh;
1308
    my $dbh   = C4::Context->dbh;
1308
    my $query = "UPDATE subscription
1309
    my $query = "UPDATE subscription
1309
        SET librarian=?, branchcode=?, aqbooksellerid=?, cost=?, aqbudgetid=?,
1310
        SET librarian=?, branchcode=?, aqbooksellerid=?, cost=?, aqbudgetid=?,
Lines 1314-1320 sub ModSubscription { Link Here
1314
            callnumber=?, notes=?, letter=?, manualhistory=?,
1315
            callnumber=?, notes=?, letter=?, manualhistory=?,
1315
            internalnotes=?, serialsadditems=?, staffdisplaycount=?,
1316
            internalnotes=?, serialsadditems=?, staffdisplaycount=?,
1316
            opacdisplaycount=?, graceperiod=?, location = ?, enddate=?,
1317
            opacdisplaycount=?, graceperiod=?, location = ?, enddate=?,
1317
            skip_serialseq=?, itemtype=?, previousitemtype=?, mana_id=?
1318
            skip_serialseq=?, itemtype=?, previousitemtype=?, mana_id=?,
1319
            auto_claim_enabled=?
1318
        WHERE subscriptionid = ?";
1320
        WHERE subscriptionid = ?";
1319
1321
1320
    my $sth = $dbh->prepare($query);
1322
    my $sth = $dbh->prepare($query);
Lines 1328-1334 sub ModSubscription { Link Here
1328
        $letter,          ($manualhistory ? $manualhistory : 0),
1330
        $letter,          ($manualhistory ? $manualhistory : 0),
1329
        $internalnotes, $serialsadditems, $staffdisplaycount, $opacdisplaycount,
1331
        $internalnotes, $serialsadditems, $staffdisplaycount, $opacdisplaycount,
1330
        $graceperiod,     $location,       $enddate,        $skip_serialseq,
1332
        $graceperiod,     $location,       $enddate,        $skip_serialseq,
1331
        $itemtype,        $previousitemtype, $mana_id,
1333
        $itemtype,        $previousitemtype, $mana_id, $auto_claim_enabled,
1332
        $subscriptionid
1334
        $subscriptionid
1333
    );
1335
    );
1334
    my $rows = $sth->rows;
1336
    my $rows = $sth->rows;
Lines 1362-1369 sub NewSubscription { Link Here
1362
    $innerloop3, $status, $notes, $letter, $firstacquidate, $irregularity,
1364
    $innerloop3, $status, $notes, $letter, $firstacquidate, $irregularity,
1363
    $numberpattern, $locale, $callnumber, $manualhistory, $internalnotes,
1365
    $numberpattern, $locale, $callnumber, $manualhistory, $internalnotes,
1364
    $serialsadditems, $staffdisplaycount, $opacdisplaycount, $graceperiod,
1366
    $serialsadditems, $staffdisplaycount, $opacdisplaycount, $graceperiod,
1365
    $location, $enddate, $skip_serialseq, $itemtype, $previousitemtype, $mana_id
1367
    $location, $enddate, $skip_serialseq, $itemtype, $previousitemtype, $mana_id,
1368
    $auto_claim_enabled
1366
    ) = @_;
1369
    ) = @_;
1370
1371
    $auto_claim_enabled //= 0;
1372
1367
    my $dbh = C4::Context->dbh;
1373
    my $dbh = C4::Context->dbh;
1368
1374
1369
    my $subscription = Koha::Subscription->new(
1375
    my $subscription = Koha::Subscription->new(
Lines 1405-1410 sub NewSubscription { Link Here
1405
            itemtype          => $itemtype,
1411
            itemtype          => $itemtype,
1406
            previousitemtype  => $previousitemtype,
1412
            previousitemtype  => $previousitemtype,
1407
            mana_id           => $mana_id,
1413
            mana_id           => $mana_id,
1414
            auto_claim_enabled => $auto_claim_enabled,
1408
        }
1415
        }
1409
    )->store;
1416
    )->store;
1410
    $subscription->discard_changes;
1417
    $subscription->discard_changes;
(-)a/installer/data/mysql/atomicupdate/bug_18783.perl (+12 lines)
Line 0 Link Here
1
$DBversion = 'XXX';
2
if ( CheckVersion($DBversion) ) {
3
    if ( !column_exists('subscription', 'auto_claim_enabled') ) {
4
        $dbh->do(q{
5
            ALTER TABLE subscription
6
            ADD COLUMN auto_claim_enabled tinyint NOT NULL DEFAULT 0 AFTER previousitemtype
7
        });
8
    }
9
10
    SetVersion($DBversion);
11
    print "Upgrade to $DBversion done (Bug 18783 - Automatic claims for serials)\n";
12
}
(-)a/installer/data/mysql/kohastructure.sql (+1 lines)
Lines 2032-2037 CREATE TABLE `subscription` ( -- information related to the subscription Link Here
2032
  `itemtype` VARCHAR( 10 ) NULL,
2032
  `itemtype` VARCHAR( 10 ) NULL,
2033
  `previousitemtype` VARCHAR( 10 ) NULL,
2033
  `previousitemtype` VARCHAR( 10 ) NULL,
2034
  `mana_id` int(11) NULL DEFAULT NULL,
2034
  `mana_id` int(11) NULL DEFAULT NULL,
2035
  `auto_claim_enabled` tinyint NOT NULL DEFAULT 0, -- enable automatic claiming
2035
  PRIMARY KEY  (`subscriptionid`),
2036
  PRIMARY KEY  (`subscriptionid`),
2036
  KEY `by_biblionumber` (`biblionumber`),
2037
  KEY `by_biblionumber` (`biblionumber`),
2037
  CONSTRAINT subscription_ibfk_1 FOREIGN KEY (periodicity) REFERENCES subscription_frequencies (id) ON DELETE SET NULL ON UPDATE CASCADE,
2038
  CONSTRAINT subscription_ibfk_1 FOREIGN KEY (periodicity) REFERENCES subscription_frequencies (id) ON DELETE SET NULL ON UPDATE CASCADE,
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-add.tt (+8 lines)
Lines 201-206 fieldset.rows table { clear: none; margin: 0; } Link Here
201
                                    <label for="graceperiod">Grace period:</label>
201
                                    <label for="graceperiod">Grace period:</label>
202
                                    <input type="text" name="graceperiod" id="graceperiod" value="[% graceperiod | html %]" size="5"/> day(s)
202
                                    <input type="text" name="graceperiod" id="graceperiod" value="[% graceperiod | html %]" size="5"/> day(s)
203
                                </li>
203
                                </li>
204
                                <li>
205
                                    <label for="auto_claim_enabled">Enable automatic claims</label>
206
                                    [% IF auto_claim_enabled %]
207
                                        <input type="checkbox" name="auto_claim_enabled" id="auto_claim_enabled" value="1" checked/>
208
                                    [% ELSE %]
209
                                        <input type="checkbox" name="auto_claim_enabled" id="auto_claim_enabled" value="1"/>
210
                                    [% END %]
211
                                </li>
204
                                <li>
212
                                <li>
205
                                     <label class="widelabel" for="staffdisplaycount">Number of issues to display to staff: </label>
213
                                     <label class="widelabel" for="staffdisplaycount">Number of issues to display to staff: </label>
206
                                     <input type="text" name="staffdisplaycount" id="staffdisplaycount" value="[% staffdisplaycount | html %]" size="4"/>
214
                                     <input type="text" name="staffdisplaycount" id="staffdisplaycount" value="[% staffdisplaycount | html %]" size="4"/>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/subscription-detail.tt (+1 lines)
Lines 110-115 Link Here
110
            [% END %]
110
            [% END %]
111
        </li>
111
        </li>
112
        <li><span class="label">Grace period:</span> [% graceperiod | html %]</li>
112
        <li><span class="label">Grace period:</span> [% graceperiod | html %]</li>
113
        <li><span class="label">Automatic claims:</span> [% IF auto_claim_enabled %]Enabled[% ELSE %]Disabled[% END %]</li>
113
        </ol>
114
        </ol>
114
    </div>
115
    </div>
115
    </div>
116
    </div>
(-)a/misc/cronjobs/serialsClaim.pl (+117 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 DateTime;
37
use Getopt::Long;
38
39
use Koha::Acquisition::Booksellers;
40
use Koha::DateUtils;
41
use Koha::Subscriptions;
42
43
use C4::Context;
44
use C4::Letters;
45
use C4::Serials;
46
47
sub usage {
48
    return <<EOT
49
Usage: $0 --letter-code LETTER_CODE [--max-claims MAX_CLAIMS]
50
EOT
51
}
52
53
my $letter_code;
54
my $max_claims;
55
56
GetOptions(
57
    'letter-code=s' => \$letter_code,
58
    'max-claims=i' => \$max_claims,
59
) or die usage();
60
61
die usage() unless $letter_code;
62
63
my $suppliers = GetSuppliersWithLateIssues();
64
foreach my $supplier (@$suppliers) {
65
    my $bookseller = Koha::Acquisition::Booksellers->find($supplier->{id});
66
    my $supplierinfo = $bookseller->name . ' (' . $bookseller->id . ')';
67
68
    my $deliverytime = $bookseller->deliverytime;
69
    unless ($deliverytime) {
70
        say STDERR "Warning: There is no delivery time set for supplier $supplierinfo. Automatic claiming is disabled for this supplier.";
71
        next;
72
    }
73
74
    my @serials = GetLateOrMissingIssues($bookseller->id);
75
    my @serialids;
76
    foreach my $serial (@serials) {
77
        if ($max_claims && $serial->{claims_count} >= $max_claims) {
78
            say "Maximum claims count reached for serial " . $serial->{serialid};
79
            next;
80
        }
81
82
        my $subscription = Koha::Subscriptions->find($serial->{subscriptionid});
83
        next unless $subscription->auto_claim_enabled;
84
85
        my $claims_count = $serial->{claims_count};
86
        my $date = $serial->{claimdate} ? $serial->{claimdate} : $serial->{planneddate};
87
        my $newclaimdate = dt_from_string($date)->add(days => $deliverytime);
88
        my $now = DateTime->now(time_zone => C4::Context->tz);
89
90
        if ($newclaimdate <= $now) {
91
            push @serialids, $serial->{serialid};
92
        }
93
    }
94
95
    if (@serialids) {
96
        my $err;
97
        eval {
98
            $err = SendAlerts('claimissues', \@serialids, $letter_code);
99
            if ( not ref $err or not exists $err->{error} ) {
100
                C4::Serials::updateClaim( \@serialids );
101
            }
102
        };
103
        if ( $@ ) {
104
            say STDERR "Error: $@ while claiming serials " . join(',', @serialids);
105
        } elsif ( ref $err and exists $err->{error} ) {
106
            if ( $err->{error} eq "no_email" ) {
107
                say STDERR "Error: Supplier $supplierinfo has no email";
108
            } elsif ( $err->{error} =~ m|Bad or missing From address| ) {
109
                say STDERR "Error: Supplier $supplierinfo has no email";
110
            } else {
111
                say STDERR "Error: " . $err->{error};
112
            }
113
        } else {
114
            say "Claim sent to $supplierinfo for serials " . join(',', @serialids);
115
        }
116
    }
117
}
(-)a/serials/subscription-add.pl (-3 / +4 lines)
Lines 349-354 sub redirect_add_subscription { Link Here
349
    my $itemtype          = $query->param('itemtype');
349
    my $itemtype          = $query->param('itemtype');
350
    my $previousitemtype  = $query->param('previousitemtype');
350
    my $previousitemtype  = $query->param('previousitemtype');
351
    my $skip_serialseq    = $query->param('skip_serialseq');
351
    my $skip_serialseq    = $query->param('skip_serialseq');
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 375-381 sub redirect_add_subscription { Link Here
375
        join(";",@irregularity), $numberpattern, $locale, $callnumber,
376
        join(";",@irregularity), $numberpattern, $locale, $callnumber,
376
        $manualhistory, $internalnotes, $serialsadditems,
377
        $manualhistory, $internalnotes, $serialsadditems,
377
        $staffdisplaycount, $opacdisplaycount, $graceperiod, $location, $enddate,
378
        $staffdisplaycount, $opacdisplaycount, $graceperiod, $location, $enddate,
378
        $skip_serialseq, $itemtype, $previousitemtype, $mana_id
379
        $skip_serialseq, $itemtype, $previousitemtype, $mana_id, $auto_claim_enabled
379
    );
380
    );
380
    if ( (C4::Context->preference('Mana') == 1) and ( grep { $_ eq "subscription" } split(/,/, C4::Context->preference('AutoShareWithMana'))) ){
381
    if ( (C4::Context->preference('Mana') == 1) and ( grep { $_ eq "subscription" } split(/,/, C4::Context->preference('AutoShareWithMana'))) ){
381
        my $result = Koha::SharedContent::send_entity( $query->param('mana_language') || '', $loggedinuser, $subscriptionid, 'subscription');
382
        my $result = Koha::SharedContent::send_entity( $query->param('mana_language') || '', $loggedinuser, $subscriptionid, 'subscription');
Lines 463-468 sub redirect_mod_subscription { Link Here
463
    my $itemtype          = $query->param('itemtype');
464
    my $itemtype          = $query->param('itemtype');
464
    my $previousitemtype  = $query->param('previousitemtype');
465
    my $previousitemtype  = $query->param('previousitemtype');
465
    my $skip_serialseq    = $query->param('skip_serialseq');
466
    my $skip_serialseq    = $query->param('skip_serialseq');
467
    my $auto_claim_enabled = $query->param('auto_claim_enabled');
466
468
467
    my $mana_id;
469
    my $mana_id;
468
    if ( $query->param('mana_id') ne "" ) {
470
    if ( $query->param('mana_id') ne "" ) {
Lines 498-504 sub redirect_mod_subscription { Link Here
498
        $status, $biblionumber, $callnumber, $notes, $letter,
500
        $status, $biblionumber, $callnumber, $notes, $letter,
499
        $manualhistory, $internalnotes, $serialsadditems, $staffdisplaycount,
501
        $manualhistory, $internalnotes, $serialsadditems, $staffdisplaycount,
500
        $opacdisplaycount, $graceperiod, $location, $enddate, $subscriptionid,
502
        $opacdisplaycount, $graceperiod, $location, $enddate, $subscriptionid,
501
        $skip_serialseq, $itemtype, $previousitemtype, $mana_id
503
        $skip_serialseq, $itemtype, $previousitemtype, $mana_id, $auto_claim_enabled
502
    );
504
    );
503
505
504
    my @additional_fields;
506
    my @additional_fields;
505
- 

Return to bug 18783