------------------------------------------------------------------------------- $Id$ -----------------------------------------------------------------------------*/ require_once 'DB.php'; // FIXME - esto debe volar!!! require_once 'MECON/Tiempo/Intervalo.php'; /** * Representa un conjunto de entradas y salidas para formar una banda horaria * * @package HE * @abstract * @version $Rev$ * @author Gonzalo Merayo */ class MECON_Tiempo_Banda { var $intervalos; function MECON_Tiempo_Banda() { $this->intervalos = array(); } function Cargar($db, $agente, $fecha) { // FIXME - lo que es base de datos debe VOLAR!!!!!!! $funcion = $db->getOne( "SELECT E.funcion FROM novedades.estado as E, novedades.web003 as S WHERE E.nrodoc = $agente AND S.nrodoc = $agente AND S.codep = E.dependencia" ); $fecha = $fecha->format("%Y%m%d"); $query = "SELECT A.tipo_acceso, A.hora FROM agentes G, accesos A WHERE G.cred = A.cred AND G.docu = $agente AND A.fecha = $fecha AND A.inconsistencia = 0 ORDER BY A.hora"; $result = $db->query($query); if(DB::isError($result)) trigger_error($result->getMessage(), E_USER_ERROR); if($funcion != 'SE') {//Version tough $int = null; while( $r = $result->fetchRow() ) { if($r[0] == 'E') $int = new MECON_Tiempo_Intervalo(new MECON_Tiempo_Hora( $r[1] ), new MECON_Tiempo_Hora( $r[1] )); if($r[0] == 'S' && $int != null) { $int->setFin( new MECON_Tiempo_Hora( $r[1] ) ); $this->agregarIntervalo( $int ); $int = null; } } } else { if($result->numRows() > 0) {//Version Light o Serenos $int = new MECON_Tiempo_Intervalo(new MECON_Tiempo_Hora('00:00'), new MECON_Tiempo_Hora('00:00')); while( $r = $result->fetchRow() ) { if($r[0] == 'E') $int = new MECON_Tiempo_Intervalo(new MECON_Tiempo_Hora( $r[1] ), new MECON_Tiempo_Hora( $r[1] )); if($r[0] == 'S' && $int != null) { $int->setFin( new MECON_Tiempo_Hora( $r[1] ) ); $this->agregarIntervalo( $int ); $int = null; } } if($int != null) { $int->setFin( new MECON_Tiempo_Hora('24:00') ); $this->agregarIntervalo( $int ); $int = null; } } } } /* * * Completa las salidas del medio del dia. * */ function CompletarSalidas() { if(count($this->intervalos) > 0) { $p = reset($this->intervalos); $u = end($this->intervalos); $p->setFin($u->fin); $this->intervalos = array($p); } } /** * Agrega un intervalo a la banda * Chequeando superposiciones y en orden * * @param Intervalo $intervalo Intervalo a agregar. */ function agregarIntervalo($intervalo) { if(! is_a($intervalo, "mecon_tiempo_intervalo")) return false; if ($intervalo->invertido()) { $intervalo->_chequear(); $this->agregarIntervalo(new MECON_Tiempo_Intervalo(new MECON_Tiempo_Hora('00:00'), new MECON_Tiempo_Hora ('24:00'))); $this->sacarIntervalo($intervalo); return true; } $n_intervalos = array(); $insertado = false; // recorre el vector de intervalos foreach( $this->intervalos as $i ) { // si se superpone con alguno, fusionar con ese if($i->seSuperpone($intervalo)) $intervalo->fusionar($i); else { if($i->inicio->greater($intervalo->inicio) && ! $insertado) { array_push($n_intervalos, $intervalo); $insertado = true; } array_push($n_intervalos, $i); } } if(! $insertado ) array_push($n_intervalos,$intervalo); $this->intervalos = $n_intervalos; return true; } /** * Saca * * */ function sacarBanda($banda) { foreach($banda->intervalos as $i) $this->sacarIntervalo($i); } /** * Saca un intervalo de una banda horaria. * */ function sacarIntervalo($intervalo) { if(! is_a($intervalo, "mecon_tiempo_intervalo")) return false; // Si el intervalo está vacío, no hace nada. $dur = $intervalo->getDuracion(); if ($dur->isEmpty()) { return true; } $n_intervalos = array(); // recorre el vector de intervalos foreach( $this->intervalos as $i ) { if($i->seSuperpone($intervalo)) { $a = $i->cortar($intervalo); $d = $a->getDuracion(); if($d->toSeconds() > 0) { $n_intervalos[] = $a; } $d = $i->getDuracion(); if($d->toSeconds() > 0) { $n_intervalos[] = $i; } } else { $n_intervalos[] = $i; } } $this->intervalos = $n_intervalos; return true; } function sacarTiempo($t) { if(! is_a($t, "date_span")) return false; $n_int = array(); while(count($this->intervalos) > 0) { $int = array_shift($this->intervalos); if($t->toSeconds() > 0) { $d = $int->getDuracion(); if($d->greater($t)) { #con cortar alcanza $ini = new MECON_Tiempo_Hora(); $ini->copy($int->inicio); $ini->add ($t); /*TODO guardar este tiempo como rechazado*/ $int->cortar($ini); $t->setFromSeconds(0); } else { #con cortar no alcanza y hay que sacar... $t->subtract($int->getDuracion()); /*TODO guardar int como rechazado*/ } } $n_int[] = $int; } $this->intervalos = $n_int; } /* * Chequea si el intervalo pedido esta cubierto por la banda, si faltan * horas en la banta se retorna el tiempo que falta * * @return Date_Span el periodo faltante * */ function chequearIntervalo($intervalo) { if(! is_a($intervalo, "mecon_tiempo_intervalo")) return false; $t = new MECON_Tiempo_Hora(); foreach ($this->intervalos as $i) $t->add ($i->superponer($intervalo)); $d = $intervalo->getDuracion(); $d->subtract($t); return $d; } /* * Chequea si la banda(parametro) esta cubierto por la banda(this), * si faltan horas en la banda(this) para llegar a banda(parametro) * se retorna el tiempo que falta * * @return Date_Span el periodo faltante * */ function chequearBanda($banda) { if(! is_a($banda, "mecon_tiempo_banda")) return false; $f = new MECON_Tiempo_Hora(); foreach ($banda->intervalos as $i) $f->add ($this->chequearIntervalo($i)); return $f; } /* * Devuelve una representacion del objeto como un string. * * @return string Representacion del objeto. * */ function toString() { $s = ''; $t = count($this->intervalos); for ($n = 0; $n < ($t - 1); $n++) { $s .= "intervalo $n: [" . $this->intervalos[$n]->toString() . '] | '; } $n = $t - 1; if ($n != -1) { $s .= "intervalo $n: [" . $this->intervalos[$n]->toString() . ']'; } return $s; } function getIntervalos() { return $this->intervalos; } /** * Corta una banda, devolviendo la banda previa al punto de corte. * * La banda actual queda con los intervalos posteriores al punto de corte * y se devuelve la banda con los intervalos anteriores. * El punto de corte puede ser tanto una hora como un intervalo. * * @param mixed $c Donde cortar. * * @return object Banda Bnada anterior al punto de corte. */ function cortar($c) { if(!is_a($c, 'mecon_tiempo_hora') and !is_a($c, 'mecon_tiempo_intervalo')) return false; $b = $this->__clone(); $b->intervalos = array(); $intervalos = array(); foreach ($this->intervalos as $i) { $a = $i->cortar($c); $da = $a->getDuracion(); if (!$da->isEmpty()) { $b->agregarIntervalo($a); } $di = $i->getDuracion(); if (!$di->isEmpty()) { $intervalos[] = $i; } } $this->intervalos = $intervalos; return $b; } /** * Devuelve el timpo total que contiene la banda. * * @return object Date_Span Tiempo total. */ function total() { $t = new Date_Span; foreach ($this->intervalos as $i) { $t->add ($i->getDuracion()); } return $t; } /** * Alias de Banda::total() para compatibilidad con Intervalo. * * @return object Date_Span Tiempo total. */ function getDuracion() { return $this->total(); } /** * Resetea la banda. */ function flush() { $this->intervalos = array(); } function copy($b) { $this->flush(); foreach ($b->intervalos as $i) { $this->intervalos[] = $i->__clone(); } } function __clone() { $class = get_class($this); $b = new $class; $b->copy($this); return $b; } } ?>