<?php
class Controllersincronizatorreceberpedido extends Controller {

    public function verificarpedidos(){

        $this->load->dmodel('setting/task');

        $this->ftrgeralregistry->permissaoAcessoUrl( $this->dmodel_setting_task->getTaskByType(Type_TaskUrl::Tp_TaskVerificaPedidos) );

        
        if(!$this->config->get('config_verifica_pedidos')){
            throw new Exception('Configuração de verificação de pedidos desabilitada!');
        }  

        $this->load->dmodel('checkout/order');
        $this->load->dmodel('wsceo/pedido/wspedido');
        $this->load->helper('Ftr_sql');
        $this->load->type('tipocomum');

        $result =	$this->dmodel_setting_task->getTaskByType(['type' => Type_TaskUrl::Tp_TaskVerificaPedidos]);

        $dataTask = array(
            'date_last_acting' => $this->db->dataAtual(),
            'type' => Type_TaskUrl::Tp_TaskVerificaPedidos
        );
        $this->dmodel_setting_task->editDateTaskByType($dataTask);

        $pedidosReplicados = array();

        $minutos = Type_ExecTimeTask::Tp_ExecTime_1min / 60;
        $tempoLimite = (new DateTime($this->db->dataAtual()))->add(new DateInterval('PT' . $minutos . 'M'));

        $return = array();
        do{
            $param_eftr = $this->ftrgeralregistry->getParametros();

            if(!$param_eftr){
                throw new Exception("Não foi possivel capturar as informações da tabela parametros!");            
            }

            $returns = $this->dmodel_wsceo_pedido_wspedido->getIdsPedidosEcommerce(25, $param_eftr['log_pedido_id'], $param_eftr['log_pedido_item_id']);

            if((!$returns) || (count($returns) <= 0)){
                break;
            }

            try{
                foreach($returns as $ret){
                  if (!in_array($ret['id'], $pedidosReplicados)){
                    $this->execute($ret['id']);
                    $pedidosReplicados[] = $ret['id'];
                  }
                }
 
                //Atualiza a ultima ECM_LOG DOS PEDIDOS REPLICADOS...
                $arrayparam = array();
                $paramPedido    = array();

                // pega maiores valores de ecm_log
                $maxValueEcmLogPedido = array_column(array_filter($returns, function($value) {
                  return $value['tipodado'] == '0';
                }), 'ecm_log');
                $maxValueEcmLogPedido = (empty($maxValueEcmLogPedido)) ? false : max($maxValueEcmLogPedido);

                $maxValueEcmLogPedidoItem = array_column(array_filter($returns, function($value) {
                  return $value['tipodado'] == '1';
                }), 'ecm_log');
                $maxValueEcmLogPedidoItem = (empty($maxValueEcmLogPedidoItem)) ? false : max($maxValueEcmLogPedidoItem);

                // atualiza logs pedido
                // linha colocada para atualizar os parametros efutura antes de dar update neles, caso alguem alterar manualmente durante a execução do processo, para não atualizar pra um valor antigo
                $param_eftr = $this->ftrgeralregistry->getParametros();

                $arrayparam[] = 'log_pedido_id';
                $paramPedido[]  = (empty($param_eftr['log_pedido_id']) || $maxValueEcmLogPedido > $param_eftr['log_pedido_id']) ?  $maxValueEcmLogPedido : $param_eftr['log_pedido_id'];

                $arrayparam[] = 'log_pedido_item_id';
                $paramPedido[]  = (empty($param_eftr['log_pedido_item_id']) || $maxValueEcmLogPedidoItem > $param_eftr['log_pedido_item_id']) ?  $maxValueEcmLogPedidoItem : $param_eftr['log_pedido_item_id'];

                $sqlUpdParam = Ftr_sql::generateUpdate('parametros_efutura', $arrayparam);
                $this->db->executeSql($sqlUpdParam, $paramPedido);
            }catch(Exception $e){
                throw new Exception($e->getMessage());
            }
        }while((count($returns) > 0) && (new DateTime($this->db->dataAtual()) < $tempoLimite));
    }

    //em determinados itens, se nada for modificado, acaba pegando null no log do pedido item
    //nesse caso eu pego o ultimo que tem... se mesmo assim n tiver, ai sim retorno null aqui...
    private function getLastPiLog($preturn){
        for($i = count($preturn)-1; $i >= 0; $i --){
            if($preturn[$i]['ecm_log_pi'] !== null){
                return $preturn[$i]['ecm_log_pi'];
            }

        }
        return null;
    }

    private function updateOrderTotal($orderid, $code, $value, $description = ''){

        $fields = array();
        $fields[] = 'text';
        $fields[] = 'value';

        if(!(empty($description))){
            $fields[] = 'title';   
        }

        $sqltotal = Ftr_sql::generateUpdate('oc_order_total', 
        $fields,
         '(order_id = ' . $orderid . ') and (code = "' . $code . '" )'); 

        $parametros = array();
        $parametros[] = $this->currency->format($value); 
        $parametros[] = $value;
        if(!(empty($description))){
            $parametros[] = $description;   
        }
        $this->db->executeSql($sqltotal, $parametros);         
    }

    private function execute($pedidoId){
        $ws_pedido = $this->dmodel_wsceo_pedido_wspedido->getPedido($pedidoId);

        if(!$ws_pedido){
            throw new Exception("Não foi possivel recuperar o pedido!");
        }

        $this->load->dmodel('log/log');
        $this->dmodel_log_log->saveLogDB(array('tipoEnviado' => Type_LogEnviado::Tp_LogRecebido, 'origem' => __METHOD__,
          'tipoLog' => Type_Log::Tp_LogPedido, 'tipoId' => Type_LogId::Tp_LogIdPedido, 'entidadeId' => $ws_pedido[0]['id_ecommerce'],
          'retorno' => $ws_pedido));

        $ws_pedidoItems = $this->dmodel_wsceo_pedido_wspedido->getPedidoItem($pedidoId);

        if(!$ws_pedidoItems){
            throw new Exception("Não foi possivel recuperar o pedido!");
        }

        $this->dmodel_log_log->saveLogDB(array('tipoEnviado' => Type_LogEnviado::Tp_LogRecebido, 'origem' => __METHOD__,
          'tipoLog' => Type_Log::Tp_LogPedido, 'tipoId' => Type_LogId::Tp_LogIdPedido, 'entidadeId' => $ws_pedido[0]['id_ecommerce'],
          'retorno' => $ws_pedidoItems));

        $ws_pedido           = $ws_pedido[0];
        $idsItemFuturaServer = array();        

        try{
            $this->db->startTransaction();

            //no for, pego a menor sequencia de acrescimo e desoconto respectivamente...
            $ecm_desc_seq   = 0;
            $ecm_acres_seq  = 0;

            //update oc_order_total
            $orderTotals = $this->dmodel_checkout_order->getOrderTotals($ws_pedido['id_ecommerce']);
            foreach($orderTotals as $total){
                switch ($total['code']) {
                    case 'total_fcpst':
                        $this->updateOrderTotal($ws_pedido['id_ecommerce'], $total['code'], $ws_pedido['total_fcp_st_valor']);
                        break;

                    case 'total_ipi':
                        $this->updateOrderTotal($ws_pedido['id_ecommerce'], $total['code'], $ws_pedido['total_ipi']);
                        break;

                    case 'total_st':
                        $this->updateOrderTotal($ws_pedido['id_ecommerce'], $total['code'], $ws_pedido['total_subs_trib_valor']);
                        break;

                    case 'shipping':
                        $description = '';
                        //Caso o frete tenha sido grátis, porém, o cliente precisou compensar, muda o valor para não ficar: "Frete Grátis: R$100,00" por ex...
                        if((round($total['value'], 2) == 0) && (round($ws_pedido['total_frete'],2) > 0) ){
                            $description = 'Frete';
                        }
                        $this->updateOrderTotal($ws_pedido['id_ecommerce'], $total['code'], $ws_pedido['total_frete'], $description);
                        break;

                    case 'sub_total':
                        $this->updateOrderTotal($ws_pedido['id_ecommerce'], $total['code'], $ws_pedido['total_produto']);
                        break;

                    case 'total':
                        $this->updateOrderTotal($ws_pedido['id_ecommerce'], $total['code'], $ws_pedido['total_pedido']);
                        break;
                    
                    default:
                        //calculando descontos / acrescimos...
                        if (round($total['value'], 2) < 0) {
                            if(($total['sort_order'] > 0) && ($total['sort_order'] < $ecm_desc_seq)){
                                $ecm_desc_seq = $total['sort_order'];
                            }
                        } else {
                            if(($total['sort_order'] > 0) && ($total['sort_order'] < $ecm_acres_seq)){
                                $ecm_acres_seq = $total['sort_order'];
                            }                            
                        }
                }             
            }

            //Atualizando totalizadores do PEDIDO tem que ficar aqui pq quando tem desconto/acrescimo o total do pedido muda...
            $sqlPedido = Ftr_sql::generateUpdate('oc_order',
                ['total', 'total_st_base', 'total_st_valor', 'total_fcpst_base', 'total_fcpst_valor', 'total_ipi_valor'],
                'order_id = ' . $ws_pedido['id_ecommerce']);

            $paramPedido    = array();
            $paramPedido[]  = $ws_pedido['total_pedido'];
            $paramPedido[]  = $ws_pedido['total_subs_trib_base'];
            $paramPedido[]  = $ws_pedido['total_subs_trib_valor'];
            $paramPedido[]  = $ws_pedido['total_fcp_st_base'];
            $paramPedido[]  = $ws_pedido['total_fcp_st_valor'];
            $paramPedido[]  = $ws_pedido['total_ipi'];

            $this->db->executeSql($sqlPedido, $paramPedido);

            $sqlInsTotal = Ftr_sql::generateInsert('oc_order_total', 
            ['order_id', 'code', 'title', 'text', 'value', 'sort_order']); 

            //Fazendo ajuste de desconto caso tenha sido modificado o valor...
            if(round($ws_pedido['total_desconto'], 2) > 0 ){
                //deleta os descontos...
                $sqldel = ' delete from oc_order_total'
                        . ' where (order_id = ?)'
                        . ' and (value < 0)';
                $this->db->executeSql($sqldel, [$ws_pedido['id_ecommerce']]);  

                //insere um ajuste...
                $insDescParam[] = $ws_pedido['id_ecommerce'];
                $insDescParam[] = 'ajuste_desconto';
                $insDescParam[] = 'Total descontos';
                $insDescParam[] = $this->currency->format(($ws_pedido['total_desconto'] * -1));
                $insDescParam[] = $ws_pedido['total_desconto'] * -1;
                $insDescParam[] = $ecm_desc_seq;

                $this->db->executeSql($sqlInsTotal, $insDescParam); 
            }

            //Fazendo ajuste de acrescimo caso tenha sido modificado o valor...
            if(round($ws_pedido['total_acrescimo'], 2) > 0){
                //deleta os acrescimos...
                $sqldel = ' delete from oc_order_total'
                        . ' where (order_id = ?)'
                        . ' and (value > 0) and (code not in("sub_total", "total", "shipping", "total_fcpst", "total_ipi", "total_st"))';
                $this->db->executeSql($sqldel, [$ws_pedido['id_ecommerce']]);  

                $insAcresParam[] = $ws_pedido['id_ecommerce'];
                $insAcresParam[] = 'ajuste_acrescimo';
                $insAcresParam[] = 'Total acrescimos';
                $insAcresParam[] = $this->currency->format($ws_pedido['total_acrescimo']);
                $insAcresParam[] = $ws_pedido['total_acrescimo'];
                $insAcresParam[] = $ecm_acres_seq;
                $this->db->executeSql($sqlInsTotal, $insAcresParam);
            }

            //Atualizando pedido item...
            $updatePedidoItem    = array();
            foreach($ws_pedidoItems as $items){
                $sql        = ""; 
                $parametros = array();                
    
                if(empty($items['id_ecommerce_item'])){    
                    $sql = Ftr_sql::generateInsert('oc_order_product', 
                                                  ['order_id', 'product_id', 'name', 'model', 'quantity', 'price', 'total', 'fcpst_valor', 'st_valor', 'ipi_valor', 'fcpst_base', 'ipi_percentual', 'reward', 'id_futura']); 
    
                    $parametros[] = (int)$ws_pedido['id_ecommerce'];                      
                }else{
                    $sql = Ftr_sql::generateUpdate('oc_order_product', 
                                                  ['product_id', 'name', 'model', 'quantity', 'price', 'total', 'fcpst_valor', 'st_valor', 'ipi_valor', 'fcpst_base', 'ipi_percentual', 'reward'],
                                                   'order_product_id = ' . $items['id_ecommerce_item']);
                }

                $parametros[] = $this->db->escape($items['id_ecommerce_produto']); 
                $parametros[] = $this->db->escape($items['descricao_efutura']);
                $parametros[] = $this->db->escape($items['referencia']);  
                $parametros[] = $items['quantidade'];
                $parametros[] = $items['valor_unitario'];    
                $parametros[] = ($items['valor_unitario'] * $items['quantidade']) 
                                 + ($items['valor_acrescimo'] - $items['valor_desconto'])
                                 + ($items['subs_trib_valor'] + $items['valor_ipi'] + $items['fcp_st_valor']);
                $parametros[] = $items['fcp_st_valor'];
                $parametros[] = $items['subs_trib_valor'];
                $parametros[] = $items['valor_ipi'];
                $parametros[] = $items['fcp_st_base'];  
                $parametros[] = $items['percentual_ipi']; 
                $parametros[] = 0;           
                if(empty($items['id_ecommerce_item'])){
                    $parametros[] = $items['id'];
                }

                $this->db->executeSql($sql, $parametros);  
                
                if(empty($items['id_ecommerce_item'])){
                    $idecmitem = $this->db->getLastId(); 
                    //Gerando lista para update no PEDIDO ITEM DO futura server...
                    $updatePedidoItem[] = array(
                        'id_futura'    => $items['id'],
                        'id_ecommerce' => $this->db->getLastId()
                    );
                } else {
                    $idecmitem = $items['id_ecommerce_item'];
                }
                $idsItemFuturaServer[] = $idecmitem;
            }

            $this->db->commit();
            
            $this->db->startTransaction();

            //Apagando todos os itens que não estão no pedido...
            if(count($idsItemFuturaServer) > 0){
                $sqlIds = implode(',', $idsItemFuturaServer);
                $this->db->executeSql('delete from oc_order_product where order_id = ? and order_product_id not in (' . $sqlIds . ')', [$ws_pedido['id_ecommerce']]);     
            }

            if(count($updatePedidoItem) > 0){
                $this->dmodel_wsceo_pedido_wspedido->updateIdEcommercePedidoItem($updatePedidoItem);
            }  
            $this->db->commit();            
        }catch(Exception $e){
            $this->db->rollback();
            throw new Exception($e->getMessage());
        }    

    }

}