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

(-)a/Koha/CurbsidePickupOpeningSlot.pm (+44 lines)
Line 0 Link Here
1
package Koha::CurbsidePickupOpeningSlot;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
6
# terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 3 of the License, or (at your option) any later
8
# version.
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License along
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18
use Modern::Perl;
19
20
use Carp;
21
22
use Koha::Database;
23
24
use base qw(Koha::Object);
25
26
=head1 NAME
27
28
CurbsidePickupOpeningSlot - Koha Curbside Pickup Slot Object class
29
30
=head1 API
31
32
=head2 Class methods
33
34
=head2 Internal methods
35
36
=head3 _type
37
38
=cut
39
40
sub _type {
41
    return 'CurbsidePickupOpeningSlot';
42
}
43
44
1;
(-)a/Koha/CurbsidePickupOpeningSlots.pm (+50 lines)
Line 0 Link Here
1
package Koha::CurbsidePickupOpeningSlots;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
6
# terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 3 of the License, or (at your option) any later
8
# version.
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License along
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18
use Modern::Perl;
19
20
use Carp;
21
22
use Koha::Database;
23
24
use Koha::CurbsidePickupOpeningSlot;
25
26
use base qw(Koha::Objects);
27
28
=head1 NAME
29
30
Koha::CurbsidePickupOpeningSlots - Koha Curbside Pickup Opening Slots Object set class
31
32
=head1 API
33
34
=head2 Class Methods
35
36
=cut
37
38
=head3 type
39
40
=cut
41
42
sub _type {
43
    return 'CurbsidePickupOpeningSlot';
44
}
45
46
sub object_class {
47
    return 'Koha::CurbsidePickupOpeningSlot';
48
}
49
50
1;
(-)a/Koha/CurbsidePickupPolicy.pm (+28 lines)
Lines 20-25 use Modern::Perl; Link Here
20
use Carp;
20
use Carp;
21
21
22
use Koha::Database;
22
use Koha::Database;
23
use Koha::Library;
24
use Koha::CurbsidePickupOpeningSlots;
23
25
24
use base qw(Koha::Object);
26
use base qw(Koha::Object);
25
27
Lines 44-49 sub library { Link Here
44
    return Koha::Library->_new_from_dbic( $rs );
46
    return Koha::Library->_new_from_dbic( $rs );
45
}
47
}
46
48
49
sub opening_slots {
50
    my ( $self ) = @_;
51
    my $rs = $self->_result->curbside_pickup_opening_slots;
52
    return unless $rs;
53
    return Koha::CurbsidePickupOpeningSlots->_new_from_dbic( $rs );
54
}
55
56
sub add_opening_slot {
57
    my ( $self, $slot ) = @_;
58
59
    my ( $day, $start, $end ) = split '-', $slot;
60
    my ( $start_hour, $start_minute ) = split ':', $start;
61
    my ( $end_hour,   $end_minute )   = split ':', $end;
62
63
    return Koha::CurbsidePickupOpeningSlot->new(
64
        {
65
            curbside_pickup_policy_id => $self->id,
66
            day                       => $day,
67
            start_hour                => $start_hour,
68
            start_minute              => $start_minute,
69
            end_hour                  => $end_hour,
70
            end_minute                => $end_minute,
71
        }
72
    )->store;
73
}
74
47
=head2 Internal methods
75
=head2 Internal methods
48
76
49
=head3 _type
77
=head3 _type
(-)a/admin/curbside_pickup.pl (-21 / +7 lines)
Lines 43-49 if ( $op eq 'save' ) { Link Here
43
        my $branchcode = $library->branchcode;
43
        my $branchcode = $library->branchcode;
44
44
45
        my $params = {
45
        my $params = {
46
47
            branchcode      => $branchcode,
46
            branchcode      => $branchcode,
48
            enabled         => scalar $input->param("enable-$branchcode") || 0,
47
            enabled         => scalar $input->param("enable-$branchcode") || 0,
49
            pickup_interval => scalar $input->param("interval-$branchcode"),
48
            pickup_interval => scalar $input->param("interval-$branchcode"),
Lines 51-78 if ( $op eq 'save' ) { Link Here
51
            patron_scheduled_pickup => scalar $input->param("patron-scheduled-$branchcode") || 0,
50
            patron_scheduled_pickup => scalar $input->param("patron-scheduled-$branchcode") || 0,
52
        };
51
        };
53
52
54
        for my $day (
53
        my $policy =
55
            qw( sunday monday tuesday wednesday thursday friday saturday ))
54
          Koha::CurbsidePickupPolicies->find_or_create( { branchcode => $branchcode } );
56
        {
55
        $policy->update($params);
57
            for my $start_end (qw( start end )) {
58
                for my $hour_min (qw( hour minute )) {
59
60
                    my $value = $input->param(
61
                        "pickup-$start_end-$hour_min-$day-$branchcode");
62
                    $value = undef if $value eq q{};
63
64
                    my $key = $day . '_' . $start_end . '_' . $hour_min;
65
56
66
                    $params->{$key} = $value;
57
        $policy->opening_slots->delete;
67
                }
58
        my @pickup_slots = $input->multi_param("pickup-slot-" . $branchcode);
68
            }
59
        for my $pickup_slot ( @pickup_slots ) {
60
            $policy->add_opening_slot($pickup_slot);
69
        }
61
        }
70
71
        my $CurbsidePickupPolicy =
72
          Koha::CurbsidePickupPolicies->find( { branchcode => $branchcode } );
73
        $CurbsidePickupPolicy->delete if $CurbsidePickupPolicy;
74
75
        Koha::CurbsidePickupPolicy->new($params)->store();
76
    }
62
    }
77
    $op = 'list';
63
    $op = 'list';
78
}
64
}
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/curbside_pickup.tt (-58 / +41 lines)
Lines 9-16 Link Here
9
[% INCLUDE 'doc-head-close.inc' %]
9
[% INCLUDE 'doc-head-close.inc' %]
10
<style>
10
<style>
11
    .pickup-slot {
11
    .pickup-slot {
12
        border: solid;
12
        border: 2px solid #b9d8d9;
13
        padding: 1em;
13
        padding: 0 .1em;
14
        margin: 0 .1em;
14
    }
15
    }
15
</style>
16
</style>
16
</head>
17
</head>
Lines 117-147 Link Here
117
                        <fieldset class="rows" style="float: none;">
118
                        <fieldset class="rows" style="float: none;">
118
                            <legend>Curbside pickup hours</legend>
119
                            <legend>Curbside pickup hours</legend>
119
120
120
                            <em>Times should be in 24-hour format ( 00:00 to 23:59 ).</em>
121
                            <em>Times should be in 24-hour format (00:00 to 23:59).</em>
121
122
122
                            <ol class="pickup_hours">
123
                            <ol class="pickup_hours"></ol>
123
                                [% BLOCK pickup_hours_day %]
124
                                    [% SET day_start_hour = d _ '_start_hour' %]
125
                                    [% SET day_start_minute = d _ '_start_minute' %]
126
                                    [% SET day_end_hour = d _ '_end_hour' %]
127
                                    [% SET day_end_minute = d _ '_end_minute' %]
128
                                    [% SET p = policies.$branchcode %]
129
                                    [% IF p.$day_start_hour && p.$day_start_minute && p.$day_end_hour && p.$day_end_minute %]
130
                                        <li>
131
                                            <span class="slot">
132
                                                <input type="hidden" class="pickup-slot" name="pickup-slot-[% l.branchcode | html %]" value="[% d | html %]-[% p.$day_start_hour %]:[% p.$day_start_minute %]-[% p.$day_end_hour %]:[% p.$day_end_minute %]" />
133
                                            </span>
134
                                        </li>
135
                                    [% END %]
136
                                [% END %]
137
                                [% PROCESS pickup_hours_day d => 'sunday' %]
138
                                [% PROCESS pickup_hours_day d => 'monday' %]
139
                                [% PROCESS pickup_hours_day d => 'tuesday' %]
140
                                [% PROCESS pickup_hours_day d => 'wednesday' %]
141
                                [% PROCESS pickup_hours_day d => 'thursday' %]
142
                                [% PROCESS pickup_hours_day d => 'friday' %]
143
                                [% PROCESS pickup_hours_day d => 'saturday' %]
144
                            </ol>
145
124
146
                            <ol>
125
                            <ol>
147
                                <li>
126
                                <li>
Lines 161-166 Link Here
161
                                            </span>
140
                                            </span>
162
                                        </select>
141
                                        </select>
163
                                        <input type="button" class="add-new-slot" data-branchcode="[% l.branchcode | html %]" value="Add" />
142
                                        <input type="button" class="add-new-slot" data-branchcode="[% l.branchcode | html %]" value="Add" />
143
                                        <span id="invalid_slot_warning" style="display:none;">Invalid format for this new slot, must be '00:00 to 23:59'.</span>
164
                                    </div>
144
                                    </div>
165
                                </li>
145
                                </li>
166
146
Lines 210-241 Link Here
210
            return String(hh).padStart(2, '0') + ':' + String(mm).padStart(2, '0');
190
            return String(hh).padStart(2, '0') + ':' + String(mm).padStart(2, '0');
211
        }
191
        }
212
        function format_slot(slot){
192
        function format_slot(slot){
213
            let start = slot[0];
193
            let day, start, end;
214
            let end = slot[1];
194
            [ day, start, end ] = slot.split("-");
215
            return format_hhmm(start) + _(" to ") + format_hhmm(end);
195
            return format_hhmm(start) + _(" to ") + format_hhmm(end);
216
        }
196
        }
197
        function delete_slot(node, branchcode){
198
            let slot = $(node).find('.pickup-slot').val();
199
            let splitted  = slot.split("-");
200
            let day = splitted[0];
201
            let start = splitted[1];
202
            let end = splitted[2];
203
            opening_slots[branchcode].splice($.inArray(start+'-'+end, opening_slots), 1);
204
            refresh_pickup_hours(branchcode);
205
        }
217
        function refresh_pickup_hours(branchcode) {
206
        function refresh_pickup_hours(branchcode) {
218
            let slots = {};
207
            let slots_per_day = {};
219
            $("#conf-"+branchcode).find("input.pickup-slot").each(function(){
208
            opening_slots[branchcode].forEach(function(slot){
220
                let splitted  = $(this).val().split("-");
209
                let day, start, end;
221
                let day = splitted[0];
210
                [ day, start, end ] = slot.split("-");
222
                let start = splitted[1];
211
                if(!slots_per_day[day]) slots_per_day[day] = [];
223
                let end = splitted[2];
212
                slots_per_day[day].push(slot);
224
225
                if(!slots[day]) slots[day] = [];
226
227
                slots[day].push([start, end]);
228
            });
213
            });
229
214
230
            let new_slot_node = $("<span class='slot'><input type='hidden' class='pickup-slot' name='pickup-slot-"+branchcode+"' value='"+day+"-"+start+"-"+end+"'/></span>");
231
            $("#conf-"+branchcode).find(".pickup_hours").append(new_slot_node);
232
233
            $("#conf-"+branchcode).find(".pickup_hours li").remove();
215
            $("#conf-"+branchcode).find(".pickup_hours li").remove();
234
216
235
            Object.keys(slots).forEach(function(day){
217
            Object.keys(slots_per_day).forEach(function(day){
236
                let li_node = $('<li><label>'+get_day_lib(day)+'<label></li>');
218
                let li_node = $('<li><label>'+get_day_lib(day)+'<label></li>');
237
                slots[day].forEach(function(slot) {
219
                slots_per_day[day].forEach(function(slot) {
238
                    li_node.append('<span>'+format_slot(slot)+'</span>');
220
                    let span_node = $('<span class="pickup-slot"></span>');
221
                    span_node.append('<input type="hidden" class="pickup-slot" name="pickup-slot-'+branchcode+'" value="'+slot+'"/>');
222
                    span_node.append('<span>'+format_slot(slot)+'</span>');
223
224
                    let delete_link = $('<a href="#" on><i class="fa fa-trash" aria-hidden="true"></i>').on('click', function(e){ e.preventDefault; delete_slot($(this).closest('li'), branchcode); });
225
                    span_node.append(delete_link);
226
227
                    span_node.appendTo(li_node);
239
                });
228
                });
240
                li_node.appendTo($("#conf-"+branchcode).find(".pickup_hours"));
229
                li_node.appendTo($("#conf-"+branchcode).find(".pickup_hours"));
241
            });
230
            });
Lines 243-277 Link Here
243
        function get_day_lib(day){
232
        function get_day_lib(day){
244
            let lib;
233
            let lib;
245
            switch(day){
234
            switch(day){
246
            case 'sunday':
235
            case '0':
247
                lib = _("Sunday");
236
                lib = _("Sunday");
248
                break;
237
                break;
249
            case 'monday':
238
            case '1':
250
                lib = _("Monday");
239
                lib = _("Monday");
251
                break;
240
                break;
252
            case 'tuesday':
241
            case '2':
253
                lib = _("Tuesday");
242
                lib = _("Tuesday");
254
                break;
243
                break;
255
            case 'wednesday':
244
            case '3':
256
                lib = _("Wednesday");
245
                lib = _("Wednesday");
257
                break;
246
                break;
258
            case 'thursday':
247
            case '4':
259
                lib = _("Thursday");
248
                lib = _("Thursday");
260
                break;
249
                break;
261
            case 'friday':
250
            case '5':
262
                lib = _("Friday");
251
                lib = _("Friday");
263
                break;
252
                break;
264
            case 'saturday':
253
            case '6':
265
                lib = _("Saturday");
254
                lib = _("Saturday");
266
                break;
255
                break;
267
            }
256
            }
268
            return lib;
257
            return lib;
269
        }
258
        }
270
259
271
        let opening_slots = {};
272
        [% FOR l IN libraries %]
273
            opening_slots["[% l.branchcode | html %]"] = [];
274
        [% END %]
275
        $(document).ready(function(){
260
        $(document).ready(function(){
276
            [% FOR l IN libraries %]
261
            [% FOR l IN libraries %]
277
                refresh_pickup_hours("[% l.branchcode | html %]");
262
                refresh_pickup_hours("[% l.branchcode | html %]");
Lines 282-288 Link Here
282
                let day = $("#day-" + branchcode).val();
267
                let day = $("#day-" + branchcode).val();
283
                let start = $("#new-start-" + branchcode).val();
268
                let start = $("#new-start-" + branchcode).val();
284
                let end = $("#new-end-" + branchcode).val();
269
                let end = $("#new-end-" + branchcode).val();
285
                // FIXME confirm selection
286
270
287
                let start_hour, start_minute, end_hour, end_minute;
271
                let start_hour, start_minute, end_hour, end_minute;
288
                [ start_hour, start_minute ] = start.split(":");
272
                [ start_hour, start_minute ] = start.split(":");
289
- 

Return to bug 30650