View Javadoc

1   /*
2    *  File: PersonenDisposition.java 
3    *  Copyright (c) 2004-2007  Peter Kliem (Peter.Kliem@jaret.de)
4    *  A commercial license is available, see http://www.jaret.de.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation; either version 2 of the License, or
9    *  (at your option) any later version.
10   *
11   *  This program is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   *  GNU General Public License for more details.
15   *
16   *  You should have received a copy of the GNU General Public License
17   *  along with this program; if not, write to the Free Software
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  package de.jaret.examples.timebars.pdi.model;
21  
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.Comparator;
25  import java.util.Iterator;
26  import java.util.List;
27  
28  import de.jaret.util.date.Interval;
29  import de.jaret.util.date.JaretDate;
30  import de.jaret.util.ui.timebars.model.AbstractTimeBarRowModel;
31  
32  /***
33   * @author Peter Kliem
34   * @version $Id: PersonenDisposition.java 259 2007-02-16 13:54:00Z olk $
35   */
36  public class PersonenDisposition extends AbstractTimeBarRowModel {
37      protected PdiCalendar _kalender;
38      protected Person _person;
39      protected List _verplanungen = new ArrayList();
40      protected List _rfgRules = new ArrayList();
41  
42      public PersonenDisposition(PdiCalendar kalender, Person person) {
43          _kalender = kalender;
44          _person = person;
45          setRowHeader(_person);
46          _rfgRules.add(new Max10hin24h());
47          _rfgRules.add(new Max60hin7Tagen());
48      }
49  
50      /***
51       * {@inheritDoc}
52       */
53      public List getIntervals() {
54          return _verplanungen;
55      }
56  
57      public void addDienst(Duty dienst) {
58          Assignment v = new Assignment(dienst.getTag(), dienst, this);
59          dienst.setAssignedTo(_person);
60          _verplanungen.add(v);
61          Collections.sort(_verplanungen, new Comparator() {
62              public int compare(Object arg0, Object arg1) {
63                  Interval i1 = (Interval) arg0;
64                  Interval i2 = (Interval) arg1;
65  
66                  return i1.getBegin().compareTo(i2.getBegin());
67              }
68          });
69          check(dienst);
70          fireElementAdded(v);
71      }
72  
73      public void remVerplanung(Assignment verplanung) {
74          _verplanungen.remove(verplanung);
75          if (verplanung.getTaetigkeit() instanceof Duty) {
76              ((Duty) verplanung.getTaetigkeit()).setAssignedTo(null);
77              verplanung.getTaetigkeit().clearProbleme();
78          }
79          checkRow();
80          fireElementRemoved(verplanung);
81      }
82  
83      /***
84       * {@inheritDoc}
85       */
86      public JaretDate getMinDate() {
87          return _kalender.getMinDate();
88      }
89  
90      public JaretDate getMaxDate() {
91          return _kalender.getMaxDate();
92      }
93  
94      /***
95       * @param dd
96       * @return
97       */
98      public boolean allowed(Duty dd) {
99          Iterator it = _verplanungen.iterator();
100         while (it.hasNext()) {
101             Assignment verp = (Assignment) it.next();
102             if (verp.intersects(dd)) {
103                 return false;
104             }
105         }
106         return true;
107     }
108 
109     public String toString() {
110         return "PDispo:" + _person.getName();
111     }
112 
113     /***
114      * @return Returns the kalender.
115      */
116     public PdiCalendar getKalender() {
117         return _kalender;
118     }
119 
120     /***
121      * @return Returns the person.
122      */
123     public Person getPerson() {
124         return _person;
125     }
126 
127     public void check(Taetigkeit taetigkeit) {
128         taetigkeit.clearProbleme();
129         Iterator it = _rfgRules.iterator();
130         while (it.hasNext()) {
131             RfgRule rule = (RfgRule) it.next();
132             rule.check(this, taetigkeit);
133         }
134     }
135 
136     public void checkRow() {
137         Iterator it = getIntervals().iterator();
138         while (it.hasNext()) {
139             Taetigkeit taetigkeit = ((Assignment) it.next()).getTaetigkeit();
140             check(taetigkeit);
141         }
142     }
143 
144     public Taetigkeit getTaetigkeit(int idx) {
145         return ((Assignment) getIntervals().get(idx)).getTaetigkeit();
146     }
147 
148     /***
149      * @param taetigkeit
150      * @return
151      */
152     public int indexOf(Taetigkeit taetigkeit) {
153         for (int i = 0; i < getIntervals().size(); i++) {
154             if (taetigkeit == getTaetigkeit(i)) {
155                 return i;
156             }
157         }
158         throw new RuntimeException("not found");
159     }
160 
161     class Max10hin24h implements RfgRule {
162 
163         /***
164          * {@inheritDoc}
165          */
166         public boolean check(PersonenDisposition pdispo, Taetigkeit taetigkeit) {
167             // nach vorne checken bis Anfang > 24h von Anfang der Tätigkeit weg
168             int idx = pdispo.indexOf(taetigkeit);
169             int i = idx - 1;
170             while (i >= 0 && taetigkeit.getBegin().diffSeconds(pdispo.getTaetigkeit(i).getBegin()) < 24 * 60 * 60) {
171                 checknachHinten(pdispo, pdispo.getTaetigkeit(i));
172                 i--;
173             }
174             // und selbst nach hinten checken
175             checknachHinten(pdispo, taetigkeit);
176             return true;
177         }
178 
179         /***
180          * @param pdispo
181          * @param taetigkeit
182          */
183         private void checknachHinten(PersonenDisposition pdispo, Taetigkeit taetigkeit) {
184             // System.out.println("Check "+((Dienst)taetigkeit).getDienstNr());
185             int az = taetigkeit.getBezahlteZeitSeconds();
186             int idx = pdispo.indexOf(taetigkeit) + 1;
187             // System.out.println("idx "+idx+" diff
188             // "+pdispo.getTaetigkeit(idx).getBegin().diffSeconds(taetigkeit.getBegin()));
189             while (idx < pdispo.getIntervals().size()
190                     && pdispo.getTaetigkeit(idx).getBegin().diffSeconds(taetigkeit.getBegin()) < 24 * 60 * 60) {
191                 // System.out.println("index "+idx+ "az "+az);
192                 int alteAz = az;
193                 az += pdispo.getTaetigkeit(idx).getBezahlteZeitSeconds();
194                 if (az > 10 * 60 * 60) {
195                     int diff = 10 * 60 * 60 - alteAz;
196                     JaretDate vorbei = pdispo.getTaetigkeit(idx).getBegin().copy();
197                     vorbei.advanceSeconds(diff);
198                     taetigkeit.addProblem("<b>" + getName() + "</b>: Überschritten etwa bei "
199                             + vorbei.toDisplayString() + "<br/");
200                     break;
201                 }
202                 idx++;
203             }
204         }
205 
206         /***
207          * {@inheritDoc}
208          */
209         public String getName() {
210             return "Max. 10h in 24h";
211         }
212 
213         /***
214          * {@inheritDoc}
215          */
216         public String getDescription() {
217             return "Nach Arbeitszeitgesetz max. 10 Stunden schutzrechtliche Arbeitszeit innerhalb 24h vom 1. Dienstbeginn zählend";
218         }
219 
220     }
221 
222     class Max60hin7Tagen implements RfgRule {
223 
224         /***
225          * {@inheritDoc}
226          */
227         public boolean check(PersonenDisposition pdispo, Taetigkeit taetigkeit) {
228             // nach vorne checken bis Anfang > 7*24h von Anfang der Tätigkeit
229             // weg
230             int idx = pdispo.indexOf(taetigkeit);
231             int i = idx - 1;
232             while (i >= 0 && taetigkeit.getBegin().diffSeconds(pdispo.getTaetigkeit(i).getBegin()) < 7 * 24 * 60 * 60) {
233                 checknachHinten(pdispo, pdispo.getTaetigkeit(i));
234                 i--;
235             }
236             // und selbst nach hinten checken
237             checknachHinten(pdispo, taetigkeit);
238             return true;
239         }
240 
241         private void checknachHinten(PersonenDisposition pdispo, Taetigkeit taetigkeit) {
242             int az = taetigkeit.getBezahlteZeitSeconds();
243             int idx = pdispo.indexOf(taetigkeit) + 1;
244             // System.out.println("idx "+idx+" diff
245             // "+pdispo.getTaetigkeit(idx).getBegin().diffSeconds(taetigkeit.getBegin()));
246             while (idx < pdispo.getIntervals().size()
247                     && pdispo.getTaetigkeit(idx).getBegin().diffSeconds(taetigkeit.getBegin()) < 7 * 24 * 60 * 60) {
248                 int alteAz = az;
249                 az += pdispo.getTaetigkeit(idx).getBezahlteZeitSeconds();
250                 if (az > 60 * 60 * 60) {
251                     int diff = 60 * 60 * 60 - alteAz;
252                     JaretDate vorbei = pdispo.getTaetigkeit(idx).getBegin().copy();
253                     vorbei.advanceSeconds(diff);
254                     taetigkeit.addProblem("<b>" + getName() + "</b>: Überschritten etwa bei "
255                             + vorbei.toDisplayString() + "<br/");
256                     break;
257                 }
258                 idx++;
259             }
260         }
261 
262         /***
263          * {@inheritDoc}
264          */
265         public String getName() {
266             return "Max 60h in 7 Tagen";
267         }
268 
269         /***
270          * {@inheritDoc}
271          */
272         public String getDescription() {
273             return "55h Arbeitszeit (bezahlte Zeit!) innerhalb von 7 aufeinanderfolgenden Tagen (laufend, nicht wochenbezogen) dürfen bei der Planung nicht überschritten werden. Bei Nichteinhaltung Anzeige, ab welchem Tag bzw. Woche. In der Disposition sind 60h möglich";
274         }
275 
276     }
277 
278 }