+<?php
+// vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4:
+// +--------------------------------------------------------------------+
+// | HORAS EXTRA |
+// +--------------------------------------------------------------------+
+// | Sistema de Horas Extra - Ministerio de Economía - Argentina |
+// +--------------------------------------------------------------------+
+// | Creado: lun abr 22 16:05:33 ART 2002 |
+// | Autor: Gonzalo Merayo <gmeray@mecon.gov.ar> |
+// +--------------------------------------------------------------------+
+//
+// $URL$
+// $Rev$
+// $Date$
+// $Author$
+//
+
+require_once 'HE/Intervalo.php';
+
+/**
+ * Representa un conjunto de entradas y salidas para formar una banda horaria
+ *
+ * @package HE
+ * @abstract
+ * @version $Rev$
+ * @author Gonzalo Merayo <gmeray@mecon.gov.ar>
+ */
+class Banda {
+
+ var $intervalos;
+
+ function Banda() {
+ $this->intervalos = array();
+ }
+
+ function Cargar($agente, $fecha)
+ {
+ $dsn = "mysql://intranet:intranet@intranet-db/bandas";
+ $db = DB::connect( $dsn , true);
+ if(DB::isError($db))
+ die($db->getMessage());
+ $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))
+ die($result->getMessage());
+
+ $sip =& new HE_DB_Persona;
+ $datos = $sip->obtener($agente);
+ $age =& new HE_DB_Agente;
+ $ag = $age->obtener($agente, $datos['codep']);
+ $funcion = @$ag['funcion'];
+
+ if($funcion != 'SE')
+ {//Version tough
+ $int == null;
+ while( $r = $result->fetchRow() )
+ {
+ if($r[0] == 'E') $int = new Intervalo(new Hora( $r[1] ), new Hora( $r[1] ));
+ if($r[0] == 'S' && $int != null)
+ {
+ $int->setFin( new Hora( $r[1] ) );
+ $this->agregarIntervalo( $int );
+ $int = null;
+ }
+ }
+ }
+ else
+ {
+ if($result->numRows() > 0)
+ {//Version Light o Serenos
+ $int = new Intervalo(new Hora('00:00'), new Hora('00:00'));
+ while( $r = $result->fetchRow() )
+ {
+ if($r[0] == 'E') $int = new Intervalo(new Hora( $r[1] ), new Hora( $r[1] ));
+ if($r[0] == 'S' && $int != null)
+ {
+ $int->setFin( new Hora( $r[1] ) );
+ $this->agregarIntervalo( $int );
+ $int = null;
+ }
+ }
+ if($int != null)
+ {
+ $int->setFin( new 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, "intervalo")) return false;
+ if ($intervalo->invertido()) {
+ $intervalo->_chequear();
+ $this->agregarIntervalo(new Intervalo(new Hora('00:00'), new 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, "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, "time_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 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 Time_Span el periodo faltante
+ *
+ */
+ function chequearIntervalo($intervalo)
+ {
+ if(! is_a($intervalo, "intervalo")) return false;
+ $t = new 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 Time_Span el periodo faltante
+ *
+ */
+ function chequearBanda($banda)
+ {
+ if(! is_a($banda, "banda")) return false;
+ $f = new 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, 'hora') and !is_a($c, '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 Time_Span Tiempo total.
+ */
+ function total() {
+ $t = new Time_Span;
+ foreach ($this->intervalos as $i) {
+ $t->add($i->getDuracion());
+ }
+ return $t;
+ }
+
+ /**
+ * Alias de Banda::total() para compatibilidad con Intervalo.
+ *
+ * @return object Time_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;
+ }
+
+}
+
+// $Id$
+?>