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

(-)a/circ/pendingreserves.pl (-2 / +91 lines)
Lines 25-40 use C4::Context; Link Here
25
use C4::Output;
25
use C4::Output;
26
use CGI qw ( -utf8 );
26
use CGI qw ( -utf8 );
27
use C4::Auth;
27
use C4::Auth;
28
use Koha::Biblios;
29
use C4::Debug;
28
use C4::Debug;
29
use C4::Items qw( ModItem ModItemTransfer );
30
use C4::Reserves qw( ModReserveCancelAll );
31
use Koha::Biblios;
30
use Koha::DateUtils;
32
use Koha::DateUtils;
33
use Koha::Holds;
31
use DateTime::Duration;
34
use DateTime::Duration;
32
35
33
my $input = new CGI;
36
my $input = new CGI;
34
my $startdate = $input->param('from');
37
my $startdate = $input->param('from');
35
my $enddate = $input->param('to');
38
my $enddate = $input->param('to');
36
37
my $theme = $input->param('theme');    # only used if allowthemeoverride is set
39
my $theme = $input->param('theme');    # only used if allowthemeoverride is set
40
my $op         = $input->param('op') || '';
41
my $borrowernumber = $input->param('borrowernumber');
42
my $reserve_id = $input->param('reserve_id');
38
43
39
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
44
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
40
    {
45
    {
Lines 47-52 my ( $template, $loggedinuser, $cookie ) = get_template_and_user( Link Here
47
    }
52
    }
48
);
53
);
49
54
55
my @messages;
56
if ( $op eq 'cancel_reserve' and $reserve_id ) {
57
    my $hold = Koha::Holds->find( $reserve_id );
58
    if ( $hold ) {
59
        $hold->cancel;
60
        push @messages, { type => 'message', code => 'hold_cancelled' };
61
    }
62
} elsif ( $op =~ m|^mark_as_lost| ) {
63
    my $hold = Koha::Holds->find( $reserve_id );
64
    die "wrong reserve_id" unless $hold; # This is a bit rude, but we are not supposed to get a wrong reserve_id
65
    my $item = $hold->item;
66
    if ( $item and C4::Context->preference('CanMarkHoldsToPullAsLost') =~ m|^allow| ) {
67
        my $patron = $hold->borrower;
68
        C4::Circulation::LostItem( $item->itemnumber );
69
        if ( $op eq 'mark_as_lost_and_notify' and C4::Context->preference('CanMarkHoldsToPullAsLost') eq 'allow_and_notify' ) {
70
            my $library = $hold->branch;
71
            my $letter = C4::Letters::GetPreparedLetter(
72
                module => 'reserves',
73
                letter_code => 'CANCEL_HOLD_ON_LOST',
74
                branchcode => $library->branchcode, # FIXME Is it what we want?
75
                lang => $patron->lang,
76
                tables => {
77
                    branches    => $library->branchcode,
78
                    borrowers   => $patron->borrowernumber,
79
                    items       => $item->itemnumber,
80
                    biblio      => $hold->biblionumber,
81
                    biblioitems => $hold->biblionumber,
82
                    reserves    => $hold->unblessed,
83
                },
84
            );
85
            if ( $letter ) {
86
                my $admin_email_address = $library->branchemail || C4::Context->preference('KohaAdminEmailAddress');
87
88
                C4::Letters::EnqueueLetter(
89
                    {   letter                 => $letter,
90
                        borrowernumber         => $patron->borrowernumber,
91
                        message_transport_type => 'email',
92
                        from_address           => $admin_email_address,
93
                    }
94
                );
95
                unless ( C4::Members::GetNoticeEmailAddress( $patron->borrowernumber ) ) {
96
                    push @messages, {type => 'alert', code => 'no_email_address', };
97
                }
98
                push @messages, { type => 'message', code => 'letter_enqueued' };
99
            } else {
100
                push @messages, { type => 'error', code => 'no_template_notice' };
101
            }
102
        }
103
        $hold->cancel;
104
        if ( $item->homebranch ne $item->holdingbranch ) {
105
            C4::Items::ModItemTransfer( $item->itemnumber, $item->holdingbranch, $item->homebranch );
106
        }
107
108
        if ( my $yaml = C4::Context->preference('UpdateItemWhenLostFromHoldList') ) {
109
            $yaml = "$yaml\n\n";  # YAML is anal on ending \n. Surplus does not hurt
110
            my $assignments;
111
            eval { $assignments = YAML::Load($yaml); };
112
            if ($@) {
113
                warn "Unable to parse UpdateItemWhenLostFromHoldList syspref : $@" if $@;
114
            }
115
            else {
116
                eval {
117
                    C4::Items::ModItem( $assignments, undef, $item->itemnumber );
118
                };
119
                warn "Unable to modify item itemnumber=" . $item->itemnumber . ": $@" if $@;
120
            }
121
        }
122
123
    } elsif ( not $item ) {
124
        push @messages, { type => 'alert', code => 'hold_placed_at_biblio_level'};
125
    } # else the url parameters have been modified and the user is not allowed to continue
126
}
127
128
50
my $today = dt_from_string;
129
my $today = dt_from_string;
51
130
52
if ( $startdate ) {
131
if ( $startdate ) {
Lines 91-101 if ($enddate_iso) { Link Here
91
170
92
my $strsth =
171
my $strsth =
93
    "SELECT min(reservedate) as l_reservedate,
172
    "SELECT min(reservedate) as l_reservedate,
173
            reserves.reserve_id,
94
            reserves.borrowernumber as borrowernumber,
174
            reserves.borrowernumber as borrowernumber,
175
95
            GROUP_CONCAT(DISTINCT items.holdingbranch 
176
            GROUP_CONCAT(DISTINCT items.holdingbranch 
96
                    ORDER BY items.itemnumber SEPARATOR '|') l_holdingbranch,
177
                    ORDER BY items.itemnumber SEPARATOR '|') l_holdingbranch,
97
            reserves.biblionumber,
178
            reserves.biblionumber,
98
            reserves.branchcode as l_branch,
179
            reserves.branchcode as l_branch,
180
            items.itemnumber,
181
            items.holdingbranch,
182
            items.homebranch,
99
            GROUP_CONCAT(DISTINCT items.itype 
183
            GROUP_CONCAT(DISTINCT items.itype 
100
                    ORDER BY items.itemnumber SEPARATOR '|') l_itype,
184
                    ORDER BY items.itemnumber SEPARATOR '|') l_itype,
101
            GROUP_CONCAT(DISTINCT items.location 
185
            GROUP_CONCAT(DISTINCT items.location 
Lines 167-172 while ( my $data = $sth->fetchrow_hashref ) { Link Here
167
            pullcount       => $data->{icount} <= $data->{rcount} ? $data->{icount} : $data->{rcount},
251
            pullcount       => $data->{icount} <= $data->{rcount} ? $data->{icount} : $data->{rcount},
168
            itypes          => [split('\|', $data->{l_itype})],
252
            itypes          => [split('\|', $data->{l_itype})],
169
            locations       => [split('\|', $data->{l_location})],
253
            locations       => [split('\|', $data->{l_location})],
254
            reserve_id      => $data->{reserve_id},
255
            holdingbranch   => $data->{holdingbranch},
256
            homebranch      => $data->{homebranch},
257
            itemnumber      => $data->{itemnumber},
170
        }
258
        }
171
    );
259
    );
172
}
260
}
Lines 180-185 $template->param( Link Here
180
    "BiblioDefaultView".C4::Context->preference("BiblioDefaultView") => 1,
268
    "BiblioDefaultView".C4::Context->preference("BiblioDefaultView") => 1,
181
    HoldsToPullStartDate => C4::Context->preference('HoldsToPullStartDate') || PULL_INTERVAL,
269
    HoldsToPullStartDate => C4::Context->preference('HoldsToPullStartDate') || PULL_INTERVAL,
182
    HoldsToPullEndDate  => C4::Context->preference('ConfirmFutureHolds') || 0,
270
    HoldsToPullEndDate  => C4::Context->preference('ConfirmFutureHolds') || 0,
271
    messages            => \@messages,
183
);
272
);
184
273
185
output_html_with_http_headers $input, $cookie, $template->output;
274
output_html_with_http_headers $input, $cookie, $template->output;
(-)a/installer/data/mysql/atomicupdate/bug_19287.sql (+5 lines)
Line 0 Link Here
1
INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES ('CanMarkHoldsToPullAsLost','do_not_allow','do_not_allow|allow|allow_and_notify','Add a button to the "Holds to pull" screen to mark an item as lost and notify the patron.','Choice');
2
3
INSERT IGNORE INTO letter(module, code, branchcode, name, is_html, title, content, message_transport_type, lang) VALUES ('reserves', 'CANCEL_HOLD_ON_LOST', '', 'Hold has been cancelled', 0, "Hold has been cancelled", "Dear [% borrower.firstname %] [% borrower.surname %],\n\nWe regret to inform you that the following item cannot longer be placed on hold, it has been marked as lost\n\nTitle: [% biblio.title %]\nAuthor: [% biblio.author %]\nCopy: [% item.copynumber %]\nLocation: [% branch.branchname %]", 'email', 'default');
4
5
INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES ('UpdateItemWhenLostFromHoldList','',NULL,'This is a list of values to update an item when it is marked as lost from the holds to pull screen','Free');
(-)a/installer/data/mysql/sysprefs.sql (+2 lines)
Lines 93-98 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
93
('BranchTransferLimitsType','ccode','itemtype|ccode','When using branch transfer limits, choose whether to limit by itemtype or collection code.','Choice'),
93
('BranchTransferLimitsType','ccode','itemtype|ccode','When using branch transfer limits, choose whether to limit by itemtype or collection code.','Choice'),
94
('CalculateFinesOnReturn','1','','Switch to control if overdue fines are calculated on return or not','YesNo'),
94
('CalculateFinesOnReturn','1','','Switch to control if overdue fines are calculated on return or not','YesNo'),
95
('CalendarFirstDayOfWeek','0','0|1|2|3|4|5|6','Select the first day of week to use in the calendar.','Choice'),
95
('CalendarFirstDayOfWeek','0','0|1|2|3|4|5|6','Select the first day of week to use in the calendar.','Choice'),
96
('CanMarkHoldsToPullAsLost','do_not_allow','do_not_allow|allow|allow_and_notify','Add a button to the "Holds to pull" screen to mark an item as lost and notify the patron.','Choice'),
96
('canreservefromotherbranches','1','','With Independent branches on, can a user from one library place a hold on an item from another library','YesNo'),
97
('canreservefromotherbranches','1','','With Independent branches on, can a user from one library place a hold on an item from another library','YesNo'),
97
('CardnumberLength', '', '', 'Set a length for card numbers with a maximum of 32 characters.', 'Free'),
98
('CardnumberLength', '', '', 'Set a length for card numbers with a maximum of 32 characters.', 'Free'),
98
('casAuthentication','0','','Enable or disable CAS authentication','YesNo'),
99
('casAuthentication','0','','Enable or disable CAS authentication','YesNo'),
Lines 558-563 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
558
('UNIMARCAuthorityField100','afrey50      ba0',NULL,'Define the contents of UNIMARC authority control field 100 position 08-35','Textarea'),
559
('UNIMARCAuthorityField100','afrey50      ba0',NULL,'Define the contents of UNIMARC authority control field 100 position 08-35','Textarea'),
559
('UNIMARCAuthorsFacetsSeparator',', ',NULL,'UNIMARC authors facets separator','short'),
560
('UNIMARCAuthorsFacetsSeparator',', ',NULL,'UNIMARC authors facets separator','short'),
560
('UNIMARCField100Language','fre',NULL,'UNIMARC field 100 default language','short'),
561
('UNIMARCField100Language','fre',NULL,'UNIMARC field 100 default language','short'),
562
('UpdateItemWhenLostFromHoldList','',NULL,'This is a list of values to update an item when it is marked as lost from the holds to pull screen','Free'),
561
('UniqueItemFields','barcode','','Space-separated list of fields that should be unique (used in acquisition module for item creation). Fields must be valid SQL column names of items table','Free'),
563
('UniqueItemFields','barcode','','Space-separated list of fields that should be unique (used in acquisition module for item creation). Fields must be valid SQL column names of items table','Free'),
562
('UpdateNotForLoanStatusOnCheckin', '', 'NULL', 'This is a list of value pairs. When an item is checked in, if the not for loan value on the left matches the items not for loan value it will be updated to the right-hand value. E.g. ''-1: 0'' will cause an item that was set to ''Ordered'' to now be available for loan. Each pair of values should be on a separate line.', 'Free'),
564
('UpdateNotForLoanStatusOnCheckin', '', 'NULL', 'This is a list of value pairs. When an item is checked in, if the not for loan value on the left matches the items not for loan value it will be updated to the right-hand value. E.g. ''-1: 0'' will cause an item that was set to ''Ordered'' to now be available for loan. Each pair of values should be on a separate line.', 'Free'),
563
('UpdateTotalIssuesOnCirc','0',NULL,'Whether to update the totalissues field in the biblio on each circ.','YesNo'),
565
('UpdateTotalIssuesOnCirc','0',NULL,'Whether to update the totalissues field in the biblio on each circ.','YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (+12 lines)
Lines 702-707 Circulation: Link Here
702
            - "Patron categories not affected by OPACHoldsIfAvailableAtPickup"
702
            - "Patron categories not affected by OPACHoldsIfAvailableAtPickup"
703
            - pref: OPACHoldsIfAvailableAtPickupExceptions
703
            - pref: OPACHoldsIfAvailableAtPickupExceptions
704
            - "(list of patron categories separated with a pipe '|')"
704
            - "(list of patron categories separated with a pipe '|')"
705
        -
706
            - pref: CanMarkHoldsToPullAsLost
707
              choices:
708
                  do_not_allow: "Do not allow to mark items as lost"
709
                  allow: "Allow to mark items as lost"
710
                  allow_and_notify: "Allow to mark items as lost and notify the patron"
711
            - "from the 'Holds to pull' screen"
712
        -
713
            - Update item's values when marked as lost from the hold to pull screen
714
            - pref: UpdateItemWhenLostFromHoldList
715
              type: textarea
716
            - This is a list of values to update an item when it is marked as lost from the holds to pull screen.
705
    Interlibrary Loans:
717
    Interlibrary Loans:
706
        -
718
        -
707
            - pref: ILLModule
719
            - pref: ILLModule
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingreserves.tt (-1 / +44 lines)
Lines 1-3 Link Here
1
[% USE Koha %]
1
[% USE KohaDates %]
2
[% USE KohaDates %]
2
[% USE ColumnsSettings %]
3
[% USE ColumnsSettings %]
3
[% USE AuthorisedValues %]
4
[% USE AuthorisedValues %]
Lines 22-27 Link Here
22
   <div id="bd">
23
   <div id="bd">
23
    <div id="yui-main">
24
    <div id="yui-main">
24
    <div class="yui-b">
25
    <div class="yui-b">
26
        [% FOR m IN messages %]
27
            <div class="dialog [% m.type %]">
28
                [% SWITCH m.code %]
29
                [% CASE 'letter_enqueued' %]
30
                    <span>The notice has been correctly enqueued.</span>
31
                [% CASE 'no_email_address' %]
32
                    <span>The patron does not have an email address defined.</span>
33
                [% CASE 'no_template_notice' %]
34
                    <span>There is no notice template with a code 'CANCEL_HOLD_ON_LOST' defined in your system.</span>
35
                [% CASE 'hold_cancelled' %]
36
                    <span>The hold has been correctly cancelled.</span>
37
                [% CASE 'hold_placed_at_biblio_level' %]
38
                    <span>The hold has been placed at biblio level. It is not possible to mark it as lost.</span>
39
                [% CASE %]
40
                    [% m.code %]
41
                [% END %]
42
            </div>
43
        [% END %]
25
44
26
<h2>Holds to pull placed between [% from | $KohaDates %] and [% to | $KohaDates %]</h2>
45
<h2>Holds to pull placed between [% from | $KohaDates %] and [% to | $KohaDates %]</h2>
27
<h3>Reported on [% todaysdate | $KohaDates %]</h3>
46
<h3>Reported on [% todaysdate | $KohaDates %]</h3>
Lines 43-48 Link Here
43
        <th class="string-sort">Available itypes</th>
62
        <th class="string-sort">Available itypes</th>
44
        <th class="string-sort">Available locations</th>
63
        <th class="string-sort">Available locations</th>
45
        <th class="title-string">Earliest hold date</th>
64
        <th class="title-string">Earliest hold date</th>
65
        <th>Action</th>
46
        </tr>
66
        </tr>
47
    </thead>
67
    </thead>
48
    <tbody>
68
    <tbody>
Lines 87-92 Link Here
87
        <td>
107
        <td>
88
            <span title="[% reserveloo.reservedate %]">[% reserveloo.reservedate | $KohaDates %] in [% Branches.GetName ( reserveloo.branch ) %]</span>
108
            <span title="[% reserveloo.reservedate %]">[% reserveloo.reservedate | $KohaDates %] in [% Branches.GetName ( reserveloo.branch ) %]</span>
89
        </td>
109
        </td>
110
        <td>
111
            <form name="cancelReserve" action="/cgi-bin/koha/circ/pendingreserves.pl" method="post">
112
                <input type="hidden" name="op" value="cancel_reserve" />
113
                <input type="hidden" name="reserve_id" value="[% reserveloo.reserve_id %]" />
114
                [% IF reserveloo.holdingbranch != reserveloo.homebranch %]
115
                    <input type="submit" value="Cancel hold and return to : [% Branches.GetName( reserveloo.homebranch ) %]" />
116
                [% ELSE %]
117
                    <input type="submit" value="Cancel hold" />
118
                [% END %]
119
            </form>
120
121
        [% IF Koha.Preference('CanMarkHoldsToPullAsLost') != 'do_not_allow' %]
122
            <form name="cancelReserve" action="/cgi-bin/koha/circ/pendingreserves.pl" method="post">
123
                <input type="hidden" name="reserve_id" value="[% reserveloo.reserve_id %]" />
124
                [% IF Koha.Preference('CanMarkHoldsToPullAsLost') == 'allow' %]
125
                    <input type="hidden" name="op" value="mark_as_lost" />
126
                    <input type="submit" value="Mark item as lost" />
127
                [% ELSIF Koha.Preference('CanMarkHoldsToPullAsLost') == 'allow_and_notify' %]
128
                    <input type="hidden" name="op" value="mark_as_lost_and_notify" />
129
                    <input type="submit" value="Mark item as lost and notify the patron" />
130
                [% END %]
131
            </form>
132
        [% END %]
90
        </tr>
133
        </tr>
91
        [% END %]
134
        [% END %]
92
    </tbody>
135
    </tbody>
Lines 104-109 Link Here
104
        <td id="itypefilter"></td>
147
        <td id="itypefilter"></td>
105
        <td id="locationfilter"></td>
148
        <td id="locationfilter"></td>
106
        <td></td>
149
        <td></td>
150
        <td></td>
107
        </tr>
151
        </tr>
108
    </tfoot>
152
    </tfoot>
109
    </table>
153
    </table>
110
- 

Return to bug 19287