1 <?php /* vim: set binary expandtab tabstop=4 shiftwidth=4 textwidth=80:
2 -------------------------------------------------------------------------------
4 -------------------------------------------------------------------------------
5 This file is part of mlib.
7 mlib is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your option)
12 mlib is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License; if not,
17 write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 Boston, MA 02111-1307 USA
19 -------------------------------------------------------------------------------
20 Creado: lun abr 22 16:05:33 ART 2002
21 Autor: Gonzalo Merayo <gmeray@mecon.gov.ar>
22 -------------------------------------------------------------------------------
24 -----------------------------------------------------------------------------*/
26 require_once 'DB.php'; // FIXME - esto debe volar!!!
27 require_once 'MLIB/Tiempo/Intervalo.php';
30 * Representa un conjunto de entradas y salidas para formar una banda horaria
35 * @author Gonzalo Merayo <gmeray@mecon.gov.ar>
37 class MLIB_Tiempo_Banda {
44 * @param $db Conexión opcional a una base de datos.
46 function MLIB_Tiempo_Banda($db = null)
49 $this->intervalos = array();
53 * Funcion que se encarga de cargar los intervalos de tiempo de un agente.
54 * Devuelve true en caso de detectar una inconsistecia de reloj o false en caso contrario
56 * @param $agente Documento del agente
57 * @param $accesos Array o Date Variable que puede ser un array con todos los accesos
58 * de un agente o un objeto Date que indica la fecha de la banda a procesar
59 * @param $db Conexión opcional a una base de datos.
61 function cargar($agente, $accesos, $db = null)
67 $funcion = $this->db->getOne(
69 FROM novedades.estado as E, novedades.web003 as S
71 E.nrodoc = $agente AND
72 S.nrodoc = $agente AND
73 S.codep = E.dependencia"
76 if (is_a($accesos,'date')) {
78 $fecha = $fecha->format("%Y%m%d");
79 $query = "SELECT TA.tipo_acceso, A.hora
80 FROM bandas.Acceso A, bandas.Agente_Credencial AC, bandas.Tipo_Acceso TA
81 WHERE AC.credencial = A.credencial
82 AND A.fecha = '$fecha'
83 AND AC.agente = $agente
84 AND TA.puerta = A.puerta
85 AND AC.desde <= '$fecha'
86 AND ( AC.hasta >= '$fecha'
89 $result = $this->db->query($query);
90 if(DB::isError($result))
91 trigger_error($result->getMessage(), E_USER_ERROR);
93 $inconsistencia = false;
97 while( $r = $result->fetchRow() )
102 $inconsistencia = true;
103 $int = new MLIB_Tiempo_Intervalo(new MLIB_Tiempo_Hora( $r[1] ),
104 new MLIB_Tiempo_Hora( $r[1] ));
110 $int->setFin( new MLIB_Tiempo_Hora( $r[1] ) );
111 $this->agregarIntervalo( $int );
115 $inconsistencia = true;
119 $inconsistencia = true;
123 if($result->numRows() > 0)
124 {//Version Light o Serenos
125 $int = new MLIB_Tiempo_Intervalo(new MLIB_Tiempo_Hora('00:00'),
126 new MLIB_Tiempo_Hora('00:00'));
127 while( $r = $result->fetchRow() )
132 //$inconsistencia = true;
133 $int = new MLIB_Tiempo_Intervalo(new MLIB_Tiempo_Hora( $r[1] ),
134 new MLIB_Tiempo_Hora( $r[1] ));
140 $int->setFin( new MLIB_Tiempo_Hora( $r[1] ) );
141 $this->agregarIntervalo( $int );
145 // $inconsistencia = true;
150 $int->setFin( new Hora('24:00') );
151 $this->agregarIntervalo( $int );
159 $inconsistencia = false;
163 if(!is_null($accesos))
165 foreach( $accesos as $r )
170 $inconsistencia = true;
171 $int = new MLIB_Tiempo_Intervalo(new MLIB_Tiempo_Hora( $r[1] ),
172 new MLIB_Tiempo_Hora( $r[1] ));
178 $int->setFin( new MLIB_Tiempo_Hora( $r[1] ) );
179 $this->agregarIntervalo( $int );
183 $inconsistencia = true;
188 $inconsistencia = true;
192 //Version Light o Serenos
193 $int = new MLIB_Tiempo_Intervalo(new MLIB_Tiempo_Hora('00:00'),
194 new MLIB_Tiempo_Hora('00:00'));
196 if(!is_null($accesos))
198 foreach( $accesos as $r )
203 //$inconsistencia = true;
204 $int = new MLIB_Tiempo_Intervalo(new MLIB_Tiempo_Hora( $r[1] ),
205 new MLIB_Tiempo_Hora( $r[1] ));
211 $int->setFin( new MLIB_Tiempo_Hora( $r[1] ) );
212 $this->agregarIntervalo( $int );
216 // $inconsistencia = true;
222 $int->setFin( new Hora('24:00') );
223 $this->agregarIntervalo( $int );
228 return $inconsistencia;
232 * Completa las salidas del medio del dia.
235 function CompletarSalidas()
237 if(count($this->intervalos) > 0) {
238 $p = reset($this->intervalos);
239 $u = end($this->intervalos);
241 $this->intervalos = array($p);
247 * Agrega un intervalo a la banda
248 * Chequeando superposiciones y en orden
250 * @param Intervalo $intervalo Intervalo a agregar.
252 function agregarIntervalo($intervalo)
254 if ($intervalo->invertido()) {
255 $intervalo->_chequear();
256 $this->agregarIntervalo(new MLIB_Tiempo_Intervalo(new MLIB_Tiempo_Hora('00:00'), new MLIB_Tiempo_Hora ('24:00')));
257 $this->sacarIntervalo($intervalo);
260 $n_intervalos = array();
262 // recorre el vector de intervalos
263 foreach( $this->intervalos as $i ) {
264 // si se superpone con alguno, fusionar con ese
265 if($i->seSuperpone($intervalo) || $i->esAdyacente($intervalo)) {
266 $intervalo->fusionar($i);
268 if($i->inicio->greater($intervalo->inicio) && ! $insertado) {
269 array_push($n_intervalos, $intervalo);
272 array_push($n_intervalos, $i);
276 array_push($n_intervalos,$intervalo);
277 $this->intervalos = $n_intervalos;
284 function sacarBanda($banda)
286 foreach($banda->intervalos as $i)
287 $this->sacarIntervalo($i);
291 * Saca un intervalo de una banda horaria.
293 function sacarIntervalo($intervalo)
295 // Si el intervalo está vacío, no hace nada.
296 $dur = $intervalo->getDuracion();
297 if ($dur->isEmpty()) {
300 $n_intervalos = array();
301 // recorre el vector de intervalos
302 foreach( $this->intervalos as $i ) {
303 if($i->seSuperpone($intervalo)) {
304 $a = $i->cortar($intervalo);
305 $d = $a->getDuracion();
306 if($d->toSeconds() > 0) {
307 $n_intervalos[] = $a;
309 $d = $i->getDuracion();
310 if($d->toSeconds() > 0) {
311 $n_intervalos[] = $i;
314 $n_intervalos[] = $i;
317 $this->intervalos = $n_intervalos;
325 function sacarTiempo($t)
328 while(count($this->intervalos) > 0) {
329 $int = array_shift($this->intervalos);
330 if($t->toSeconds() > 0) {
331 $d = $int->getDuracion();
332 if($d->greater($t)) {
334 $ini = new MLIB_Tiempo_Hora();
335 $ini->copy($int->inicio);
337 /*TODO guardar este tiempo como rechazado*/
339 $t->setFromSeconds(0);
341 #con cortar no alcanza y hay que sacar...
342 $t->subtract($int->getDuracion());
343 /*TODO guardar int como rechazado*/
348 $this->intervalos = $n_int;
352 * Chequea si el intervalo pedido esta cubierto por la banda, si faltan
353 * horas en la banta se retorna el tiempo que falta
355 * @return Date_Span el periodo faltante
357 function chequearIntervalo($intervalo)
359 $t = new MLIB_Tiempo_Hora();
360 foreach ($this->intervalos as $i)
361 $t->add($i->superponer($intervalo));
362 $d = $intervalo->getDuracion();
368 * Chequea si la banda(parametro) esta cubierto por la banda(this),
369 * si faltan horas en la banda(this) para llegar a banda(parametro)
370 * se retorna el tiempo que falta
372 * @return Date_Span el periodo faltante
374 function chequearBanda($banda)
376 $f = new MLIB_Tiempo_Hora();
377 foreach ($banda->intervalos as $i)
378 $f->add($this->chequearIntervalo($i));
384 * Devuelve una representacion del objeto como un string.
386 * @return string Representacion del objeto.
391 $t = count($this->intervalos);
392 for ($n = 0; $n < ($t - 1); $n++) {
393 $s .= "intervalo $n: [" . $this->intervalos[$n]->toString() . '] | ';
397 $s .= "intervalo $n: [" . $this->intervalos[$n]->toString() . ']';
402 function getIntervalos()
404 return $this->intervalos;
408 * Corta una banda, devolviendo la banda previa al punto de corte.
410 * La banda actual queda con los intervalos posteriores al punto de corte
411 * y se devuelve la banda con los intervalos anteriores.
412 * El punto de corte puede ser tanto una hora como un intervalo.
414 * @param mixed $c Donde cortar.
416 * @return object Banda Bnada anterior al punto de corte.
420 $b = $this->__clone();
421 $b->intervalos = array();
422 $intervalos = array();
423 foreach ($this->intervalos as $i) {
425 $da = $a->getDuracion();
426 if (!$da->isEmpty()) {
427 $b->agregarIntervalo($a);
429 $di = $i->getDuracion();
430 if (!$di->isEmpty()) {
434 $this->intervalos = $intervalos;
439 * Devuelve el timpo total que contiene la banda.
441 * @return object Date_Span Tiempo total.
446 foreach ($this->intervalos as $i) {
447 $t->add($i->getDuracion());
453 * Alias de Banda::total() para compatibilidad con Intervalo.
455 * @return object Date_Span Tiempo total.
457 function getDuracion()
459 return $this->total();
463 * Chequea si el período pasado como argumento se superpone con la banda.
464 * @param $periodo Puede ser un MLIB_Tiempo_Intervalo o MLIB_Tiempo_Banda.
465 * @return true si se superpone, false si no.
467 function seSuperpone($periodo)
469 $intervalos = array($periodo);
470 if (is_a($periodo, 'MLIB_tiempo_banda')) {
471 $intervalos = $periodo->intervalos;
473 foreach ($intervalos as $i) {
474 if ($i->seSuperpone($this->intervalos)) {
486 $this->intervalos = array();
492 foreach ($b->intervalos as $i) {
493 $this->intervalos[] = $i->__clone();
499 $class = get_class($this);