ticket_system-appointment-queueid config, RT#34237
[freeside.git] / rt / share / html / Search / Schedule.html
1 <& /Elements/Header, Title => 'Schedule', JavaScript => 0 &>
2
3 <SCRIPT TYPE="text/javascript">
4
5 % if ( $cells ) {
6
7   function boxon(what) {
8     var $this = $(what);
9     for ( var c=0; c < <%$cells%>; c++) {
10
11       $this.css('background-color', '#ffffdd');
12       if ( c == 0 ) {
13         $this.css('border-top', '1px double black');
14         $this.css('border-left', '1px double black');
15         $this.css('border-right', '1px solid black');
16       } else if ( c == <%$cells-1%> ) {
17         $this.css('border-left', '1px double black');
18         $this.css('border-right', '1px solid black');
19         $this.css('border-bottom', '1px solid black');
20       } else {
21         $this.css('border-left', '1px double black');
22         $this.css('border-right', '1px solid black');
23       }
24
25       var rownum = $this.parent().prevAll('tr').length;
26       var colnum = $this.prevAll('td').length;
27       $this = $this.parent().parent().children('tr').eq(rownum+1).children('td').eq(colnum);
28     }
29   }
30
31   function boxoff(what) {
32     var $this = $(what);
33     for ( var c=0; c < <%$cells%>; c++) {
34
35       //$this.css('background-color', '');
36       //$this.css('border', ''); //IE8 woes, removes cell borders
37       $this.removeAttr('style'); //slightly "flashy" on cell changes under IE8
38                                  //but at least it doesn't remove cell borders
39
40       var rownum = $this.parent().prevAll('tr').length;
41       var colnum = $this.prevAll('td').length;
42       $this = $this.parent().parent().children('tr').eq(rownum+1).children('td').eq(colnum);
43     }
44   }
45
46
47 % }
48
49   var drag_cells = 0;
50   var drag_hi;
51   function boxon_drop(event, ui) {
52     //var $this = $(what);
53     var $this = $(this);
54
55     drag_cells = ui.draggable.data('cells');
56
57     if ( drag_hi ) {
58       boxoff_do(drag_hi);
59     }
60     drag_hi = $this;
61
62     for ( var c=0; c < drag_cells; c++) {
63
64       /* well, its not exactly what i want, would prefer if it could properly
65          mouse in-out, but this sorta helps for now?
66          revisit when everthing else is working */
67 /*      $this.effect("highlight", {}, 1500); */
68
69       $this.css('background-color', '#ffffdd');
70       if ( c == 0 ) {
71         $this.css('border-top', '1px double black');
72         $this.css('border-left', '1px double black');
73         $this.css('border-right', '1px solid black');
74       } else if ( c == (drag_cells-1) ) {
75         $this.css('border-left', '1px double black');
76         $this.css('border-right', '1px solid black');
77         $this.css('border-bottom', '1px solid black');
78       } else {
79         $this.css('border-left', '1px double black');
80         $this.css('border-right', '1px solid black');
81       }
82
83       var rownum = $this.parent().prevAll('tr').length;
84       var colnum = $this.prevAll('td').length;
85       $this = $this.parent().parent().children('tr').eq(rownum+1).children('td').eq(colnum);
86     }
87
88
89   }
90
91   function boxoff_do(what) {
92
93     var $this = what;
94
95     for ( var c=0; c < drag_cells; c++) {
96
97       //$this.css('background-color', '');
98       //$this.css('border', ''); //IE8 woes, removes cell borders
99       $this.removeAttr('style'); //slightly "flashy" on cell changes under IE8
100                                  //but at least it doesn't remove cell borders
101
102       var rownum = $this.parent().prevAll('tr').length;
103       var colnum = $this.prevAll('td').length;
104       $this = $this.parent().parent().children('tr').eq(rownum+1).children('td').eq(colnum);
105     }
106   }
107
108   function reschedule_appointment( event, ui ) {
109
110 %   #get the ticket number and appointment length (from the draggable object)
111     var ticketid = ui.draggable.data('ticketid');
112     var length   = ui.draggable.data('length');
113     var bgcolor  = ui.draggable.data('bgcolor');
114
115 %   #and.. the new date and time, and username (from the droppable object)
116     var starts   = $(this).data('starts');
117     var username = $(this).data('username');
118
119     var due = parseInt(starts) + parseInt(length);
120
121     var n_epoch        = $(this).data('epoch');
122     var n_st_tod_row   = $(this).data('tod_row');
123
124     var draggable = ui.draggable;
125     var droppable = $(this);
126     draggable.effect( "transfer", { to: droppable }, 1000 );
127
128 %   #tell the backend to reschedule it
129     var url = "<% popurl(3) %>misc/xmlhttp-ticket-update.html?" +
130               "id=" + ticketid + ";starts=" + starts + ";due=" + due +
131               ";username=" + username;
132
133     $.getJSON( url, function( data ) {
134       if ( data.error && data.error.length ) {
135 %       #error?  "that shouldn't happen" but should display 
136         alert(data.error);
137 %       #XX and should revert the dragable...
138       } else {
139
140         //draggable.effect( "transfer", { to: droppable }, 1000 );
141
142         var label = data.sched_label;
143
144 %       #remove the old appointment entirely
145         var epoch        = ui.draggable.data('epoch');
146         var st_tod_row   = ui.draggable.data('tod_row');
147         var old_username = ui.draggable.data('username');
148         var cells        = ui.draggable.data('cells');
149         for ( var c=0; c < cells; c++) {
150           var tod_row = parseInt(st_tod_row) + (c * <%$timestep%>);
151           var td_id = 'td_' + epoch +
152                       '_' + String( tod_row ) +
153                       '_' + old_username;
154           $('#'+td_id).css('background-color', '#FFFFFF');
155           $('#'+td_id).text('');
156 %         #(and make those boxes droppable)
157           $('#'+td_id).droppable({
158             over: boxon_drop,
159             drop: reschedule_appointment,
160             tolerance: 'pointer'
161           });
162         }
163
164 %       #maybe use that animation which shows the box from point A to B
165
166         if ( drag_hi ) {
167           boxoff_do(drag_hi);
168         }
169         for ( var d=0; d < cells; d++) {
170           var n_tod_row = parseInt(n_st_tod_row) + (d * <%$timestep%>);
171           var n_td_id = 'td_' + n_epoch +
172                         '_' + String( n_tod_row ) +
173                         '_' + username;
174           $('#'+n_td_id).css('background-color', bgcolor);
175 %         #remove their droppable
176           $('#'+n_td_id).droppable('destroy');
177           if ( d == 0 ) {
178             $('#'+n_td_id).text(label);
179 %           #(and make the top draggable, so we could do it all over again)
180             $('#'+n_td_id).draggable({
181               containment: '.titlebox-content',
182 %#              revert:      'invalid',
183               revert: true,
184               revertDuration: 0,
185             });
186             $('#'+n_td_id).data('ticketid', ticketid );
187             $('#'+n_td_id).data('length',   length );
188             $('#'+n_td_id).data('cells',    cells );
189             $('#'+n_td_id).data('bgcolor',  bgcolor );
190           }
191         }
192
193       }
194
195     });
196
197   }
198
199 </SCRIPT>
200
201 <& /Search/Calendar.html,
202      @_,
203      Query       => "( Status = 'new' OR Status = 'open' OR Status = 'stalled')
204                      AND ( Type = 'reminder' OR 'Type' = 'ticket' )
205                      AND Queue.id = $queueid ",
206      slots       => scalar(@usernames),
207      Embed       => 'Schedule.html',
208      DimPast     => 1,
209      Display     => 'Schedule',
210      DisplayArgs => [ username  => \@usernames,
211                       LengthMin => $LengthMin,
212                       #oops, more freeside abstraction-leaking
213                       custnum   => $ARGS{custnum},
214                       pkgnum    => $ARGS{pkgnum},
215                     ],
216 &>
217
218 <%ONCE>
219
220 my $timestep =  RT->Config->Get('CalendarWeeklySizeMin') || 30; #1/2h
221
222 </%ONCE>
223 <%init>
224
225 #abstraction-leaking
226 my $conf = new FS::Conf;
227 my $queueid = $conf->config('ticket_system-appointment-queueid')
228   or die "ticket_system-appointment-queueid configuration not set";
229
230 my @files = ();
231 #if ( ! $initialized ) {
232   push @files, map "overlibmws$_", ( '', qw( _iframe _draggable _crossframe ) );
233   push @files, map { "${_}contentmws" } qw( iframe ajax );
234 #%}
235
236 my @usernames = ();
237 if ( ref($ARGS{username}) ) {
238   @usernames = @{ $ARGS{username} };
239 } elsif ( $ARGS{username} ) {
240   @usernames = ( $ARGS{username} );
241 } else {
242   #look them up ourslves... again, more FS abstraction-leaking, but 
243   # we want to link to the schedule view, and better than doing this every
244   # menu render
245   use FS::Record qw( qsearch );
246   use FS::sched_item;
247   my @sched_item = qsearch('sched_item', { 'disabled' => '', });
248   @usernames = map $_->access_user->username, @sched_item;
249 }
250
251 ( my $LengthMin = $ARGS{LengthMin} ) =~ /^\d+$/ or die 'non-numeric LengthMin';
252
253 my $cells = int($LengthMin / $timestep);
254 $cells++ if $LengthMin % $timestep;
255
256 </%init>