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

(-)a/installer/data/mysql/atomicupdate/bug_17015_add_holidaytype.sql (+9 lines)
Line 0 Link Here
1
CREATE TABLE `discrete_calendar` (
2
    `date` datetime not NULL,
3
    `branchcode` varchar(10) NOT NULL,  
4
    `isopened` tinyint(1) DEFAULT 1,
5
    `holidaytype` varchar(1) default '',
6
    `note` varchar(30) DEFAULT NULL,
7
    `openhour` time,
8
    `closehour` time,
9
 PRIMARY KEY (`branchcode`,`date`));
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/discrete_calendar.tt (+749 lines)
Line 0 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Tools &rsaquo; [% branchname %] calendar</title>
3
[% INCLUDE 'doc-head-close.inc' %]
4
[% INCLUDE 'calendar.inc' %]
5
<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/css/datatables.css" />
6
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/timepicker/1.3.5/jquery.timepicker.min.css">
7
<script src="//cdnjs.cloudflare.com/ajax/libs/timepicker/1.3.5/jquery.timepicker.min.js"></script>
8
[% INCLUDE 'datatables.inc' %]
9
<script type="text/javascript">
10
//<![CDATA[
11
    var weekdays = new Array(_("Sundays"),_("Mondays"),_("Tuesdays"),_("Wednesdays"),_("Thursdays"),_("Fridays"),_("Saturdays"));
12
    $("#jcalendar-container").datepicker({dateFormat:'mm/dd/yy', minDate: new Date(15,10,14) });
13
    /* Creates all the structures to deal with all different kinds of holidays */
14
    var week_days = new Array();
15
    var holidays = new Array();
16
    var day_month_holidays = new Array();
17
    var datesInfos = new Array();
18
    [% FOREACH WEEK_DAYS_LOO IN week_days %]
19
    week_days["[% WEEK_DAYS_LOO.weekday %]"] = {title:"[% WEEK_DAYS_LOO.note %]"};
20
    [% END %]
21
    [% FOREACH HOLIDAYS_LOO IN HOLIDAYS_LOOP %]
22
    holidays["[% HOLIDAYS_LOO.date %]"] = {outputdate: "[% HOLIDAYS_LOOP.outputdate %]", title:"[% HOLIDAYS_LOO.note %]"};
23
    [% END %]
24
    [% FOREACH DAY_MONTH_HOLIDAYS_LOO IN repeatable_holidays %]
25
    day_month_holidays["[%DAY_MONTH_HOLIDAYS_LOO.month%]/[% DAY_MONTH_HOLIDAYS_LOO.day %]"] = {title:"[% DAY_MONTH_HOLIDAYS_LOO.note %]"};
26
    [% END %]
27
    [% FOREACH date IN datesInfos %]
28
    datesInfos["[% date.date %]"] = {title : "[% date.note %]", outputdate : "[% date.outputdate %]", holidaytype:"[% date.holidaytype %]", openhour: "[% date.openhour %]", closehour: "[% date.closehour %]"};
29
    [% END %]
30
31
    function holidayOperation(formObject, opType) {
32
        var op = document.getElementsByName('operation');
33
        op[0].value = opType;
34
        formObject.submit();
35
    }
36
37
    // This function shows the "Show Holiday" panel //
38
    function showHoliday (dayName, day, month, year, weekDay, title, holidayType) {
39
        $("#newHoliday").slideUp("fast");
40
        $("#showHoliday").slideDown("fast");
41
        $("#copyHoliday").slideUp("fast");
42
        $('#showDaynameOutput').html(dayName);
43
        $('#showDayname').val(dayName);
44
        $('#showBranchNameOutput').html($("#branch :selected").text());
45
        $('.showHoliday #BranchName').val($("#branch").val());
46
        $('#showDayOutput').html(day);
47
        $('.showHoliday #Day').val(day);
48
        $('.showHoliday #Month').val(month);
49
        $('.showHoliday #Year').val(year);
50
        $('#showMonthOutput').html(month);
51
        $('#showYearOutput').html(year);
52
        $('.showHoliday #Weekday').val(weekDay);
53
        $('.showHoliday #Title').val(title);
54
        $('#HolidayType').val(holidayType);
55
56
        if(holidayType == 'weekday') {
57
            $("#showOperationDelLabel").html(_("Delete this holiday."));
58
            $("#holtype").attr("class","key repeatableweekly").html(_("Holiday repeating weekly"));
59
        } else if(holidayType == 'daymonth') {
60
            $("#showOperationDelLabel").html(_("Delete this holiday."));
61
            $("#holtype").attr("class","key repeatableyearly").html(_("Holiday repeating yearly"));
62
        } else if(holidayType == 'float') {
63
            $("#showOperationDelLabel").html(_("Delete this holiday."));
64
            $("#holtype").attr("class","key float").html(_("Floating holiday"));
65
        } else if(holidayType == 'N') {
66
            $("#showOperationDelLabel").html(_("Delete this holiday."));
67
            $("#holtype").attr("class","key exception").html(_("Needs validation"));
68
        } else {
69
            $("#showOperationDelLabel").html(_("Delete this holiday."));
70
            $("#holtype").attr("class","key holiday").html(_("Unique holiday"));
71
        }
72
    }
73
74
    // This function shows the "Add Holiday" panel //
75
    function newHoliday (dayName, day, month, year, weekDay) {
76
        $("#showHoliday").slideUp("fast");
77
        $("#copyHoliday").slideUp("fast");
78
        $("#newHoliday").slideDown("fast");
79
        $("#newDaynameOutput").html(dayName);
80
        $("#newDayname").val(dayName);
81
        $("#newBranchNameOutput").html($('#branch :selected').text());
82
        $(".newHoliday ,#BranchName").val($('#branch').val());
83
        $("#newDayOutput").html(day);
84
        $(".newHoliday #Day").val(day);
85
        $(".newHoliday #Month").val(month);
86
        $(".newHoliday #Year").val(year);
87
        $("#newMonthOutput").html(month);
88
        $("#newYearOutput").html(year);
89
        $(".newHoliday, #Weekday").val(weekDay);
90
    }
91
92
    function copyHoliday() {
93
        $("#copyHoliday").slideDown("fast");
94
        $("#newHoliday").slideUp("fast");
95
        $("#showHoliday").slideUp("fast");
96
        $(".copyHoliday #showBranchNameOutput").html($('#branch :selected').text());
97
        $(".copyHoliday #newBranch").val($('#branch').val());
98
    }
99
100
    function hidePanel(aPanelName) {
101
        $("#"+aPanelName).slideUp("fast");
102
    }
103
104
    function changeBranch () {
105
        var branch = $("#branch option:selected").val();
106
        location.href='/cgi-bin/koha/tools/discrete_calendar.pl?branch=' + branch + '&calendardate=' + "[% calendardate %]";
107
    }
108
109
    function Help() {
110
        newin=window.open("/cgi-bin/koha/help.pl","KohaHelp",'width=600,height=600,toolbar=false,scrollbars=yes');
111
    }
112
113
    /* This function gives css clases to each kind of day */
114
    function dateStatusHandler(date) {
115
        date = getSeparetedDate(date);
116
        var day = date.day;
117
        var month = date.month;
118
        var year = date.year;
119
        var weekDay = date.weekDay;
120
        var dayName = weekdays[weekDay];
121
        var dayMonth = date.dayMonth;
122
        var dateString = date.dateString;
123
124
        if (datesInfos[dateString] && datesInfos[dateString].holidaytype =='W'){
125
            return [true, "repeatableweekly", _("Weekly holiday: %s").format(datesInfos[dateString].title)];
126
        } else if (datesInfos[dateString] && datesInfos[dateString].holidaytype == 'R') {
127
            return [true, "repeatableyearly", _("Yearly holiday: %s").format(datesInfos[dateString].title)];
128
        } else if (datesInfos[dateString] && datesInfos[dateString].holidaytype == 'N') {
129
            return [true, "exception", _("Need validation: %s").format(datesInfos[dateString].title)];
130
        } else if (datesInfos[dateString] && datesInfos[dateString].holidaytype == 'F') {
131
            return [true, "float", _("Floating holiday: %s").format(datesInfos[dateString].title)];
132
        } else if (datesInfos[dateString] && datesInfos[dateString].holidaytype == 'E') {
133
            return [true, "holiday", _("Single holiday: %s").format(datesInfos[dateString].title)];
134
        } else {
135
            return [true, "normalday", _("Normal day")];
136
        }
137
    }
138
139
    /* This function is in charge of showing the correct panel considering the kind of holiday */
140
    function dateChanged(calendar) {
141
        calendar = getSeparetedDate(calendar);
142
        var day = calendar.day;
143
        var month = calendar.month;
144
        var year = calendar.year;
145
        var weekDay = calendar.weekDay;
146
        var dayName = weekdays[weekDay];
147
        var dayMonth = calendar.dayMonth;
148
        var dateString = calendar.dateString;
149
        //set value of form hidden field fromDate
150
        document.getElementById('fromDate').value = dateString;
151
            if (datesInfos[dateString].holidaytype =='E') {
152
                showHoliday(dayName, day, month, year, weekDay, datesInfos[dateString].title,'ymd');
153
                showDateInfo(dateString);
154
            } else if (datesInfos[dateString].holidaytype =='W') {
155
                showHoliday(dayName, day, month, year, weekDay, datesInfos[dateString].title, 'weekday');
156
                showDateInfo(dateString);
157
            } else if (datesInfos[dateString].holidaytype =='R') {
158
                showHoliday(dayName, day, month, year, weekDay, datesInfos[dateString].title, 'daymonth');
159
                showDateInfo(dateString);
160
            } else if (datesInfos[dateString].holidaytype =='F') {
161
                showHoliday(dayName, day, month, year, weekDay, datesInfos[dateString].title, 'float');
162
                showDateInfo(dateString);
163
            } else if (datesInfos[dateString].holidaytype =='N') {
164
                showHoliday(dayName, day, month, year, weekDay, datesInfos[dateString].title, 'N');
165
                showDateInfo(dateString);
166
            }else {
167
                newHoliday(dayName, day, month, year, weekDay);
168
                showDateInfo(dateString);
169
            }
170
    };
171
172
    function showDateInfo (date){
173
        $("#dateInfo").css('visibility', 'visible');
174
        document.getElementById('openHour').value =datesInfos[date].openhour;
175
        document.getElementById('closeHour').value =datesInfos[date].closehour;
176
        $('#openHour').timepicker({
177
            timeFormat: 'HH:mm:ss',
178
            interval: 15,
179
            minTime: '05',
180
            maxTime: '23:45',
181
            defaultTime: datesInfos[date].openhour,
182
            startTime: '05:00',
183
            dynamic: false,
184
            dropdown: true,
185
            scrollbar: true
186
        });
187
        $('#closeHour').timepicker({
188
            timeFormat: 'HH:mm:ss',
189
            interval: 15,
190
            minTime: '05',
191
            maxTime: '11:45pm',
192
            defaultTime: datesInfos[date].closehour,
193
            startTime: '05:00',
194
            dynamic: false,
195
            dropdown: true,
196
            scrollbar: true
197
        });
198
        document.getElementById('closeHour').value =datesInfos[date].closehour;
199
        document.getElementById('date').innerHTML = datesInfos[date].outputdate;
200
        //FIXME
201
        if (datesInfos[date].holidaytype !=''){
202
            var type = datesInfos[date].holidaytype;
203
            $('#holidayType option[value="'+ type +'"]').attr('selected', true)
204
        }else{
205
            $('#holidayType option[value="none"]').attr('selected', true)
206
        }
207
        $(".dateDetailsPanel ,#BranchName").val($('#branch').val());
208
209
    }
210
    function getSeparetedDate(date){
211
        var mydate = new Array();
212
        var day = (date.getDate() < 10 ? '0' : '') + date.getDate();
213
        var month = ((date.getMonth()+1) < 10 ? '0' : '') + (date.getMonth() +1);
214
        var year = date.getFullYear();
215
        var weekDay = date.getDay();
216
        var dayMonth = (date.getMonth()+1) + '/' + date.getDate();
217
        var dateString = year + '-' + month + '-' + day;
218
        mydate = {dateObj : date, date : date ,dateString : dateString, dayMonth: dayMonth, weekDay: weekDay, year: year, month: month, day: day};
219
220
        return mydate;
221
    }
222
223
    function validateForm(form){
224
225
        if(form =='copyHoliday' && document.getElementById('from_copyTo').value){
226
            var from_DateFrom = new Date(document.getElementById('from_copyFrom').value);
227
            var from_DateTo = new Date(document.getElementById('from_copyTo').value);
228
            var to_DateFrom = new Date(document.getElementById('to_copyFrom').value);
229
            var to_DateTo = new Date(document.getElementById('to_copyTo').value);
230
            var from_start = Math.floor( from_DateFrom.getTime() / (3600*24*1000)); //days as integer from..
231
            var from_end   = Math.floor( from_DateTo.getTime() / (3600*24*1000)); //days as integer from..
232
            var to_start = Math.floor( to_DateFrom.getTime() / (3600*24*1000)); //days as integer from..
233
            var to_end   = Math.floor( to_DateTo.getTime() / (3600*24*1000)); //days as integer from..
234
            var from_daysDiff = from_end - from_start;
235
            var to_daysDiff = to_end - to_start;
236
            if(from_daysDiff == to_daysDiff || from_daysDiff ==1){
237
                document.getElementById('daysnumber').value = to_daysDiff;
238
                return true;
239
            }else{
240
                alert("You have to pick the same number of days if you choose 2 ranges");
241
                return false;
242
            }
243
        }else if (form =='changeHours'){
244
            var openhour = document.getElementById('openHour').value;
245
            var closehour = document.getElementById('closeHour').value;;
246
            var fromDate = document.getElementById('fromDate').value;
247
            var toDate = document.getElementById('toDate').value;
248
            var message = "You are changing the";
249
            if (openhour) message = message +" open hour to " + openhour + ", ";
250
            if (closehour) message = message +" close hour to " + closehour + ", ";
251
            if (fromDate) message = message + "From " + fromDate;
252
            if (toDate) message = message + "To " + toDate;
253
            message+="\n Would you like to continue?";
254
            return confirm(message);
255
        }else{
256
            return 1;
257
        }
258
    }
259
260
    //Check if date range have the same opening, closing hours and holiday type if there's one.
261
    function checkRange(date){
262
        date = new Date(date);
263
        document.getElementById('toDate').value = getSeparetedDate(date).dateString;
264
        var fromDate = new Date($("#jcalendar-container").datepicker("getDate"));
265
        var sameHoliday =true;
266
        var sameOpenHours =true;
267
        var sameCloseHours =true;
268
        for (var i = fromDate; i < date ; i.setDate(i.getDate() + 1)) {
269
            var myDate1 = getSeparetedDate(i);
270
            var date1 = myDate1.dateString;
271
            var holidayType1 = datesInfos[date1].holidaytype;
272
            var openhours1 = datesInfos[date1].openhour;
273
            var closehours1 = datesInfos[date1].closehour;
274
            for (var j = fromDate; j < date ; j.setDate(j.getDate() + 1)) {
275
                var myDate2 = getSeparetedDate(j);
276
                var date2 = myDate2.dateString;
277
                var holidayType2 = datesInfos[date2].holidaytype;
278
                var openhours2 = datesInfos[date2].openhour;
279
                var closehours2 = datesInfos[date2].closehour;
280
281
                if (sameHoliday && holidayType1 != holidayType2){
282
                    document.getElementById('holidayType').innerHTML = '';
283
                    sameHoliday=false;
284
                }
285
                if(sameOpenHours && (openhours1 != openhours2)){
286
                    document.getElementById('openHour').value ='';
287
                    sameOpenHours=false;
288
                }
289
                if(sameCloseHours && (closehours1 != closehours2)){
290
                    document.getElementById('closeHour').value ='';
291
                    sameCloseHours=false;
292
                }
293
            }
294
            if (!sameOpenHours && !sameCloseHours && !sameHoliday){
295
                return false;
296
            }
297
        }
298
        return true;
299
}
300
    $(document).ready(function() {
301
        $(".hint").hide();
302
        $("#branch").change(function(){
303
            changeBranch();
304
        });
305
        $("#holidayweeklyrepeatable>tbody>tr").each(function(){
306
            var first_td = $(this).find('td').first();
307
            first_td.html(weekdays[first_td.html()]);
308
        });
309
        $("a.helptext").click(function(){
310
            $(this).parent().find(".hint").toggle(); return false;
311
        });
312
        $("#dateofrange").datepicker();
313
        $("#datecancelrange").datepicker();
314
        $("#dateofrange").each(function () { this.value = "" });
315
        $("#datecancelrange").each(function () { this.value = "" });
316
        //Copy holidays From
317
        $("#from_copyFromDp").datepicker();
318
        $("#from.copyToDp").datepicker();
319
        $("#from_copyFromDp").each(function () { this.value = "" });
320
        $("#copyToDp").each(function () { this.value = "" });
321
        //Copy holidays To
322
        $("#to_copyFromDp").datepicker();
323
        $("#to_copyToDp").datepicker();
324
        $("#to_copyFromDp").each(function () { this.value = "" });
325
        $("#to_copyToDp").each(function () { this.value = "" });
326
        $("#jcalendar-container").datepicker({
327
          beforeShowDay: function(thedate) {
328
            return dateStatusHandler(thedate);
329
            },
330
        onSelect: function(dateText, inst) {
331
            dateChanged($(this).datepicker("getDate"));
332
        },
333
        defaultDate: new Date("[% keydate %]"),
334
        minDate: new Date("[% minDate %]"),
335
        maxDate: new Date("[% maxDate %]")
336
        });
337
        $("#dateofrange, #datecancelrange").change(function(){
338
            checkRange($(this).datepicker("getDate"));
339
        });
340
        $("#from_copyFromDp").change(function(){
341
            document.getElementById('from_copyFrom').value = getSeparetedDate($(this).datepicker("getDate")).dateString;
342
        });
343
        $("#from_copyToDp").change(function(){
344
            document.getElementById('from_copyTo').value = getSeparetedDate($(this).datepicker("getDate")).dateString;
345
        });
346
        $("#to_copyFromDp").change(function(){
347
            document.getElementById('to_copyFrom').value = getSeparetedDate($(this).datepicker("getDate")).dateString;
348
        });
349
        $("#to_copyToDp").change(function(){
350
            document.getElementById('to_copyTo').value = getSeparetedDate($(this).datepicker("getDate")).dateString;
351
        });
352
        $(".hidePanel").on("click",function(){
353
            if( $(this).hasClass("showHoliday") ){
354
                hidePanel("showHoliday");
355
            }if ($(this).hasClass('newHoliday')) {
356
                hidePanel("newHoliday");
357
            }else {
358
                hidePanel("copyHoliday");
359
            }
360
        })
361
    });
362
//]]>
363
</script>
364
<!-- Datepicker colors -->
365
<style type="text/css"> .key { padding : 3px; white-space:nowrap; line-height:230%; }
366
.ui-datepicker { font-size : 150%; }
367
.ui-datepicker th, .ui-datepicker .ui-datepicker-title select { font-size : 80%; }
368
.ui-datepicker td a { padding : .5em; }
369
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { font-size : 80%; }
370
.key { padding : 3px; white-space:nowrap; line-height:230%; }
371
.normalday { background-color :  #EDEDED; color :  Black; border : 1px solid #BCBCBC; }
372
.ui-datepicker-unselectable { padding :.5em; white-space:nowrap;}
373
.ui-state-disabled { padding :.5em; white-space:nowrap;}
374
.exception { background-color :  #b3d4ff; color :  Black; border : 1px solid #BCBCBC; }
375
.float { background-color :  #66ff33; color :  Black; border : 1px solid #BCBCBC; }
376
.holiday {  background-color :  #ffaeae; color :  Black;  border : 1px solid #BCBCBC; }
377
.repeatableweekly {  background-color :  #FFFF99; color :  Black;  border : 1px solid #BCBCBC; }
378
.repeatableyearly {  background-color :  #FFCC66; color :  Black;  border : 1px solid #BCBCBC; }
379
td.exception a.ui-state-default { background:  #b3d4ff none; color :  Black; border : 1px solid #BCBCBC; }
380
td.float a.ui-state-default { background:  #66ff33 none; color :  Black; border : 1px solid #BCBCBC; }
381
td.holiday a.ui-state-default {  background:  #ffaeae none; color :  Black;  border : 1px solid #BCBCBC; }
382
td.repeatableweekly a.ui-state-default {  background:  #FFFF99 none; color :  Black;  border : 1px solid #BCBCBC; }
383
td.repeatableyearly a.ui-state-default {  background:  #FFCC66 none; color :  Black;  border : 1px solid #BCBCBC; }
384
.information { z-index : ; background-color :  #DCD2F1; width : 300px; display : none; border : 1px solid #000000; color :  #000000; font-size :  8pt; font-weight :  bold; background-color :  #FFD700; cursor :  pointer; padding : 2px; }
385
.panel { z-index : 1; display : none; border : 3px solid #CCC; padding : 3px; margin-top: .3em;  background-color: #FEFEFE; } fieldset.brief { border : 0; margin-top: 0; }
386
#showHoliday { margin : .5em 0; } h1 select { width: 20em; } div.yui-b fieldset.brief ol { font-size:100%; } div.yui-b fieldset.brief li, div.yui-b fieldset.brief li.radio  { padding:0.2em 0; } .help { margin:.3em 0;border:1px solid #EEE;padding:.3em .7em; font-size : 90%; } #holidayweeklyrepeatable, #holidaysyearlyrepeatable, #holidaysunique, #holidayexceptions { font-size : 90%; margin-bottom : 1em;} .calendar td, .calendar th, .calendar .button, .calendar tbody .day { padding : .7em; font-size: 110%; } .calendar { width: auto; border : 0; }
387
.copyHoliday form li{ display:table-row } .copyHoliday form li b, .copyHoliday form li input{ display:table-cell; margin-bottom: 2px; }
388
</style>
389
</head>
390
<body id="tools_holidays" class="tools">
391
[% INCLUDE 'header.inc' %]
392
[% INCLUDE 'cat-search.inc' %]
393
394
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; [% branchname %] calendar</div>
395
396
<div id="doc3" class="yui-t1">
397
398
   <div id="bd">
399
    <div id="yui-main">
400
    <div class="yui-b">
401
    <h2>[% branchname %] calendar</h2>
402
    <div class="yui-g">
403
    <div class="yui-u first">
404
        <label for="branch">Define the holidays for:</label>
405
            <select id="branch" name="branch">
406
                [% FOREACH branchloo IN branchloop %]
407
                    [% IF ( branchloo.selected ) %]
408
                        <option value="[% branchloo.value %]" selected="selected">[% branchloo.branchname %]</option>
409
                    [% ELSE %]
410
                        <option value="[% branchloo.value %]">[% branchloo.branchname %]</option>
411
                    [% END %]
412
                [% END %]
413
            </select>
414
415
            <h3>Calendar information</h3>
416
            <form style="display :flex" method="get" onsubmit="return validateForm('changeHours')">
417
            <div id="jcalendar-container" style="display:inline-block">
418
            </div>
419
420
            <div class="dateDetailsPanel" id="dateInfo" style="margin:0 auto;display:inline-block; visibility:hidden;">
421
                <table style="display :flex">
422
                    <tr>
423
                        <th>Date</th>
424
                        <th id="date"></th>
425
                    </tr>
426
                    <tr>
427
                        <th>Holiday type</th>
428
                        <th id="holidayType">
429
                            <select name ='holidayType'>
430
                            <option value="none">Not a holiday</option>
431
                            <option value="R">Fixed</option>
432
                            <option value="E">Exception</option>
433
                            <option value="W">Weekly</option>
434
                            <option value="F">Floating</option>
435
                            <option value="N">Need validation</option>
436
                        </select>
437
                    </th>
438
                    </tr>
439
                    <tr>
440
                        <th>Open hour</th>
441
                        <th><input type="text" name="openHour" id='openHour' style="display :flex"></th>
442
                    </tr>
443
                    <tr>
444
                        <th>Close hour</th>
445
                        <th><input type="text" name="closeHour" id='closeHour' style="display :flex"></th>
446
                    </tr>
447
                </table>
448
                <input type="hidden" name="action" value="hourschange">
449
                <input type="hidden" name="branch" value="[%branch%]">
450
                <input type="hidden" name="fromDate" id='fromDate'>
451
                <input type="hidden" name="toDate" id='toDate'>
452
                <input type="hidden" id="BranchName" name="BranchName" />
453
                <input type="submit" name="submit" value="Update">
454
            </div>
455
        </form>
456
        <input type="button" name="name" value="Copy holiday" onclick="copyHoliday()"/>
457
    <!-- ******************************** FLAT PANELS ******************************************* -->
458
    <!-- *****           Makes all the flat panel to deal with holidays                     ***** -->
459
    <!-- **************************************************************************************** -->
460
461
    <!-- ********************** Panel for showing already loaded holidays *********************** -->
462
    <div class="panel showHoliday" id="showHoliday">
463
         <form method="post">
464
             <input type="hidden" id="HolidayType" name="HolidayType" value="" />
465
            <fieldset class="brief">
466
            <h3>Edit this holiday</h3>
467
            <span id="holtype"></span>
468
            <ol>
469
            <li>
470
                <strong>Library:</strong> <span id="showBranchNameOutput"></span>
471
                <input type="hidden" id="BranchName" name="BranchName" />
472
            </li>
473
            <li>
474
                <strong>From date:</strong>
475
                <span id="showDaynameOutput"></span>,
476
477
                                [% IF ( dateformat == "us" ) %]<span id="showMonthOutput"></span>/<span id="showDayOutput"></span>/<span id="showYearOutput"></span>[% ELSIF ( dateformat == "metric") %]<span id="showDayOutput"></span>/<span id="showMonthOutput"></span>/<span id="showYearOutput"></span>[% ELSIF ( dateformat == "dmydot") %]<span id="showDayOutput"></span>.<span id="showMonthOutput"></span>.<span id="showYearOutput"></span>[% ELSE %]<span id="showYearOutput"></span>/<span id="showMonthOutput"></span>/<span id="showDayOutput"></span>[% END %]
478
479
                <input type="hidden" id="showDayname" name="showDayname" />
480
                <input type="hidden" id="Weekday" name="Weekday" />
481
                <input type="hidden" id="Day" name="Day" />
482
                <input type="hidden" id="Month" name="Month" />
483
                <input type="hidden" id="Year" name="Year" />
484
            </li>
485
            <li class="dateinsert">
486
                <b>To Date : </b>
487
                <input type="text" id="datecancelrange" name="datecancelrange" size="20" value="[% datecancelrange %]" class="datepicker"/>
488
            </li>
489
            <li><label for="Title">Title: </label><input type="text" name="Title" id="Title" size="35" /></li>
490
            <!-- Title is necessary for exception radio button to work properly -->
491
            <li class="radio"><input type="radio" name="Operation" id="showOperationDel" value="delete" /> <label for="showOperationDel" id="showOperationDelLabel">Delete this holiday</label>
492
                <a href="#" class="helptext">[?]</a>
493
                <div class="hint">This will delete this holiday only.</div></li>
494
            <li class="radio"><input type="radio" name="Operation" id="showOperationDel" value="deleteType" /> <label for="showOperationDel" id="showOperationDelLabel">Delete this holiday type</label>
495
                <a href="#" class="helptext">[?]</a>
496
                <div class="hint">This will delete all the holidays of this type expect floats. If it's a weekly holiday on the Mondays, this will remove all the upcoming Mondays holidays. If it's a yearly holiday on 25 December,
497
                    this will delete all the upcoming holidays on the 25 December</div></li>
498
            <li class="radio"><input type="radio" name="Operation" id="showOperationDelRange" value="deleterange" /> <label for="showOperationDelRange" id="showOperationDelLabelRange">Delete the single holidays on a range</label>.
499
                <a href="#" class="helptext">[?]</a>
500
                <div class="hint">This will delete all the holidays between two given dates.</div>
501
            </li>
502
            <li class="radio"><input type="radio" name="Operation" id="showOperationEdit" value="edit" checked="checked" /> <label for="showOperationEdit">Edit this holiday</label>
503
                <a href="#" class="helptext">[?]</a>
504
                <div class="hint">This will save changes to the holiday's title and description. If the information for a repeatable holiday is modified, it affects all of the dates on which the holiday is repeated.</div></li>
505
            </ol>
506
            <fieldset class="action">
507
                <input type="hidden" name="action" value="edit">
508
                <input type="submit" name="submit" value="Save" />
509
                <a href="#" class="cancel hidePanel showHoliday">Cancel</a>
510
            </fieldset>
511
            </fieldset>
512
        </form>
513
    </div>
514
515
    <div class="panel copyHoliday" id="copyHoliday">
516
         <form  method="post" onsubmit="return validateForm('copyHoliday')">
517
             <input type="hidden" id="HolidayType" name="HolidayType" value="" />
518
            <fieldset class="brief">
519
            <h2>Copy holiday</h2>
520
            <span id="holtype"></span>
521
            <ol>
522
            <li>
523
                <strong>Library:</strong> <span id="showBranchNameOutput"></span>
524
                <input type="hidden" id="newBranch" name="newBranch" />
525
            </li>
526
            <li>
527
                <h3>Copy from :</h3>
528
            </li>
529
            <li class="dateinsert">
530
                <b>From Date : </b>
531
                <input type="text" id="from_copyFromDp" size="20" value="[% from_copyFrom %]" class="datepicker"/>
532
                <b>To Date : </b>
533
                <input type="text" id="from_copyToDp" size="20" value="[% from_copyTo %]" class="datepicker"/>
534
            </li>
535
            <li>
536
                <h3>Apply To : </h3>
537
            </li>
538
            <li class="dateinsert">
539
                <b>From Date : </b>
540
                <input type="text" id="to_copyFromDp" size="20" value="[% to_copyFrom %]" class="datepicker"/>
541
                <b>To Date : </b>
542
                <input type="text" id="to_copyToDp" size="20" value="[% to_copyTo %]" class="datepicker"/>
543
            </li>
544
545
            </ol>
546
            <fieldset class="action">
547
                <input type="hidden" name="from_copyFrom" id='from_copyFrom' value="">
548
                <input type="hidden" name="from_copyTo" id='from_copyTo'value="">
549
                <input type="hidden" name="to_copyFrom" id='to_copyFrom'value="">
550
                <input type="hidden" name="to_copyTo" id='to_copyTo'value="">
551
                <input type="hidden" name="daysnumber" id='daysnumber'value="">
552
                <input type="hidden" name="branch" value="[%branch%]">
553
                <input type="hidden" name="action" value="copy">
554
                <input type="submit" name="submit" value="Save" />
555
                <a href="#" class="cancel hidePanel copyHoliday">Cancel</a>
556
            </fieldset>
557
            </fieldset>
558
        </form>
559
560
        <form method="post">
561
            <fieldset class="brief">
562
                <h2>Copy entire calendar</h2>
563
                <input type="submit" name="name" value="Copy this calendar to"/>
564
                <select id="branchCopy" name="branchCopy">
565
                    [% FOREACH branchloo IN branchloop %]
566
                    <option value="[% branchloo.value %]">[% branchloo.branchname %]</option>
567
                    [% END %]
568
                </select>
569
                <input type="hidden" name="branch" value="[%branch%]"/>
570
                <input type="hidden" name="action" value="copy"/>
571
                <input type="hidden" name="operation" value="copyBranch"/>
572
            </fieldset>
573
        </form>
574
    </div>
575
576
    <!-- ***************************** Panel to deal with new holidays **********************  -->
577
    <div class="panel newHoliday" id="newHoliday">
578
         <form method="post">
579
                <input type="hidden" name="branchCodes" id="branchCodes" value="[% branchcodes %]" />
580
            <fieldset class="brief">
581
            <h3>Add new holiday</h3>
582
            <ol>
583
            <li>
584
                <strong>Library:</strong>
585
                <span id="newBranchNameOutput"></span>
586
                <input type="hidden" id="BranchName" name="BranchName" />
587
            </li>
588
            <li>
589
                <strong>From date:</strong>
590
                <span id="newDaynameOutput"></span>,
591
592
                         [% IF ( dateformat == "us" ) %]<span id="newMonthOutput"></span>/<span id="newDayOutput"></span>/<span id="newYearOutput"></span>[% ELSIF ( dateformat == "metric" ) %]<span id="newDayOutput"></span>/<span id="newMonthOutput"></span>/<span id="newYearOutput"></span>[% ELSIF ( dateformat == "dmydot" ) %]<span id="newDayOutput"></span>.<span id="newMonthOutput"></span>.<span id="newYearOutput"></span>[% ELSE %]<span id="newYearOutput"></span>/<span id="newMonthOutput"></span>/<span id="newDayOutput"></span>[% END %]
593
594
                <input type="hidden" id="newDayname" name="showDayname" />
595
                <input type="hidden" id="Weekday" name="Weekday" />
596
                <input type="hidden" id="Day" name="Day" />
597
                <input type="hidden" id="Month" name="Month" />
598
                <input type="hidden" id="Year" name="Year" />
599
            </li>
600
            <li class="dateinsert">
601
                <b>To date: </b>
602
                <input type="text" id="dateofrange" name="dateofrange" size="20" value="[% dateofrange %]" class="datepicker" />
603
            </li>
604
            <li><label for="title">Title: </label><input type="text" name="Title" id="title" size="35" /></li>
605
            <li class="radio"><input type="radio" name="Operation" id="newOperationOnce" value="holiday" checked="checked" />
606
            <label for="newOperationOnce">Holiday only on this day</label>.
607
            <a href="#" class="helptext">[?]</a>
608
            <div class="hint">Make a single holiday. For example, selecting August 1, 2012 will make it a holiday, but will not affect August 1 in other years.</div>
609
            </li>
610
            <li class="radio"><input type="radio" name="Operation" id="newOperationDay" value="weekday" />
611
                            <label for="newOperationDay">Holiday repeated every same day of the week</label>.
612
                            <a href="#" class="helptext">[?]</a>
613
                            <div class="hint">Make this weekday a holiday, every week. For example, if your library is closed on Saturdays, use this option to make every Saturday a holiday.</div>
614
                            </li>
615
            <li class="radio"><input type="radio" name="Operation" id="newOperationYear" value="repeatable" />
616
                            <label for="newOperationYear">Holiday repeated yearly on the same date</label>.
617
                            <a href="#" class="helptext">[?]</a>
618
                            <div class="hint">This will take this day and month as a reference to make it a holiday. Through this option, you can repeat this rule for every year. For example, selecting August 1 will make August 1 a holiday every year.</div>
619
                            </li>
620
            <li class="radio"><input type="radio" name="Operation" id="newOperationField" value="holidayrange" />
621
                            <label for="newOperationField">Holidays on a range</label>.
622
                            <a href="#" class="helptext">[?]</a>
623
                            <div class="hint">Make a single holiday on a range. For example, selecting August 1, 2012  and August 10, 2012 will make all days between August 1 and 10 a holiday, but will not affect August 1-10 in other years.</div>
624
                            </li>
625
            <li class="radio"><input type="radio" name="Operation" id="newOperationFieldyear" value="holidayrangerepeat" />
626
                            <label for="newOperationFieldyear">Holidays repeated yearly on a range</label>.
627
                            <a href="#" class="helptext">[?]</a>
628
                            <div class="hint">Make a single holiday on a range repeated yearly. For example, selecting August 1, 2012  and August 10, 2012 will make all days between August 1 and 10 a holiday, and will affect August 1-10 in other years.</div>
629
                            </li>
630
                <li class="radio">
631
                <input type="checkbox" name="allBranches" id="allBranches" />
632
                <label for="allBranches">Copy to all libraries</label>.
633
                <a href="#" class="helptext">[?]</a>
634
                <div class="hint">If checked, this holiday will be copied to all libraries. If the holiday already exists for a library, no change is made.</div>
635
                </li></ol>
636
                <fieldset class="action">
637
                    <input type="hidden" name="action" value="add">
638
                    <input type="submit" name="submit" value="Save" />
639
                    <a href="#" class="cancel hidePanel newHoliday">Cancel</a>
640
                </fieldset>
641
                </fieldset>
642
         </form>
643
    </div>
644
645
    <!-- *************************************************************************************** -->
646
    <!-- ******                          END OF FLAT PANELS                               ****** -->
647
    <!-- *************************************************************************************** -->
648
649
<!-- ************************************************************************************** -->
650
<!-- ******                              MAIN SCREEN CODE                            ****** -->
651
<!-- ************************************************************************************** -->
652
653
</div>
654
<div class="yui-u">
655
<div class="help">
656
<h4>Hints</h4>
657
    <ul>
658
        <li>Search in the calendar the day you want to set as holiday.</li>
659
        <li>Click the date to add or edit a holiday.</li>
660
        <li>Specify how the holiday should repeat.</li>
661
        <li>Click Save to finish.</li>
662
    </ul>
663
<h4>Key</h4>
664
    <p>
665
        <span class="key normalday">Working day</span>
666
        <span class="key holiday">Unique holiday</span>
667
        <span class="key repeatableweekly">Holiday repeating weekly</span>
668
        <span class="key repeatableyearly">Holiday repeating yearly</span>
669
        <span class="key exception">Need validation</span>
670
        <span class="key float">Floating holiday</span>
671
    </p>
672
</div>
673
<div id="holiday-list">
674
675
[% IF ( week_days ) %]
676
<h3>Weekly - Repeatable holidays</h3>
677
<table id="holidayweeklyrepeatable">
678
<thead>
679
<tr>
680
  <th class="repeatableweekly">Day of week</th>
681
  <th class="repeatableweekly">Title</th>
682
</tr>
683
</thead>
684
<tbody>
685
  [% FOREACH WEEK_DAYS_LOO IN week_days %]
686
  <tr>
687
  <td>[% WEEK_DAYS_LOO.weekday %]</td>
688
  </td>
689
  <td>[% WEEK_DAYS_LOO.note %]</td>
690
  </tr>
691
  [% END %]
692
</tbody>
693
</table>
694
[% END %]
695
696
[% IF ( repeatable_holidays ) %]
697
<h3>Yearly - Repeatable holidays</h3>
698
<table id="holidaysyearlyrepeatable">
699
<thead>
700
<tr>
701
  [% IF ( dateformat == "metric" ) %]
702
  <th class="repeatableyearly">Day/month</th>
703
  [% ELSE %]
704
  <th class="repeatableyearly">Month/day</th>
705
  [% END %]
706
  <th class="repeatableyearly">Title</th>
707
</tr>
708
</thead>
709
<tbody>
710
  [% FOREACH DAY_MONTH_HOLIDAYS_LOO IN repeatable_holidays %]
711
  <tr>
712
  <td><span title="[% DAY_MONTH_HOLIDAYS_LOO.DATE_SORT %]">[%DAY_MONTH_HOLIDAYS_LOO.month%]/[% DAY_MONTH_HOLIDAYS_LOO.day %]</span></td>
713
  <td>[% DAY_MONTH_HOLIDAYS_LOO.note %]</td>
714
  </tr>
715
  [% END %]
716
</tbody>
717
</table>
718
[% END %]
719
720
[% IF ( HOLIDAYS_LOOP ) %]
721
<h3>Unique upcoming holidays</h3>
722
<table id="holidaysunique">
723
<thead>
724
<tr>
725
  <th class="holiday">Date</th>
726
  <th class="holiday">Title</th>
727
</tr>
728
</thead>
729
<tbody>
730
    [% FOREACH HOLIDAYS_LOO IN HOLIDAYS_LOOP %]
731
<tr>
732
  <td><a href="/cgi-bin/koha/tools/discrete_calendarte_holiday.pl?branch=[% branch %]&amp;calendardate=[% HOLIDAYS_LOO.date %]"><span title="[% HOLIDAYS_LOO.DATE_SORT %]">[% HOLIDAYS_LOO.outputdate %]</span></a></td>
733
  <td>[% HOLIDAYS_LOO.note %]</td>
734
</tr>
735
  [% END %]
736
</tbody>
737
</table>
738
[% END %]
739
</div>
740
</div>
741
</div>
742
</div>
743
</div>
744
745
<div class="yui-b noprint">
746
[% INCLUDE 'tools-menu.inc' %]
747
</div>
748
</div>
749
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt (-5 / +10 lines)
Lines 24-30 Link Here
24
    <dt><a href="/cgi-bin/koha/reviews/reviewswaiting.pl">Comments</a> [% IF ( pendingcomments ) %]<span class="holdcount"><a href="/cgi-bin/koha/reviews/reviewswaiting.pl">[% pendingcomments %]</a></span>[% END %]</dt>
24
    <dt><a href="/cgi-bin/koha/reviews/reviewswaiting.pl">Comments</a> [% IF ( pendingcomments ) %]<span class="holdcount"><a href="/cgi-bin/koha/reviews/reviewswaiting.pl">[% pendingcomments %]</a></span>[% END %]</dt>
25
	<dd>Moderate patron comments. </dd>
25
	<dd>Moderate patron comments. </dd>
26
    [% END %]
26
    [% END %]
27
    
27
28
    [% IF ( CAN_user_tools_import_patrons ) %]
28
    [% IF ( CAN_user_tools_import_patrons ) %]
29
    <dt><a href="/cgi-bin/koha/tools/import_borrowers.pl">Import patrons</a></dt>
29
    <dt><a href="/cgi-bin/koha/tools/import_borrowers.pl">Import patrons</a></dt>
30
    <dd>Import patron data</dd>
30
    <dd>Import patron data</dd>
Lines 39-45 Link Here
39
    <dt><a href="/cgi-bin/koha/tools/overduerules.pl">Overdue notice/status triggers</a></dt>
39
    <dt><a href="/cgi-bin/koha/tools/overduerules.pl">Overdue notice/status triggers</a></dt>
40
    <dd>Set notice/status triggers for overdue items</dd>
40
    <dd>Set notice/status triggers for overdue items</dd>
41
    [% END %]
41
    [% END %]
42
    
42
43
    [% IF ( CAN_user_tools_label_creator ) %]
43
    [% IF ( CAN_user_tools_label_creator ) %]
44
    <dt><a href="/cgi-bin/koha/patroncards/home.pl">Patron card creator</a></dt>
44
    <dt><a href="/cgi-bin/koha/patroncards/home.pl">Patron card creator</a></dt>
45
    <dd>Create printable patron cards</dd>
45
    <dd>Create printable patron cards</dd>
Lines 74-79 Link Here
74
    <dd>Define days when the library is closed</dd>
74
    <dd>Define days when the library is closed</dd>
75
    [% END %]
75
    [% END %]
76
76
77
	[% IF ( CAN_user_tools_edit_calendar ) %]
78
    <dt><a href="/cgi-bin/koha/tools/discrete_calendar.pl">Discrete calendar</a></dt>
79
    <dd>Define days when the library is closed</dd>
80
    [% END %]
81
77
    [% IF ( CAN_user_tools_manage_csv_profiles ) %]
82
    [% IF ( CAN_user_tools_manage_csv_profiles ) %]
78
    <dt><a href="/cgi-bin/koha/tools/csv-profiles.pl">CSV profiles</a></dt>
83
    <dt><a href="/cgi-bin/koha/tools/csv-profiles.pl">CSV profiles</a></dt>
79
	<dd>Manage CSV export profiles</dd>
84
	<dd>Manage CSV export profiles</dd>
Lines 93-99 Link Here
93
    <dt><a href="/cgi-bin/koha/tools/scheduler.pl">Task scheduler</a></dt>
98
    <dt><a href="/cgi-bin/koha/tools/scheduler.pl">Task scheduler</a></dt>
94
    <dd>Schedule tasks to run</dd>
99
    <dd>Schedule tasks to run</dd>
95
    [% END %]
100
    [% END %]
96
	
101
97
    [% IF ( CAN_user_tools_edit_quotes ) %]
102
    [% IF ( CAN_user_tools_edit_quotes ) %]
98
    <dt><a href="/cgi-bin/koha/tools/quotes.pl">Edit quotes for QOTD feature</a></dt>
103
    <dt><a href="/cgi-bin/koha/tools/quotes.pl">Edit quotes for QOTD feature</a></dt>
99
    <dd>Quote editor for Quote-of-the-day feature in OPAC</dd>
104
    <dd>Quote editor for Quote-of-the-day feature in OPAC</dd>
Lines 118-124 Link Here
118
    <dt><a href="/cgi-bin/koha/tools/batchMod.pl?del=1">Batch item deletion</a></dt>
123
    <dt><a href="/cgi-bin/koha/tools/batchMod.pl?del=1">Batch item deletion</a></dt>
119
    <dd>Delete a batch of items</dd>
124
    <dd>Delete a batch of items</dd>
120
    [% END %]
125
    [% END %]
121
    
126
122
    [% IF ( CAN_user_tools_items_batchmod ) %]
127
    [% IF ( CAN_user_tools_items_batchmod ) %]
123
    <dt><a href="/cgi-bin/koha/tools/batchMod.pl">Batch item modification</a></dt>
128
    <dt><a href="/cgi-bin/koha/tools/batchMod.pl">Batch item modification</a></dt>
124
    <dd>Modify items in a batch</dd>
129
    <dd>Modify items in a batch</dd>
Lines 153-159 Link Here
153
    <dt><a href="/cgi-bin/koha/labels/label-home.pl">Label creator</a></dt>
158
    <dt><a href="/cgi-bin/koha/labels/label-home.pl">Label creator</a></dt>
154
    <dd>Create printable labels and barcodes from catalog data</dd>
159
    <dd>Create printable labels and barcodes from catalog data</dd>
155
    [% END %]
160
    [% END %]
156
    
161
157
    [% IF ( CAN_user_tools_label_creator ) %]
162
    [% IF ( CAN_user_tools_label_creator ) %]
158
    <dt><a href="/cgi-bin/koha/labels/spinelabel-home.pl">Quick spine label creator</a></dt>
163
    <dt><a href="/cgi-bin/koha/labels/spinelabel-home.pl">Quick spine label creator</a></dt>
159
    <dd>Enter a barcode to generate a printable spine label. For use with dedicated label printers</dd>
164
    <dd>Enter a barcode to generate a printable spine label. For use with dedicated label printers</dd>
(-)a/misc/cronjobs/add_days_discrete_calendar.pl (+119 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
#
4
#   This script adds one day into discrete_calendar table based on the same day from the week before
5
#
6
use strict;
7
use warnings;
8
use DateTime;
9
use DateTime::Format::Strptime;
10
use Getopt::Long;
11
use C4::Context;
12
13
# Options
14
my $help = 0;
15
GetOptions (
16
    'help|?|h' => \$help);
17
18
my $usage = << 'ENDUSAGE';
19
20
This script adds days into discrete_calendar table based on the same day from the week before.
21
22
Examples :
23
    The latest date on discrete_calendar is : 28-07-2017
24
    The current date : 01-08-2016
25
    The dates that will be added are : 29-07-2017, 30-07-2017, 31-07-2017, 01-08-2017
26
Open close exemples :
27
    Date added is : 29-07-2017
28
    Opening/closing hours will be base on : 22-07-2017 (- 7 days)
29
    Library open or closed will be based on : 29-07-2017 (- 1 year)
30
This script has the following parameters:
31
    -h --help: this message
32
33
PS: This is for testing purposes, the method of knowing whether it's opened or not may be changed.
34
35
ENDUSAGE
36
my $dbh = C4::Context->dbh;
37
my $query = "select distinct weekday(date), note from discrete_calendar where holidaytype='W'";
38
my $stmt = $dbh->prepare($query);
39
$stmt->execute();
40
my @week_days_discrete;
41
while (my ($weekday,$note) = $stmt->fetchrow_array){
42
    push @week_days_discrete, {weekday => $weekday, note => $note};
43
}
44
45
exit;
46
47
if ($help) {
48
    print $usage;
49
    exit;
50
}
51
#getting the all the branches
52
my $selectBranchesSt = 'SELECT branchcode FROM branches';
53
my $selectBranchesSth = $dbh->prepare($selectBranchesSt);
54
$selectBranchesSth->execute();
55
my @branches = ();
56
while ( my $branchCode = $selectBranchesSth->fetchrow_array ) {
57
58
    push @branches,$branchCode;
59
}
60
61
#get the latest date in the table
62
$query = "select max(date) from discrete_calendar";
63
$stmt = $dbh->prepare($query);
64
$stmt->execute();
65
my $latestedDate = $stmt->fetchrow_array;
66
my $parser = DateTime::Format::Strptime->new(
67
    pattern => '%Y-%m-%d %H:%M:%S',
68
    on_error => 'croak',
69
);
70
$latestedDate = $parser->parse_datetime($latestedDate);
71
72
my $endDate = DateTime->today;
73
$endDate->add(years => 1, days=>1);
74
my $newDay = $latestedDate->clone();
75
$endDate->add(days => 20);
76
for ($newDay->add(days => 1);$newDay <= $endDate;$newDay->add(days => 1)){
77
    my $lastWeekDay = $newDay->clone();
78
    $lastWeekDay->add(days=> -8);
79
    my $dayOfWeek = $lastWeekDay->day_of_week;
80
    # Representation fix
81
    # DateTime object dow (1-7) where Monday is 1
82
    # Arrays are 0-based where 0 = Sunday, not 7.
83
    $dayOfWeek -= 1 unless $dayOfWeek == 7;
84
    $dayOfWeek = 0 if $dayOfWeek == 7;
85
86
    #getting the close and opening hour of the same day from last week
87
    my $openhour = "select openhour from openinghours where weekcode=?";
88
    $stmt = $dbh->prepare($openhour);
89
    $stmt->execute($dayOfWeek);
90
    $openhour = $stmt->fetchrow_array;
91
92
    my $closehour = "select closehour from openinghours where weekcode=?";
93
    $stmt = $dbh->prepare($closehour);
94
    $stmt->execute($dayOfWeek);
95
    $closehour = $stmt->fetchrow_array;
96
97
    #checking if it was open on the same day from last year
98
    my $yearAgo = $newDay->clone();
99
    $yearAgo = $yearAgo->add(years => -1);
100
    my $last_year = 'select isopened,holidaytype,note from discrete_calendar where date=? and branchcode=?';
101
    my $add_Day = 'INSERT INTO discrete_calendar (date,branchcode,isopened,openhour,closehour) VALUES (?,?,?,?,?)';
102
    
103
    #insert into discrete_calendar for each branch
104
    foreach my $branchCode(@branches){
105
        $stmt = $dbh->prepare($last_year);
106
        $stmt->execute($yearAgo,$branchCode);
107
        my ($isOpened, $holidaytype, $note) = $stmt->fetchrow_array;
108
        if ($holidaytype && $holidaytype eq "W" || $holidaytype eq 'E'){
109
            $isOpened = 1;
110
            $note ='';
111
        }elsif ($holidaytype && $holidaytype eq "F"){
112
            $holidaytype = 'N';
113
        }
114
        $holidaytype = '' if $isOpened;
115
        my $add_Day = 'INSERT INTO discrete_calendar (date,branchcode,isopened,holidaytype, note,openhour,closehour) VALUES (?,?,?,?,?,?,?)';
116
        $stmt = $dbh->prepare($add_Day);
117
        $stmt->execute($newDay,$branchCode,$isOpened,$holidaytype,$note, $openhour,$closehour);
118
    }
119
}
(-)a/misc/generate_discrete_calendar.pl (+172 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
#
4
#   Script that fills the discrete_calendar table with dates, using the other date-related tables
5
#
6
use strict;
7
use warnings;
8
use DateTime;
9
use DateTime::Format::Strptime;
10
use Getopt::Long;
11
use C4::Context;
12
13
# Options
14
my $generate = 0;
15
my $help = 0;
16
my $daysInFuture = 365;
17
GetOptions (
18
            'days|?|d=i' => \$daysInFuture,
19
            'generate' => \$generate,
20
            'help|?|h' => \$help);
21
my $usage = << 'ENDUSAGE';
22
23
Script that manages the discrete_calendar table.
24
25
This script has the following parameters :
26
    --days --d : how many days in the future will be created, by default it's 365
27
    -h --help: this message
28
    --generate: fills discrete_calendar table with dates from the last two years and the next one
29
30
ENDUSAGE
31
32
if ($help) {
33
    print $usage;
34
    exit;
35
}
36
#if ($generate) {
37
38
    my $dbh = C4::Context->dbh;
39
40
    my $currentDate = DateTime->today;
41
42
    # two years ago
43
    my $startDate = DateTime->new(
44
            day       => $currentDate->day(),
45
            month     => $currentDate->month(),
46
            year      => $currentDate->year()-2,
47
            time_zone => C4::Context->tz()
48
          )->truncate( to => 'day' );
49
50
    # a year into the future
51
    my $endDate = DateTime->new(
52
            day       => $currentDate->day(),
53
            month     => $currentDate->month(),
54
            year      => $currentDate->year(),
55
            time_zone => C4::Context->tz()
56
          )->truncate( to => 'day' );
57
    $endDate->add(days=> $daysInFuture);
58
59
    # finds branches;
60
    my $selectBranchesSt = 'SELECT branchcode FROM branches';
61
    my $selectBranchesSth = $dbh->prepare($selectBranchesSt);
62
    $selectBranchesSth->execute();
63
    my @branches = ();
64
    while ( my $branchCode = $selectBranchesSth->fetchrow_array ) {
65
66
        push @branches,$branchCode;
67
    }
68
69
    # finds what days are closed for each branch
70
    my %repeatableHolidaysPerBranch = ();
71
    my %specialHolidaysPerBranch = ();
72
    my $selectWeeklySt;
73
    my $selectWeeklySth;
74
75
76
    foreach my $branch (@branches){
77
78
        $selectWeeklySt = 'SELECT weekday, title, day, month FROM repeatable_holidays WHERE branchcode = ?';
79
        $selectWeeklySth = $dbh->prepare($selectWeeklySt);
80
        $selectWeeklySth->execute($branch);
81
82
        my @weeklyHolidays = ();
83
84
        while ( my ($weekDay, $title, $day, $month) = $selectWeeklySth->fetchrow_array ) {
85
            push @weeklyHolidays,{weekday => $weekDay, title => $title, day => $day, month => $month};
86
87
        }
88
89
        $repeatableHolidaysPerBranch{$branch} = \@weeklyHolidays;
90
91
        my $selectSpecialHolidayDateSt = 'SELECT day,month,year,title FROM special_holidays WHERE branchcode = ? AND isexception = 0';
92
        my $specialHolidayDatesSth = $dbh->prepare($selectSpecialHolidayDateSt);
93
        $specialHolidayDatesSth -> execute($branch);
94
        # Tranforms dates from specialHolidays table in DateTime for our new table
95
        my @specialHolidayDates = ();
96
        while ( my ($day, $month, $year, $title) = $specialHolidayDatesSth->fetchrow_array ) {
97
98
            my $specialHolidayDate = DateTime->new(
99
                day       => $day,
100
                month     => $month,
101
                year      => $year,
102
                time_zone => C4::Context->tz()
103
              )->truncate( to => 'day' );
104
            push @specialHolidayDates,{date=>$specialHolidayDate, title=> $title};
105
        }
106
107
        $specialHolidaysPerBranch{$branch} = \@specialHolidayDates;
108
    }
109
    # Fills table with dates and sets 'isopened' according to the branch's weekly restrictions (repeatable_holidays)
110
    my $insertDateSt;
111
    my $insertDateSth;
112
113
    # Loop that does everything in the world
114
    for (my $tempDate = $startDate->clone(); $tempDate <= $endDate;$tempDate->add(days => 1)){
115
        foreach my $branch (@branches){
116
            my $dayOfWeek = $tempDate->day_of_week;
117
            # Representation fix
118
            # DateTime object dow (1-7) where Monday is 1
119
            # Arrays are 0-based where 0 = Sunday, not 7.
120
            $dayOfWeek -=1 unless $dayOfWeek ==7;
121
            $dayOfWeek =0 if $dayOfWeek ==7;
122
123
            my $openhour = "select openhour from openinghours where branchcode=? and weekcode=?";
124
            my $stmt = $dbh->prepare($openhour);
125
            $stmt->execute($branch,$dayOfWeek);
126
            $openhour = $stmt->fetchrow_array;
127
            my $closehour = "select closehour from openinghours where branchcode=? and weekcode=?";
128
            $stmt = $dbh->prepare($closehour);
129
            $stmt->execute($branch,$dayOfWeek);
130
            $closehour = $stmt->fetchrow_array;
131
132
            # Finds closed days
133
            my $isOpened =1;
134
            my $specialDescription = "";
135
            my $holidaytype ='';
136
            $dayOfWeek = $tempDate->day_of_week;
137
            foreach my $holidayWeekDay (@{$repeatableHolidaysPerBranch{$branch}}){
138
                if($holidayWeekDay->{weekday} && $dayOfWeek == $holidayWeekDay->{weekday}){
139
                    $isOpened = 0;
140
                    $specialDescription = $holidayWeekDay->{title};
141
                    $holidaytype = 'W';
142
                }elsif($holidayWeekDay->{day} && $holidayWeekDay->{month}){
143
                    my $date = DateTime->new(
144
                        day       => $holidayWeekDay->{day},
145
                        month     => $holidayWeekDay->{month},
146
                        year      => $tempDate->year(),
147
                        time_zone => C4::Context->tz()
148
                      )->truncate( to => 'day' );
149
150
                    if ($tempDate == $date) {
151
                        $isOpened = 0;
152
                        $specialDescription = $holidayWeekDay->{title};
153
                        $holidaytype = 'R';
154
                    }
155
                }
156
            }
157
158
            foreach my $specialDate (@{$specialHolidaysPerBranch{$branch}}){
159
                if($tempDate->datetime() eq $specialDate->{date}->datetime() ){
160
                    $isOpened = 0;
161
                    $specialDescription = $specialDate->{title};
162
                    $holidaytype = 'E';
163
                }
164
            }
165
            #final insert statement
166
167
            $insertDateSt = 'INSERT INTO discrete_calendar (date,branchcode,isopened,holidaytype,note,openhour,closehour) VALUES (?,?,?,?,?,?,?)';
168
            $insertDateSth = $dbh->prepare($insertDateSt);
169
            $insertDateSth->execute($tempDate,$branch,$isOpened,$holidaytype,$specialDescription,$openhour,$closehour);
170
        }
171
    }
172
#}
(-)a/tools/discrete_calendar.pl (-1 / +476 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
#####Sets holiday periods for each branch. Datedues will be extended if branch is closed -TG
19
use strict;
20
use warnings;
21
22
use CGI qw ( -utf8 );
23
use DateTime;
24
use DateTime::Format::Strptime;
25
26
use C4::Auth;
27
use C4::Branch; # GetBranches
28
use C4::Output;
29
use Koha::DateUtils;
30
31
my $input = new CGI;
32
my $today = DateTime->today;
33
my $dbh = C4::Context->dbh();
34
35
my $branchcode = $input->param('BranchName');
36
my $weekday = $input->param('Weekday');
37
my $day = $input->param('Day');
38
my $month = $input->param('Month');
39
my $year = $input->param('Year');
40
my $dateofrange = $input->param('dateofrange');
41
my $holidaytype = $input->param('HolidayType');
42
my $allbranches = $input->param('allBranches');
43
my $operation   = $input->param('Operation');
44
my $title = $input->param('Title');
45
my $first_dt = DateTime->new(year => $year, month  => $month,  day => $day) if $year && $month && $day;
46
my $end_dt   = eval { dt_from_string( $dateofrange ); };
47
48
my $query;
49
my $stmt;
50
my $action = $input->param('action') || '';
51
# Get the template to use
52
my ($template, $loggedinuser, $cookie)
53
    = get_template_and_user({template_name => "tools/discrete_calendar.tt",
54
                             type => "intranet",
55
                             query => $input,
56
                             authnotrequired => 0,
57
                             flagsrequired => {tools => 'edit_calendar'},
58
                             debug => 1,
59
                           });
60
my $branch= $input->param('branch') || C4::Context->userenv->{'branch'};
61
62
63
64
# calendardate - date passed in url for human readability (syspref)
65
# if the url has an invalid date default to 'now.'
66
my $calendarinput_dt = eval { dt_from_string( scalar $input->param('calendardate') ); } || dt_from_string;
67
my $calendardate = output_pref( { dt => $calendarinput_dt, dateonly => 1 } );
68
69
if($action eq 'add'){
70
    if($allbranches) {
71
        my $branch;
72
        my @branchcodes = split(/\|/, $input->param('branchCodes'));
73
        foreach $branch (@branchcodes) {
74
            add_Holiday($operation, $branch, $weekday, $day, $month, $title);
75
        }
76
    } else {
77
        add_Holiday($operation, $branchcode, $weekday, $day, $month, $title);
78
    }
79
}elsif($action eq 'copy'){
80
81
    if($operation eq 'copyBranch'){
82
        copyToBranch();
83
    }else{
84
        copyHoliday($branch);
85
    }
86
}elsif($action eq 'hourschange'){
87
    changeHours();
88
}elsif( $action eq 'edit'){
89
    delete_holidays($branchcode, $weekday, $day, $month);
90
}
91
sub isOpened{
92
	my ($branchcode, $date) = @_;
93
	my $query = "select isopened from discrete_calendar where branchcode=? and date=?";
94
	my $stmt = $dbh->prepare($query);
95
	$stmt->execute($branchcode, $date);
96
	my $isopened = $stmt->fetchrow_array;
97
98
	return $isopened;
99
}
100
101
sub add_Holiday{
102
	my ($operation, $branchcode, $weekday, $day, $month, $title) = @_;
103
	my $startDate = output_pref( { dt => $first_dt, dateonly => 1, dateformat => 'iso' } );
104
	my $endDate = output_pref( { dt => $end_dt, dateonly => 1, dateformat => 'iso' } );
105
106
	if($operation eq 'holiday'){
107
		if (isOpened($branchcode,$startDate)) {
108
			insert_single_day($branchcode, $title);
109
		}
110
	}elsif($operation eq 'weekday'){
111
		if (isOpened($branchcode,$startDate)) {
112
			insert_weekday_day($branchcode, $weekday, $title);
113
		}
114
	}elsif($operation eq 'repeatable'){
115
		if (isOpened($branchcode,$startDate)) {
116
			insert_yearly_holiday($branchcode, $day, $month, $title);
117
		}
118
	}elsif($operation eq 'holidayrange'){
119
		insert_range_holiday($branchcode, $title);
120
	}elsif($operation eq 'holidayrangerepeat'){
121
		insert_range_holiday_repeat($branchcode, $title);
122
	}
123
}
124
125
sub insert_single_day{
126
	my ($branchcode,$title) = @_;
127
	my $startDate = output_pref( { dt => $first_dt, dateonly => 1, dateformat => 'iso' } );
128
    my $query = "update discrete_calendar set isOpened=0, note=?, holidaytype='E' where branchcode=? and isOpened=1 and date=? and date>=?";
129
	my $stmt = $dbh->prepare($query);
130
131
	$stmt->execute($title, $branchcode, $startDate, $today);
132
}
133
134
sub insert_weekday_day{
135
	my ($branchcode, $weekday, $title) = @_;
136
	$weekday+=1;
137
	my $startDate = output_pref( { dt => $first_dt, dateonly => 1, dateformat => 'iso' } );
138
	my $today = DateTime->today;
139
	my $query = "update discrete_calendar set isOpened=0, note=?, holidaytype='W' where branchcode=? and isOpened=1 and DAYOFWEEK(date)=? and date >=?";
140
	my $stmt = $dbh->prepare($query);
141
142
	$stmt->execute($title,$branchcode,$weekday,$today);
143
}
144
145
sub insert_yearly_holiday{
146
	my ($branchcode, $day, $month, $title) = @_;
147
	my $startDate = output_pref( { dt => $first_dt, dateonly => 1, dateformat => 'iso' } );
148
	my $today = DateTime->today;
149
	my $query = "update discrete_calendar set isOpened=0, note=?, holidaytype='R' where branchcode=? and isOpened=1 and MONTH(date)=? and DAY(date)=? and  date >=?";
150
	my $stmt = $dbh->prepare($query);
151
152
	$stmt->execute($title,$branchcode,$month,$day,$today);
153
}
154
155
sub insert_range_holiday{
156
	my ($branchcode, $title) = @_;
157
	my $startDate = output_pref( { dt => $first_dt, dateonly => 1, dateformat => 'iso' } );
158
	my $endDate = output_pref( { dt => $end_dt, dateonly => 1, dateformat => 'iso' } );
159
	my $query = "update discrete_calendar set isOpened=0, note=?, holidaytype='E' where branchcode=? and isOpened=1 and (date between ? and ?)";
160
	my $stmt = $dbh->prepare($query);
161
162
	$stmt->execute($title,$branchcode, $startDate, $endDate);
163
}
164
165
sub insert_range_holiday_repeat{
166
	my ($branchcode, $title) = @_;
167
	my $parser = DateTime::Format::Strptime->new(
168
	  pattern => '%m-%d',
169
	  on_error => 'croak',
170
	);
171
	my $startDate = $parser->format_datetime($first_dt);
172
	my $endDate = $parser->format_datetime($end_dt);
173
	my $today = DateTime->today;
174
	my $query = "update discrete_calendar set isOpened=0, note=?, holidaytype='R' where branchcode=? and isOpened=1 and (DATE_FORMAT(date,'\%m-\%d') BETWEEN ? AND ? ) and date > ?";
175
	my $stmt = $dbh->prepare($query);
176
177
	$stmt->execute($title,$branchcode, $startDate, $endDate,$today);
178
}
179
180
sub copyHoliday{
181
    # ADD BRANCH CODE TO QUEIRES
182
    my ($branch) = @_;
183
    my $from_copyFrom = $input->param('from_copyFrom') || '';
184
    my $from_copyTo = $input->param('from_copyTo') || '';
185
    my $to_copyFrom = $input->param('to_copyFrom') || '';
186
    my $to_copyTo = $input->param('to_copyTo') || '';
187
    my $daysnumber= $input->param('daysnumber');
188
    my $copyFromType =  $from_copyFrom && !$from_copyTo ? 'oneDay': 'range';
189
190
    if ($copyFromType eq 'oneDay'){
191
        $query = "select isopened,holidaytype,note, openhour, closehour from discrete_calendar where date=? and branchcode=?";
192
        $stmt = $dbh->prepare($query);
193
        $stmt->execute($from_copyFrom,$branch);
194
195
        my @data = $stmt->fetchrow_array;
196
        push @data, $to_copyFrom;
197
        push @data, $to_copyTo if $to_copyTo;
198
        push @data, $branch;
199
        $query = "update discrete_calendar set isopened=?, holidaytype=?, note=?, openhour=?, closehour=? where date=? and branchcode=?";
200
        $query = "update discrete_calendar set isopened=?, holidaytype=?, note=?, openhour=?, closehour=? where date between ? and ? and branchcode=?" if  $to_copyTo;
201
        $stmt = $dbh->prepare($query);
202
        $stmt->execute(@data);
203
204
    }else{
205
        my $parser = DateTime::Format::Strptime->new(
206
        pattern => '%Y-%m-%d',
207
        on_error => 'croak',
208
        );
209
        my $startDate = $parser->parse_datetime($from_copyFrom);
210
        my $endDate = $parser->parse_datetime($from_copyTo);
211
212
        if($daysnumber ==6){
213
            for (my $tempDate = $startDate->clone(); $tempDate <= $endDate;$tempDate->add(days => 1)){
214
                $query = "select DAYOFWEEK(date),isopened,holidaytype,note, openhour, closehour from discrete_calendar where date=? and branchcode=?";
215
                $stmt = $dbh->prepare($query);
216
                $stmt->execute($tempDate,$branch);
217
                my @data = $stmt->fetchrow_array;
218
                my $weekday = shift @data;
219
220
                push @data ,($to_copyFrom, $to_copyTo, $weekday,$branch);
221
                $query ="update discrete_calendar set isopened=?, holidaytype=?, note=?, openhour=?, closehour=? where  date between ? and ? and DAYOFWEEK(date)=? and branchcode=?";
222
223
                $stmt = $dbh->prepare($query);
224
                $stmt->execute(@data);
225
            }
226
        }else{
227
            my $to_startDate = $parser->parse_datetime($to_copyFrom);
228
            my $to_endDate = $parser->parse_datetime($to_copyTo);
229
            for (my $tempDate = $startDate->clone(); $tempDate <= $endDate;$tempDate->add(days => 1)){
230
231
                $query = "select isopened,holidaytype,note, openhour, closehour from discrete_calendar where date=? and branchcode=?";
232
                $stmt = $dbh->prepare($query);
233
                $stmt->execute($tempDate, $branch);
234
                my @data = $stmt->fetchrow_array;
235
236
                push @data ,($to_startDate, $branch);
237
                $query ="update discrete_calendar set isopened=?, holidaytype=?, note=?, openhour=?, closehour=? where  date=? and branchcode=?";
238
                $stmt = $dbh->prepare($query);
239
                $stmt->execute(@data);
240
                $to_startDate->add(days =>1);
241
            }
242
        }
243
244
245
}
246
}
247
sub copyToBranch{
248
    my $newBranch = $input->param('newBranch');
249
    $query = "select isopened, holidaytype, note,openhour, closehour, date from discrete_calendar where branchcode=?";
250
    $stmt = $dbh->prepare($query);
251
    $stmt->execute($branch);
252
    my @data;
253
    while (@data = $stmt->fetchrow_array) {
254
        push @data, $newBranch;
255
        $query = "update discrete_calendar set isopened=?, holidaytype=?, note=?, openhour=?, closehour=? where  date=? and branchcode=?";
256
        my $newstmt = $dbh->prepare($query);
257
        $newstmt->execute(@data);
258
    }
259
260
}
261
262
sub delete_holidays{
263
    my ($branchcode, $weekday, $day, $month) = @_;
264
    $weekday+=1;
265
    my $startDate = DateTime->new(year => $year, month  => $month,  day => $day);
266
    my $endDate = dt_from_string( scalar $input->param('datecancelrange') ) || '' if $input->param('datecancelrange');
267
    my $query;
268
    my $stmt;
269
270
    if($operation eq 'edit'){
271
        edit_holiday($branchcode, $title, $weekday, $day, $month);
272
    }else{
273
        if($operation eq 'delete'){
274
            $query = "update discrete_calendar set isOpened=1, holidaytype='', note='' where branchcode=? and date=? and isopened=0";
275
            $stmt = $dbh->prepare($query);
276
277
            $stmt->execute($branchcode, $startDate);
278
        }elsif($operation eq 'deleterange'){
279
            $startDate = output_pref( { dt => $startDate, dateonly => 1, dateformat => 'iso' } );
280
            $endDate = output_pref( { dt => $endDate, dateonly => 1, dateformat => 'iso' } );
281
            $query = "update discrete_calendar set isOpened=1, holidaytype='', note='' where branchcode=? and (date between ? and ?) and isopened=0";
282
            $stmt = $dbh->prepare($query);
283
284
            $stmt->execute($branchcode, $startDate, $endDate);
285
        }else{
286
            if($holidaytype eq 'weekday') {
287
                #This one deletes a weekly repeated holiday from the full table
288
                $query = "update discrete_calendar set isOpened=1, holidaytype='', note='' where branchcode=? and  holidaytype='W' and DAYOFWEEK(date)=? and date >=? and isopened=0";
289
                $stmt = $dbh->prepare($query);
290
291
                $stmt->execute($branchcode,$weekday,$today);
292
            }elsif($holidaytype eq 'daymonth'){
293
                #This one deletes a given holiday day and repeats for the ful calendar ex: 03 august of every year in the table
294
                $query = "update discrete_calendar set isOpened=1, holidaytype='', note='' where branchcode=? and MONTH(date)=? and DAY(date)=? and  date >=? and isopened=0";
295
                $stmt = $dbh->prepare($query);
296
                $stmt->execute($branchcode, $month, $day, $today);
297
            }
298
        }
299
    }
300
}
301
302
sub edit_holiday{
303
    my ($branchcode, $title, $weekday, $day, $month) = @_;
304
    my $today = DateTime->today;
305
    my $startDate = DateTime->new(year => $year, month  => $month,  day => $day);
306
    my $query;
307
    my $stmt;
308
309
    if($holidaytype eq 'weekday') {
310
        #This one deletes a weekly repeated holiday from the full table
311
        $query = "update discrete_calendar set note=? where branchcode=? and DAYOFWEEK(date)=? and date >=? and isopened=0";
312
        $stmt = $dbh->prepare($query);
313
314
        $stmt->execute($title, $branchcode,$weekday,$today);
315
    } elsif ($holidaytype eq 'daymonth') {
316
        #This one deletes a given holiday day and repeats for the ful calendar ex: 03 august of every year in the table
317
        $query = "update discrete_calendar set note=? where branchcode=? and MONTH(date)=? and DAY(date)=? and  date >=? and isopened=0";
318
        $stmt = $dbh->prepare($query);
319
        $stmt->execute($title, $branchcode, $month, $day, $today);
320
    } elsif ($holidaytype eq 'ymd' || $holidaytype eq 'float' || $holidaytype eq 'N') {
321
        #This one deletes only a holiday based on a given date
322
        $query = "update discrete_calendar set note=? where branchcode=? and date=? and isopened=0";
323
        $stmt = $dbh->prepare($query);
324
325
        $stmt->execute($title,$branchcode, $startDate);
326
    }
327
}
328
329
sub changeHours{
330
    my @params;
331
    my $openhour = $input->param('openHour') || '';
332
    my $closehour = $input->param('closeHour') || '';
333
    my $fromDate = $input->param('fromDate') || '';
334
    my $toDate = $input->param('toDate') || '';
335
    my $holidaytype = $input->param('holidayType') || '';
336
    my $isopened = 0;
337
338
    if( $holidaytype eq 'none'){
339
        $isopened = 1;
340
        $holidaytype='';
341
    }
342
    if($openhour && $closehour){
343
        $query = "update discrete_calendar set openhour=?, closehour=?, isopened =?, holidaytype=? where branchcode=?";
344
        push @params, ($openhour, $closehour, $isopened, $holidaytype, $branchcode);
345
    }elsif($openhour && !$closehour){
346
            $query = "update discrete_calendar set openhour=?, isopened =?, holidaytype=? where branchcode=?";
347
            push @params, ($openhour, $isopened, $holidaytype, $branchcode);
348
    }elsif(!$openhour && $closehour){
349
        $query = "update discrete_calendar set closehour=?, isopened =?, holidaytype=? where branchcode=?";
350
        push @params,($closehour, $isopened, $holidaytype, $branchcode);
351
    }
352
    if ($toDate && $fromDate) {
353
        $query .= " and date between ? and ?";
354
        push @params, ($fromDate, $toDate);
355
    } else {
356
        $query .= " and date=?";
357
        push @params, $fromDate;
358
    }
359
360
    $stmt = $dbh->prepare($query);
361
    $stmt->execute(@params);
362
}
363
# keydate - date passed to calendar.js.  calendar.js does not process dashes within a date.
364
365
my $keydate = output_pref( { dt => $calendarinput_dt, dateonly => 1, dateformat => 'iso' } );
366
$keydate =~ s/-/\//g;
367
368
# Set all the branches.
369
my $onlymine =
370
  (      C4::Context->preference('IndependentBranches')
371
      && C4::Context->userenv
372
      && !C4::Context->IsSuperLibrarian()
373
      && C4::Context->userenv->{branch} ? 1 : 0 );
374
if ( $onlymine ) {
375
    $branch = C4::Context->userenv->{'branch'};
376
}
377
my $branchname = GetBranchName($branch);
378
my $branches   = GetBranches($onlymine);
379
my @branchloop;
380
for my $thisbranch (
381
    sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} }
382
    keys %{$branches} ) {
383
    push @branchloop,
384
      { value      => $thisbranch,
385
        selected   => $thisbranch eq $branch,
386
        branchname => $branches->{$thisbranch}->{'branchname'},
387
      };
388
}
389
390
# branches calculated - put branch codes in a single string so they can be passed in a form
391
my $branchcodes = join '|', keys %{$branches};
392
393
# check if it's changing hours
394
395
396
# Get all the holidays
397
398
#discrete_calendar weekdays
399
$query = "select distinct DAYOFWEEK(date), note from discrete_calendar where branchcode =? and holidaytype='W' order by DAYOFWEEK(date)";
400
$stmt = $dbh->prepare($query);
401
$stmt->execute($branch);
402
my @week_days;
403
while (my ($weekday,$note) = $stmt->fetchrow_array){
404
    push @week_days, {weekday => ($weekday-1), note => $note};
405
}
406
407
#discrete_calendar repeatable
408
$query = "select distinct day(date), month(date) from discrete_calendar where branchcode =? and holidaytype='R'";
409
$stmt = $dbh->prepare($query);
410
$stmt->execute($branch);
411
my @repeatable_holidays;
412
while (my ($day, $month, $note) = $stmt->fetchrow_array){
413
    push @repeatable_holidays, {day=> $day, month => $month , note => $note};
414
}
415
416
#single hildays (exceptions)
417
$query = "select DATE(date), note from discrete_calendar where branchcode =? and holidaytype='E'";
418
$stmt = $dbh->prepare($query);
419
420
$stmt->execute($branch);
421
422
my @single_holidays;
423
while (my ($date,$note) = $stmt->fetchrow_array){
424
    my $outputdate = dt_from_string($date);
425
    $outputdate = output_pref( { dt => $outputdate, dateonly => 1 } );
426
    push @single_holidays, {date =>  $date, outputdate => $outputdate, note => $note};
427
}
428
#Calendar maximum date
429
my $minDate;
430
$query = "select distinct DATE(date) from discrete_calendar where date = (select min(date) from discrete_calendar)";
431
$stmt = $dbh->prepare($query);
432
$stmt->execute();
433
$minDate = $stmt->fetchrow_array;
434
#Calendar minimum date
435
my $maxDate;
436
$query = "select distinct DATE(date) from discrete_calendar where date = (select max(date) from discrete_calendar)";
437
$stmt = $dbh->prepare($query);
438
$stmt->execute();
439
$maxDate = $stmt->fetchrow_array;
440
441
my @datesInfos =();
442
$query = "select DATE(date), holidaytype, openhour, closehour, note from discrete_calendar where branchcode=?";
443
$stmt = $dbh->prepare($query);
444
$stmt->execute($branch);
445
while (my ($date, $holidaytype, $openhour, $closehour, $note) = $stmt->fetchrow_array){
446
    my $outputdate = dt_from_string($date);
447
    $outputdate = output_pref( { dt => $outputdate, dateonly => 1 } );
448
    push @datesInfos, {date=> $date, outputdate => $outputdate, holidaytype => $holidaytype , openhour => $openhour, closehour => $closehour, note => $note};
449
}
450
451
#Not finished yet
452
my $timeFormat = C4::Context->preference('TimeFormat') || '24hr';
453
if($timeFormat eq '24hr'){
454
    $timeFormat = 'HH:mm:ss';
455
}else{
456
    $timeFormat = 'HH:mm:ss';
457
}
458
$template->param(
459
    branchloop               => \@branchloop,
460
    HOLIDAYS_LOOP            => \@single_holidays,
461
    calendardate             => $calendardate,
462
    keydate                  => $keydate,
463
    branchcodes              => $branchcodes,
464
    branch                   => $branch,
465
    branchname               => $branchname,
466
    branch                   => $branch,
467
    week_days                => \@week_days,
468
    repeatable_holidays      => \@repeatable_holidays,
469
    minDate                  => $minDate,
470
    maxDate                  => $maxDate,
471
    datesInfos               => \@datesInfos,
472
    timeFormat               => $timeFormat,
473
);
474
475
# Shows the template with the real values replaced
476
output_html_with_http_headers $input, $cookie, $template->output;

Return to bug 17015