KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > compiere > model > MSchedule


1 /******************************************************************************
2  * The contents of this file are subject to the Compiere License Version 1.1
3  * ("License"); You may not use this file except in compliance with the License
4  * You may obtain a copy of the License at http://www.compiere.org/license.html
5  * Software distributed under the License is distributed on an "AS IS" basis,
6  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
7  * the specific language governing rights and limitations under the License.
8  * The Original Code is Compiere ERP & CRM Business Solution
9  * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
10  * Portions created by Jorg Janke are Copyright (C) 1999-2002 Jorg Janke, parts
11  * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
12  * Contributor(s): ______________________________________.
13  *****************************************************************************/

14 package org.compiere.model;
15
16 import java.sql.*;
17 import java.math.*;
18 import java.util.*;
19
20 import org.compiere.util.*;
21
22 /**
23  * Scheduling Utilities.
24  *
25  * @author Jorg Janke
26  * @version $Id: MSchedule.java,v 1.12 2003/11/02 07:49:19 jjanke Exp $
27  */

28 public class MSchedule
29 {
30     /**
31      * Constructor
32      * @param ctx context
33      */

34     public MSchedule (Properties ctx)
35     {
36         m_ctx = ctx;
37     } // MSchedule
38

39     private Properties m_ctx;
40     private int m_S_Resource_ID;
41     private boolean m_isAvailable = true;
42     private boolean m_isSingleAssignment = true;
43     private int m_S_ResourceType_ID = 0;
44     private int m_C_UOM_ID = 0;
45
46     private Timestamp m_startDate = null;
47     private Timestamp m_endDate = null;
48
49     /** Resource Type Name */
50     private String JavaDoc m_typeName = null;
51     /** Resource Type Start Time */
52     private Timestamp m_slotStartTime = null;
53     /** Resource Type End Time */
54     private Timestamp m_slotEndTime = null;
55
56     /** Time Slots */
57     private MAssignmentSlot[] m_timeSlots = null;
58
59     /** Begin Timestamp 1/1/1970 */
60     public static final Timestamp EARLIEST = new Timestamp(new GregorianCalendar(1970,1,1).getTimeInMillis());
61     /** End Timestamp 12/31/2070 */
62     public static final Timestamp LATEST = new Timestamp(new GregorianCalendar(2070,12,31).getTimeInMillis());
63
64
65     /*************************************************************************/
66
67     /**
68      * Get Assignments for timeframe.
69      * <pre>
70      * - Resource is Active and Available
71      * - Resource UnAvailability
72      * - NonBusinessDay
73      * - ResourceType Available
74      * </pre>
75      * @param S_Resource_ID resource
76      * @param start_Date start date
77      * @param end_Date optional end date, need to provide qty to calculate it
78      * @param qty optional qty in ResourceType UOM - ignored, if end date is not null
79      * @param getAll if true return all errors
80      * @return Array of existing Assigments or null - if free
81      */

82     public MAssignmentSlot[] getAssignmentSlots (int S_Resource_ID,
83         Timestamp start_Date, Timestamp end_Date,
84         BigDecimal qty, boolean getAll)
85     {
86         Log.trace(Log.l4_Data, "MSchedule.getAssignmentSlots", start_Date);
87         if (m_S_Resource_ID != S_Resource_ID)
88             getBaseInfo (S_Resource_ID);
89         //
90
ArrayList list = new ArrayList();
91         MAssignmentSlot ma = null;
92
93         if (!m_isAvailable)
94         {
95             ma = new MAssignmentSlot (EARLIEST, LATEST,
96                 Msg.getMsg (m_ctx, "ResourceNotAvailable"), "", MAssignmentSlot.STATUS_NotAvailable);
97             if (!getAll)
98                 return new MAssignmentSlot[] {ma};
99             list.add(ma);
100         }
101
102         m_startDate = start_Date;
103         m_endDate = end_Date;
104         if (m_endDate == null)
105             m_endDate = UOMConversion.getEndDate(m_ctx, m_startDate, m_C_UOM_ID, qty);
106         Log.trace(Log.l5_DData, "- EndDate=" + m_endDate);
107
108
109         // Resource Unavailability -------------------------------------------
110
// Log.trace(Log.l6_Database, "- Unavailability -");
111
String JavaDoc sql = "SELECT Description, DateFrom, DateTo "
112           + "FROM S_ResourceUnavailable "
113           + "WHERE S_Resource_ID=?" // #1
114
+ " AND DateTo >= ?" // #2 start
115
+ " AND DateFrom <= ?" // #3 end
116
+ " AND IsActive='Y'";
117         try
118         {
119     // Log.trace(Log.l6_Database, sql, "ID=" + S_Resource_ID + ", Start=" + m_startDate + ", End=" + m_endDate);
120
PreparedStatement pstmt = DB.prepareStatement(sql);
121             pstmt.setInt(1, m_S_Resource_ID);
122             pstmt.setTimestamp(2, m_startDate);
123             pstmt.setTimestamp(3, m_endDate);
124             ResultSet rs = pstmt.executeQuery();
125             while (rs.next())
126             {
127                 ma = new MAssignmentSlot (TimeUtil.getDay(rs.getTimestamp(2)),
128                     TimeUtil.getNextDay(rs.getTimestamp(3)), // user entered date need to convert to not including end time
129
Msg.getMsg (m_ctx, "ResourceUnAvailable"), rs.getString(1),
130                     MAssignmentSlot.STATUS_UnAvailable);
131             // Log.trace(Log.l6_Database, "- Unavailable", ma);
132
if (getAll)
133                     createDaySlot (list, ma);
134                 else
135                     list.add(ma);
136             }
137             rs.close();
138             pstmt.close();
139         }
140         catch (SQLException e)
141         {
142             Log.error("MSchedule.getAssignmentSlots-2", e);
143             ma = new MAssignmentSlot (EARLIEST, LATEST,
144                 Msg.getMsg (m_ctx, "ResourceUnAvailable"), e.toString(),
145                 MAssignmentSlot.STATUS_UnAvailable);
146         }
147         if (ma != null && !getAll)
148             return new MAssignmentSlot[] {ma};
149
150
151         // NonBusinessDay ----------------------------------------------------
152
// Log.trace(Log.l6_Database, "- NonBusinessDay -");
153
// "WHERE TRUNC(Date1) BETWEEN TRUNC(?) AND TRUNC(?)" causes
154
// ORA-00932: inconsistent datatypes: expected NUMBER got TIMESTAMP
155
sql = MRole.getDefault(m_ctx, false).addAccessSQL (
156             "SELECT Name, Date1 FROM C_NonBusinessDay "
157             + "WHERE TRUNC(Date1) BETWEEN ? AND ?",
158             "C_NonBusinessDay", false, false); // not qualified - RO
159
try
160         {
161             Timestamp startDay = TimeUtil.getDay(m_startDate);
162             Timestamp endDay = TimeUtil.getDay(m_endDate);
163     // Log.trace(Log.l6_Database, sql, "Start=" + startDay + ", End=" + endDay);
164
PreparedStatement pstmt = DB.prepareStatement(sql);
165             pstmt.setTimestamp(1, startDay);
166             pstmt.setTimestamp(2, endDay);
167             ResultSet rs = pstmt.executeQuery();
168             while (rs.next())
169             {
170                 ma = new MAssignmentSlot (TimeUtil.getDay(rs.getTimestamp(2)),
171                     TimeUtil.getNextDay(rs.getTimestamp(2)), // user entered date need to convert to not including end time
172
Msg.getMsg(m_ctx, "NonBusinessDay"), rs.getString(1),
173                     MAssignmentSlot.STATUS_NonBusinessDay);
174                 Log.trace(Log.l6_Database, "- NonBusinessDay", ma);
175                 list.add(ma);
176             }
177             rs.close();
178             pstmt.close();
179         }
180         catch (SQLException e)
181         {
182             Log.error("MSchedule.getAssignmentSlots-3", e);
183             ma = new MAssignmentSlot (EARLIEST, LATEST,
184                 Msg.getMsg(m_ctx, "NonBusinessDay"), e.toString(),
185                 MAssignmentSlot.STATUS_NonBusinessDay);
186         }
187         if (ma != null && !getAll)
188             return new MAssignmentSlot[] {ma};
189
190
191         // ResourceType Available --------------------------------------------
192
// Log.trace(Log.l6_Database, "- ResourceTypeAvailability -");
193
sql = "SELECT Name, IsTimeSlot,TimeSlotStart,TimeSlotEnd, " // 1..4
194
+ "IsDateSlot,OnMonday,OnTuesday,OnWednesday," // 5..8
195
+ "OnThursday,OnFriday,OnSaturday,OnSunday " // 9..12
196
+ "FROM S_ResourceType "
197             + "WHERE S_ResourceType_ID=?";
198         try
199         {
200             PreparedStatement pstmt = DB.prepareStatement(sql);
201             pstmt.setInt(1, m_S_ResourceType_ID);
202             ResultSet rs = pstmt.executeQuery();
203             if (rs.next())
204             {
205                 m_typeName = rs.getString(1);
206                 // TimeSlot
207
if ("Y".equals(rs.getString(2)))
208                 {
209                     m_slotStartTime = TimeUtil.getDayTime (m_startDate, rs.getTimestamp(3));
210                     m_slotEndTime = TimeUtil.getDayTime (m_endDate, rs.getTimestamp(4));
211                     if (TimeUtil.inRange(m_startDate, m_endDate, m_slotStartTime, m_slotEndTime))
212                     {
213                         ma = new MAssignmentSlot (m_slotStartTime, m_slotEndTime,
214                             Msg.getMsg(m_ctx, "ResourceNotInSlotTime"), m_typeName,
215                             MAssignmentSlot.STATUS_NotInSlotTime);
216                         if (getAll)
217                             createTimeSlot (list,
218                                 rs.getTimestamp(3), rs.getTimestamp(4));
219                     }
220                 } // TimeSlot
221

222                 // DaySlot
223
if ("Y".equals(rs.getString(5)))
224                 {
225                     if (TimeUtil.inRange(m_startDate, m_endDate,
226                         "Y".equals(rs.getString(6)), "Y".equals(rs.getString(7)), // Mo..Tu
227
"Y".equals(rs.getString(8)), "Y".equals(rs.getString(9)), "Y".equals(rs.getString(10)), // We..Fr
228
"Y".equals(rs.getString(11)), "Y".equals(rs.getString(12))))
229                     {
230                         ma = new MAssignmentSlot (m_startDate, m_endDate,
231                             Msg.getMsg(m_ctx, "ResourceNotInSlotDay"), m_typeName,
232                             MAssignmentSlot.STATUS_NotInSlotDay);
233                         if (getAll)
234                             createDaySlot (list,
235                                 "Y".equals(rs.getString(6)), "Y".equals(rs.getString(7)), // Mo..Tu
236
"Y".equals(rs.getString(8)), "Y".equals(rs.getString(9)), "Y".equals(rs.getString(10)), // We..Fr
237
"Y".equals(rs.getString(11)), "Y".equals(rs.getString(12)));
238                     }
239                 } // DaySlot
240

241             }
242             rs.close();
243             pstmt.close();
244         }
245         catch (SQLException e)
246         {
247             Log.error("MSchedule.getAssignmentSlots-4", e);
248             ma = new MAssignmentSlot (EARLIEST, LATEST,
249                 Msg.getMsg(m_ctx, "ResourceNotInSlotDay"), e.toString(),
250                 MAssignmentSlot.STATUS_NonBusinessDay);
251         }
252         if (ma != null && !getAll)
253             return new MAssignmentSlot[] {ma};
254
255         // Assignments -------------------------------------------------------
256
sql = "SELECT S_ResourceAssignment_ID "
257             + "FROM S_ResourceAssignment "
258             + "WHERE S_Resource_ID=?" // #1
259
+ " AND AssignDateTo >= ?" // #2 start
260
+ " AND AssignDateFrom <= ?" // #3 end
261
+ " AND IsActive='Y'";
262         try
263         {
264             PreparedStatement pstmt = DB.prepareStatement(sql);
265             pstmt.setInt(1, m_S_Resource_ID);
266             pstmt.setTimestamp(2, m_startDate);
267             pstmt.setTimestamp(3, m_endDate);
268             ResultSet rs = pstmt.executeQuery();
269             while (rs.next())
270             {
271                 MAssignment mAssignment = new MAssignment(Env.getCtx(), rs.getInt(1));
272                 ma = new MAssignmentSlot (mAssignment);
273                 if (!getAll)
274                     break;
275                 list.add(ma);
276             }
277             rs.close();
278             pstmt.close();
279         }
280         catch (SQLException e)
281         {
282             Log.error("MSchedule.getAssignmentSlots-5", e);
283             ma = new MAssignmentSlot (EARLIEST, LATEST,
284                 Msg.translate(m_ctx, "S_R"), e.toString(),
285                 MAssignmentSlot.STATUS_NotConfirmed);
286         }
287         if (ma != null && !getAll)
288             return new MAssignmentSlot[] {ma};
289
290         /*********************************************************************/
291
292         // fill m_timeSlots (required for layout)
293
createTimeSlots();
294
295         // Clean list - date range
296
ArrayList clean = new ArrayList(list.size());
297         for (int i = 0; i < list.size(); i++)
298         {
299             MAssignmentSlot mas = (MAssignmentSlot)list.get(i);
300             if ((mas.getStartTime().equals(m_startDate) || mas.getStartTime().after(m_startDate))
301                     && (mas.getEndTime().equals(m_endDate) || mas.getEndTime().before(m_endDate)))
302                 clean.add(mas);
303         }
304         // Delete Unavailability TimeSlots when all day assigments exist
305
MAssignmentSlot[] sorted = new MAssignmentSlot[clean.size()];
306         clean.toArray(sorted);
307         Arrays.sort(sorted, new MAssignmentSlot()); // sorted by start/end date
308
list.clear(); // used as day list
309
clean.clear(); // cleaned days
310
Timestamp sortedDay = null;
311         for (int i = 0; i < sorted.length; i++)
312         {
313             if (sortedDay == null)
314                 sortedDay = TimeUtil.getDay(sorted[i].getStartTime());
315             if (sortedDay.equals(TimeUtil.getDay(sorted[i].getStartTime())))
316                 list.add(sorted[i]);
317             else
318             {
319                 // process info list -> clean
320
layoutSlots (list, clean);
321                 // prepare next
322
list.clear();
323                 list.add(sorted[i]);
324                 sortedDay = TimeUtil.getDay(sorted[i].getStartTime());
325             }
326         }
327         // process info list -> clean
328
layoutSlots (list, clean);
329
330         // Return
331
MAssignmentSlot[] retValue = new MAssignmentSlot[clean.size()];
332         clean.toArray(retValue);
333         Arrays.sort(retValue, new MAssignmentSlot()); // sorted by start/end date
334
return retValue;
335     } // getAssignmentSlots
336

337     /**
338      * Copy valid Slots of a day from list to clear and layout
339      * @param list list with slos of the day
340      * @param clean list with only valid slots
341      */

342     private void layoutSlots (ArrayList list, ArrayList clean)
343     {
344         int size = list.size();
345     // System.out.println("Start List=" + size + ", Clean=" + clean.size());
346
if (size == 0)
347             return;
348         else if (size == 1)
349         {
350             MAssignmentSlot mas = (MAssignmentSlot)list.get(0);
351             layoutY (mas);
352             clean.add (mas);
353             return;
354         }
355
356         // Delete Unavailability TimeSlots when all day assigments exist
357
boolean allDay = false;
358         for (int i = 0; !allDay && i < size; i++)
359         {
360             MAssignmentSlot mas = (MAssignmentSlot)list.get(i);
361             if (mas.getStatus() == MAssignmentSlot.STATUS_NotAvailable
362                 || mas.getStatus() == MAssignmentSlot.STATUS_UnAvailable
363                 || mas.getStatus() == MAssignmentSlot.STATUS_NonBusinessDay
364                 || mas.getStatus() == MAssignmentSlot.STATUS_NotInSlotDay)
365                 allDay = true;
366
367         }
368         if (allDay)
369         {
370             // delete Time Slot
371
for (int i = 0; i < list.size(); i++)
372             {
373                 MAssignmentSlot mas = (MAssignmentSlot)list.get(i);
374                 if (mas.getStatus() == MAssignmentSlot.STATUS_NotInSlotTime)
375                     list.remove(i--);
376             }
377         }
378
379         // Copy & Y layout remaining
380
for (int i = 0; i < list.size(); i++)
381         {
382             MAssignmentSlot mas = (MAssignmentSlot)list.get(i);
383             layoutY (mas);
384             clean.add (mas);
385         }
386
387         // X layout
388
int maxYslots = m_timeSlots.length;
389         int[] xSlots = new int[maxYslots]; // number of parallel slots
390
for (int i = 0; i < list.size(); i++)
391         {
392             MAssignmentSlot mas = (MAssignmentSlot)list.get(i);
393             for (int y = mas.getYStart(); y < mas.getYEnd(); y++)
394                 xSlots[y]++;
395         }
396         // Max parallel X Slots
397
int maxXslots = 0;
398         for (int y = 0; y < xSlots.length; y++)
399         {
400             if (xSlots[y] > maxXslots)
401                 maxXslots = xSlots[y];
402         }
403         // Only one column
404
if (maxXslots < 2)
405         {
406             for (int i = 0; i < list.size(); i++)
407             {
408                 MAssignmentSlot mas = (MAssignmentSlot)list.get(i);
409                 mas.setX(0, 1);
410             }
411             return;
412         }
413
414         // Create xy Matrix
415
ArrayList[][] matrix = new ArrayList[maxXslots][maxYslots];
416         // Populate Matrix first column
417
for (int y = 0; y < maxYslots; y++)
418         {
419             ArrayList xyList = new ArrayList();
420             matrix[0][y] = xyList;
421             // see if one assignment fits into slot
422
for (int i = 0; i < list.size(); i++)
423             {
424                 MAssignmentSlot mas = (MAssignmentSlot)list.get(i);
425                 if (y >= mas.getYStart() && y <= mas.getYEnd())
426                     xyList.add(mas);
427             }
428             // initiate right columns
429
for (int x = 1; x < maxXslots; x++)
430                 matrix[x][y] = new ArrayList();
431         } // for all y slots
432

433         /**
434          * (AB)() -> (B)(A) -> (B)(A)
435          * (BC)() -> (BC)() -> (B)(C)
436          * - if the row above is empty, move the first one right
437          * - else - check col_1..x above and move any content if the same
438          * - if size > 0
439          * - if the element is is not the same as above,
440          * move to the first empty column on the right
441          */

442         // if in one column cell, there is more than one, move it to the right
443
for (int y = 0; y < maxYslots; y++)
444         {
445             // if an element is the same as the line above, move it there
446
if (y > 0 && matrix[0][y].size() > 0)
447             {
448                 for (int x = 1; x < maxXslots; x++)
449                 {
450                     if (matrix[x][y-1].size() > 0) // above slot is not empty
451
{
452                         Object JavaDoc above = matrix[x][y-1].get(0);
453                         for (int i = 0; i < matrix[x][y].size(); i++)
454                         {
455                             if (above.equals(matrix[0][y].get(i))) // same - move it
456
{
457                                 matrix[x][y].add(matrix[0][y].get(i));
458                                 matrix[0][y].remove(i--);
459                             }
460                         }
461                     }
462                 }
463             } // if an element is the same as the line above, move it there
464

465             // we need to move items to the right
466
if (matrix[0][y].size() > 1)
467             {
468                 Object JavaDoc above = null;
469                 if (y > 0 && matrix[0][y-1].size() > 0)
470                     above = matrix[0][y-1].get(0);
471                 //
472
for (int i = 0; matrix[0][y].size() > 1; i++)
473                 {
474                     Object JavaDoc move = matrix[0][y].get(i);
475                     if (!move.equals(above)) // we can move it
476
{
477                         for (int x = 1; move != null && x < maxXslots; x++)
478                         {
479                             if (matrix[x][y].size() == 0) // found an empty slot
480
{
481                                 matrix[x][y].add(move);
482                                 matrix[0][y].remove(i--);
483                                 move = null;
484                             }
485                         }
486                     }
487                 }
488             } // we need to move items to the right
489
} // for all y slots
490

491         // go through the matrix and assign the X position
492
for (int y = 0; y < maxYslots; y++)
493         {
494             for (int x = 0; x < maxXslots; x++)
495             {
496                 if (matrix[x][y].size() > 0)
497                 {
498                     MAssignmentSlot mas = (MAssignmentSlot)matrix[x][y].get(0);
499                     mas.setX(x, xSlots[y]);
500                 }
501             }
502         }
503         // clean up
504
matrix = null;
505     } // layoutSlots
506

507     /**
508      * Layout Y axis
509      * @param mas assignment slot
510      */

511     private void layoutY (MAssignmentSlot mas)
512     {
513         int timeSlotStart = getTimeSlotIndex(mas.getStartTime(), false);
514         int timeSlotEnd = getTimeSlotIndex(mas.getEndTime(), true);
515         if (TimeUtil.isAllDay(mas.getStartTime(), mas.getEndTime()))
516             timeSlotEnd = m_timeSlots.length - 1;
517         //
518
mas.setY (timeSlotStart, timeSlotEnd);
519     } // layoutY
520

521     /**
522      * Return the Time Slot index for the time.
523      * Based on start time and not including end time
524      * @param time time (day is ignored)
525      * @param endTime if true, the end time is included
526      * @return slot index
527      */

528     private int getTimeSlotIndex (Timestamp time, boolean endTime)
529     {
530         // Just one slot
531
if (m_timeSlots.length <= 1)
532             return 0;
533         // search for it
534
for (int i = 0; i < m_timeSlots.length; i++)
535         {
536             if (m_timeSlots[i].inSlot (time, endTime))
537                 return i;
538         }
539         Log.error("MSchedule.getTimeSlotIndex - did not find Slot for " + time + " end=" + endTime);
540         return 0;
541     } // getTimeSlotIndex
542

543
544     /**
545      * Get Basic Info
546      * @param S_Resource_ID resource
547      */

548     private void getBaseInfo (int S_Resource_ID)
549     {
550         // Resource is Active and Available
551
String JavaDoc sql = MRole.getDefault(m_ctx, false).addAccessSQL (
552             "SELECT r.IsActive,r.IsAvailable,null," // r.IsSingleAssignment,"
553
+ "r.S_ResourceType_ID,rt.C_UOM_ID "
554             + "FROM S_Resource r, S_ResourceType rt "
555             + "WHERE r.S_Resource_ID=?"
556             + " AND r.S_ResourceType_ID=rt.S_ResourceType_ID",
557             "r", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO);
558         //
559
try
560         {
561             PreparedStatement pstmt = DB.prepareStatement(sql);
562             pstmt.setInt(1, S_Resource_ID);
563             ResultSet rs = pstmt.executeQuery();
564             if (rs.next())
565             {
566                 if (!"Y".equals(rs.getString(1))) // Active
567
m_isAvailable = false;
568                 if (m_isAvailable && !"Y".equals(rs.getString(2))) // Available
569
m_isAvailable = false;
570                 m_isSingleAssignment = "Y".equals(rs.getString(3));
571                 //
572
m_S_ResourceType_ID = rs.getInt(4);
573                 m_C_UOM_ID = rs.getInt(5);
574             // Log.trace(Log.l6_Database, "- Resource_ID=" + m_S_ResourceType_ID + ",IsAvailable=" + m_isAvailable);
575
}
576             else
577                 m_isAvailable = false;
578             rs.close();
579             pstmt.close();
580         }
581         catch (SQLException e)
582         {
583             Log.error("MSchedule.getBaseInfo", e);
584             m_isAvailable = false;
585         }
586         m_S_Resource_ID = S_Resource_ID;
587     } // getBaseInfo
588

589     /**
590      * Create Unavailable Timeslots.
591      * For every day from startDay..endDay create unavailable slots
592      * for 00:00..startTime and endTime..24:00
593      * @param list list to add time slots to
594      * @param startTime start time in day
595      * @param endTime end time in day
596      */

597     private void createTimeSlot (ArrayList list,
598         Timestamp startTime, Timestamp endTime)
599     {
600     // Log.trace(Log.l5_DData, "MSchedule.createTimeSlot");
601
GregorianCalendar cal = new GregorianCalendar(Language.getLanguage().getLocale());
602         cal.setTimeInMillis(m_startDate.getTime());
603         // End Date for Comparison
604
GregorianCalendar calEnd = new GregorianCalendar(Language.getLanguage().getLocale());
605         calEnd.setTimeInMillis(m_endDate.getTime());
606
607         while (cal.before(calEnd))
608         {
609             // 00:00..startTime
610
cal.set(Calendar.HOUR_OF_DAY, 0);
611             cal.set(Calendar.MINUTE, 0);
612             cal.set(Calendar.SECOND, 0);
613             cal.set(Calendar.MILLISECOND, 0);
614             Timestamp start = new Timestamp (cal.getTimeInMillis());
615             //
616
GregorianCalendar cal_1 = new GregorianCalendar(Language.getLanguage().getLocale());
617             cal_1.setTimeInMillis(startTime.getTime());
618             cal.set(Calendar.HOUR_OF_DAY, cal_1.get(Calendar.HOUR_OF_DAY));
619             cal.set(Calendar.MINUTE, cal_1.get(Calendar.MINUTE));
620             cal.set(Calendar.SECOND, cal_1.get(Calendar.SECOND));
621             Timestamp end = new Timestamp (cal.getTimeInMillis());
622             //
623
MAssignmentSlot ma = new MAssignmentSlot (start, end,
624                 Msg.getMsg(m_ctx, "ResourceNotInSlotTime"), "",
625                 MAssignmentSlot.STATUS_NotInSlotTime);
626             list.add(ma);
627
628             // endTime .. 00:00 next day
629
cal_1.setTimeInMillis(endTime.getTime());
630             cal.set(Calendar.HOUR_OF_DAY, cal_1.get(Calendar.HOUR_OF_DAY));
631             cal.set(Calendar.MINUTE, cal_1.get(Calendar.MINUTE));
632             cal.set(Calendar.SECOND, cal_1.get(Calendar.SECOND));
633             start = new Timestamp (cal.getTimeInMillis());
634             //
635
cal.set(Calendar.HOUR_OF_DAY, 0);
636             cal.set(Calendar.MINUTE, 0);
637             cal.set(Calendar.SECOND, 0);
638             cal.add(Calendar.DAY_OF_YEAR, 1);
639             end = new Timestamp (cal.getTimeInMillis());
640             //
641
ma = new MAssignmentSlot (start, end,
642                 Msg.getMsg(m_ctx, "ResourceNotInSlotTime"), "",
643                 MAssignmentSlot.STATUS_NotInSlotTime);
644             list.add(ma);
645         }
646     } // createTimeSlot
647

648     /**
649      * Create Unavailable Dayslots.
650      * For every day from startDay..endDay create unavailable slots
651      * @param list list to add Day slots to
652      * @param OnMonday true if OK to have appointments (i.e. blocked if false)
653      * @param OnTuesday true if OK
654      * @param OnWednesday true if OK
655      * @param OnThursday true if OK
656      * @param OnFriday true if OK
657      * @param OnSaturday true if OK
658      * @param OnSunday true if OK
659      */

660     private void createDaySlot (ArrayList list,
661         boolean OnMonday, boolean OnTuesday, boolean OnWednesday,
662         boolean OnThursday, boolean OnFriday, boolean OnSaturday, boolean OnSunday)
663     {
664     // Log.trace(Log.l5_DData, "MSchedule.createDaySlot");
665
GregorianCalendar cal = new GregorianCalendar(Language.getLanguage().getLocale());
666         cal.setTimeInMillis(m_startDate.getTime());
667         // End Date for Comparison
668
GregorianCalendar calEnd = new GregorianCalendar(Language.getLanguage().getLocale());
669         calEnd.setTimeInMillis(m_endDate.getTime());
670
671         while (cal.before(calEnd))
672         {
673             int weekday = cal.get(Calendar.DAY_OF_WEEK);
674             if ((!OnSaturday && weekday == Calendar.SATURDAY)
675                 || (!OnSunday && weekday == Calendar.SUNDAY)
676                 || (!OnMonday && weekday == Calendar.MONDAY)
677                 || (!OnTuesday && weekday == Calendar.TUESDAY)
678                 || (!OnWednesday && weekday == Calendar.WEDNESDAY)
679                 || (!OnThursday && weekday == Calendar.THURSDAY)
680                 || (!OnFriday && weekday == Calendar.FRIDAY))
681             {
682                 // 00:00..00:00 next day
683
cal.set(Calendar.HOUR_OF_DAY, 0);
684                 cal.set(Calendar.MINUTE, 0);
685                 cal.set(Calendar.SECOND, 0);
686                 cal.set(Calendar.MILLISECOND, 0);
687                 Timestamp start = new Timestamp (cal.getTimeInMillis());
688                 cal.add(Calendar.DAY_OF_YEAR, 1);
689                 Timestamp end = new Timestamp (cal.getTimeInMillis());
690
691                 MAssignmentSlot ma = new MAssignmentSlot (start, end,
692                     Msg.getMsg(m_ctx, "ResourceNotInSlotDay"), "",
693                     MAssignmentSlot.STATUS_NotInSlotDay);
694                 list.add(ma);
695             }
696             else // next day
697
cal.add(Calendar.DAY_OF_YEAR, 1);
698         }
699     } // createDaySlot
700

701     /**
702      * Create a day slot for range
703      * @param list list
704      * @param ma assignment
705      */

706     private void createDaySlot (ArrayList list, MAssignmentSlot ma)
707     {
708     // Log.trace(Log.l5_DData, "MSchedule.createDaySlot", ma);
709
//
710
Timestamp start = ma.getStartTime();
711         GregorianCalendar calStart = new GregorianCalendar();
712         calStart.setTime(start);
713         calStart.set(Calendar.HOUR_OF_DAY, 0);
714         calStart.set(Calendar.MINUTE, 0);
715         calStart.set(Calendar.SECOND, 0);
716         calStart.set(Calendar.MILLISECOND, 0);
717         Timestamp end = ma.getEndTime();
718         GregorianCalendar calEnd = new GregorianCalendar();
719         calEnd.setTime(end);
720         calEnd.set(Calendar.HOUR_OF_DAY, 0);
721         calEnd.set(Calendar.MINUTE, 0);
722         calEnd.set(Calendar.SECOND, 0);
723         calEnd.set(Calendar.MILLISECOND, 0);
724         //
725
while (calStart.before(calEnd))
726         {
727             Timestamp xStart = new Timestamp(calStart.getTimeInMillis());
728             calStart.add(Calendar.DAY_OF_YEAR, 1);
729             Timestamp xEnd = new Timestamp(calStart.getTimeInMillis());
730             MAssignmentSlot myMa = new MAssignmentSlot (xStart, xEnd,
731                 ma.getName(), ma.getDescription(), ma.getStatus());
732             list.add(myMa);
733         }
734     } // createDaySlot
735

736     /*************************************************************************/
737
738     /**
739      * Get Day Time Slots for Date
740      * @return "heading" or null
741      */

742     public MAssignmentSlot[] getDayTimeSlots ()
743     {
744         return m_timeSlots;
745     } // getDayTimeSlots
746

747     /**
748      * Create Time Slots
749      */

750     private void createTimeSlots()
751     {
752         // development error
753
if (m_typeName == null)
754             throw new IllegalStateException JavaDoc("ResourceTyoeName not set");
755
756         ArrayList list = new ArrayList();
757         UOM uom = UOM.get (m_ctx, m_C_UOM_ID);
758         int minutes = UOMConversion.convertToMinutes (m_ctx, m_C_UOM_ID, UOMConversion.ONE);
759         Log.trace(Log.l4_Data, "MSchedule.createDayTimeSlots", "Minutes=" + minutes);
760         //
761
if (minutes > 0 && minutes < 60*24)
762         {
763             // Set Start Time
764
GregorianCalendar cal = new GregorianCalendar();
765             cal.setTime(m_startDate);
766             cal.set(Calendar.HOUR_OF_DAY, 0);
767             cal.set(Calendar.MINUTE, 0);
768             cal.set(Calendar.SECOND, 0);
769             cal.set(Calendar.MILLISECOND, 0);
770             // we have slots - create first
771
if (m_slotStartTime != null)
772             {
773                 long start = cal.getTimeInMillis();
774                 cal.setTime(TimeUtil.getDayTime(m_startDate, m_slotStartTime)); // set to start time
775
cal.set(Calendar.SECOND, 0);
776                 cal.set(Calendar.MILLISECOND, 0);
777                 list.add(new MAssignmentSlot(start, cal.getTimeInMillis()));
778             }
779             // Set End Time
780
GregorianCalendar calEnd = new GregorianCalendar();
781             if (m_slotEndTime != null)
782             {
783                 calEnd.setTime(TimeUtil.getDayTime(m_startDate, m_slotEndTime));
784                 calEnd.set(Calendar.SECOND, 0);
785                 calEnd.set(Calendar.MILLISECOND, 0);
786             }
787             else // No Slot - all day
788
{
789                 calEnd.setTime(m_startDate);
790                 calEnd.set(Calendar.HOUR_OF_DAY, 0);
791                 calEnd.set(Calendar.MINUTE, 0);
792                 calEnd.set(Calendar.SECOND, 0);
793                 calEnd.set(Calendar.MILLISECOND, 0);
794                 calEnd.add(Calendar.DAY_OF_YEAR, 1);
795             }
796 //System.out.println("Start=" + new Timestamp(cal.getTimeInMillis()));
797
//System.out.println("Endt=" + new Timestamp(calEnd.getTimeInMillis()));
798

799             // Set end Slot Time
800
GregorianCalendar calEndSlot = new GregorianCalendar();
801             calEndSlot.setTime(cal.getTime());
802             calEndSlot.add(Calendar.MINUTE, minutes);
803
804             while (cal.before(calEnd))
805             {
806                 list.add(new MAssignmentSlot(cal.getTimeInMillis(), calEndSlot.getTimeInMillis()));
807                 // Next Slot
808
cal.add(Calendar.MINUTE, minutes);
809                 calEndSlot.add(Calendar.MINUTE, minutes);
810             }
811             // create last slot
812
calEndSlot.setTime(cal.getTime());
813             calEndSlot.set(Calendar.HOUR_OF_DAY, 0);
814             calEndSlot.set(Calendar.MINUTE, 0);
815             calEndSlot.set(Calendar.SECOND, 0);
816             calEndSlot.set(Calendar.MILLISECOND, 0);
817             calEndSlot.add(Calendar.DAY_OF_YEAR, 1); // 00:00 next day
818
list.add(new MAssignmentSlot(cal.getTimeInMillis(), calEndSlot.getTimeInMillis()));
819         }
820
821         else // Day, ....
822
{
823             list.add (new MAssignmentSlot(TimeUtil.getDay(m_startDate), TimeUtil.getNextDay(m_startDate)));
824         }
825
826         //
827
m_timeSlots = new MAssignmentSlot[list.size()];
828         list.toArray(m_timeSlots);
829     } // createTimeSlots
830

831     /*************************************************************************/
832
833     /**
834      * Get Resource ID. Set by getAssignmentSlots
835      * @return current resource
836      */

837     public int getS_Resource_ID()
838     {
839         return m_S_Resource_ID;
840     } // getS_Resource_ID
841

842     /**
843      * Return Start Date. Set by getAssignmentSlots
844      * @return start date
845      */

846     public Timestamp getStartDate ()
847     {
848         return m_startDate;
849     } // getStartDate
850

851     /**
852      * Return End Date. Set by getAssignmentSlots
853      * @return end date
854      */

855     public Timestamp getEndDate ()
856     {
857         return m_endDate;
858     } // getEndDate
859

860 } // MSchedule
861
Popular Tags