<?php
class BancoMovimientosImport extends ImportFromExcel {
    private $_maxColumnIndex = 8;  
    private $_cuentasBancarias = null;
    private $_cuentasContables = null;
    private $_chequesRepetidos = null; // Almacena los cheques que se intentar importar, pero que ya estan registrados.
        
    /*Valores para cheques*/
    private $_keysCheck = array('movimiento','fecha','cuentaBancaria','comentarios','monto','numCheque','cuentaContable','pagarA');
    private $_formaCheck = null;
    private $_tipoCheck = null;
    
    /* Valores para depositos*/
    private $_keysDeposit = array('movimiento','fecha','cuentaBancaria','descripcion','monto','numDocumento','cuentaContable','recibidode');
    private $_formaDeposit = 5; //Forma 5 = Transferencia por default cuando se importa desde excel.
    private $_tipoDeposit = 1;// Tipo 1 = Depositos en tabla cuentas_movimientos
    private $_prefijoDeposit = 'Cliente-';
    
    /*Valores para Debitos-Retiros*/
    private $_keysDebit = array('movimiento','fecha','cuentaBancaria','descripcion','monto','numDocumento','cuentaContable','recibidode');
    private $_formaDebit = 5; //Forma 5 = Transferencia por default cuando se importa desde excel.
    private $_tipoDebit = 2;// Tipo 2 = Retiros en tabla cuentas_movimientos
    private $_prefijoDebit = 'Proveedor-';
    
    public function __construct($upload, $file) {
        $_SESSION['chequesRepetidos'] = array();
        parent::__construct($upload, $file);
    }
    
    public function getMaxColumnIndex(){
        return $this->_maxColumnIndex;
    }
    
    public function existChequesRepetidos(){
        if(count($this->getChequesRepetidos()) > 0){
            return true;
        }
        return null;
    }
    
    public function setChequeRepetido($numCheque,$originalInfo,$newInfo){
        $_SESSION['chequesRepetidos'][$numCheque]['origin'] = $originalInfo;
        
        $key = strtolower(str_replace(' ','',trim($numCheque.$newInfo['fecha'].$newInfo['pagarA'].$newInfo['monto'])));
        $_SESSION['chequesRepetidos'][$numCheque]['new'][$key] = $newInfo;
    }
    
    public function getChequesRepetidos(){
        return $_SESSION['chequesRepetidos'];
    }
    
    public function doSave(){
        try {
            $login = new Login();
            
            if (!($this->_entity instanceof EntityRepository)) {
                throw new Exception('The entity is not declared, please set before save the file.');
            }
            
            $objPHPExcel = $this->getExcelObj();
            $objPHPExcel->setActiveSheetIndex(0);
            $sheet = $objPHPExcel->getActiveSheet();
            
            $maxRow = $sheet->getHighestRow();            
            $dateCols = array(1);
            
            for (
                $i = 2,
                $data = null;
                $i <= $maxRow;
                $i++) {
                
                $cell = $sheet->getCellByColumnAndRow(0, $i);
                $movimiento = $cell->getValue();
                $movimiento = trim(strtolower($movimiento));
                
                if($movimiento === 'check'){   
                    $this->_entity = new ChequeEntity();
                    $entity = clone $this->_entity;
                    $keys = $this->_keysCheck;                 
                    
                }elseif($movimiento === 'deposit'){
                    $this->_entity = new BancoMovimientoEntity();
                    $entity = clone $this->_entity;
                    $keys = $this->_keysDeposit;
                    $forma = $this->_formaDeposit;
                    $tipo = $this->_tipoDeposit;
                    $prefijo = $this->_prefijoDeposit;
                    
                }elseif($movimiento === 'debit'){
                    $this->_entity = new BancoMovimientoEntity();    
                    $entity = clone $this->_entity;
                    $keys = $this->_keysDebit;
                    $forma = $this->_formaDebit;
                    $tipo = $this->_tipoDebit;
                    $prefijo = $this->_prefijoDebit;
                }else{
                    $this->_feedbackMsg = "Value '{$movimiento}' is invalid for the Transaction field";
                    throw new Exception($this->getFeedbackMsg());                    
                }                 
                
                for ($j = 0; $j < $this->getMaxColumnIndex(); $j++) {
                    $cell = $sheet->getCellByColumnAndRow($j, $i);
                    if(in_array($j, $dateCols)){
                        $value = $this->getDateFromActiveSheet("B$i");                        
                        $entity->setOption($keys[$j],$value->format('Y-m-d'));                      
                    }else{
                        $entity->setOption($keys[$j], $cell->getValue());
                    }
                    
                    /* Valida campos cuentaBancaria y cuentaContable que sea numerico */
                    if($j == 2){$this->validateCuentaBancaria($cell->getValue());}
                    if($j == 6){
                        $cuentaContable = $cell->getValue();
                        $this->validateCuentaContable($cuentaContable);                        
                    }
                    
                    /* Valida campo Monto que sea numerico float/double */
                    if($j == 4){ 
                        $monto = $cell->getValue();  
                        //Quito signos negativos
                        $monto = abs($monto);
                        $entity->setMonto($monto);
                        /* Numeros con punto decimal y numeros SIN punto decimal $cell->getValue() los setea como Float */
                        //echo var_dump($monto);var_dump(is_float($monto));echo "<BR>";
                        if(!is_float($monto)){
                            $this->_feedbackMsg = "The value '{$monto}' for the field Ammount is invalid, you should use a number formata like: 200 or 252.50 ";
                            throw new Exception($this->getFeedbackMsg());
                        }
                    }
                }
                
                /* Se setean opciones "default" dependiendo del movimiento */
                $entity->setUsuario();
                if(strtolower($movimiento) === 'deposit' || strtolower($movimiento) === 'debit'){
                    $entity->setOption('forma',$forma);
                    $entity->setOption('tipo',$tipo);
                    if(is_numeric($entity->getRecibidoDe())){
                        $entity->setOption('recibidode',$prefijo.$entity->getRecibidoDe());
                    }         
                    $data = $entity->getOptions();
                    $this->_entity->insert($data);        
                      
                }elseif(strtolower($movimiento) === 'check'){
                    if(is_numeric($entity->getPagarA())){
                        $entity->setOption('pagarA',$prefijo.$entity->getPagarA());
                    }   
                      
                    $data = $entity->getOptions();  
                    /* Cheques detalles*/
                    $cargo = array();
                    $cargo['cuentaContable'] = $cuentaContable;
                    $cargo['monto'] = $entity->getMonto();
                    $cargo['descripcion'] = $entity->getComentarios();
                    $data['cargo'] = array($cargo);
                    
                    $result = $entity->existCheque($entity->getNumCheque(),$entity->getCuentaBancaria());
                    if($result){
                        $newInfo = $data;
                        $originalInfo = $result;
                        $this->setChequeRepetido($entity->getNumCheque(), $originalInfo, $newInfo);
                    }else{
                        $this->_entity->saveImport($data); 
                    }
                }                                    
                unset($entity);
                unset($data);
            }

            if (!$this->isValid()) {
                throw new Exception($this->getFeedbackMsg());
            }           

            unset($objPHPExcel);
            unset($sheet);
            unset($data);
            $this->deleteTempFile();
            
            $this->_feedbackMsg = "The Excel File has been imported successfully.";
            return true;
        } catch (Exception $exc) {
            $this->deleteTempFile();
            $this->_feedbackMsg = $exc->getMessage();
            return false;
        }
    }
    
    public function validateCuentaBancaria($value){                     
        if(!$this->isNumeric($value)){
            $this->_feedbackMsg = "The value '{$value}' for the field Bank account is invalid, you should use a number format like: 5 or 59 ";
            throw new Exception($this->getFeedbackMsg());
        }
        
        if(!$this->existCuentaBancaria($value)){
           $this->_feedbackMsg = "The Id '{$value}' for Bank account doesn't exist.";
           throw new Exception($this->getFeedbackMsg());
        }
    }
    
    public function validateCuentaContable($value){                     
        if(!$this->isNumeric($value)){
            $this->_feedbackMsg = "The value '{$value}' for the field Accounting account is invalid, you should use a number format like: 5 or 59 ";
            throw new Exception($this->getFeedbackMsg());
        }
        
        if(!$this->existCuentaContable($value)){
           $this->_feedbackMsg = "The Id '{$value}' for Accounting account doesn't exist.";
           throw new Exception($this->getFeedbackMsg());
        }
    }
    
    public function existCuentaBancaria($value){
        $this->setIdCuentasBancarias();
        if(!in_array($value, $this->getCuentasBancarias())){
            return null;
        }
        return true;
    }
    
    public function existCuentaContable($value){
        $this->setIdCuentasContables();
        if(!in_array($value, $this->getCuentasContables())){
            return null;
        }
        return true;
    }
    
    public function setIdCuentasBancarias(){
        if($this->_cuentasBancarias !== null){ return null;}
        $repo = new BancoCuentaRepository();
        $cuentas = $repo->getListCuentas();        
        
        $idCuentas = array();
        if(count($cuentas) > 0){
            foreach($cuentas as $cuenta){
                $idCuentas[] = $cuenta['id'];
            }
        }
 
        $this->_cuentasBancarias = $idCuentas;
    }
    
    public function getCuentasBancarias(){
        return $this->_cuentasBancarias;
    }
    
    public function setIdCuentasContables(){
        if($this->_cuentasContables !== null){ return null;}
        $repo = new CatalogoCuentaRepository();
        $cuentas = $repo->getListIdCuentasSubcuentas();   

        if(count($cuentas) > 0){
         $this->_cuentasContables = $cuentas;
        }        
    }
    
    public function getCuentasContables(){
        return $this->_cuentasContables;
    }
    
    public function isNumeric($value){
        /*  is_numeric - Comprueba si una variable es un número o un string numérico. Opcionalmente con signo,decimal y parte exponencial. */
        /* Al importar numero con comas, estas desaparecen. Entonces 23,4 se valida como 234*/
        if(!is_numeric($value) || strpos( $value, "." ) !== false || $value <= 0 ){
            return null;
        }
        return true;
    }
    
}