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