<?php

/**
 * factura_pos actions.
 *
 * @package    cartera
 * @subpackage factura_pos
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class factura_posActions extends sfQuery {
    /*
     * ------------VARIABLES PARA SERVICIOS DE CONSULTA - LIST
     */

    protected $table_names = array(
        'CA_FACTURA_POS',
        'CA_PUNTO_VENTA',
        'INTERCEROS_DU_DIR_V',
        'INTERCEROS_V',
//        'INTERCER_DU',
//        'INTERCER_DU_DIR',
        'CA_CAJA',
        'CA_ESTADO_CAJA',
        'CA_FACTURA_POS_MOVIMIENTOS_CON',
        'IN_MOVIMIENTOS_CON'
    ); //tablas para construir el sql, por medio de joins
    protected $table_join_ids = array(
        'CA_PUNTO_VENTA' => array(
            'id_punto_venta' => 'CA_FACTURA_POS'
        ),
        'INTERCEROS_V' =>
        array(
            'cajero-id_mae_ter' => 'CA_FACTURA_POS'
        ),
        'INTERCEROS_DU_DIR_V' =>
        array(
            'id_mae_ter' => 'CA_FACTURA_POS'
        ),
//        'INTERCER_DU, LEFT' =>
//        array(
//            'id_mae_ter' => 'INTERCEROS'
//        ),
//        'INTERCER_DU_DIR, LEFT' =>
//        array(
//            'id_mt_ubi' => 'INTERCER_DU'
//        ),
        'CA_CAJA' =>
        array(
            'id_punto_venta' => 'CA_FACTURA_POS',
            'id_caja' => 'CA_FACTURA_POS'
        ),
        'CA_ESTADO_CAJA' =>
        array(
            'id_estado_caja' => 'CA_FACTURA_POS',
        ),
        'CA_FACTURA_POS_MOVIMIENTOS_CON,LEFT' =>
        array(
            'id_factura' => 'CA_FACTURA_POS'
        ),
        'IN_MOVIMIENTOS_CON,LEFT' =>
        array(
            'id_movimientos_con' => 'CA_FACTURA_POS_MOVIMIENTOS_CON',
            'id_vigencia' => 'CA_FACTURA_POS_MOVIMIENTOS_CON',
            'id_cen_op' => 'CA_FACTURA_POS_MOVIMIENTOS_CON',
            'id_tipo_movimiento' => 'CA_FACTURA_POS_MOVIMIENTOS_CON'
        )
    ); //si posee tablas para joins, identificar la relacion de los campos con las tablas
    protected $fields = array(
        'CA_FACTURA_POS' =>
        array(
            'id_factura' => 'id_factura',
            'id_anhos' => 'id_anhos',
            'id_punto_venta' => 'id_punto_venta',
            'id_caja' => 'id_caja',
            'sec_factura' => 'sec_factura',
            'id_mae_ter' => 'id_mae_ter',
            'fecha_facturacion' => 'fecha_facturacion',
            'valor_bruto' => 'valor_bruto',
            'valor_iva' => 'valor_iva',
            'valor_reten' => 'valor_reten',
            'valor_total' => 'valor_total',
            'cajero' => 'cajero',
            'observaciones' => 'observaciones',
            'estado' => 'estado',
            'fecha_anu' => 'fecha_anu',
            'motivo_anu' => 'motivo_anu',
            'id_estado_caja' => 'id_estado_caja',
            'valor_dcto' => 'valor_dcto',
            'porc_dcto' => 'porc_dcto'
        ),
        'CA_PUNTO_VENTA' =>
        array(
            'nombre' => 'punto_venta',
            'encabezado' => 'encabezado',
            'pie_pagina' => 'pie_pagina'
        ),
        'INTERCEROS_V' =>
        array(
            'num_doc' => 'num_doc_caj',
            'razon_soc' => 'razon_soc_caj',
            'num_doc,||, ,||,razon_soc' => 'tercero_caj'
        ),
        'INTERCEROS_DU_DIR_V' =>
        array(
            'num_doc' => 'num_doc',
            'razon_soc' => 'razon_soc',
            'num_doc,||, - ,||,razon_soc' => 'tercero',
            'mail' => 'mail',
//        ),
//        'INTERCER_DU_DIR' =>
//        array(
            'direccion' => 'direccion',
            'tel' => 'tel',
            'ciudad' => 'ciudad'
        ),
        'CA_CAJA' =>
        array(
            'prefijo' => 'prefijo'
        ),
        'CA_ESTADO_CAJA' =>
        array(
            'sesion' => 'sesion',
            'fecha_estado' => 'fecha_estado',
            'estado' => 'estado_caja'
        ),
        'CA_FACTURA_POS_MOVIMIENTOS_CON' =>
        array(
            'id_movimientos_con' => 'id_movimientos_con',
            'id_vigencia' => 'id_vigencia',
            'id_cen_op' => 'id_cen_op',
            'id_tipo_movimiento' => 'id_tipo_movimiento'
        ),
        'IN_MOVIMIENTOS_CON' =>
        array(
            'id_concepto_movimiento' => 'id_concepto_movimiento',
            'num_doc' => 'num_doc_mov',
            'id_ts_td' => 'id_ts_td',
            'fecha_doc' => 'fecha_doc',
            'id_mae_ter_ini' => 'id_mae_ter_ini',
            'id_mae_ter_fin' => 'id_mae_ter_fin',
            'id_espacio_ini' => 'id_espacio_ini',
            'id_espacio_fin' => 'id_espacio_fin',
            'id_tipo_almacenamiento_ini' => 'id_tipo_almacenamiento_ini',
            'id_tipo_almacenamiento_fin' => 'id_tipo_almacenamiento_fin',
            'observaciones' => 'observaciones_mov',
            'id_cen_op_fin' => 'id_cen_op_fin',
            'valor_factura' => 'valor_factura',
            'valor_ajuste' => 'valor_ajuste',
            'id_usuario' => 'id_usuario',
            'tiene_iva' => 'tiene_iva'
        )
    ); //por cada tabla especificar los campos del select
    protected $table_field_conditions = array(
        'CA_FACTURA_POS' => array(
            'id_factura,a' => array('!=' => array(-1)),
            'id_factura,b' => array('=' => array('id_factura')),
            'id_anhos' => array('=' => array('id_anhos')),
            'id_punto_venta' => array('=' => array('id_punto_venta')),
            'id_caja' => array('=' => array('id_caja')),
            'sec_factura,a' => array('=' => array('sec_factura')),
            'sec_factura,b' => array('>=' => array('sec_factura_ini')),
            'sec_factura,c' => array('<=' => array('sec_factura_fin')),
            'id_mae_ter' => array('=' => array('id_mae_ter')),
            'fecha_facturacion' => array('BETWEENFECHA' => array('fecha_ini', 'fecha_fin')),
            'estado' => array('=' => array('estado')),
            'cajero' => array('=' => array('cajero')),
            'id_tip_mon' => array('=' => array('id_tip_mon')),
            'valor_total,a' => array('>=' => array('valor_ini')),
            'valor_total,b' => array('<=' => array('valor_fin')),
            'valor_total,c' => array('=' => array('valor_exacto')),
            'rownum,start' => array('>' => array('_startRow')),
            'rownum,end' => array('<=' => array('_endRow'))
        ),
        'CA_ESTADO_CAJA' => array(
            'sesion' => array('=' => array('sesion'))
        )
    ); //por cada tabla se dan los campos, opcion de filtro y variable que entra para los posibles filtros
    protected $fields_orderBy = array(
        'sec_factura'
    ); //campos para el ordenamiento de la consulta

    /*
     * Variables manejo de log
     */
    //true - consulta de administracion
    protected $is_admin = false;
    //true - la tabla principal de busqueda no es una vista
    protected $is_filtro = true;


    /*
     * ------------VARIABLES PARA SERVICIO DE SUMATORIA - SUM
     *
     */
    protected $summatory_data = array(
        'CA_FACTURA_POS' => array(
            'fields' => array('valor_bruto', 'valor_iva', 'valor_total'),
            'labels' => array('id_factura,Total'),
            'count' => 'id_factura'
        )
    ); //se especifica por tabla los campos de suma y condiciones de filtro


    /*
     * ------------VARIABLES PARA SERVICIOS CRUD
     */
    protected $id_name = 'id_factura'; //identificador de la tabla
    protected $id_names = array('id_factura'); //llave primaria
    protected $field_names = array('id_anhos', 'id_punto_venta', 'id_caja', 'sec_factura', 'id_mae_ter', 'fecha_facturacion', 'valor_bruto', 'valor_iva', 'valor_total',
        'cajero', 'observaciones', 'estado', 'fecha_anu', 'motivo_anu', 'id_estado_caja', 'valor_reten'); //campos de la tabla, sin la llave primaria
    protected $table_name = 'CA_FACTURA_POS'; //tabla en la cual se aplican los cambios
    protected $has_activo = true; //si posee campo en la tabla de nombre activo ---- ESTADO PARA REGALIAS
    protected $has_vigencia = false; //si posee vigencia
    protected $has_cen_op = false; //si posee centro de operacion
    protected $has_id_cia = false; //si posee compañia
    protected $has_secuencia = true; //si posee secuencia la tabla
    /*
     * campos para fecha sistema con hora
     */
    protected $campo_fecha_sistema_hora = array(
        'fecha_facturacion'
    );
    protected $check_exists = array('id_factura'); //para verificar que no exista la combinacion de estos campos en la tabla
    protected $has_check_exists = true; //para acutalizar registro si valida campos en check_exists
    /*
     * Manejo de registro log
     */
    protected $id_unico = 'id_factura'; //identificador unico de la tabla

    // Validate
    /**
     * Ejecuta una validación previa a la ejecución de una operación tipo Add
     *
     * @param sfWebRequest $request
     * @return array 
     */

    protected function validateAdd(sfWebRequest $request) {

        /*
         * Se instancia la clase del manejo del log
         */
        $logger = sfContext::getInstance()->getLogger();
        $logger->info("Entro a preprocessRequest");

        //valor por defecto
        $errors = null;

        /*
         * Validar la operación, ya sea por SQL
         * Variables - 20150227
         */
        $valor_total = $request['valor_total'];
        $valor_pago_total_pd = $request['valor_pago_total_pd'];

        /**
         * Valida que el valor de pago sea mayor o igual al total de la factura - 20150227
         */
        if ($valor_pago_total_pd < $valor_total) {
            $errors['mensaje'] = "El valor del pago es inferior a la factura.";
            $errors['servicio'] = "factura_pos";
            $logger->info("El valor del pago(" . $valor_pago_total_pd . ") es inferior a la factura(" . $valor_total . ").");
        } else {
            $logger->info("Valida que el valor de pago(" . $valor_pago_total_pd . ") sea mayor o igual al total de la factura(" . $valor_total . ").");
        }

        /*
         *  Generar errores en $errors
         */

        return $errors;
    }

    /**
     * Ejecuta una validación previa a la ejecución de una operación tipo Update
     *
     * @param sfWebRequest $request
     * @return array 
     */
    protected function validateUpdate(sfWebRequest $request) {

        //valor por defecto
        $errors = null;

        /*
         *  Validar la operación, ya sea por SQL
         */

        /*
         *  Generar errores en $errors
         */

        return $errors;
    }

    /**
     * Ejecuta una validación previa a la ejecución de una operación tipo Remove
     *
     * @param sfWebRequest $request
     * @return array 
     */
    protected function validateRemove(sfWebRequest $request) {

        //valor por defecto
        $errors = null;

        /*
         *  Validar la operación, ya sea por SQL
         */

        /*
         *  Generar errores en $errors
         */

        return $errors;
    }

    /**
     * Acciones anteriores a la original
     * 
     * return sfWebRequest Changed Request with additional parameters.
     * 
     * @param type $Action ( ADD, UPDATE, REMOVE )
     * @param sfWebRequest $request
     * @return \sfWebRequest 
     */
    protected function preprocessRequest($Action, sfWebRequest $request) {

        /*
         * Se instancia la clase del manejo del log
         */
        $logger = sfContext::getInstance()->getLogger();
        $logger->info("Entro a preprocessRequest");

        /*
         * Procesar Request
         */
        //accion add
        if ($Action == "ADD") {
            
        }

        //accion update
        if ($Action == "UPDATE") {
            
        }

        //accion remove
        if ($Action == "REMOVE") {
            
        }

        return $request;
    }

    /**
     * Acciones posteriores a la original
     * 
     * return sfWebRequest Changed Request with additional parameters.
     * 
     * @param type $Action ( ADD, UPDATE, REMOVE )
     * @param sfWebRequest $request
     * @return \sfWebRequest 
     */
    protected function postprocessRequest($Action, sfWebRequest $request, $list_data_post) {

        /*
         * Se instancia la clase del manejo del log
         */
        $logger = sfContext::getInstance()->getLogger();
        $logger->info("Entro a postprocessRequest - " . $list_data_post);

        /*
         * Procesar Request
         */
        //accion add
        if ($Action == "ADD") {
            
        }

        //accion update
        if ($Action == "UPDATE") {
            
        }

        //accion remove
        if ($Action == "REMOVE") {
            
        }

        return $request;
    }

    /**
     * Metodo para anular una factura
     *
     * @param sfWebRequest $request
     */
    public function executeUpdate(sfWebRequest $request) {

        //Revisar que sea post
        //$this->forward404Unless($request->isMethod('post'));
        //Guardar los parametros del request en el log
        $this->logMessage("---BEGIN Logging request");
        foreach ($request->getPostParameters() as $key => $value) {
            $this->logMessage("request[$key] = $value");
        }
        $this->logMessage("--------------------------------------------------/  Ip: " . $_SERVER['REMOTE_ADDR']);
        foreach ($request->getGetParameters() as $key => $value) {
            $this->logMessage("request[$key] = $value");
        }
        $this->logMessage("---END Logging request");



        //sentencia sql
        $sql = <<<EOD
ALTER SESSION SET NLS_DATE_FORMAT = "YYYY-MM-DD"
EOD;

        //ejecuta el sql
        CN_TABLE::executeSQL($sql);

        /*
         * variables por defecto para el registro de log
         */
        //obtiene el valor para su identificador unico
        $id_tabla = 'null';
        if (isset($request[$this->id_unico])) {
            $id_tabla = $request[$this->id_unico];
        }

        //validar vigencia
        $id_vigencia = 'null';
        if ($this->has_vigencia) {
            if (isset($request['id_vigencia'])) {
                $id_vigencia = $request['id_vigencia'];
            }
        }

        //validar centro de operacion
        $id_cen_op = 'null';
        if ($this->has_cen_op) {
            if (isset($request['id_cen_op'])) {
                $id_cen_op = $request['id_cen_op'];
            }
        }

        $id_cia = 'null';
        if ($this->has_id_cia) {
            if (isset($request['id_cia'])) {
                $id_cia = $request['id_cia'];
            }
        }

        //obtener id maestro tabla
        $id_mae_bd = CN_TABLE::consultarIdTablaBD($this->table_name);

        //5 - indica operacion de anulacion de registro
        $id_ope_bd = 5;

        //id del maestro tercero
        $id_mae_ter = 1;
        if (isset($request['id_username'])) {
            $id_mae_ter = $request['id_username'];
        }
        //el username desde qebsafiERP
        $usuario = 'admin';
        if (isset($request['username']) && $request['username'] != '') {
            $usuario = $request['username'];
        }
        //comando que identifica la funcionalidad
        $comando = 'sin comando';
        if (isset($request['comando'])) {
            $comando = $request['comando'];
        }

        /*
         * Construir observacion
         */
        $observacion = "'Se anulo " . $this->id_unico . ": " . $id_tabla . " desde la funcionalidad: " . $comando . "'";



        $id_punto_venta_log = 'null';
        if (isset($request['punto_venta_log'])) {
            $id_punto_venta_log = $request['punto_venta_log'];
        }

        //validar errores de procedimiento
        try {

            $resultado = array();

            /*
             * Variables obligatorias
             */

            $id_factura = $request['id_factura'];
            $fecha_sistema = $request['fecha_anu'];
//            $fecha_sistema = CN_TABLE::fechaSistema();
            $motivo_anu = 'null';
            if (isset($request['motivo_anu'])) {
                if ($request['motivo_anu'] != 'null') {
                    $motivo_anu = "'" . $request['motivo_anu'] . "'";
                } else {
                    $motivo_anu = 'null';
                }
            }
            $username = 'null';
            if (isset($request['username'])) {
                $username = $request['username'];
            }


            /*
             * Anular registro de factura pos
             */
            //sentencia sql
            $sql = <<<EOD
UPDATE CA_FACTURA_POS SET estado = 0, 
    fecha_anu = to_date('$fecha_sistema','YYYY-MM-DD HH24:MI:SS'),
    motivo_anu =  $motivo_anu 
        WHERE (id_factura = $id_factura) 
EOD;
            //ejecuta el sql
            CN_TABLE::executeSQL($sql);

            /*
             * Anula movimiento banco
             */
            //sentencia sql
            $sql = <<<EOD
declare

  factura number := $id_factura;
  id_mov_banc number := 0;
  l_query  VARCHAR2(1000) ;

begin

  -- Obtener factura_pago por id_factura  
  
  -- Recorer factura_pago que poseean forma de pago que aplica banco
  -- Factura pago Anulada estado en 0
  for RecordIndex in (    select 
    pago.*,
    pos.id_anhos,
    pos.id_punto_venta,
    pos.id_caja,
    pos.sec_factura,
    pos.id_mae_ter,
    pos.estado,
    pos.fecha_anu,
    pos.motivo_anu
    from ca_factura_pago pago
    join ca_factura_pos pos on pos.id_factura = pago.id_factura
    join ts_pc_fp fp on fp.id = pago.id_ts_pc_fp and fp.aplica_bn = 1
    where  pago.id_factura = factura  )
  loop
  
  -- Obtener por cada una el id del movimiento de banco        
      l_query := q'[SELECT mb.id FROM ts_mov_banc mb WHERE mb.numero_doc = ']' ||  recordindex.num_doc || q'[']' ||
                  ' and mb.id_mae_ter = ' || recordindex.id_mae_ter || 
                  ' and mb.id_ts_bn = ' || recordindex.id_bn || ' and mb.id_ts_cb = ' || recordindex.id_cb || 
                  ' and mb.valor = '  || recordindex.valor || ' ' ||
                  q'[and mb.observaciones like '%]' || RecordIndex.sec_factura || q'[%']' || ' '  ;
      
      execute immediate l_query into id_mov_banc ;
      --dbms_output.put_line(l_query) ;
      --DBMS_OUTPUT.PUT_LINE(id_mov_banc) ;

  -- Por cada una anular movimiento banco
      update  ts_mov_banc set estado = 1 where id = id_mov_banc;
  
  -- Por cada una crear movimiento banco anulado
  
      insert into ts_anu_mov_banc ( id_anu_mov_banc, id_mov_banc, fecha_anul, concepto, observaciones, usuario, fecha_log ) 
      values ( null, id_mov_banc, trunc(recordindex.fecha_anu), 'ANULACIÓN FACT. POS',
      'ANULACIÓN FACTURA POS No. ' || RecordIndex.sec_factura , '$username', trunc(sysdate) );
  

  END LOOP;

end ;

EOD;
            //ejecuta el sql
            CN_TABLE::executeSQL($sql);

            //Resultado para el Template
            $this->list_data = $resultado;
            $this->logMessage("[FACTURA_POS] Anulado registro.");

            $this->logMessage("[sfApiActions] Entro registro LOG.");
            $sql = CN_TABLE::registroTableLog($id_tabla, $id_vigencia, $id_cen_op, $id_cia, $id_mae_bd, $id_ope_bd, $id_mae_ter, $usuario, $comando, $observacion, $id_punto_venta_log);
        } catch (Exception $e) {

            $mensaje = "ERROR!!!";

            $this->logMessage($mensaje);
            $this->logMessage("state 2");
            $this->logMessage("Code " . $e->getCode());
            $this->logMessage("Message " . $e->getMessage());

            $this->status = 2;
            $this->mensajeError = $mensaje;
            $this->list_data = array(
                array(
                    'Code' => $e->getCode(),
                    'Message' => $e->getMessage(),
                    'Line' => $e->getLine(),
                    'Trace' => $e->getTraceAsString(),
                    'mensaje' => $mensaje
                )
            );
        }

        /*
         * (SGC-1, ANM-2, SGR-3, CYC-4, COL-5, INCI-6, LOCAL-7)
         */
        $array = sfYaml::load(dirname(__FILE__) . '/../../../config/app-gwt.yml');

        $int = 0;
        foreach ($array as $routeName => $routeData) {
            //echo $routeName . "\n";
            if ('entidad_cliente' == $routeName) {
                foreach ($routeData as $key => $value) {
                    //echo $value . "\n";
                    if ($key == 'value') {
                        $entidadCliente = $value;
                    }
                }
            }
            $int++;
        }

        /**
         * Segun entidad
         */
        if ($entidadCliente == 2) {
            try {
                //sentencia sql
                $sql = <<<EOD
SELECT
    *
FROM ca_factura_abaco
where
id_factura = $id_factura               
EOD;

                //ejecuta el sql
                $result = CN_TABLE::executeSQL($sql);

                /**
                 * Llamado a abaco anulacion si aplica - 20190815
                 */
                if (count($result) > 0) {
                    $this->logMessage("Llamado a abaco anulacion si aplica");

                    //Llamado a abaco
                    $array_abaco = $this->llamadoAbaco($id_factura);
                }
            } catch (Exception $exc) {
                $this->logMessage("ERROR!!!");
                $this->logMessage($exc->getTraceAsString());
            }
        }
    }

    /**
     * Se hace llamado a Abaco Anulacion - 20190815
     * @param type $id_factura
     */
    public function llamadoAbaco($id_factura = null) {

        $id_factura_filtro = $id_factura;

        //Log especifico de procesos completos - 20160527
        $logPath = sfConfig::get('sf_log_dir') . '/factura_portal_abaco.log';
        $this->custom_logger = new sfFileLogger(new sfEventDispatcher(), array('file' => $logPath));

        $this->custom_logger->info("----------------------------------------BEGIN llamadoAbaco Anulacion. id_factura::" . $id_factura);
        $this->logMessage("----------------------------------------BEGIN llamadoAbaco Anulacion. id_factura::" . $id_factura);


        $id_tabla = $id_factura;
        $id_vigencia = 'null';
        $id_cen_op = 'null';
        $id_cia = 'null';

        //obtener id maestro tabla
        $id_mae_bd = CN_TABLE::consultarIdTablaBD('CA_FACTURA_ABACO');

        //  1- CONSULTAR, 2- ACTUALIZAR, 3 - ADICIONAR, 4 - ELIMINAR, 5 - ANULAR
        $id_ope_bd = 5;
        //id del maestro tercero
        $id_mae_ter_log = 1;
        $usuario = 'admin';
        $comando = 'debito';
        //construir observacion
        $observacion = "'Se ingreso a generar llamadoAbaco anulacion.'";

        $id_punto_venta = '62';

        CN_TABLE::registroTableLog($id_tabla, $id_vigencia, $id_cen_op, $id_cia, $id_mae_bd, $id_ope_bd, $id_mae_ter_log, $usuario, $comando, $observacion, $id_punto_venta);

        try {

            /**
             * Abrir nueva conexion con la Base de Datos
             */
            $this->conn = Doctrine_Manager::getInstance()->getCurrentConnection();
            $this->conn->beginTransaction();

            $array = sfYaml::load(dirname(__FILE__) . '/../../../config/app-gwt.yml');

            $int = 0;
            foreach ($array as $routeName => $routeData) {
                //echo $routeName . "\n";
                if ('url_abaco' == $routeName) {
                    foreach ($routeData as $key => $value) {
                        //echo $value . "\n";
                        if ($key == 'value') {
                            $url_abaco = $value;
                        }
                    }
                }
                if ('ipServidorCorreo' == $routeName) {
                    foreach ($routeData as $key => $value) {
                        //echo $value . "\n";
                        if ($key == 'value') {
                            $ipServidorCorreo = $value;
                        }
                    }
                }
                if ('correoEnvio' == $routeName) {
                    foreach ($routeData as $key => $value) {
                        //echo $value . "\n";
                        if ($key == 'value') {
                            $correoEnvio = $value;
                        }
                    }
                }
                $int++;
            }


            //valores por defecto
            $message = '';
            $successful = 'false';
            $idrequest = '';
            $idInvoice = '';

            if (!is_null($id_factura_filtro)) {

                $whereFactura = 'and tab0.id_factura = ' . $id_factura_filtro;
                $idInvoice = $id_factura_filtro;
            }


            /**
             * For de ca_facturas_abaco sin procesar para el estado_abaco en 0
             * Se coloca validación para cuando no tiene nombre o apellido - 20190618
             * Se valida en el nombre del tercero las comillas dobles - 20190628
             */
            $sql = <<<EOD
select
    
tab0.*,
pos.sec_factura,
pos.observaciones,
DECODE(ter.id_tip_ter, 1, 2, 2, 1) as id_tip_ter,
ter.num_doc,
DECODE(ter.id_tipo_doc, 1,13, 26,22, 27,11, 28,12, 29,31, 31,41, 81,31) as id_tipo_doc,
ter.dv,
                    
upper(ter.direccion) as direccion,
upper(ter.ciudad) as ciudad,
upper(dep.descripcion) as departamento,
dep.coddepto as coddepto,
upper( nvl(mun.codmun_text, nvl(mundep.codmun_text, case when dep.coddepto is null then '11001' else dep.coddepto||'001' end ) ) ) as codmun_text,
upper(replace(ter.razon_soc,'"','')) as razon_soc,
case when DECODE(ter.id_tip_ter, 1, 2, 2, 1) = 2 and ter.pnombre is null then upper(replace(ter.razon_soc,'"','')) else upper(replace(ter.pnombre,'"','')) end as pnombre,
upper(replace(ter.snombre,'"','')) as snombre,
case when DECODE(ter.id_tip_ter, 1, 2, 2, 1) = 2 and ter.papellido is null then upper(replace(ter.razon_soc,'"','')) else upper(replace(ter.papellido,'"','')) end as papellido,
ter.tel,
nvl( pos.email_web, nvl(ter.mail,ter.mail_con) ) as mail,

upper(produc.descripcion) as producto,
prod.valor_uni_bruto,
prod.valor_uni_total,

produc.codigo,
to_char(pos.fecha_facturacion,'dd/mm/yyyy') as fecha_facturacion,
upper(caj.prefijo || ' - ' || caj.ubicacion) as caja,
upper(bn.descripcion) as banco,
cb.numero_cuenta as cuenta,
upper(fp.descripcion) as tipo_pago,
upper(pag.oficina) as oficina,
pag.num_doc as pin,

pos.valor_total - pos.valor_iva as valorsiniva,
pos.valor_iva,
pos.valor_total,
upper(numero_a_texto(pos.valor_total)) as valor_total_text

from ca_factura_abaco tab0

left join ca_factura_pos pos
on pos.id_factura = tab0.id_factura

left join ca_caja caj
on caj.id_caja = pos.id_caja

left join ca_factura_prod prod
on pos.id_factura = prod.id_factura

left join ca_producto produc
on produc.id_producto = prod.id_producto

left join ca_factura_pago pag
on pos.id_factura = pag.id_factura

left join ts_pc_fp fp
on fp.id = pag.id_ts_pc_fp

left join ts_bn bn
on bn.id_bn = pag.id_bn

left join ts_cb cb
on cb.id_cb = pag.id_cb

left join interceros_du_dir_v ter
on ter.id_mae_ter = pos.id_mae_ter

left join departamento dep
on dep.coddepto = ter.copdepto

left join municipios mundep
on mundep.depto = dep.id_depto
and upper(mundep.municipio) = upper(ter.ciudad)

left join municipios mun
on mun.codmun = ter.codmun

where
pos.estado = 0 
and tab0.estado_abaco = 1 
and tab0.anulado_abaco = 0 
and tab0.id_factura is not null 
$whereFactura 

order by
tab0.fecha_log                
EOD;

            //ejecuta el sql
            $resultado = CN_TABLE::executeSQL($sql);
            foreach ($resultado as $value) {

                //Se agreaga sec_anulacion - 20190830
                $sql = <<<EOD
SELECT
nvl(max(sec_anulacion)+1,1) as sec_anulacion
FROM ca_factura_abaco             
EOD;

                //ejecuta el sql
                $resultado_sec = CN_TABLE::executeSQL($sql);

                $sec_anulacion = $resultado_sec[0]['sec_anulacion'];
                $this->logMessage("Procesar el llamadoAbaco sec_anulacion: " . $sec_anulacion);

                $id_factura = $value['id_factura'];

                $this->custom_logger->info("Procesar el llamadoAbaco id_factura: " . $id_factura);
                $this->logMessage("Procesar el llamadoAbaco id_factura: " . $id_factura);

                $sec_factura = $value['sec_factura'];
                $observaciones = $value['observaciones'];
                $id_tip_ter = $value['id_tip_ter'];
                $num_doc = $value['num_doc'];
                $id_tipo_doc = $value['id_tipo_doc'];
                $dv = $value['dv'];
                $direccion = $value['direccion'];
                $direccion = str_replace('"', '', $direccion);
                $ciudad = $value['ciudad'];
                $departamento = $value['departamento'];
                $coddepto = $value['coddepto'];
                $codmun_text = $value['codmun_text'];
                $razon_soc = $value['razon_soc'];
                $pnombre = $value['pnombre'];
                $snombre = $value['snombre'];
                $papellido = $value['papellido'];
                $tel = $value['tel'];
                $mail = $value['mail'];

                $producto = $value['producto'];
                $valor_uni_bruto = $value['valor_uni_bruto'];
                $valor_uni_total = $value['valor_uni_total'];

                $codigo = $value['codigo'];
                $fecha_facturacion = $value['fecha_facturacion'];
                $caja = $value['caja'];
                $banco = $value['banco'];
                $cuenta = $value['cuenta'];
                $tipo_pago = $value['tipo_pago'];
                $oficina = $value['oficina'];
                $pin = $value['pin'];

                $valorsiniva = $value['valorsiniva'];
                $valor_iva = $value['valor_iva'];
                $valor_total = $value['valor_total'];
                $valor_total_text = $value['valor_total_text'];

                /** Ejemplo de JSON - ABACO
                  {
                  "username" : "adm_anm@yopmail.com",				//[Usuario del ANM previamente creado en la plataforma. Este usuario cambia de ambiente de producción a ambiente de pruebas]
                  "password" : "G+AiJ1Cq84iauVtdWTuhLk/xBGR0cC1rR3n0tScwWyM=",      //[Contraseña de acceso asociado al usuario - SHA256 codificada Base 64 de la contraseña registrada en la plataforma]
                  "objectType" :0,                                                  //[FACTURA(0), NOTA_CREDITO(1), NOTA_DEBITO(2)]
                  "invoiceIdType" :1,						//[FACTURA_DE_VENTA(0), FACTURA_DE_COMPRA_VENTA(1)]
                  "idRange" :174,							//[Identificador del rango de facturación registrado en la plataforma Ábaco. Esta información cambia de ambiente de pruebas a ambiente de producción]
                  "idObject" :"4",							//[Identificador de la Factura generado por la plataforma WebSafi]
                  "idInvoiceType" :120,						//[Identificador de la plantilla PDF a utilizar. Esta información cambia de ambiente de pruebas a ambiente de producción]
                  "idNoteType" : null,						//[Identificador de la plantilla PDF a utilizar para notas crédito. Esta información cambia de ambiente de pruebas a ambiente de producción]
                  "signed" : false,							//[true si se va a firmar digitalmente la factura]
                  "send" : false,							//[true si se va a enviar a la DIAN]
                  "sendToCustomer" : false,						//[true si se va a enviar al cliente]
                  "notificationStrings" : ["EMAIL"],				//[Mecanismo de envío de la factura al cliente]
                  "description" :"descripción de la factura",			//[Descripción de la factura]
                  "currencyCode" :"COP",						//[Código de moneda]
                  "customer" : {
                  "personType" :1,							//[PERSONA_JURIDICA(1), PERSONA_NATURAL(2), GRAN_CONTRIBUYENTE(3)]
                  "personId" :"890903937",						//[No. de documento]
                  "idType" :31,							//[NIT(31), REGISTRO_CIVIL(11), TARJETA_DE_IDENTIDAD(12), CEDULA_DE_CIUDADANIA(13), TARJETA_DE_EXTRANJERIA(21), CEDULA_DE_EXTRANJERIA(22), PASAPORTE(41), DOCUMENTO_DE_IDENTIFICACION_EXTRANJERO(42), NUIP(91)]
                  "schemeType" :0,							//[REGIMEN_SIMPLIFICADO(0), REGIMEN_OTRO(1), REGIMEN_COMUN(2),REGIMEN_CLIENTE_EN_EL_EXTERIOR(-1)]
                  "address" :"CALLE 12 7 46",					//[Dirección del adquirente]
                  "city" :"Bogotá, D.C.",						//[Ciudad del adquirente]
                  "department" :"BOGOTÁ DC",					//[Departamento del adquirente]
                  "citySubDivision" :"",						//[Barrio o zona del adquirente]
                  "countryCode" :"CO",						//[Código del país]
                  "organizationName" :"BANCO COLPATRIA S.A.",			//[Razón social o nombre del adquirente]
                  "firstName" :"",							//[Primer nombre]
                  "middleName" :"",							//[Segundo nombre]
                  "lastName" :"",							//[Apellido]
                  "codePhoneNumber" :"",						//[Código telefónico del país. i.e. +57]
                  "cellPhone" :"",							//[Número celular]
                  "email" :"diego.bulla@software-colombia.com"			//[Correo electrónico]
                  },
                  "lines" : [ {
                  "description" :"CERTIFICADO DE REGISTRO MINERO DIGITAL ",         //[Descripción del item facturado No. 1]
                  "quantity" : 1,							//[Cantidad del ítem facturado No. 1]
                  "currencyCode" :"COP",						//[Código de moneda]
                  "unityPrice" : 69000.00,						//[Precio unitario]
                  "noteLine" : null,						//[Observaciones]
                  "accountingCost" : null,						//[Centro de costo]
                  "totalPrice" : 69000.00,						//[Precio total]
                  "taxes" : [{
                  "taxAmount": 100000.0,						//[Base para el cálculo del impuesto]
                  "taxEvidenceType": false,                                         //[true: Impuesto retenido - false: Impuesto no retenido]
                  "taxableAmount": 19000.0,                                         //[Valor del impuesto]
                  "percent": 19.0,							//[Procentaje del impuesto]
                  "currencyCode": "COP",						//[Código de moneda]
                  "taxTypeCode": "01"						//[VALOR_TOTAL_DE_IVA("01"), VALOR_TOTAL_DE_IMPUESTO_AL_CONSUMO("02"), VALOR_TOTAL_DE_ICA("03"), VALOR_TOTAL_DE_IMPUESTO_NACIONAL_AL_CONSUMO("04")]
                  }] ,
                  },{
                  "description": "Esferos",
                  "quantity": 1,
                  "currencyCode": "COP",
                  "unityPrice": 120000.0,
                  "noteLine": null,
                  "accountingCost": null,
                  "totalPrice": 120000.0,
                  "taxes": []
                  }
                  ],
                  "extraWSProperties" : {
                  "Codigo" : "SM-40",                                               //[Opcional: Nombre y valor de propiedades adicionales que no se enviarán a la DIAN pero sí se mostrarán en la factura]
                  "Fecha" :"25/10/2018",						//[Opcional: Nombre y valor de propiedades adicionales que no se enviarán a la DIAN pero sí se mostrarán en la factura]
                  "Caja" :"01 - PRINCIPAL",						//[Opcional: Nombre y valor de propiedades adicionales que no se enviarán a la DIAN pero sí se mostrarán en la factura]
                  "Banco" :"BANCO DE BOGOTA",					//[Opcional: Nombre y valor de propiedades adicionales que no se enviarán a la DIAN pero sí se mostrarán en la factura]
                  "Cuenta" :"000021980",						//[Opcional: Nombre y valor de propiedades adicionales que no se enviarán a la DIAN pero sí se mostrarán en la factura]
                  "Recibo" :"CODIGO BARRAS",					//[Opcional: Nombre y valor de propiedades adicionales que no se enviarán a la DIAN pero sí se mostrarán en la factura]
                  "Oficina" :"VENTAS PORTAL WEB - CODIGO BARRAS",                   //[Opcional: Nombre y valor de propiedades adicionales que no se enviarán a la DIAN pero sí se mostrarán en la factura]
                  "Num" :"20180815093337"						//[Opcional: Nombre y valor de propiedades adicionales que no se enviarán a la DIAN pero sí se mostrarán en la factura]
                  },
                  "amountNoTaxes" :69000.00,					//[Total de la factura sin impuestos]
                  "amountTaxes" :13110.00,						//[Total de impuestos]
                  "totalAmount" :82110.00,						//[Total de la factura con impuestos]
                  "totalAmountText" :"DOSCIENTOS DIEZ MIL DOSCIENTOS SETENTA Y NUEVE PESOS CON DIEZ Y OCHO CENTAVOS M/CTE.************" //[Texto Total de la factura con impuestos]
                  }
                 */
                /**
                 * Paso Produccion - 20190215
                  "idRange" de 174 A   85, 191 a 102 NC - anuladas
                  "idInvoiceType" de  120 A 121, 180 a 139 NC - anuladas
                  "signed" :  false  A  true
                  "send": false  A  true
                  "sendToCustomer" :  false  A  true
                  "username": adm_anm@yopmail.com   A   factura.electronica@anm.gov.co
                 * 
                 * Novedad Anualcion - 20190515
                 * A diferencia de la factura, los atributos mostrados arriba son los únicos que cambian:

                  objectType: 0-Factura, 1-Nota Crédito, 2-Nota Débito
                  invoiceIdType y idInvoiceType: Ahora deben ser omitidos o nulos
                  idNoteType : Contiene el ID de la plantilla creada en Abaco. Si es null se usará una por defecto
                  invoiceSourceId: Contiene el consecutivo de la factura a la que se aplica la nota.
                  noteTypeId: Código del concepto de la nota. Debe regirse con los valores dados por la DIAN como se muestra a continuación:(imagen 1)
                 *  
                  1.	Se debe cambiar el rango de numeración de "idRange" :174, a "idRange" :191 para Notas
                  2.	Se debe trasmitir bajo la numeración 1 a 9999999, por lo tanto el que se debería transmitir es "idObject" :"9",
                  3.	Se debe considerar el ID de la plantilla para notas que corresponde a "idNoteType": 180.  - 20190829
                 */
                /*
                 * Incidente #14878
                  "idRange" de 174 A 135
                 */
                /** Incidente #15151 - 20191129
                  "idObject": "SETT27", De esta manera se debe enviar en ambiente de pruebas las facturas, puedes utilizar desde número SETT28.
                  "idVerificationDigit": "1", En este campo se debe agregar el dígito de verificación de los Nit cliente.
                  "city": "15244", El código de la ciudad debe estar alineado a los códigos brindados y que te adjunto nuevamente.
                  "department" :"91", El código de la departamento debe estar alineado a los códigos brindados y que te adjunto nuevamente.
                 */
                //Parametros de app.yml - 20191129
                $username = sfConfig::get('app_username');
                $password = sfConfig::get('app_password');
                $idRange = sfConfig::get('app_idRange');
                $idInvoiceType = sfConfig::get('app_idInvoiceType');
                $signed = sfConfig::get('app_signed');
                $send = sfConfig::get('app_send');
                $sendToCustomer = sfConfig::get('app_sendToCustomer');
                $idRangeAnu = sfConfig::get('app_idRangeAnu');
                $idNoteType = sfConfig::get('app_idNoteType');

                $json_clave = <<<EOD
{
	"username" : "$username",
	"password" : "$password",
EOD;
                $json_cuerpo = <<<EOD
	"objectType" :1,
        "noteTypeId": 2,
	"idRange" :$idRangeAnu,
	"idObject" :"NC$sec_anulacion",
	"idNoteType" : $idNoteType,
        "invoiceSourceId" : "$sec_factura",
	"signed" : $signed,
	"send" : $send,
	"sendToCustomer" : $sendToCustomer,
	"notificationStrings" : ["EMAIL"],
	"description" :"$observaciones",
	"currencyCode" :"COP",
	"customer" : {
		"personType" :$id_tip_ter,
		"personId" :"$num_doc",
		"idType" :$id_tipo_doc,
		"idVerificationDigit" :"$dv",
		"schemeType" :0,
		"address" :"$direccion",
		"city" :"$codmun_text",
		"department" :"$coddepto",
		"citySubDivision" :"",
		"countryCode" :"CO",
		"organizationName" :"$razon_soc",
		"firstName" :"$pnombre",
		"middleName" :"$snombre",
		"lastName" :"$papellido",
		"codePhoneNumber" :"",
		"cellPhone" :"$tel",
		"email" :"$mail"
	},
	"lines" : [ 
		{
		"description" :"$producto - $observaciones",
                "quantity" : 1,
		"currencyCode" :"COP",
		"unityPrice" : $valor_uni_bruto,
		"noteLine" : null,
		"accountingCost" : null,
		"totalPrice" : $valor_uni_total,
		"taxes" : []
		}
	],
	"extraWSProperties" : {
		"Codigo" : "$codigo",
		"Fecha" :"$fecha_facturacion",
		"Caja" :"$caja",
		"Banco" :"$banco",
		"Cuenta" :"$cuenta",
		"Recibo" :"$tipo_pago",
		"Oficina" :"$oficina",
		"Num" :"$pin"
	},
	"amountNoTaxes" :$valorsiniva,
	"amountTaxes" :$valor_iva,
	"totalAmount" :$valor_total,
	"totalAmountText" :"$valor_total_text M/CTE.************"
}
EOD;
                //Json de envio
                //Separa JSON por clave visible en log - 20191120
                $json = <<<EOD
$json_clave
$json_cuerpo                        
EOD;
                //echo $json;
                //die();
                $this->custom_logger->info("---Formato Json de envio:" . $json_cuerpo);
                $this->logMessage("---Formato Json de envio:" . $json_cuerpo);

                //Ejemplo Json simple
                //$data = array("name" => "Hagrid", "age" => "36");
                //$data_string = json_encode($data);
                $data_string = $json;

                /**
                 * Llamado CURL
                 */
                $ch = curl_init($url_abaco);
                //Parametros de retorno en cURL
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                    'Content-Type: application/json',
                    'Content-Length: ' . strlen($data_string))
                );
                //Ejecuta la petición
                $respuesta = curl_exec($ch);
                //$respuesta = "";
                $this->custom_logger->info("[DEBITO] respuesta: " . $respuesta . ".\n");
                $this->logMessage("[DEBITO] respuesta: " . $respuesta);
                //Error CURL
                if ($respuesta === false) {
                    $message = curl_error($ch);
                    //echo $message;
                } elseif (count($respuesta) <= 0) {
                    $this->logMessage("[DEBITO] Sin respuesta.");
                    $message = "Sin respuesta.";
                }
                //Se cierra la conexión
                curl_close($ch);
                //die();
                //echo $respuesta;
                $arrayRespuesta = json_decode($respuesta, true);
                //print_r($arrayRespuesta);
                //die();
                //valida que esten las variables en la respuesta
                $this->logMessage("************Valida que esten las variables en la respuesta************");
                //if (isset($arrayRespuesta['idInvoice']) && isset($arrayRespuesta['message'])) {
                //if (true) {
                $pos = strpos($respuesta, 'idInvoice');
                $pos2 = strpos($respuesta, 'message');
                if ($pos !== false && $pos2 !== false) {

                    $this->logMessage("Si vienen variables en la respuesta de llamadoAbaco anulacion.");

                    $idInvoice = $arrayRespuesta['idInvoice'];
                    $message = $arrayRespuesta['message'];
                    $message = str_replace("'", "'|| chr(39) ||'", $message);
                    $successful = $arrayRespuesta['successful'];
                    if (isset($arrayRespuesta['idrequest'])) {
                        $idrequest = $arrayRespuesta['idrequest'];
                    } else {
                        $idrequest = '';
                    }

                    //valida successful
                    if ($successful == 'true') {
                        $successful = 'true';
                        $estado_abaco = '1';
                        $fecha_abaco = 'sysdate';
                    } else {
                        $successful = 'false';
                        $estado_abaco = '0';
                        $fecha_abaco = 'null';
                        $sec_anulacion = '';
                    }

                    //actualizar registro de CA_FACTURA_ABACO      
                    $sql = <<<EOD
update CA_FACTURA_ABACO
set 
message_anulado = '$message',
anulado_abaco = '$estado_abaco',
fecha_anulado = $fecha_abaco,
sec_anulacion = '$sec_anulacion'
where
id_factura = $id_factura  
EOD;
                    //ejecuta el sql
                    $this->conn->execute($sql);
                } else {

                    $this->logMessage("No vienen variables en la respuesta de llamadoAbaco anulacion.");
                }
            }

            //die();
            /**
             * Incidente #10372, Llamado a servicio envio correo ABACO - 20181114
             */
            /*
             * Registro de consulta en tabla de log 1 - CONSULTAR, 2 - ACTUALIZAR, 3 - ADICIONAR, 4	- ELIMINAR, 5 - ANULAR
             */
            $id_ope_bd = 5;
            //construir observacion
            $observacion = "'INICIO LLAMADO ENVIO CORREO ABACO'";
            //$this->custom_logger->info("[DEBITO] " . $observacion . ".\n");
            //CN_TABLE::registroTableLog($id_tabla, $id_vigencia, $id_cen_op, $id_cia, $id_mae_bd, $id_ope_bd, $id_mae_ter_log, $usuario, $comando, $observacion, $id_punto_venta);
            //$this->llamadoCorreoAbaco($id_factura);
            //$this->logMessage("[DEBITO] Fin llamado a servicio envio correo ABACO.");


            $this->custom_logger->info("----------------------------------------FIN llamadoAbaco anulacion");
            $this->logMessage("----------------------------------------FIN llamadoAbaco anulacion");

            /*
             * COMMIT DE TODAS LAS TRANSACCIONES
             */
            $this->conn->commit();
            //die();

            $array_abaco = array(
                'message' => $message,
                'successful' => $successful,
                'idRequest' => $idrequest,
                'idinvoice' => $idInvoice
            );

            return $array_abaco;
        } catch (Exception $e) {

            //ROLLBACK DE TODAS LAS TRANSACCIONES EN CASO DE QUE OCURRA ALGUN ERROR
            $this->conn->rollback();

            $mensaje = "ERROR!!!";

            $this->logMessage($mensaje);
            $this->custom_logger->info("[DEBITO] Exception:: " . $mensaje);
            $this->logMessage("state");
            $this->logMessage("Code " . $e->getCode());
            $this->logMessage("Message " . $e->getMessage());


            /*
             * Registro de consulta en tabla de log 1 - CONSULTAR, 2 - ACTUALIZAR, 3 - ADICIONAR, 4	- ELIMINAR, 5 - ANULAR
             */
            $id_ope_bd = 5;
            $observacion = "'Se termino el proceso de debito llamadoAbaco anulacion, se generaron errores en el proceso de creación...'";
            $this->custom_logger->info("[DEBITO] Exception:: " . $observacion . ".\n");

            /**
             * Abrir nueva conexion con la Base de Datos
             */
            $this->conn = Doctrine_Manager::getInstance()->getCurrentConnection();
            $this->conn->beginTransaction();

            CN_TABLE::registroTableLog($id_tabla, $id_vigencia, $id_cen_op, $id_cia, $id_mae_bd, $id_ope_bd, $id_mae_ter_log, $usuario, $comando, $observacion, $id_punto_venta);

            $this->conn->commit();

            $this->custom_logger->info("----------------------------------------FIN Exception llamadoAbaco anulacion");
            $this->logMessage("----------------------------------------FIN Exception llamadoAbaco anulacion");


            $array_abaco = array(
                'message' => "Message " . $e->getMessage(),
                'successful' => 'false',
                'idRequest' => '',
                'idinvoice' => ''
            );

            return $array_abaco;
        }
    }

}
