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

(-)a/C4/Overdues.pm (-34 lines)
Lines 52-58 BEGIN { Link Here
52
        GetBranchcodesWithOverdueRules
52
        GetBranchcodesWithOverdueRules
53
        get_chargeable_units
53
        get_chargeable_units
54
        GetOverduesForBranch
54
        GetOverduesForBranch
55
        GetOverdueMessageTransportTypes
56
        parse_overdues_letter
55
        parse_overdues_letter
57
        GetIssuesIteminfo
56
        GetIssuesIteminfo
58
    );
57
    );
Lines 766-804 sub GetOverduesForBranch { Link Here
766
    }
765
    }
767
}
766
}
768
767
769
=head2 GetOverdueMessageTransportTypes
770
771
    my $message_transport_types = GetOverdueMessageTransportTypes( $branchcode, $categorycode, $letternumber);
772
773
    return a arrayref with all message_transport_type for given branchcode, categorycode and letternumber(1,2 or 3)
774
775
=cut
776
777
sub GetOverdueMessageTransportTypes {
778
    my ( $branchcode, $categorycode, $letternumber ) = @_;
779
    return unless $categorycode and $letternumber;
780
    my $dbh = C4::Context->dbh;
781
    my $sth = $dbh->prepare( "
782
        SELECT message_transport_type
783
        FROM overduerules odr LEFT JOIN overduerules_transport_types ott USING (overduerules_id)
784
        WHERE branchcode = ?
785
          AND categorycode = ?
786
          AND letternumber = ?
787
    " );
788
    $sth->execute( $branchcode, $categorycode, $letternumber );
789
    my @mtts;
790
    while ( my $mtt = $sth->fetchrow ) {
791
        push @mtts, $mtt;
792
    }
793
794
    # Put 'print' in first if exists
795
    # It avoid to sent a print notice with an email or sms template is no email or sms is defined
796
    @mtts = uniq( 'print', @mtts )
797
        if grep { $_ eq 'print' } @mtts;
798
799
    return \@mtts;
800
}
801
802
=head2 parse_overdues_letter
768
=head2 parse_overdues_letter
803
769
804
parses the letter template, replacing the placeholders with data
770
parses the letter template, replacing the placeholders with data
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc (-1 / +1 lines)
Lines 25-31 Link Here
25
                <li><a href="/cgi-bin/koha/tools/letter.pl">Notices and slips</a></li>
25
                <li><a href="/cgi-bin/koha/tools/letter.pl">Notices and slips</a></li>
26
            [% END %]
26
            [% END %]
27
            [% IF ( CAN_user_tools_edit_notice_status_triggers ) %]
27
            [% IF ( CAN_user_tools_edit_notice_status_triggers ) %]
28
                <li><a href="/cgi-bin/koha/tools/overduerules.pl">Overdue notice/status triggers</a></li>
28
                <li><a href="/cgi-bin/koha/admin/circulation_triggers">Overdue notice/status triggers</a></li>
29
            [% END %]
29
            [% END %]
30
            [% IF ( CAN_user_tools_label_creator ) %]
30
            [% IF ( CAN_user_tools_label_creator ) %]
31
                <li><a href="/cgi-bin/koha/patroncards/home.pl">Patron card creator</a></li>
31
                <li><a href="/cgi-bin/koha/patroncards/home.pl">Patron card creator</a></li>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/overduerules.tt (-205 lines)
Lines 1-205 Link Here
1
[% USE raw %]
2
[% USE Asset %]
3
[% USE Koha %]
4
[% USE Branches %]
5
[% PROCESS 'i18n.inc' %]
6
[% SET footerjs = 1 %]
7
[% INCLUDE 'doc-head-open.inc' %]
8
<title
9
    >[% FILTER collapse %]
10
        [% t("Overdue notice/status triggers") | html %]
11
        &rsaquo; [% t("Tools") | html %] &rsaquo; [% t("Koha") | html %]
12
    [% END %]</title
13
>
14
[% INCLUDE 'doc-head-close.inc' %]
15
</head>
16
17
<body id="tools_overduerules" class="tools">
18
[% WRAPPER 'header.inc' %]
19
    [% INCLUDE 'cat-search.inc' %]
20
[% END %]
21
22
[% WRAPPER 'sub-header.inc' %]
23
    [% WRAPPER breadcrumbs %]
24
        [% WRAPPER breadcrumb_item %]
25
            <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a>
26
        [% END %]
27
        [% WRAPPER breadcrumb_item bc_active= 1 %]
28
            <span>Overdue notice/status triggers</span>
29
        [% END %]
30
    [% END #/ WRAPPER breadcrumbs %]
31
[% END #/ WRAPPER sub-header.inc %]
32
33
[% WRAPPER 'main-container.inc' aside='tools-menu' %]
34
    <h1>Defining [% IF ( branch ) %]overdue actions for [% Branches.GetName( branch ) | html %][% ELSE %]default overdue actions[% END %]</h1>
35
    <div class="help">
36
        <p>Delay is the number of days after a checkout is due before an action is triggered. </p>
37
        <p>If you want Koha to trigger an action (send a letter or restrict a member), a delay value is required.</p>
38
        <p>Columns must be filled left to right: if the first column is blank, other columns will be ignored. </p>
39
    </div>
40
    <form method="get" action="/cgi-bin/koha/tools/overduerules.pl" id="selectlibrary">
41
        <label for="branch">Select a library:</label>
42
        <select id="branch" name="branch">
43
            <option value="">Default</option>
44
            [% PROCESS options_for_libraries libraries => Branches.all( selected => branch ) %]
45
        </select>
46
        <input type="submit" class="btn btn-primary" value="Select" />
47
    </form>
48
    [% IF ( ERROR ) %]
49
        <div class="alert alert-warning">
50
            <h3>Data error</h3>
51
            <p>The following errors were found. Please correct them and submit again:</p>
52
            <ul>
53
                [% IF ( ERRORDELAY ) %]
54
                    <li>Delay [% ERRORDELAY | html %] for [% BORERR | html %] patron category has some unexpected characters. There should be only numerical characters. </li>
55
                [% END %]
56
                [% IF ( ERRORUSELESSDELAY ) %]
57
                    <li>No letter or restriction action specified for delay [% ERRORUSELESSDELAY | html %] for [% BORERR | html %] patron category. If a delay is supplied, either a letter, restrict action, or both should be specified.</li>
58
                [% END %]
59
                [% IF ( ERRORORDER ) %]
60
                    <li>The first notice's delay should be less than the second, which should be less than the third for the <strong>[% BORERR | html %]</strong> patron category </li>
61
                [% END %]
62
            </ul>
63
        </div>
64
    [% END %]
65
    [% IF ( table ) %]
66
        <form method="post" id="overduerulesf" action="/cgi-bin/koha/tools/overduerules.pl">
67
            [% INCLUDE 'csrf-token.inc' %]
68
            <input type="hidden" name="op" value="cud-save" />
69
            <input type="hidden" name="branch" value="[% branch | html %]" />
70
            <h3>Rules for overdue actions: [% IF ( branch ) %][% Branches.GetName( branch ) | html %][% ELSE %]default library[% END %]</h3>
71
            [% IF ( datasaved ) %]<div class="alert alert-info">Changes saved.</div>[% END %]
72
73
            [% WRAPPER tabs id= "rulestabs" %]
74
                [% WRAPPER tabs_nav %]
75
                    [% FOR tab IN tabs %]
76
                        [% WRAPPER tab_item tabname= tab.id %]
77
                        [% END %]
78
                    [% END %]
79
                [% END # /WRAPPER tabs_nav %]
80
81
                [% WRAPPER tab_panels %]
82
                    [% FOR tab IN tabs %]
83
                        [% WRAPPER tab_panel tabname=tab.id %]
84
                            <table class="overduerulest" id="overduerulest-[% tab.id | html %]">
85
                                <thead>
86
                                    <tr>
87
                                        <th>Patron category</th>
88
                                        <th class="NoSort" scope="col">Delay</th>
89
                                        <th class="NoSort" scope="col">Letter</th>
90
                                        <th class="NoSort" scope="col">Restrict</th>
91
                                        [% FOREACH mtt IN message_transport_types %]
92
                                            [% NEXT IF mtt == 'itiva' AND !Koha.Preference('TalkingTechItivaPhoneNotification') %]
93
                                            [% NEXT IF mtt == 'phone' AND !Koha.Preference('PhoneNotification') %]
94
                                            <th class="NoSort" scope="col">
95
                                                [% SWITCH mtt %]
96
                                                [% CASE 'email' %]
97
                                                    <span>Email</span>
98
                                                [% CASE 'print' %]
99
                                                    <span>[% tp('Message transport type', 'Print') | html %]</span>
100
                                                [% CASE 'sms' %]
101
                                                    <span>SMS</span>
102
                                                [% CASE 'feed' %]
103
                                                    <span>Feed</span>
104
                                                [% CASE 'itiva' %]
105
                                                    <span>Phone (i-tiva)</span>
106
                                                [% CASE 'phone' %]
107
                                                    <span>Phone</span>
108
                                                [% CASE %]
109
                                                    <span>[% mtt | html %]</span>
110
                                                [% END %]
111
                                            </th>
112
                                        [% END %]
113
                                    </tr>
114
                                </thead>
115
                                <tbody>
116
                                    [% FOREACH value IN tab.values %]
117
                                        <tr>
118
                                            <th scope="row">[% value.line | html %]</th>
119
                                            <td>
120
                                                <input type="text" inputmode="numeric" pattern="[0-9]*" name="delay[% tab.number | html %]-[% value.overduename | html %]" value="[% value.delay | html %]" />
121
                                            </td>
122
                                            <td>
123
                                                <select name="letter[% tab.number | html %]-[% value.overduename | html %]">
124
                                                    <option value="">No notice</option>
125
                                                    [% FOREACH letter IN letters %]
126
                                                        [% IF letter.code == value.selected_lettercode %]
127
                                                            <option value="[% letter.code | html %]" selected="selected">[% letter.name | html %] ( [% letter.code | html %] )</option>
128
                                                        [% ELSE %]
129
                                                            <option value="[% letter.code | html %]">[% letter.name | html %] ( [% letter.code | html %] )</option>
130
                                                        [% END %]
131
                                                    [% END %]
132
                                                </select>
133
                                            </td>
134
                                            <td>
135
                                                [% IF ( value.debarred ) %]
136
                                                    <input type="checkbox" name="debarred[% tab.number | html %]-[% value.overduename | html %]" checked="checked" value="1" />
137
                                                [% ELSE %]
138
                                                    <input type="checkbox" name="debarred[% tab.number | html %]-[% value.overduename | html %]" value="1" />
139
                                                [% END %]
140
                                            </td>
141
                                            [% FOREACH mtt IN value.message_transport_types %]
142
                                                [% NEXT IF mtt.value == 'itiva' AND !Koha.Preference('TalkingTechItivaPhoneNotification') %]
143
                                                [% NEXT IF mtt.value == 'phone' AND !Koha.Preference('PhoneNotification') %]
144
                                                <td>
145
                                                    [% IF mtt.selected %]
146
                                                        <input type="checkbox" name="mtt[% tab.number | html %]-[% value.overduename | html %]" value="[% mtt.value | html %]" checked="checked" />
147
                                                    [% ELSE %]
148
                                                        [% IF mtt.value == "sms" and not Koha.Preference("SMSSendDriver") %]
149
                                                            <input type="checkbox" name="mtt[% tab.number | html %]-[% value.overduename | html %]" value="[% mtt.value | html %]" disabled="disabled" />
150
                                                        [% ELSE %]
151
                                                            <input type="checkbox" name="mtt[% tab.number | html %]-[% value.overduename | html %]" value="[% mtt.value | html %]" />
152
                                                        [% END %]
153
                                                    [% END %]
154
                                                </td>
155
                                            [% END # /FOREACH mtt %]
156
                                        </tr>
157
                                    [% END # /FOREACH value %]
158
                                </tbody>
159
                            </table>
160
                        [% END # /tab_panel# %]
161
                    [% END %]
162
                [% END # /WRAPPER tab_panels %]
163
            [% END # /WRAPPER tabs %]
164
165
            <fieldset class="action"><input type="submit" class="btn btn-primary" value="Save changes" /></fieldset>
166
        </form>
167
    [% ELSE %]
168
        <div class="alert alert-warning">
169
            <p>You don't have patron categories defined, or the patron categories are not set to receive overdue notices.</p>
170
            <p>If this is not what you were expecting, go to <a href="/cgi-bin/koha/admin/categories.pl">patron categories</a></p>
171
        </div>
172
    [% END %]
173
[% END %]
174
175
[% MACRO jsinclude BLOCK %]
176
    [% Asset.js("js/tools-menu.js") | $raw %]
177
    [% INCLUDE 'datatables.inc' %]
178
    <script>
179
        var tab_map = { 0: _("First"), 1: _("Second"), 2: _("Third") };
180
        $(document).ready(function () {
181
            $("#selectlibrary").find("input:submit").hide();
182
            $("#branch").change(function () {
183
                $("#selectlibrary").submit();
184
            });
185
            $("#rulestabs li > a").each(function (i) {
186
                $(this).html(tab_map[i]);
187
            });
188
            if ($("#rulestabs .tab-pane.active").length < 1) {
189
                $("#rulestabs a:first").tab("show");
190
            }
191
            $(".overduerulest").kohaTable({
192
                columnDefs: [{ targets: ["NoSort"], orderable: false, searchable: false }],
193
                dom: '<"top pager"f>rt<"clear">',
194
                paginate: false,
195
            });
196
197
            $("#overduerulesf").on("submit", function (e) {
198
                $(".overduerulest").DataTable().search("").draw();
199
                return true;
200
            });
201
        });
202
    </script>
203
[% END %]
204
205
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt (-1 / +1 lines)
Lines 64-70 Link Here
64
                [% END %]
64
                [% END %]
65
65
66
                [% IF ( CAN_user_tools_edit_notice_status_triggers ) %]
66
                [% IF ( CAN_user_tools_edit_notice_status_triggers ) %]
67
                    <dt><a href="/cgi-bin/koha/tools/overduerules.pl">Overdue notice/status triggers</a></dt>
67
                    <dt><a href="/cgi-bin/koha/admin/circulation_triggers">Overdue notice/status triggers</a></dt>
68
                    <dd>Set notice/status triggers for overdue items</dd>
68
                    <dd>Set notice/status triggers for overdue items</dd>
69
                [% END %]
69
                [% END %]
70
70
(-)a/t/db_dependent/Overdues.t (-72 / +2 lines)
Lines 1-7 Link Here
1
#!/usr/bin/perl;
1
#!/usr/bin/perl;
2
2
3
use Modern::Perl;
3
use Modern::Perl;
4
use Test::More tests => 18;
4
use Test::More tests => 8;
5
use Test::Warn;
5
use Test::Warn;
6
6
7
use C4::Context;
7
use C4::Context;
Lines 11-18 use Koha::Libraries; Link Here
11
use t::lib::Mocks;
11
use t::lib::Mocks;
12
use t::lib::TestBuilder;
12
use t::lib::TestBuilder;
13
13
14
use_ok( 'C4::Overdues', qw( GetOverdueMessageTransportTypes GetBranchcodesWithOverdueRules UpdateFine ) );
14
use_ok( 'C4::Overdues', qw( GetBranchcodesWithOverdueRules UpdateFine ) );
15
can_ok( 'C4::Overdues', 'GetOverdueMessageTransportTypes' );
16
can_ok( 'C4::Overdues', 'GetBranchcodesWithOverdueRules' );
15
can_ok( 'C4::Overdues', 'GetBranchcodesWithOverdueRules' );
17
16
18
my $schema  = Koha::Database->new->schema;
17
my $schema  = Koha::Database->new->schema;
Lines 24-98 my $dbh = C4::Context->dbh; Link Here
24
$dbh->do(q|DELETE FROM letter|);
23
$dbh->do(q|DELETE FROM letter|);
25
$dbh->do(q|DELETE FROM message_queue|);
24
$dbh->do(q|DELETE FROM message_queue|);
26
$dbh->do(q|DELETE FROM message_transport_types|);
25
$dbh->do(q|DELETE FROM message_transport_types|);
27
$dbh->do(q|DELETE FROM overduerules|);
28
$dbh->do(q|DELETE FROM overduerules_transport_types|);
29
30
$dbh->do(
31
    q|
32
    INSERT INTO message_transport_types( message_transport_type ) VALUES ('email'), ('phone'), ('print'), ('sms')
33
|
34
);
35
36
$dbh->do(
37
    q|
38
    INSERT INTO overduerules ( overduerules_id, branchcode, categorycode ) VALUES
39
    (1, 'CPL', 'PT'),
40
    (2, 'CPL', 'YA'),
41
    (3, '', 'PT'),
42
    (4, '', 'YA')
43
|
44
);
45
46
$dbh->do(
47
    q|INSERT INTO overduerules_transport_types (overduerules_id, letternumber, message_transport_type) VALUES
48
    (1, 1, 'email'),
49
    (1, 2, 'sms'),
50
    (1, 3, 'email'),
51
    (2, 3, 'print'),
52
    (3, 1, 'email'),
53
    (3, 2, 'email'),
54
    (3, 2, 'sms'),
55
    (3, 3, 'sms'),
56
    (3, 3, 'email'),
57
    (3, 3, 'print'),
58
    (4, 2, 'sms')
59
|
60
);
61
62
my $mtts;
63
64
$mtts = C4::Overdues::GetOverdueMessageTransportTypes( 'CPL', 'PT' );
65
is( $mtts, undef, 'GetOverdueMessageTransportTypes: returns undef if no letternumber given' );
66
67
$mtts = C4::Overdues::GetOverdueMessageTransportTypes( 'CPL', undef, 1 );
68
is( $mtts, undef, 'GetOverdueMessageTransportTypes: returns undef if no categorycode given' );
69
70
$mtts = C4::Overdues::GetOverdueMessageTransportTypes('CPL');
71
is( $mtts, undef, 'GetOverdueMessageTransportTypes: returns undef if no letternumber and categorycode given' );
72
73
$mtts = C4::Overdues::GetOverdueMessageTransportTypes( 'CPL', 'PT', 1 );
74
is_deeply( $mtts, ['email'], 'GetOverdueMessageTransportTypes: first overdue is by email for PT (CPL)' );
75
76
$mtts = C4::Overdues::GetOverdueMessageTransportTypes( 'CPL', 'PT', 2 );
77
is_deeply( $mtts, ['sms'], 'GetOverdueMessageTransportTypes: second overdue is by sms for PT (CPL)' );
78
79
$mtts = C4::Overdues::GetOverdueMessageTransportTypes( 'CPL', 'PT', 3 );
80
is_deeply( $mtts, ['email'], 'GetOverdueMessageTransportTypes: third overdue is by email for PT (CPL)' );
81
82
$mtts = C4::Overdues::GetOverdueMessageTransportTypes( '', 'PT', 1 );
83
is_deeply( $mtts, ['email'], 'GetOverdueMessageTransportTypes: first overdue is by email for PT (default)' );
84
85
$mtts = C4::Overdues::GetOverdueMessageTransportTypes( '', 'PT', 2 );
86
is_deeply(
87
    $mtts, [ 'email', 'sms' ],
88
    'GetOverdueMessageTransportTypes: second overdue is by email and sms for PT (default)'
89
);
90
91
$mtts = C4::Overdues::GetOverdueMessageTransportTypes( '', 'PT', 3 );
92
is_deeply(
93
    $mtts, [ 'print', 'sms', 'email' ],
94
    'GetOverdueMessageTransportTypes: third overdue is by print, sms and email for PT (default). With print in first.'
95
);
96
26
97
# Test GetBranchcodesWithOverdueRules
27
# Test GetBranchcodesWithOverdueRules
98
$dbh->do(q|DELETE FROM circulation_rules WHERE rule_name LIKE 'overdue_%' |);
28
$dbh->do(q|DELETE FROM circulation_rules WHERE rule_name LIKE 'overdue_%' |);
(-)a/tools/overduerules.pl (-328 lines)
Lines 1-327 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2000-2002 Katipo Communications
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
use Modern::Perl;
21
use CGI qw ( -utf8 );
22
use C4::Context;
23
use C4::Output qw( output_html_with_http_headers );
24
use C4::Auth   qw( get_template_and_user );
25
use C4::Letters;
26
use C4::Members;
27
use C4::Overdues qw( GetOverdueMessageTransportTypes );
28
use Koha::Libraries;
29
30
use Koha::Patron::Categories;
31
32
our $input = CGI->new;
33
my $dbh = C4::Context->dbh;
34
35
my @patron_categories = Koha::Patron::Categories->search( { overduenoticerequired => { '>' => 0 } } )->as_list;
36
my @category_codes    = map { $_->categorycode } @patron_categories;
37
our @rule_params = qw(delay letter debarred);
38
39
# blank_row($category_code) - return true if the entire row is blank.
40
sub blank_row {
41
    my ($category_code) = @_;
42
    for my $rp (@rule_params) {
43
        for my $n ( 1 .. 3 ) {
44
            my $key = "${rp}${n}-$category_code";
45
46
            if ( utf8::is_utf8($key) ) {
47
                utf8::encode($key);
48
            }
49
50
            my $value = $input->param($key);
51
            if ($value) {
52
                return 0;
53
            }
54
        }
55
    }
56
    return 1;
57
}
58
59
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
60
    {
61
        template_name => "tools/overduerules.tt",
62
        query         => $input,
63
        type          => "intranet",
64
        flagsrequired => { tools => 'edit_notice_status_triggers' },
65
    }
66
);
67
68
my $type = $input->param('type');
69
70
my $branch = $input->param('branch');
71
$branch =
72
      defined $branch                                                    ? $branch
73
    : C4::Context->preference('DefaultToLoggedInLibraryOverdueTriggers') ? C4::Context::mybranch()
74
    : Koha::Libraries->search->count() == 1                              ? undef
75
    :                                                                      undef;
76
$branch ||= q{};
77
78
my $op = $input->param('op');
79
$op ||= q{};
80
81
my $err = 0;
82
83
# save the values entered into tables
84
my %temphash;
85
my $input_saved = 0;
86
if ( $op eq 'cud-save' ) {
87
    my @names      = $input->multi_param();
88
    my $sth_search = $dbh->prepare("SELECT count(*) AS total FROM overduerules WHERE branchcode=? AND categorycode=?");
89
90
    my $sth_insert = $dbh->prepare(
91
        "INSERT INTO overduerules (branchcode,categorycode, delay1,letter1,debarred1, delay2,letter2,debarred2, delay3,letter3,debarred3) VALUES (?,?,?,?,?,?,?,?,?,?,?)"
92
    );
93
    my $sth_update = $dbh->prepare(
94
        "UPDATE overduerules SET delay1=?, letter1=?, debarred1=?, delay2=?, letter2=?, debarred2=?, delay3=?, letter3=?, debarred3=? WHERE branchcode=? AND categorycode=?"
95
    );
96
    my $sth_delete     = $dbh->prepare("DELETE FROM overduerules WHERE branchcode=? AND categorycode=?");
97
    my $sth_insert_mtt = $dbh->prepare( "
98
        INSERT INTO overduerules_transport_types(
99
            overduerules_id, letternumber, message_transport_type
100
        ) VALUES (
101
            (SELECT overduerules_id FROM overduerules WHERE branchcode = ? AND categorycode = ?), ?, ?
102
        )
103
    " );
104
    my $sth_delete_mtt = $dbh->prepare( "
105
        DELETE FROM overduerules_transport_types
106
        WHERE overduerules_id = (SELECT overduerules_id FROM overduerules WHERE branchcode = ? AND categorycode = ?)
107
    " );
108
109
    foreach my $key (@names) {
110
111
        # ISSUES
112
        if ( $key =~ /(delay|letter|debarred)([1-3])-(.*)/ ) {
113
            my $type  = $1;                    # data type
114
            my $num   = $2;                    # From 1 to 3
115
            my $bor   = $3;                    # borrower category
116
            my $value = $input->param($key);
117
            if ( $type eq 'delay' ) {
118
                $temphash{$bor}->{"$type$num"} = ( $value =~ /^\d+$/ && int($value) > 0 ) ? int($value) : '';
119
            } else {
120
121
                # type is letter
122
                $temphash{$bor}->{"$type$num"} = $value if $value ne '';
123
            }
124
        }
125
    }
126
127
    # figure out which rows need to be deleted
128
    my @rows_to_delete = grep { blank_row($_) } @category_codes;
129
130
    foreach my $bor ( keys %temphash ) {
131
132
        # get category name if we need it for an error message
133
        my $bor_category      = Koha::Patron::Categories->find($bor);
134
        my $bor_category_name = $bor_category ? $bor_category->description : $bor;
135
136
        # Do some Checking here : delay1 < delay2 <delay3 all of them being numbers
137
        # Raise error if not true
138
        if ( $temphash{$bor}->{delay1} =~ /[^0-9]/ and $temphash{$bor}->{delay1} ne "" ) {
139
            $template->param( "ERROR" => 1, "ERRORDELAY" => "delay1", "BORERR" => $bor_category_name );
140
            $err = 1;
141
        } elsif ( $temphash{$bor}->{delay2} =~ /[^0-9]/ and $temphash{$bor}->{delay2} ne "" ) {
142
            $template->param( "ERROR" => 1, "ERRORDELAY" => "delay2", "BORERR" => $bor_category_name );
143
            $err = 1;
144
        } elsif ( $temphash{$bor}->{delay3} =~ /[^0-9]/ and $temphash{$bor}->{delay3} ne "" ) {
145
            $template->param( "ERROR" => 1, "ERRORDELAY" => "delay3", "BORERR" => $bor_category_name );
146
            $err = 1;
147
        } elsif ( $temphash{$bor}->{delay1} and not( $temphash{$bor}->{"letter1"} or $temphash{$bor}->{"debarred1"} ) )
148
        {
149
            $template->param( "ERROR" => 1, "ERRORUSELESSDELAY" => "delay1", "BORERR" => $bor_category_name );
150
            $err = 1;
151
        } elsif ( $temphash{$bor}->{delay2} and not( $temphash{$bor}->{"letter2"} or $temphash{$bor}->{"debarred2"} ) )
152
        {
153
            $template->param( "ERROR" => 1, "ERRORUSELESSDELAY" => "delay2", "BORERR" => $bor_category_name );
154
            $err = 1;
155
        } elsif ( $temphash{$bor}->{delay3} and not( $temphash{$bor}->{"letter3"} or $temphash{$bor}->{"debarred3"} ) )
156
        {
157
            $template->param( "ERROR" => 1, "ERRORUSELESSDELAY" => "delay3", "BORERR" => $bor_category_name );
158
            $err = 1;
159
        } elsif (
160
            $temphash{$bor}->{delay3} and ( $temphash{$bor}->{delay3} <= $temphash{$bor}->{delay2}
161
                or $temphash{$bor}->{delay3} <= $temphash{$bor}->{delay1} )
162
            or $temphash{$bor}->{delay2} and ( $temphash{$bor}->{delay2} <= $temphash{$bor}->{delay1} )
163
            )
164
        {
165
            $template->param( "ERROR" => 1, "ERRORORDER" => 1, "BORERR" => $bor_category_name );
166
            $err = 1;
167
        }
168
        unless ($err) {
169
            if (   ( $temphash{$bor}->{delay1} and ( $temphash{$bor}->{"letter1"} or $temphash{$bor}->{"debarred1"} ) )
170
                or ( $temphash{$bor}->{delay2} and ( $temphash{$bor}->{"letter2"} or $temphash{$bor}->{"debarred2"} ) )
171
                or ( $temphash{$bor}->{delay3} and ( $temphash{$bor}->{"letter3"} or $temphash{$bor}->{"debarred3"} ) )
172
                )
173
            {
174
                $sth_search->execute( $branch, $bor );
175
                my $res = $sth_search->fetchrow_hashref();
176
                if ( $res->{'total'} > 0 ) {
177
                    $sth_update->execute(
178
                        ( $temphash{$bor}->{"delay1"}    ? $temphash{$bor}->{"delay1"}    : undef ),
179
                        ( $temphash{$bor}->{"letter1"}   ? $temphash{$bor}->{"letter1"}   : "" ),
180
                        ( $temphash{$bor}->{"debarred1"} ? $temphash{$bor}->{"debarred1"} : 0 ),
181
                        ( $temphash{$bor}->{"delay2"}    ? $temphash{$bor}->{"delay2"}    : undef ),
182
                        ( $temphash{$bor}->{"letter2"}   ? $temphash{$bor}->{"letter2"}   : "" ),
183
                        ( $temphash{$bor}->{"debarred2"} ? $temphash{$bor}->{"debarred2"} : 0 ),
184
                        ( $temphash{$bor}->{"delay3"}    ? $temphash{$bor}->{"delay3"}    : undef ),
185
                        ( $temphash{$bor}->{"letter3"}   ? $temphash{$bor}->{"letter3"}   : "" ),
186
                        ( $temphash{$bor}->{"debarred3"} ? $temphash{$bor}->{"debarred3"} : 0 ),
187
                        $branch, $bor
188
                    );
189
                } else {
190
                    $sth_insert->execute(
191
                        $branch, $bor,
192
                        ( $temphash{$bor}->{"delay1"}    ? $temphash{$bor}->{"delay1"}    : 0 ),
193
                        ( $temphash{$bor}->{"letter1"}   ? $temphash{$bor}->{"letter1"}   : "" ),
194
                        ( $temphash{$bor}->{"debarred1"} ? $temphash{$bor}->{"debarred1"} : 0 ),
195
                        ( $temphash{$bor}->{"delay2"}    ? $temphash{$bor}->{"delay2"}    : 0 ),
196
                        ( $temphash{$bor}->{"letter2"}   ? $temphash{$bor}->{"letter2"}   : "" ),
197
                        ( $temphash{$bor}->{"debarred2"} ? $temphash{$bor}->{"debarred2"} : 0 ),
198
                        ( $temphash{$bor}->{"delay3"}    ? $temphash{$bor}->{"delay3"}    : 0 ),
199
                        ( $temphash{$bor}->{"letter3"}   ? $temphash{$bor}->{"letter3"}   : "" ),
200
                        ( $temphash{$bor}->{"debarred3"} ? $temphash{$bor}->{"debarred3"} : 0 )
201
                    );
202
                }
203
204
                $sth_delete_mtt->execute( $branch, $bor );
205
                for my $letternumber ( 1 .. 3 ) {
206
                    my @mtt = $input->multi_param("mtt${letternumber}-$bor");
207
                    next unless @mtt;
208
                    for my $mtt (@mtt) {
209
                        $sth_insert_mtt->execute( $branch, $bor, $letternumber, $mtt );
210
                    }
211
                }
212
            }
213
        }
214
    }
215
    unless ($err) {
216
        for my $category_code (@rows_to_delete) {
217
            $sth_delete->execute( $branch, $category_code );
218
        }
219
        $template->param( datasaved => 1 );
220
        $input_saved = 1;
221
    }
222
}
223
224
my $letters = C4::Letters::GetLettersAvailableForALibrary(
225
    {
226
        branchcode => $branch,
227
        module     => "circulation",
228
    }
229
);
230
231
my $message_transport_types = C4::Letters::GetMessageTransportTypes();
232
my ( @first, @second, @third );
233
for my $patron_category (@patron_categories) {
234
    if ( %temphash and not $input_saved ) {
235
236
        # if we managed to save the form submission, don't
237
        # reuse %temphash, but take the values from the
238
        # database - this makes it easier to identify
239
        # bugs where the form submission was not correctly saved
240
        for my $i ( 1 .. 3 ) {
241
            my %row = (
242
                overduename => $patron_category->categorycode,
243
                line        => $patron_category->description,
244
            );
245
            $row{delay}               = $temphash{ $patron_category->categorycode }->{"delay$i"};
246
            $row{debarred}            = $temphash{ $patron_category->categorycode }->{"debarred$i"};
247
            $row{selected_lettercode} = $temphash{ $patron_category->categorycode }->{"letter$i"};
248
            my @selected_mtts = @{ GetOverdueMessageTransportTypes( $branch, $patron_category->categorycode, $i ) };
249
            my @mtts;
250
            for my $mtt (@$message_transport_types) {
251
                push @mtts, {
252
                    value    => $mtt,
253
                    selected => ( grep { /$mtt/ } @selected_mtts ) ? 1 : 0,
254
                };
255
            }
256
            $row{message_transport_types} = \@mtts;
257
            if ( $i == 1 ) {
258
                push @first, \%row;
259
            } elsif ( $i == 2 ) {
260
                push @second, \%row;
261
            } else {
262
                push @third, \%row;
263
            }
264
        }
265
    } else {
266
267
        #getting values from table
268
        my $sth2 = $dbh->prepare("SELECT * from overduerules WHERE branchcode=? AND categorycode=?");
269
        $sth2->execute( $branch, $patron_category->categorycode );
270
        my $dat = $sth2->fetchrow_hashref;
271
        for my $i ( 1 .. 3 ) {
272
            my %row = (
273
                overduename => $patron_category->categorycode,
274
                line        => $patron_category->description,
275
            );
276
277
            $row{selected_lettercode} = $dat->{"letter$i"};
278
279
            if ( $dat->{"delay$i"} )    { $row{delay}    = $dat->{"delay$i"}; }
280
            if ( $dat->{"debarred$i"} ) { $row{debarred} = $dat->{"debarred$i"}; }
281
            my @selected_mtts = @{ GetOverdueMessageTransportTypes( $branch, $patron_category->categorycode, $i ) };
282
            my @mtts;
283
            for my $mtt (@$message_transport_types) {
284
                push @mtts, {
285
                    value    => $mtt,
286
                    selected => ( grep { /$mtt/ } @selected_mtts ) ? 1 : 0,
287
                };
288
            }
289
            $row{message_transport_types} = \@mtts;
290
            if ( $i == 1 ) {
291
                push @first, \%row;
292
            } elsif ( $i == 2 ) {
293
                push @second, \%row;
294
            } else {
295
                push @third, \%row;
296
            }
297
298
        }
299
    }
300
}
301
302
my @tabs = (
303
    {
304
        id     => 'first',
305
        number => 1,
306
        values => \@first,
307
    },
308
    {
309
        id     => 'second',
310
        number => 2,
311
        values => \@second,
312
    },
313
    {
314
        id     => 'third',
315
        number => 3,
316
        values => \@third,
317
    },
318
);
319
320
$template->param(
321
    table                   => ( @first or @second or @third ? 1 : 0 ),
322
    branch                  => $branch,
323
    tabs                    => \@tabs,
324
    message_transport_types => $message_transport_types,
325
    letters                 => $letters,
326
);
327
output_html_with_http_headers $input, $cookie, $template->output;
328
- 

Return to bug 10190