1 <?php /* vim: set binary expandtab tabstop=4 shiftwidth=4 textwidth=80:
2 -------------------------------------------------------------------------------
5 -------------------------------------------------------------------------------
6 This file is part of meconlib.
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)
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.
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 -------------------------------------------------------------------------------
25 -----------------------------------------------------------------------------*/
27 require_once 'DB.php'; // FIXME - esto debe volar!!!
28 require_once 'MECON/Tiempo/Intervalo.php';
31 * Representa un conjunto de entradas y salidas para formar una banda horaria
36 * @author Gonzalo Merayo <gmeray@mecon.gov.ar>
38 class MECON_Tiempo_Banda {
45 * @param $db Conexión opcional a una base de datos.
47 function MECON_Tiempo_Banda($db = null)
50 $this->intervalos = array();
54 * Funcion que se encarga de cargar los intervalos de tiempo de un agente.
55 * Devuelve true en caso de detectar una inconsistecia de reloj o false en caso contrario
57 * @param $agente Documento del agente
58 * @param $accesos Array o Date Variable que puede ser un array con todos los accesos
59 * de un agente o un objeto Date que indica la fecha de la banda a procesar
60 * @param $db Conexión opcional a una base de datos.
62 function cargar($agente, $accesos, $db = null)
68 $funcion = $this->db->getOne(
70 FROM novedades.estado as E, novedades.web003 as S
72 E.nrodoc = $agente AND
73 S.nrodoc = $agente AND
74 S.codep = E.dependencia"
77 if (is_a($accesos,'date')) {
79 $fecha = $fecha->format("%Y%m%d");
80 $query = "SELECT TA.tipo_acceso, A.hora
81 FROM Acceso A, Agente_Credencial AC, Tipo_Acceso TA
82 WHERE AC.credencial = A.credencial
83 AND A.fecha = '$fecha'
84 AND AC.agente = $agente
85 AND TA.puerta = A.puerta
86 AND AC.desde <= '$fecha'
87 AND ( AC.hasta >= '$fecha'
90 $result = $this->db->query($query);
91 if(DB::isError($result))
92 trigger_error($result->getMessage(), E_USER_ERROR);
94 $inconsistencia = false;
98 while( $r = $result->fetchRow() )
103 $inconsistencia = true;
104 $int = new Mecon_Tiempo_Intervalo(new Mecon_Tiempo_Hora( $r[1] ),
105 new Mecon_Tiempo_Hora( $r[1] ));
111 $int->setFin( new Mecon_Tiempo_Hora( $r[1] ) );
112 $this->agregarIntervalo( $int );
116 $inconsistencia = true;
120 $inconsistencia = true;
124 if($result->numRows() > 0)
125 {//Version Light o Serenos
126 $int = new Mecon_Tiempo_Intervalo(new Mecon_Tiempo_Hora('00:00'),
127 new Mecon_Tiempo_Hora('00:00'));
128 while( $r = $result->fetchRow() )
133 //$inconsistencia = true;
134 $int = new Mecon_Tiempo_Intervalo(new Mecon_Tiempo_Hora( $r[1] ),
135 new Mecon_Tiempo_Hora( $r[1] ));
141 $int->setFin( new Mecon_Tiempo_Hora( $r[1] ) );
142 $this->agregarIntervalo( $int );
146 // $inconsistencia = true;
151 $int->setFin( new Hora('24:00') );
152 $this->agregarIntervalo( $int );
160 $inconsistencia = false;
164 if(!is_null($accesos))
166 foreach( $accesos as $r )
171 $inconsistencia = true;
172 $int = new Mecon_Tiempo_Intervalo(new Mecon_Tiempo_Hora( $r[1] ),
173 new Mecon_Tiempo_Hora( $r[1] ));
179 $int->setFin( new Mecon_Tiempo_Hora( $r[1] ) );
180 $this->agregarIntervalo( $int );
184 $inconsistencia = true;
189 $inconsistencia = true;
193 //Version Light o Serenos
194 $int = new Mecon_Tiempo_Intervalo(new Mecon_Tiempo_Hora('00:00'),
195 new Mecon_Tiempo_Hora('00:00'));
197 if(!is_null($accesos))
199 foreach( $accesos as $r )
204 //$inconsistencia = true;
205 $int = new Mecon_Tiempo_Intervalo(new Mecon_Tiempo_Hora( $r[1] ),
206 new Mecon_Tiempo_Hora( $r[1] ));
212 $int->setFin( new Mecon_Tiempo_Hora( $r[1] ) );
213 $this->agregarIntervalo( $int );
217 // $inconsistencia = true;
223 $int->setFin( new Hora('24:00') );
224 $this->agregarIntervalo( $int );
229 return $inconsistencia;
233 * Completa las salidas del medio del dia.
236 function CompletarSalidas()
238 if(count($this->intervalos) > 0) {
239 $p = reset($this->intervalos);
240 $u = end($this->intervalos);
242 $this->intervalos = array($p);
248 * Agrega un intervalo a la banda
249 * Chequeando superposiciones y en orden
251 * @param Intervalo $intervalo Intervalo a agregar.
253 function agregarIntervalo($intervalo)
255 if ($intervalo->invertido()) {
256 $intervalo->_chequear();
257 $this->agregarIntervalo(new MECON_Tiempo_Intervalo(new MECON_Tiempo_Hora('00:00'), new MECON_Tiempo_Hora ('24:00')));
258 $this->sacarIntervalo($intervalo);
261 $n_intervalos = array();
263 // recorre el vector de intervalos
264 foreach( $this->intervalos as $i ) {
265 // si se superpone con alguno, fusionar con ese
266 if($i->seSuperpone($intervalo)) {
267 $intervalo->fusionar($i);
269 if($i->inicio->greater($intervalo->inicio) && ! $insertado) {
270 array_push($n_intervalos, $intervalo);
273 array_push($n_intervalos, $i);
277 array_push($n_intervalos,$intervalo);
278 $this->intervalos = $n_intervalos;
285 function sacarBanda($banda)
287 foreach($banda->intervalos as $i)
288 $this->sacarIntervalo($i);
292 * Saca un intervalo de una banda horaria.
294 function sacarIntervalo($intervalo)
296 // Si el intervalo está vacío, no hace nada.
297 $dur = $intervalo->getDuracion();
298 if ($dur->isEmpty()) {
301 $n_intervalos = array();
302 // recorre el vector de intervalos
303 foreach( $this->intervalos as $i ) {
304 if($i->seSuperpone($intervalo)) {
305 $a = $i->cortar($intervalo);
306 $d = $a->getDuracion();
307 if($d->toSeconds() > 0) {
308 $n_intervalos[] = $a;
310 $d = $i->getDuracion();
311 if($d->toSeconds() > 0) {
312 $n_intervalos[] = $i;
315 $n_intervalos[] = $i;
318 $this->intervalos = $n_intervalos;
326 function sacarTiempo($t)
329 while(count($this->intervalos) > 0) {
330 $int = array_shift($this->intervalos);
331 if($t->toSeconds() > 0) {
332 $d = $int->getDuracion();
333 if($d->greater($t)) {
335 $ini = new MECON_Tiempo_Hora();
336 $ini->copy($int->inicio);
338 /*TODO guardar este tiempo como rechazado*/
340 $t->setFromSeconds(0);
342 #con cortar no alcanza y hay que sacar...
343 $t->subtract($int->getDuracion());
344 /*TODO guardar int como rechazado*/
349 $this->intervalos = $n_int;
353 * Chequea si el intervalo pedido esta cubierto por la banda, si faltan
354 * horas en la banta se retorna el tiempo que falta
356 * @return Date_Span el periodo faltante
358 function chequearIntervalo($intervalo)
360 $t = new MECON_Tiempo_Hora();
361 foreach ($this->intervalos as $i)
362 $t->add($i->superponer($intervalo));
363 $d = $intervalo->getDuracion();
369 * Chequea si la banda(parametro) esta cubierto por la banda(this),
370 * si faltan horas en la banda(this) para llegar a banda(parametro)
371 * se retorna el tiempo que falta
373 * @return Date_Span el periodo faltante
375 function chequearBanda($banda)
377 $f = new MECON_Tiempo_Hora();
378 foreach ($banda->intervalos as $i)
379 $f->add($this->chequearIntervalo($i));
385 * Devuelve una representacion del objeto como un string.
387 * @return string Representacion del objeto.
392 $t = count($this->intervalos);
393 for ($n = 0; $n < ($t - 1); $n++) {
394 $s .= "intervalo $n: [" . $this->intervalos[$n]->toString() . '] | ';
398 $s .= "intervalo $n: [" . $this->intervalos[$n]->toString() . ']';
403 function getIntervalos()
405 return $this->intervalos;
409 * Corta una banda, devolviendo la banda previa al punto de corte.
411 * La banda actual queda con los intervalos posteriores al punto de corte
412 * y se devuelve la banda con los intervalos anteriores.
413 * El punto de corte puede ser tanto una hora como un intervalo.
415 * @param mixed $c Donde cortar.
417 * @return object Banda Bnada anterior al punto de corte.
421 $b = $this->__clone();
422 $b->intervalos = array();
423 $intervalos = array();
424 foreach ($this->intervalos as $i) {
426 $da = $a->getDuracion();
427 if (!$da->isEmpty()) {
428 $b->agregarIntervalo($a);
430 $di = $i->getDuracion();
431 if (!$di->isEmpty()) {
435 $this->intervalos = $intervalos;
440 * Devuelve el timpo total que contiene la banda.
442 * @return object Date_Span Tiempo total.
447 foreach ($this->intervalos as $i) {
448 $t->add($i->getDuracion());
454 * Alias de Banda::total() para compatibilidad con Intervalo.
456 * @return object Date_Span Tiempo total.
458 function getDuracion()
460 return $this->total();
464 * Chequea si el período pasado como argumento se superpone con la banda.
465 * @param $periodo Puede ser un MECON_Tiempo_Intervalo o MECON_Tiempo_Banda.
466 * @return true si se superpone, false si no.
468 function seSuperpone($periodo)
470 $intervalos = array($periodo);
471 if (is_a($periodo, 'mecon_tiempo_banda')) {
472 $intervalos = $periodo->intervalos;
474 foreach ($intervalos as $i) {
475 if ($i->seSuperpone($this->intervalos)) {
487 $this->intervalos = array();
493 foreach ($b->intervalos as $i) {
494 $this->intervalos[] = $i->__clone();
500 $class = get_class($this);