Método que agrega un detalle al listado que se enviará
@param detalle Arreglo con los datos de la boleta que se desea agregar
@author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl)
@version 2015-12-14
338223
public function agregar(array $detalle)
    {
        $this->detalles[] = array_merge([
            'TpoDoc' => false,
            'FolioDoc' => false,
            'Anulado' => false,
            'TpoServ' => 3,
            'FchEmiDoc' => false,
            'FchVencDoc' => false,
            'PeriodoDesde' => false,
            'PeriodoHasta' => false,
            'CdgSIISucur' => false,
            'RUTCliente' => false,
            'CodIntCli' => false,
            'MntExe' => false,
            'MntTotal' => false,
            'MntNoFact' => false,
            'MntPeriodo' => false,
            'SaldoAnt' => false,
            'VlrPagar' => false,
            'TotTicketBoleta' => false,
        ], $detalle);
    }
658370
def AgregarMercaderia(self, orden=None, cod_tipo_prod=None, kilos=None, unidades=None, tropa=None, kilos_rec=None, unidades_rec=None, **kwargs):
        ""
        mercaderia = dict(orden=orden, tropa=tropa, codTipoProd=cod_tipo_prod, kilos=kilos, unidades=unidades,
                          kilosRec=kilos_rec, unidadesRec=unidades_rec)
        self.remito['arrayMercaderias'].append(dict(mercaderia=mercaderia))
        return True
998010
private function normalizar_boletas(array &$datos)
    {
        // cambiar tags de DTE a boleta si se pasaron
        if ($datos['Encabezado']['Emisor']['RznSoc']) {
            $datos['Encabezado']['Emisor']['RznSocEmisor'] = $datos['Encabezado']['Emisor']['RznSoc'];
            $datos['Encabezado']['Emisor']['RznSoc'] = false;
        }
        if ($datos['Encabezado']['Emisor']['GiroEmis']) {
            $datos['Encabezado']['Emisor']['GiroEmisor'] = $datos['Encabezado']['Emisor']['GiroEmis'];
            $datos['Encabezado']['Emisor']['GiroEmis'] = false;
        }
        $datos['Encabezado']['Emisor']['Acteco'] = false;
        $datos['Encabezado']['Emisor']['Telefono'] = false;
        $datos['Encabezado']['Emisor']['CorreoEmisor'] = false;
        $datos['Encabezado']['Emisor']['CdgVendedor'] = false;
        $datos['Encabezado']['Receptor']['GiroRecep'] = false;
        if (!empty($datos['Encabezado']['Receptor']['CorreoRecep'])) {
            $datos['Referencia'][] = [
                'NroLinRef' => !empty($datos['Referencia']) ? (count($datos['Referencia'])+1) : 1,
                'RazonRef' => mb_substr('Email receptor: '.$datos['Encabezado']['Receptor']['CorreoRecep'], 0, 90),
            ];
        }
        $datos['Encabezado']['Receptor']['CorreoRecep'] = false;
        // quitar otros tags que no son parte de las boletas
        $datos['Encabezado']['IdDoc']['FmaPago'] = false;
        $datos['Encabezado']['IdDoc']['FchCancel'] = false;
        $datos['Encabezado']['IdDoc']['MedioPago'] = false;
        $datos['Encabezado']['IdDoc']['TpoCtaPago'] = false;
        $datos['Encabezado']['IdDoc']['NumCtaPago'] = false;
        $datos['Encabezado']['IdDoc']['BcoPago'] = false;
        $datos['Encabezado']['IdDoc']['TermPagoGlosa'] = false;
        $datos['Encabezado']['RUTSolicita'] = false;
        $datos['Encabezado']['IdDoc']['TpoTranCompra'] = false;
        $datos['Encabezado']['IdDoc']['TpoTranVenta'] = false;
        // si es boleta no nominativa se deja sólo el RUT en el campo del receptor
        /*if ($datos['Encabezado']['Receptor']['RUTRecep']=='66666666-6') {
            $datos['Encabezado']['Receptor'] = ['RUTRecep'=>'66666666-6'];
        }*/
        // ajustar las referencias si existen
        if (!empty($datos['Referencia'])) {
            if (!isset($datos['Referencia'][0])) {
                $datos['Referencia'] = [$datos['Referencia']];
            }
            foreach ($datos['Referencia'] as &$r) {
                foreach (['TpoDocRef', 'FolioRef', 'FchRef'] as $c) {
                    if (isset($r[$c])) {
                        unset($r[$c]);
                    }
                }
            }
        }
    }
381587
public function index() {
        $this->layout = 'Stats.default';
        $this->elementMenu = 'Stats.menu';
        
        // por default ordenar por sumatoria de dinero vendido
        $conditions['order'] = array('ventas DESC',"cant DESC");
        if ( !empty( $this->request->query ) && $this->request->query['cant_o_tot'] == 1 ) {
            // ordenado por cantidad de unidades vendidas            
            $conditions['order'] = array("cant DESC", 'ventas DESC');
        }

        

        $this->Prg->commonProcess();
        $conds = $this->DetalleComanda->parseCriteria( $this->Prg->parsedParams() );
        $conditions['conditions'] = $conds;
        $conditions['conditions']['Mesa.deleted'] = 0;


		$this->DetalleComanda->Producto->recursive = -1;        
        $conditions['group'] = array('Producto.id', 'Producto.name');        
        $conditions['joins'] = array(
            array(
                'table' => 'detalle_comandas',
                'alias' => 'DetalleComanda',
                'type' => 'left',
                'conditions' => 'Producto.id = DetalleComanda.producto_id',
            ),
            array(
                'table' => 'comandas',
                'alias' => 'Comanda',
                'type' => 'left',
                'conditions' => 'Comanda.id = DetalleComanda.comanda_id',
            ),
            array(
                'table' => 'mesas',
                'alias' => 'Mesa',
                'type' => 'left',
                'conditions' => 'Mesa.id = Comanda.mesa_id',
            ), 
        );
        $conditions['fields'] = array(
            'Producto.name', 
            'sum(DetalleComanda.cant-DetalleComanda.cant_eliminada)*Producto.precio as "ventas"',
            'Producto.precio', 
            'sum(DetalleComanda.cant-DetalleComanda.cant_eliminada) as "cant"',
            );


        if ( empty($this->request->query['desde']) ) {
            $desde = $this->DetalleComanda->find('first', array(
                'order' => array('DetalleComanda.created' => 'ASC')
                ));
            $desde = $desde['DetalleComanda']['created'];
        } else {
            $desde = $this->request->query['desde'];
        }

        if ( empty($this->request->query['hasta']) ) {
            $hasta = $this->DetalleComanda->find('first', array(
                'order' => array('DetalleComanda.created' => 'DESC')
                ));
            $hasta = $hasta['DetalleComanda']['created'];
        } else {
            $hasta = $this->request->query['hasta'];
        }
                                

        $comandas  = $this->DetalleComanda->Producto->find('all', $conditions);
        $cantTotal = 0;
        $ventasTotal = 0;
        foreach ($comandas as $c) {
            $cantTotal += $c[0]['cant'];
            $ventasTotal += $c[0]['ventas'];
        }

        if ( !empty( $this->request->query ) && $this->request->query['cant_o_tot'] == 1 ) {
            $this->request->data['DetalleComanda']['cant_o_tot']  = 1;
        }

        $this->set('categorias', $this->DetalleComanda->Producto->Categoria->generateTreeList());
        $this->set('productos', $this->DetalleComanda->Producto->find('list', array('order' => 'name')));
        $this->set('tags', $this->DetalleComanda->Producto->Tag->find('list', array('order' => 'name')));
		$this->set(compact('comandas', 'cantTotal', 'ventasTotal','tags', 'desde', 'hasta'));
	}
28235
private function normalizarDetalle(array &$detalle)
    {
        // agregar nodos (esto para mantener orden del XML)
        $detalle = array_merge([
            'Folio' => false,
            'Anulado' => false,
            'Operacion' => false,
            'TpoOper' => false,
            'FchDoc' => date('Y-m-d'),
            'RUTDoc' => false,
            'RznSoc' => false,
            'MntNeto' => false,
            'TasaImp' => 0,
            'IVA' => 0,
            'MntTotal' => false,
            'MntModificado' => false,
            'TpoDocRef' => false,
            'FolioDocRef' => false,
            'FchDocRef' => false,
        ], $detalle);
        // acortar razon social
        if ($detalle['RznSoc']) {
            $detalle['RznSoc'] = mb_substr($detalle['RznSoc'], 0, 50);
        }
        // calcular valores que no se hayan entregado
        if (!$detalle['IVA'] and $detalle['TasaImp'] and $detalle['MntNeto']) {
            $detalle['IVA'] = round($detalle['MntNeto'] * ($detalle['TasaImp']/100));
        }
        // calcular monto total si no se especificó
        if ($detalle['MntTotal']===false) {
            $detalle['MntTotal'] = $detalle['MntNeto'] + $detalle['IVA'];
        }
    }
75837
def AgregarEmisor(self, tipo_cbte, pto_vta, nro_cbte, cod_caracter=None,
                      fecha_inicio_act=None, iibb=None, nro_ruca=None,
                      nro_renspa=None, cuit_autorizado=None, **kwargs):
        ""
        # cod_caracter y fecha_inicio_act no es requerido para ajustes
        d = {'tipoComprobante': tipo_cbte, 'puntoVenta': pto_vta,
             'nroComprobante': nro_cbte, 
             'codCaracter': cod_caracter,
             'fechaInicioActividades': fecha_inicio_act,
             'iibb': iibb,
             'nroRUCA': nro_ruca,
             'nroRenspa': nro_renspa,
             'cuitAutorizado': cuit_autorizado}
        self.solicitud['emisor'].update(d)
        return True
668652
def AgregarOpcional(self, codigo=None, descripcion=None, **kwargs):
        ""
        self.opcionales.append(dict(
                                    opcional=dict(
                                        codigo=codigo,
                                        descripcion=descripcion,
                                    ))
                            )
        return True
150776
public function subtract(DataList $list)
    {
        if ($this->dataClass() != $list->dataClass()) {
            throw new InvalidArgumentException('The list passed must have the same dataclass as this class');
        }

        return $this->alterDataQuery(function (DataQuery $query) use ($list) {
            $query->subtract($list->dataQuery());
        });
    }
480618
def AgregarPercepcion(self, codigo_concepto=None, detalle_aclaratoria=None,
                               base_calculo=None, alicuota=None, importe_final=None,
                               **kwargs):
        ""
        # liquidación secundaria (sin importe final)
        self.percepciones.append(dict(
                                percepcion=dict(
                                    detalleAclaratoria=detalle_aclaratoria,
                                    baseCalculo=base_calculo,
                                    alicuota=alicuota,
                                    importeFinal=importe_final,
                                ))
                        )            
        return True
1062581
def AgregarDeduccion(self, codigo_concepto=None, detalle_aclaratorio=None,
                               dias_almacenaje=None, precio_pkg_diario=None,
                               comision_gastos_adm=None, base_calculo=None,
                               alicuota=None, **kwargs):
        ""
        # limpiar campo según validación (comision_gastos_adm puede ser 0.00!)
        if codigo_concepto != "CO" and comision_gastos_adm is not None \
            and float(comision_gastos_adm) == 0:
            comision_gastos_adm = None
        # no enviar campos para prevenir errores AFIP 1705, 1707, 1708
        if base_calculo is not None:
            if codigo_concepto == "AL":
                base_calculo = None
            if codigo_concepto == "CO" and float(base_calculo) == 0:
                base_calculo = None         # no enviar, por retrocompatibilidad
        if codigo_concepto != "AL":
            dias_almacenaje = None
            precio_pkg_diario = None
        self.deducciones.append(dict(
                                    deduccion=dict(
                                        codigoConcepto=codigo_concepto,
                                        detalleAclaratorio=detalle_aclaratorio,
                                        diasAlmacenaje=dias_almacenaje,
                                        precioPKGdiario=precio_pkg_diario,
                                        comisionGastosAdm=comision_gastos_adm,
                                        baseCalculo=base_calculo,
                                        alicuotaIva=alicuota, 
                                    ))
                            )
        return True
119998
protected function _deleteRoles(array $delete = [])
    {
        if (empty($delete)) {
            return true;
        }
        return count($delete) === (new \Cms\Orm\CmsCategoryRoleQuery)
                ->whereCmsCategoryId()->equals($this->_category->getPk())
                ->andFieldCmsRoleId()->equals($delete)
                ->find()->delete();
    }
1133553
def AgregarTributo(self, cod_tributo, descripcion=None,     
                       base_imponible=None, alicuota=None, importe=None):
        ""
        trib = {'codTributo': cod_tributo, 'descripcion': descripcion, 
                'baseImponible': base_imponible, 'alicuota': alicuota, 
                'importe': importe}
        if 'ajusteFinanciero' in self.solicitud:
            self.solicitud['ajusteFinanciero']['tributo'].append(trib)
        else:
            self.solicitud['tributo'].append(trib)
        return True
1086279
def AgregarOperador(self, cuit, iibb=None, nro_ruca=None, nro_renspa=None, 
                        cuit_autorizado=None, **kwargs):
        ""
        d = {'cuit': cuit, 
             'iibb': iibb,
             'nroRUCA': nro_ruca,
             'nroRenspa': nro_renspa,
             'cuitAutorizado': cuit_autorizado}
        self.solicitud['receptor']['operador'] = d
        return True
149354
def ObtenerTablaParametros(self, tipo_recurso, sep="||"):
        ""        
        if not self.client:
            self.Conectar()
        self.response = self.client("parametros", "v1", tipo_recurso)
        result = json.loads(self.response)
        ret = {}
        if result['success']:
            data = result['data']
            # armo un diccionario con los datos devueltos:
            key = [k for k in data[0].keys() if k.startswith("id")][0]
            val = [k for k in data[0].keys() if k.startswith("desc")][0]
            for it in data:
                ret[it[key]] = it[val]
            self.data = data
        else:
            error = result['error']
            self.Excepcion = error['mensaje']
        if sep:
            return ["%s%%s%s%%s%s" % (sep, sep, sep) % it for it in sorted(ret.items())]
        else:
            return ret
740529
def AutorizarAnticipo(self):
        ""

        # extraer y adaptar los campos para el anticipo
        anticipo = {"liquidacion": self.liquidacion}
        liq = anticipo["liquidacion"] 
        liq["campaniaPpal"] = self.liquidacion["campaniaPPal"]
        liq["codLocProcedencia"] = self.liquidacion["codLocalidadProcedencia"]
        liq["descPuertoLocalidad"] = self.liquidacion["desPuertoLocalidad"]
        
        if self.opcionales:
            liq['opcionales'] = self.opcionales

        if self.retenciones:
            anticipo['retenciones'] = self.retenciones

        if self.deducciones:
            anticipo['deducciones'] = self.deducciones
        
        # llamo al webservice:
        ret = self.client.lpgAutorizarAnticipo(
                        auth={
                            'token': self.Token, 'sign': self.Sign,
                            'cuit': self.Cuit, },
                        anticipo=anticipo,
                        )

        # analizo la respusta
        ret = ret['liqReturn']
        self.__analizar_errores(ret)
        self.AnalizarLiquidacion(ret.get('autorizacion'), self.liquidacion)
        return True
1353652
public function agregarRuta($metodo, $ruta, $accion, array $parametros = null, $estado_http = 200)
    {
        // Normalizamos el uri de la ruta argumentada
        $ruta = $this->normalizarUri($ruta);

        // Limpiamos y dividimos la ruta en partes
        $partes = explode('/', trim($ruta, '/ '));

        // Contamos las partes resultantes
        $conteo_partes = count($partes);

        // Declaramos la rama base como actual
        $rama_actual = &$this->arbol_rutas;

        // Preparamos variable que clasifica la ruta como simple
        $es_simple = true;

        // Verificamos si hay suficientes partes para recorrerlas
        if (!($conteo_partes === 1 && $partes[0] === '')) {

            // Recorremos las partes para actualizar la rama actual
            for ($i = 0; $i < $conteo_partes; $i++) {

                if (substr($partes[$i], 0, 1) == ':') {
                    $es_simple = false;
                    if (!isset($rama_actual['ramas']['*'])) {
                        $rama_actual['ramas']['*'] = ['ramas' => [], 'nombre' => substr($partes[$i], 1)];
                    }

                    $rama_actual = &$rama_actual['ramas']['*'];
                } else {
                    if (!isset($rama_actual['ramas'][$partes[$i]])) {
                        $rama_actual['ramas'][$partes[$i]] = ['ramas' => []];
                    }

                    $rama_actual = &$rama_actual['ramas'][$partes[$i]];
                }
            }

        }

        // Preparamos el metodo argumentado
        $metodo = (array)$metodo;

        // Insertamos la ruta a la rama actual
        $rama_actual['ruta'] = $ruta;

        // Preparamos las acciones de la rama actual
        if (!isset($rama_actual['x'])) {
            $rama_actual['x'] = [];
        }

        // Recorremos los metodos para agregar las respectivas acciones
        foreach ($metodo as $m) {
            // Agregamos ruta simple en caso necesario
            if ($es_simple) {
                $this->rutas_simples[$ruta][strtoupper($m)]['accion'] = $accion;
                $this->rutas_simples[$ruta][strtoupper($m)]['estado_http'] = $estado_http;
                if (isset($parametros)) {
                    $this->rutas_simples[$ruta][strtoupper($m)]['parametros'] = $parametros;
                }
            } else {
                $rama_actual['x'][strtoupper($m)]['accion'] = $accion;
                $rama_actual['x'][strtoupper($m)]['estado_http'] = $estado_http;
                if (isset($parametros)) {
                    $rama_actual['x'][strtoupper($m)]['parametros'] = $parametros;
                }
            }
        }

        // Liberamos memoria
        unset($rama_actual);
    }
539568
public function listado_de_productos_con_sabores($id, $con_entrada = DETALLE_COMANDA_TRAER_TODOS, $contain = null){
		//inicialiozo variable return
		$items = array();

		if($id != 0){
			$this->id = $id;
		}

		
		$this->DetalleComanda->order = 'Producto.categoria_id';
		/*
		$this->DetalleComanda->recursive = 2;
		
		// le saco todos los modelos que no necesito paraqe haga mas rapido la consulta
		$this->DetalleComanda->Producto->unBindModel(array('hasMany' => array('DetalleComanda'), 
																 'belongsTo'=> array('Categoria')));
												 
		$this->DetalleComanda->DetalleSabor->unBindModel(array('belongsTo' => array('DetalleComanda')));
		*/
		unset($condiciones);
		$condiciones[]['DetalleComanda.comanda_id'] = $this->id;
		
		switch($con_entrada){
			case DETALLE_COMANDA_TRAER_PLATOS_PRINCIPALES: // si quiero solo platos principales
				$condiciones[]['DetalleComanda.es_entrada'] = 0;
				break;
			case DETALLE_COMANDA_TRAER_ENTRADAS: // si quiero solo entradas
				$condiciones[]['DetalleComanda.es_entrada'] = 1;
				break;
			default: // si quiero todo = DETALLE_COMANDA_TRAER_TODoS
				break;
		}

		if (empty($contain) ) {
			$contain = array(
				'Producto'=>array('Printer'),
				'Comanda'=> array('Mesa'=>array('Mozo')),
				'DetalleSabor'=>array('Sabor')
			);
		}
		
		$items = $this->DetalleComanda->find('all',array('conditions'=>$condiciones,
														'contain'=>$contain));
		return $items;
	}