]> git.llucax.com Git - mecon/meconlib.git/blob - lib/MECON/Feriado.php
71aecd66dd40bbcf2235e4ef5088634e579f79be
[mecon/meconlib.git] / lib / MECON / Feriado.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: mié abr 10 18:05:33 ART 2002                               |
22 Autor:  Leandro Lucarella <llucar@mecon.gov.ar>
23 -------------------------------------------------------------------------------
24 $Id$
25 -----------------------------------------------------------------------------*/
26
27 require_once 'MECON/DBO.php';
28 require_once 'Date.php';
29 require_once 'Time/Span.php';
30 require_once 'HE/DB.php';
31
32 /**
33  * Información sobre feriados.
34  *
35  * Abstracción para hacer ABM sobre la información de los días feriados.
36  * También sirve para hacer consultas y búsquedas.
37  *
38  * @package HE
39  * @version $Rev$
40  * @author  Leandro Lucarella <llucar@mecon.gov.ar>
41  * @todo Probar. Agregar _updateDBInfo() a todas las funciones de Date que
42  *       modifiquen la fecha.
43  */
44 class MECON_Feriado extends Date {
45
46     /**
47      * Base de datos a usar para las consultas.
48      * @private
49      */
50     var $_db;
51
52     /**
53      * Tipo de día (Feriado, Laborable o No Laborable).
54      * @private
55      */
56     var $_tipo;
57
58     /// Hora en la que empieza el feriado.
59     var $desde;
60
61     /// Descripción del feriado.
62     var $descripcion;
63
64     function MECON_Feriado($db, $date = null) {
65         $this->_db = $db;
66         parent::Date($date);
67     }
68
69     function setDate($date = null) {
70         parent::setDate($date);
71         $this->_updateDBInfo($date);
72     }
73
74     function copy($date) {
75         parent::copy($date);
76         if (@$date->_tipo) {
77             $this->_tipo = $date->_tipo;
78             $this->desde = $date->desde;
79             $this->descripcion = $date->descripcion;
80         } else {
81             $this->_updateDBInfo();
82         }
83     }
84
85     function setYear($y) {
86         parent::setYear($y);
87         $this->_updateDBInfo();
88     }
89
90     function setMonth($m) {
91         parent::setMonth($m);
92         $this->_updateDBInfo();
93     }
94
95     function setDay($d) {
96         parent::setDay($d);
97         $this->_updateDBInfo();
98     }
99
100     function setHour($h) {
101         parent::setHour($h);
102         $this->_updateDBInfo();
103     }
104
105     function setMinute($m) {
106         parent::setMinute($m);
107         $this->_updateDBInfo();
108     }
109
110     function setSecond($s) {
111         parent::setSecond($s);
112         $this->_updateDBInfo();
113     }
114
115     function _updateDBInfo() {
116         // Resetea valores.
117         $this->desde = null;
118         $this->descripcion = null;
119         // Se fija según el tipo de día.
120         $dia = $this->format('%w');
121         switch ($dia) {
122             case 0: // Domingo.
123                 $this->_tipo = 'feriado';
124                 break;
125             case 6: // Sábado.
126                 $tipo = 'no laborable';
127                 // sigue abajo, no hay break.
128             default: // Cualquier día.
129                 $this->_tipo = isset($tipo) ? $tipo : 'laborable';
130                 // Verificamos si hay algo en la DB.
131                 $fecha = $this->getDate();
132                 $datos = $this->_db->getRow("SELECT * FROM novedades.feriado WHERE fecha = '$fecha'", null, DB_FETCH_ASSOC);
133                 // Si hay un error, lo pasamos a quien nos llama.
134                 if (DB::isError($datos)) {
135                     return $datos;
136                 // Si hay un resultado, actualizamos los datos.
137                 } elseif ($datos) {
138                     $this->_tipo = $datos['tipo'];
139                     $this->desde = $datos['desde'];
140                     $this->descripcion = $datos['descripcion'];
141                 }
142         }
143         return true;
144     }
145
146     /**
147      * Obtiene el tipo de día (teniendo en cuenta la hora).
148      * 
149      * Si el día es asueto se fija la hora almacenada en esta fecha y devuelve
150      * 'asueto' o 'laborable' dependiendo de a partir de qué hora se declaró el
151      * asueto.
152      *
153      * @return 'laborable', 'no laborable', 'asueto' o 'feriado'.
154      */
155     function getTipo() {
156         if ($this->_tipo == 'asueto') {
157             $desde = new Time_Span($this->desde);
158             $hora = new Time_Span($this->format('%H:%M'));
159             if ($hora->greaterEqual($desde)) {
160                 return $this->_tipo;
161             } else {
162                 // Posible pitfall, en teoría sólo puede declararse asueto un
163                 // día laborable.
164                 return 'laborable';
165             }
166         } else {
167             return $this->_tipo;
168         }
169     }
170
171     /**
172      * Indica si un día es laborable.
173      *
174      * @return bool   false si no es laborable (o hubo error).
175      *
176      * @access public
177      */
178     function esLaborable() {
179         return getTipo() == 'laborable';
180     }
181
182     /**
183      * Indica si un día es no laborable.
184      *
185      * @return bool   false si no es no laborable (o hubo error).
186      *
187      * @access public
188      */
189     function esNoLaborable() {
190         return getTipo() == 'no laborable';
191     }
192
193     /**
194      * Indica si un día es feriado.
195      *
196      * @return bool   false si no es feriado (o hubo error).
197      *
198      * @access public
199      */
200     function esFeriado() {
201         return getTipo() == 'feriado';
202     }
203
204     /**
205      * Indica si un día es asueto.
206      *
207      * @param  string $fecha Fecha de a chequear (el día actual por
208      *                       defecto).
209      * @param  string $hora  Hora en la que se quiere chequear.
210      *
211      * @return bool   false si no es asueto (o hubo error).
212      *
213      * @access public
214      */
215     function esAsueto() {
216         return getTipo() == 'asueto';
217     }
218
219     /**
220      * Busca feriados que se encuentren en un rango de fechas.
221      *
222      * Ejemplo:
223      * if ( $feriado->buscarRango( '2002/10/01', '2002/12/31' ) )
224      *     while ( $f = $feriado->siguiente() )
225      *         var_dump( $f );
226      * elseif ( $feriado->error() )
227      *     die( 'Errores: ' . $feriado->errores();
228      * else
229      *     print( 'No se encontraron feriados en ese rango de fechas' );
230      *
231      * @param  string $ini   Fecha de inicio del rango en donde buscar (por
232      *                       defecto el primer día del mes en curso).
233      * @param  string $fin   Fecha de fin del rango en donde buscar (por
234      *                       defecto el último día del mes en curso).
235      * @param  array $orden  Órden de los resultados. Es un array
236      *                       asociativo con el campo por el cual ordenar
237      *                       como clave y si es descendente o ascendente
238      *                       como valor. Por defecto se toma fecha
239      *                       ascendente.
240      *
241      * @return bool  false si no se encontró nada (o hubo error).
242      *
243      * @todo Pasar a método estático.
244      */
245     function buscarRango( $ini = '', $fin = '', $orden = null ) {
246
247         $ini = empty( $ini ) ? strftime( '%Y/01/01', time() ) : $ini;
248         $fin = empty( $fin ) ? strftime( '%Y/12/31', time() ) : $fin;
249         $ord = ( $ord != 'fecha' and $ord != 'descripcion' and $ord != 'tipo' ) ? 'fecha' : $ord;
250
251         // Valida ambas fechas y que una sea anterior a la otra.
252         if ( ! $this->_es_anterior( $ini, $fin ) )
253             return false;
254
255         // Si no se especifica orden lo inicializa.
256         if ( is_null( $orden ) )
257             $orden = array('fecha' => HE_DB_ASC);
258
259         // Genera un array con las clausulas del ORDER BY del query
260         $order = array();
261         foreach ( $orden as $campo => $ord )
262             $order[] = sprintf( "%s %s", $campo, $ord );
263             
264         // Si no son arrays sale con error.
265         if ( ! is_array( $campos ) or ! is_array( $orden ) ) {
266             $this->raiseError( 'Parámetro incorrecto, no es un array', HE_ERROR );
267             return false;
268         }
269
270         // Prepara el query con el rango de fechas
271         $query = sprintf(
272             'SELECT *
273                 FROM
274                     %s.%s
275                 WHERE
276                     %s <= fecha AND
277                     fecha <= %s
278                 %s',
279             $this->_basededatos,
280             $this->_tabla,
281             $this->_db->quote( $ini ),
282             $this->_db->quote( $fin ),
283             $order ? ( ' ORDER BY ' . join( ',', $order ) ) : ''
284         );
285
286         $resultado =& $this->_db->query( $query );
287         if ( DB::isError( $resultado ) ) {   // Hubo un error
288             $this->_error->agregar( $resultado );
289             return false;
290         } elseif ( $resultado->numRows() ) { // Tiene algún resultado
291             $this->_resultado =& $resultado;
292             return true;
293         } else {
294             return false;
295         }
296
297     }
298
299 }
300
301 // $Id$
302 ?>