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