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

Return to bug 10190