]> git.llucax.com Git - mecon/meconlib.git/blob - lib/MECON/Tiempo/Banda.php
Generalizacion de Arbol
[mecon/meconlib.git] / lib / MECON / Tiempo / Banda.php
1 <?php
2 // vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4:
3 // +--------------------------------------------------------------------+
4 // |                          HORAS EXTRA                               |
5 // +--------------------------------------------------------------------+
6 // |    Sistema de Horas Extra - Ministerio de Economía - Argentina     |
7 // +--------------------------------------------------------------------+
8 // | Creado: lun abr 22 16:05:33 ART 2002                               |
9 // | Autor:  Gonzalo Merayo <gmeray@mecon.gov.ar>                    |
10 // +--------------------------------------------------------------------+
11 //
12 // $URL$
13 // $Rev$
14 // $Date$
15 // $Author$
16 //
17
18 require_once 'DB.php'; // FIXME - esto debe volar!!!
19 require_once 'MECON/Tiempo/Intervalo.php';
20
21 /**
22  * Representa un conjunto de entradas y salidas para formar una banda horaria
23  *
24  * @package HE
25  * @abstract
26  * @version $Rev$
27  * @author  Gonzalo Merayo <gmeray@mecon.gov.ar>
28  */
29 class Banda {
30
31   var $intervalos;
32
33   function Banda() {
34     $this->intervalos = array();
35   }
36  
37   function Cargar($agente, $fecha)
38   {
39     // FIXME - lo que es base de datos debe VOLAR!!!!!!!
40     $dsn = "mysql://intranet:intranet@intranet-db/bandas";
41     $db =& DB::connect($dsn , true);
42     if(DB::isError($db))
43       die($db->getMessage());
44
45     $funcion = $db->getOne(
46         "SELECT E.funcion
47             FROM novedades.estado as E, novedades.web003 as S
48             WHERE
49                 E.nrodoc = $agente AND
50                 S.nrodoc = $agente AND
51                 S.codep  = E.dependencia"
52     );
53
54     $fecha = $fecha->format("%Y%m%d");
55     $query = "SELECT A.tipo_acceso, A.hora 
56               FROM agentes G, accesos A
57               WHERE G.cred = A.cred
58               AND G.docu = $agente
59               AND A.fecha = $fecha
60               AND A.inconsistencia = 0
61               ORDER BY A.hora";
62     $result = $db->query($query);
63     if(DB::isError($result))
64       die($result->getMessage());
65
66     if($funcion != 'SE')
67     {//Version tough
68       $int == null;
69       while( $r = $result->fetchRow() )
70       {
71         if($r[0] == 'E') $int = new Intervalo(new Hora( $r[1] ), new Hora( $r[1] ));
72         if($r[0] == 'S' && $int != null)
73         {
74           $int->setFin( new Hora( $r[1] ) );
75           $this->agregarIntervalo( $int );
76           $int = null;
77         }
78       }
79     }
80     else
81     {
82       if($result->numRows() > 0)
83       {//Version Light o Serenos
84         $int = new Intervalo(new Hora('00:00'), new Hora('00:00'));
85         while( $r = $result->fetchRow() )
86         {
87           if($r[0] == 'E') $int = new Intervalo(new Hora( $r[1] ), new Hora( $r[1] ));
88           if($r[0] == 'S' && $int != null)
89           {
90             $int->setFin( new Hora( $r[1] ) );
91             $this->agregarIntervalo( $int );
92             $int = null;
93           }
94         }
95         if($int != null)
96         {
97           $int->setFin( new Hora('24:00') );
98           $this->agregarIntervalo( $int );
99           $int = null;
100         }
101       }
102     }
103   }
104
105   /*
106   *
107   * Completa las salidas del medio del dia.
108   *
109   */
110   function CompletarSalidas()
111   {
112     if(count($this->intervalos) > 0)
113     {
114       $p = reset($this->intervalos);
115       $u = end($this->intervalos);
116       $p->setFin($u->fin);
117       $this->intervalos = array($p);
118     }
119   }
120
121
122   /**
123   * Agrega un intervalo a la banda
124   * Chequeando superposiciones y en orden
125   *
126   * @param Intervalo $intervalo Intervalo a agregar.
127   */
128   function agregarIntervalo($intervalo)
129   {
130     if(! is_a($intervalo, "intervalo")) return false;
131     if ($intervalo->invertido()) {
132         $intervalo->_chequear();
133         $this->agregarIntervalo(new Intervalo(new Hora('00:00'), new Hora ('24:00')));
134         $this->sacarIntervalo($intervalo);
135         return true;
136     }
137     $n_intervalos = array();
138     $insertado = false;
139     // recorre el vector de intervalos
140     foreach( $this->intervalos as $i )
141     {
142       // si se superpone con alguno, fusionar con ese
143       if($i->seSuperpone($intervalo))
144         $intervalo->fusionar($i);
145       else{
146         if($i->inicio->greater($intervalo->inicio) && ! $insertado)
147         {
148           array_push($n_intervalos, $intervalo);
149           $insertado = true;
150         }
151         array_push($n_intervalos, $i);
152       }
153     }
154     if(! $insertado ) array_push($n_intervalos,$intervalo);
155     $this->intervalos = $n_intervalos;
156     return true;
157   }
158
159   /**
160   * Saca 
161   *
162   *
163   */
164   function sacarBanda($banda)
165   {
166     foreach($banda->intervalos as $i)
167       $this->sacarIntervalo($i);
168   }
169
170   /**
171   * Saca un intervalo de una banda horaria.
172   *
173   */
174   function sacarIntervalo($intervalo)
175   {
176     if(! is_a($intervalo, "intervalo")) return false;
177     // Si el intervalo está vacío, no hace nada.
178     $dur = $intervalo->getDuracion();
179     if ($dur->isEmpty()) {
180         return true;
181     }
182     $n_intervalos = array();
183     // recorre el vector de intervalos
184     foreach( $this->intervalos as $i )
185     {
186       if($i->seSuperpone($intervalo)) {
187         $a = $i->cortar($intervalo);
188         $d = $a->getDuracion();
189         if($d->toSeconds() > 0) {
190           $n_intervalos[] = $a;
191         }
192         $d = $i->getDuracion();
193         if($d->toSeconds() > 0) {
194           $n_intervalos[] = $i;
195         }
196       } else {
197         $n_intervalos[] = $i;
198       }
199     }
200     $this->intervalos = $n_intervalos;
201     return true;
202     
203   }
204
205   function sacarTiempo($t)
206   {
207     if(! is_a($t, "date_span")) return false;
208     $n_int = array();
209     while(count($this->intervalos) > 0)
210     {
211       $int = array_shift($this->intervalos);
212       if($t->toSeconds() > 0){
213         $d = $int->getDuracion();
214         if($d->greater($t))
215         {
216           #con cortar alcanza
217           $ini = new Hora();
218           $ini->copy($int->inicio);
219           $ini->add($t);
220           /*TODO guardar este tiempo como rechazado*/$int->cortar($ini);
221           $t->setFromSeconds(0);
222         }else{
223           #con cortar no alcanza y hay que sacar...
224           $t->subtract($int->getDuracion());
225           /*TODO guardar int como rechazado*/
226         }
227       }
228       $n_int[] = $int;
229     }
230     $this->intervalos = $n_int;
231   }
232
233   /*
234   * Chequea si el intervalo pedido esta cubierto por la banda, si faltan
235   *  horas en la banta se retorna el tiempo que falta
236   *
237   * @return Date_Span el periodo faltante
238   *
239   */
240   function chequearIntervalo($intervalo)
241   {
242     if(! is_a($intervalo, "intervalo")) return false;
243     $t = new Hora();
244     foreach ($this->intervalos as $i)
245       $t->add($i->superponer($intervalo));
246     $d = $intervalo->getDuracion();
247     $d->subtract($t);
248     return $d;
249   }
250
251   /*
252   * Chequea si la banda(parametro) esta cubierto por la banda(this),
253   *  si faltan horas en la banda(this) para llegar a banda(parametro)
254   *  se retorna el tiempo que falta
255   *
256   * @return Date_Span el periodo faltante
257   *
258   */
259   function chequearBanda($banda)
260   {
261     if(! is_a($banda, "banda")) return false;
262     $f = new Hora();
263     foreach ($banda->intervalos as $i)
264       $f->add($this->chequearIntervalo($i));
265     return $f;
266   }
267
268
269   /*
270   * Devuelve una representacion del objeto como un string.
271   *
272   * @return string Representacion del objeto.
273   *
274   */
275   function toString()
276   {
277     $s = '';
278     $t = count($this->intervalos);
279     for ($n = 0; $n < ($t - 1); $n++) {
280         $s .= "intervalo $n: [" . $this->intervalos[$n]->toString() . '] | ';
281     }
282     $n = $t - 1;
283     if ($n != -1) {
284         $s .= "intervalo $n: [" . $this->intervalos[$n]->toString() . ']';
285     }
286     return $s;
287   }
288
289   function getIntervalos() {
290     return $this->intervalos;
291   }
292
293   /**
294    * Corta una banda, devolviendo la banda previa al punto de corte.
295    *
296    * La banda actual queda con los intervalos posteriores al punto de corte
297    * y se devuelve la banda con los intervalos anteriores.
298    * El punto de corte puede ser tanto una hora como un intervalo.
299    *
300    * @param mixed $c Donde cortar.
301    *
302    * @return object Banda Bnada anterior al punto de corte.
303    */
304   function cortar($c)
305   {
306     if(!is_a($c, 'hora') and !is_a($c, 'intervalo')) return false;
307     $b = $this->__clone();
308     $b->intervalos = array();
309     $intervalos = array();
310     foreach ($this->intervalos as $i) {
311       $a = $i->cortar($c);
312       $da = $a->getDuracion();
313       if (!$da->isEmpty()) {
314         $b->agregarIntervalo($a);
315       }
316       $di = $i->getDuracion();
317       if (!$di->isEmpty()) {
318         $intervalos[] = $i;
319       }
320     }
321     $this->intervalos = $intervalos;
322     return $b;
323   }
324
325   /**
326    * Devuelve el timpo total que contiene la banda.
327    *
328    * @return object Date_Span Tiempo total.
329    */
330   function total() {
331     $t = new Date_Span;
332     foreach ($this->intervalos as $i) {
333       $t->add($i->getDuracion());
334     }
335     return $t;
336   }
337
338   /**
339    * Alias de Banda::total() para compatibilidad con Intervalo.
340    *
341    * @return object Date_Span Tiempo total.
342    */
343   function getDuracion() {
344     return $this->total();
345   }
346
347   /**
348    * Resetea la banda.
349    */
350   function flush() {
351     $this->intervalos = array();
352   }
353
354   function copy($b) {
355     $this->flush();
356     foreach ($b->intervalos as $i) {
357       $this->intervalos[] = $i->__clone();
358     }
359   }
360
361   function __clone() {
362     $class = get_class($this);
363     $b = new $class;
364     $b->copy($this);
365     return $b;
366   }
367
368 }
369
370 // $Id$
371 ?>