<?php
final class DModelproccessordertosituation extends Model {
    private $countSegundos = 0;
    function getDate(){
        $this->countSegundos ++;
        $dateInt = new DateInterval('PT' . $this->countSegundos . 'S');

        $atual   = $this->db->dataAtual();
        $date = new DateTime($atual);

        $date->add($dateInt);
        return $date->format('Y-m-d H:i:s');
    }

    function updateOrderHistory($order_id, $order_status_id, $client_notify = null){

      if(is_null($client_notify)){
        $client_notify = $this->ftrgeralregistry->getClienteNotify($order_status_id);
      }

      $this->db->query("UPDATE `" . DB_PREFIX . "order` SET order_status_id = '" . (int)$order_status_id . "', date_modified = NOW() WHERE order_id = '" . (int)$order_id . "'");
        $this->db->query("INSERT INTO " . DB_PREFIX . "order_history SET order_id = '" . (int)$order_id . "', order_status_id = '" . (int)$order_status_id. "', notify = '" . ($client_notify ? (int)$client_notify : 0) . "', date_added = current_timestamp(2)");
        //1 milisegundo... sim, é uma merda (ou gambi monstra se preferir chamar) só pra não correr risco de errar na ordenação de status... :/
        usleep(10000);
    }

    function getNameFromStatus($status_id){
        $retorno = $this->db->query("select `name` from oc_order_status where order_status_id = $status_id");
        return $retorno->row['name'];
    }

    function getProccessByStatus($order_status_id, $processo_venda_id){

      $this->load->type('tipofuturaserver');

      $processo_iniciado      = Type_StatusProcVenda::TpStProcVend_Iniciado;
      $processo_finalizado    = Type_StatusProcVenda::TpStProcVend_Finalizado;
      $proccess_disabled      = Type_UtilizaProccessVenda::TpUtPv_Nao;

      $sqlNewProccess = "
            select
              pci.ordem,
              pci.tipo,

              case pts.tipo_status when $processo_iniciado then
                pci.order_situation_ini_id
              else
                case pts.tipo_status when $processo_finalizado then
                  pci.order_situation_suc_id
                  else pci.order_situation_err_id
                end
              end as situation_id,
              pts.tipo_status proccess_status,
              os.name as name_status
            from oc_proccess_control_item pci
            inner join oc_proccess_to_status pts on (pts.proccess_control_item_id = pci.proccess_control_item_id)
            inner join oc_order_status os on (os.order_status_id = pts.order_status_id)
            where (pts.order_status_id = $order_status_id)       and
                  (pci.proccess_control_id = $processo_venda_id) and
                  (pci.utiliza <> $proccess_disabled)
            limit 1;
        ";

      return $this->db->query($sqlNewProccess)->row;
    }

    function updateHistory($order_id, $order_status_id){
        $this->countSegundos = 0;

        $this->load->type('tipocomum');
        $this->load->type('tipofuturaserver');
        $this->load->helper('ftr_validacao');
        $this->load->dmodel('checkout/order');
        $this->load->dmodel('localisation/order_status');

        if(($this->config->get('processo_venda_status') == Type_DsimDnao::Tp_Nao) || (empty($this->config->get('processo_venda_id')))){
            return false;
        }
        $processo_venda_empresa = $this->config->get('processo_venda_id');
        $processos              = $this->getConfigProccess($processo_venda_empresa, Type_StatusProcVenda::TpStProcVend_Finalizado);
        $proccess_disabled      = Type_UtilizaProccessVenda::TpUtPv_Nao;

        $last_order_situation_id = null;
        $last_proccess_status    = null;
        $last_proccess_Atual     = null;
        $liberacao_financeira_status = Type_LibFinanceira::TpLibFinan_SemLiberacao;

        $processo_iniciado   = Type_StatusProcVenda::TpStProcVend_Iniciado;
        $processo_finalizado = Type_StatusProcVenda::TpStProcVend_Finalizado;

        //O módulo está habilitado, porém, ainda não foi configurado corretamente.
        if(!$processos){
            return false;
        }

        //capturando o processo que se encaixa no novo status
        $sqlNewProccess = "
            select
              pci.ordem,
              pci.tipo,

              case pts.tipo_status when $processo_iniciado then
                pci.order_situation_ini_id
              else
                case pts.tipo_status when $processo_finalizado then
                  pci.order_situation_suc_id
                  else pci.order_situation_err_id
                end
              end as situation_id,
              pts.tipo_status proccess_status,
              os.name as name_status
            from oc_proccess_control_item pci
            inner join oc_proccess_to_status pts on (pts.proccess_control_item_id = pci.proccess_control_item_id)
            inner join oc_order_status os on (os.order_status_id = pts.order_status_id)
            where (pts.order_status_id = $order_status_id)            and
                  (pci.proccess_control_id = $processo_venda_empresa) and
                  (pci.utiliza <> $proccess_disabled)
            limit 1;
        ";

      $lastProccessOrder = $this->getLastOrderProcess($order_id, $processo_venda_empresa);
      $proccess_aux      = $this->db->query($sqlNewProccess)->row;

      if((sizeof($proccess_aux) <= 0) || (( (sizeof($lastProccessOrder) > 0) && ($lastProccessOrder['ordem'] == $proccess_aux['ordem'])) && ($lastProccessOrder['proccess_status'] == $proccess_aux['proccess_status']))){
          $newProccess = false;
      }else{
          $newProccess = $proccess_aux;
      }

      $this->db->startTransaction();
      try{
          if(sizeof($lastProccessOrder) <= 0){//Se não tiver status anterior, então vamos colocar status de inicializado...
              //Se o primeiro status for igual ao status inicial, não atualiza a order history, porque se não vai duplicar...
              if((int)$order_status_id !== (int)$this->config->get('processo_venda_order_status_started')){
                $this->updateOrderHistory($order_id, $this->config->get('processo_venda_order_status_started'));
              }

              $proccess_name = $this->getNameFromStatus($this->config->get('processo_venda_order_status_started'));

              $this->addOrderToSituation(
                 $order_id,
                Type_PedLogType::TpPedLgTp_ProcessoVenda,
                Type_ContrlProcVenda::TpStContrlProcVenda_ProdInicial,
                null,
                Type_StatusProcVenda::TpStProcVend_Finalizado,
                 $proccess_name,
                $last_order_situation_id,
                $last_proccess_status,
                $last_proccess_Atual,
                $liberacao_financeira_status
              );
          }

          $jaAddHistory_Baixado = false;
          //Colocando status anteriores obrigatórios. Se o status informado não corresponder ao novo, ai n tem porque fazer isso...
          if($newProccess){

            if((sizeof($lastProccessOrder) > 0)  && ($newProccess['ordem'] <= $lastProccessOrder['ordem'])){
            $abrePedido = false;
            $allOrderProccess =  $this->getOrderProcess($order_id, $processo_venda_empresa);
            foreach ($allOrderProccess as $proc) {

              if (($proc['status'] == Type_ContrlProcVenda::TpStContrlProcVenda_LiberacaoBaixa) &&
                    (($proc['ordem'] > $newProccess['ordem']) || (($proc['ordem'] == $newProccess['ordem']) && ($proc['proccess_status'] == Type_StatusProcVenda::TpStProcVend_Finalizado)))
                 ) {$abrePedido = true;}

              if( ($proc['ordem'] > $newProccess['ordem']) || (($proc['ordem'] >= $newProccess['ordem']) && ($proc['proccess_status'] !== $newProccess['proccess_status'])) ){
                $this->deleteOrderToSituation($proc['order_to_situation_id']);
              }
            }

            if($abrePedido) {
              //Se vai deletar a liberação da baixa, então vamos abrir o pedido...
              $this->addOrderToSituation(
                $order_id,
                Type_PedLogType::TpPedLgTp_Pedido,
                Type_PedidoStatus::TpPSt_Aberto,
                null,
                null,
                '',
                $last_order_situation_id,
                $last_proccess_status,
                $last_proccess_Atual,
                $liberacao_financeira_status
              );
            }

            }else {
                foreach ($processos as $proc) {
                  if (($proc['ordem'] < $newProccess['ordem']) && ((sizeof($lastProccessOrder) <= 0) || ($proc['ordem'] > $lastProccessOrder['ordem'])) && ($proc['utiliza'] == Type_UtilizaProccessVenda::TpUtPv_Obrigatorio)) {
                    //se estiver depois do processo de baixa, quer dizer que a baixa já foi feita, adcionando histórico....
                    if (($proc['tipo'] == Type_ContrlProcVenda::TpStContrlProcVenda_LiberacaoBaixa)) {
                      $this->addOrderToSituation(
                        $order_id,
                        Type_PedLogType::TpPedLgTp_Pedido,
                        Type_PedidoStatus::TpPSt_Baixado,
                        null,
                        null,
                        '',
                        $last_order_situation_id,
                        $last_proccess_status,
                        $last_proccess_Atual,
                        $liberacao_financeira_status
                      );
                      $jaAddHistory_Baixado = true;
                    }

                    $this->addOrderToSituation(
                      $order_id,
                      Type_PedLogType::TpPedLgTp_ProcessoVenda,
                      $proc['tipo'],
                      $proc['order_situation_suc_id'],
                      Type_StatusProcVenda::TpStProcVend_Finalizado,
                      $proc['name_status_completo'],
                      $last_order_situation_id,
                      $last_proccess_status,
                      $last_proccess_Atual,
                      $liberacao_financeira_status
                    );

                    $this->updateOrderHistory($order_id, $proc['id_status_completo']);
                  }
                }
              }

              //Agora vamos incluir o novo status...
              //se o pedido está sendo liberado para baixa com sucesso, vamos incluir o log de baixa...
              if(($newProccess['tipo'] == Type_ContrlProcVenda::TpStContrlProcVenda_LiberacaoBaixa) && ($newProccess['proccess_status'] == Type_StatusProcVenda::TpStProcVend_Finalizado)){
                if(!$jaAddHistory_Baixado) {
                  $this->addOrderToSituation(
                    $order_id,
                    Type_PedLogType::TpPedLgTp_Pedido,
                    Type_PedidoStatus::TpPSt_Baixado,
                    null,
                    null,
                    '',
                    $last_order_situation_id,
                    $last_proccess_status,
                    $last_proccess_Atual,
                    $liberacao_financeira_status
                  );
                }
              }

              $this->addOrderToSituation(
                 $order_id,
                Type_PedLogType::TpPedLgTp_ProcessoVenda,
                 $newProccess['tipo'],
                 $newProccess['situation_id'],
                 $newProccess['proccess_status'],
                 $newProccess['name_status'],
                $last_order_situation_id,
                $last_proccess_status,
                $last_proccess_Atual,
                $liberacao_financeira_status
              );
          }

          //Se vamos cancelar o pedido...
          //select_order_status_aban_id or select_order_status_canc_id
          $canceled_status_list = $this->dmodel_localisation_order_status->getOrderStatusServerList(Type_PedidoStatus::TpPSt_Cancelado,$order_status_id);

          if(($order_status_id == $this->config->get('select_order_status_aban_id')) || $canceled_status_list || ($order_status_id == $this->config->get('select_order_status_canc_id') )
              && (($lastProccessOrder['status'] != Type_ContrlProcVenda::TpStContrlProcVenda_PedidoCancelado) && (!$newProccess))
            ){
            $this->addOrderToSituation(
              $order_id,
              Type_PedLogType::TpPedLgTp_Pedido,
              Type_PedidoStatus::TpPSt_Cancelado,
              null,
              Type_StatusProcVenda::TpStProcVend_Finalizado,
              '',
              $last_order_situation_id,
              $last_proccess_status,
              $last_proccess_Atual,
              $liberacao_financeira_status
            );

            $this->addOrderToSituation(
              $order_id,
              Type_PedLogType::TpPedLgTp_ProcessoVenda,
              Type_ContrlProcVenda::TpStContrlProcVenda_PedidoCancelado,
              null,
              Type_StatusProcVenda::TpStProcVend_Finalizado,
               $this->getNameFromStatus($order_status_id),
              $last_order_situation_id,
              $last_proccess_status,
              $last_proccess_Atual,
              $liberacao_financeira_status
            );

          }

          if((!(is_null($last_proccess_status))) && (!(is_null($last_proccess_Atual))) ){

              $addtionalFields = "";

              if ($liberacao_financeira_status != Type_LibFinanceira::TpLibFinan_SemLiberacao){
                $addtionalFields .= " status_libfinan = $liberacao_financeira_status ,";
                $addtionalFields .= " data_hora_libfinan = current_timestamp ,";
              }
              //Atualizando dados do pedido com o ultimo status...
              $this->db->executeSql("update oc_order set
                                    order_situation_id = ?,
                                    $addtionalFields
                                    proccess_atual     = ?,
                                    proccess_status    = ?
                                  where order_id = ?",
                  [$last_order_situation_id, $last_proccess_Atual, $last_proccess_status, $order_id]);
          }

          $this->db->commit();
      }catch(Exception $e){
          $this->db->rollback();
          throw new Exception($e->getMessage());
      }
    }

    private function addOrderToSituation($order_id, $tipo, $status, $order_situation_id, $proccess_status, $obs, &$out_situation, &$out_proccess_status, &$out_proccess_atual, &$added_liberacao_financeira){
      $this->db->executeSql("INSERT INTO `oc_order_to_situation`
                                              (`order_id`, `tipo`, `status`,  `order_situation_id`, `proccess_status`, `data_hora`, `observacao`, `origem_log`, `enviado_status_futura`)
                                           VALUES
                                              (?, ?, ?, ?, ?, ?, ?, ?, ?);",
        [$order_id, $tipo, $status,  $order_situation_id, $proccess_status, $this->getDate(), $obs, Type_OrigemRegistro::TpOr_eCommerce, Type_DsimDnao::Tp_Nao]);

      $out_situation       = $order_situation_id;
      $out_proccess_status = $proccess_status;
      $out_proccess_atual  = $status;

      if (($status == Type_ContrlProcVenda::TpStContrlProcVenda_LiberaoFinanceira)){

        if(($proccess_status == Type_StatusProcVenda::TpStProcVend_Finalizado)){
          $added_liberacao_financeira = Type_LibFinanceira::TpLibFinan_Liberado;
        }elseif($proccess_status == Type_StatusProcVenda::TpStProcVend_EmErro){
          $added_liberacao_financeira = Type_LibFinanceira::TpLibFinan_LiberacaoRecusada;
        }

      }
    }

    private function deleteOrderToSituation($situation_id){
      $this->db->executeSql("delete from oc_order_to_situation where order_to_situation_id = ?", [$situation_id]);
    }

    function getConfigProccess($proccess_control_id, $tipo_status_proccess = false, $max_order_status = false){
        $proccess_disabled      = Type_UtilizaProccessVenda::TpUtPv_Nao;
        $tipo_sucesso           = Type_StatusProcVenda::TpStProcVend_Finalizado;
        $sql = "
              select
                pi.ordem,
                pi.utiliza,
                pi.tipo,";

        if($tipo_status_proccess){
            $sql .= "  os.name as name_status_completo,";
            $sql .= "  os.order_status_id as id_status_completo,";
        }

        $sql .=  "  pi.order_situation_suc_id
                  from oc_proccess_control_item pi";

        $sqlWhere = " where pi.proccess_control_id  = $proccess_control_id and (pi.utiliza <> $proccess_disabled)";
        if($tipo_status_proccess){
            $sqlWhere .= " and pts.tipo_status = $tipo_status_proccess";
            $sql      .= " inner join oc_proccess_to_status pts on (pts.proccess_control_item_id = pi.proccess_control_item_id and pts.tipo_status = $tipo_sucesso)";
            $sql      .= " inner join oc_order_status os on (os.order_status_id = pts.order_status_id)";
        }
        if($max_order_status){
          $sqlWhere .= " and (pi.ordem <= $max_order_status) ";
        }
        $sql .= $sqlWhere . " order by pi.ordem";

        return $this->db->query($sql)->rows;
    }

  function getOrderProcess($order_id, $processo_venda){
    $proccess_disabled      = Type_UtilizaProccessVenda::TpUtPv_Nao;
    $processo_iniciado   = Type_StatusProcVenda::TpStProcVend_Iniciado;
    $processo_finalizado = Type_StatusProcVenda::TpStProcVend_Finalizado;
    $processo_erro       = Type_StatusProcVenda::TpStProcVend_EmErro;
    $tipo                = Type_PedLogType::TpPedLgTp_ProcessoVenda;
    $pedido_cancelado    = Type_ContrlProcVenda::TpStContrlProcVenda_PedidoCancelado;

    $sql = "
            select
              ots.*,
              pci.tipo as tipo_processo,
              pci.ordem
            from oc_order_to_situation ots
            left join oc_proccess_control p on (p.proccess_control_id = $processo_venda)
            left join oc_proccess_control_item pci on (pci.proccess_control_id = p.proccess_control_id and pci.utiliza <> $proccess_disabled)
            where ots.order_id = $order_id and (
                                                        (pci.order_situation_ini_id = ots.order_situation_id and ots.proccess_status = $processo_iniciado)
                                                     or (pci.order_situation_suc_id = ots.order_situation_id and ots.proccess_status = $processo_finalizado)
                                                     or (pci.order_situation_err_id = ots.order_situation_id and ots.proccess_status = $processo_erro)
                                                     or (ots.status = $pedido_cancelado)
                                               )
                  and ots.tipo = $tipo
            order by ots.data_hora desc, order_to_situation_id desc
        ";
    return $this->db->query($sql)->rows;
  }

    function getLastOrderProcess($order_id, $processo_venda, $maxOrdem = false){
        $proccess_disabled      = Type_UtilizaProccessVenda::TpUtPv_Nao;
        $processo_iniciado   = Type_StatusProcVenda::TpStProcVend_Iniciado;
        $processo_finalizado = Type_StatusProcVenda::TpStProcVend_Finalizado;
        $processo_erro       = Type_StatusProcVenda::TpStProcVend_EmErro;
        $tipo                = Type_PedLogType::TpPedLgTp_ProcessoVenda;
        $pedido_cancelado    = Type_ContrlProcVenda::TpStContrlProcVenda_PedidoCancelado;

        $addFilter = "";
        if($maxOrdem){
          $addFilter .= " and (pci.ordem <= $maxOrdem)";
        }

        $sql = "
            select
              ots.*,
              pci.tipo as tipo_processo,
              pci.ordem
            from oc_order_to_situation ots
            left join oc_proccess_control p on (p.proccess_control_id = $processo_venda)
            left join oc_proccess_control_item pci on (
                pci.proccess_control_id = p.proccess_control_id and pci.utiliza <> $proccess_disabled
                and (
                            (pci.order_situation_ini_id = ots.order_situation_id and ots.proccess_status = $processo_iniciado)
                         or (pci.order_situation_suc_id = ots.order_situation_id and ots.proccess_status = $processo_finalizado)
                         or (pci.order_situation_err_id = ots.order_situation_id and ots.proccess_status = $processo_erro)
                   )
            )
            where ots.order_id = $order_id
                  and ots.tipo = $tipo
                  $addFilter
            order by ots.data_hora desc, order_to_situation_id desc
            limit 1
        ";
        return $this->db->query($sql)->row;
    }

    function getProcessosOrder($order_id, $max_order_status_id = false){
        $this->load->helper('ftr_validacao');
        $retorno = array();

        $processo_venda_empresa = $this->config->get('processo_venda_id');

        if($max_order_status_id){
          $maxProccess =  $this->getProccessByStatus($max_order_status_id, $processo_venda_empresa);

          $ordem = false;
          if(sizeof($maxProccess) > 0){
            $ordem = $maxProccess['ordem'];
          }
          $lastProccessVenda      = $this->getLastOrderProcess($order_id, $processo_venda_empresa, $ordem);
          $processosConfigurados  = $this->getConfigProccess($processo_venda_empresa, false, $ordem);
        }else{
          $lastProccessVenda      = $this->getLastOrderProcess($order_id, $processo_venda_empresa);
          $processosConfigurados  = $this->getConfigProccess($processo_venda_empresa);
        }

        if(!$lastProccessVenda){
            return false;
        }

        $proccess_ini = $this->getProccessStatus($order_id, Type_ContrlProcVenda::TpStContrlProcVenda_ProdInicial);
        $retorno[] = array(
          'processo_tipo'              => Type_ContrlProcVenda::TpStContrlProcVenda_ProdInicial,
          'processo_name'              => Type_ContrlProcVenda::getNickFromValue(Type_ContrlProcVenda::TpStContrlProcVenda_ProdInicial),
          'proccesso_status'           => sizeof($proccess_ini) > 0 ? $proccess_ini['proccess_status'] : Type_StatusProcVenda::TpStProcVend_Finalizado,
          'processo_com_andamento'     => true,
          'processo_status_name'       => sizeof($proccess_ini) > 0 ? $proccess_ini['name']      : false,
          'data_hora_status'           => sizeof($proccess_ini) > 0 ? date('d/m/Y', strtotime($proccess_ini['data_hora'])) : false,
          'processo_observacao'        => sizeof($proccess_ini) > 0 ? $proccess_ini['comment'] : false
        );

        $i = 1;
        foreach($processosConfigurados as $config){

            $aux = $this->getProccessStatus($order_id, $config['tipo']);

            if(($lastProccessVenda['proccess_status'] == Type_StatusProcVenda::TpStProcVend_Finalizado)             &&
               ($lastProccessVenda['status']          == Type_ContrlProcVenda::TpStContrlProcVenda_PedidoCancelado) &&
               (sizeof($aux) <= 0)
            ){
                continue;
            }


            if((sizeof($aux) > 0) && (!$retorno[$i-1]['processo_com_andamento'])){
              while(!$retorno[$i-1]['processo_com_andamento']){
                unset($retorno[$i-1]);
                $i --;
              }
            }

            $retorno[$i] = array(
                'processo_tipo'              => $config['tipo'],
                'processo_name'              => Type_ContrlProcVenda::getNickFromValue($config['tipo']),
                'proccesso_status'           => sizeof($aux) > 0 ? $aux['proccess_status'] : false,
                'processo_com_andamento'     => sizeof($aux) > 0,
                'processo_status_name'       => sizeof($aux) > 0 ? $aux['name']      : false,
                'data_hora_status'           => sizeof($aux) > 0 ? date('d/m/Y', strtotime($aux['data_hora'])) : false,
                'processo_observacao'        => sizeof($aux) > 0 ? $aux['comment'] : false
            );

            $i ++;
        }

        if(($lastProccessVenda['proccess_status']  == Type_StatusProcVenda::TpStProcVend_Finalizado)             &&
            ($lastProccessVenda['status']          == Type_ContrlProcVenda::TpStContrlProcVenda_PedidoCancelado)
        ){
            $cancelado = $this->getProccessStatus($order_id, Type_ContrlProcVenda::TpStContrlProcVenda_PedidoCancelado);

            $retorno[] = array(
                'processo_tipo'              => Type_ContrlProcVenda::TpStContrlProcVenda_PedidoCancelado,
                'processo_name'              => Type_ContrlProcVenda::getNickFromValue(Type_ContrlProcVenda::TpStContrlProcVenda_PedidoCancelado),
                'proccesso_status'           => sizeof($cancelado) > 0 ? $cancelado['proccess_status'] : false,
                'processo_com_andamento'     => sizeof($cancelado) > 0,
                'processo_status_name'       => sizeof($cancelado) > 0 ? $cancelado['name']      : false,
                'data_hora_status'           => sizeof($cancelado) > 0 ? date('d/m/Y', strtotime($cancelado['data_hora'])) : false,
                'processo_observacao'        => sizeof($cancelado) > 0 ? $cancelado['comment'] : false
            );
        }

        return $retorno;
    }


    function getProccessStatus($order_id, $processo_type){
        $tipo                   = Type_PedLogType::TpPedLgTp_ProcessoVenda;
        $tipo_status_prioridade = Type_ProcessoVendaStatusPrior::TpPrVnStPrincipal;
        $proccess_disabled      = Type_UtilizaProccessVenda::TpUtPv_Nao;

        $processo_iniciado   = Type_StatusProcVenda::TpStProcVend_Iniciado;
        $processo_finalizado = Type_StatusProcVenda::TpStProcVend_Finalizado;
        $processo_erro       = Type_StatusProcVenda::TpStProcVend_EmErro;

        $this->load->type('tipofuturaserver');

        $processo_venda_empresa = $this->config->get('processo_venda_id');

        if((Type_ContrlProcVenda::TpStContrlProcVenda_PedidoCancelado == $processo_type) || (Type_ContrlProcVenda::TpStContrlProcVenda_ProdInicial == $processo_type)){

          $this->load->dmodel('localisation/order_status');
          $canceled_status_list = $this->dmodel_localisation_order_status->getOrderStatusServerList(Type_PedidoStatus::TpPSt_Cancelado,false,true);
          if($canceled_status_list){
            $canceled_status_list = $canceled_status_list.','.$this->config->get('select_order_status_canc_id');
          }else{
            $canceled_status_list = $this->config->get('select_order_status_canc_id');
          }

          $status_verificacao = (Type_ContrlProcVenda::TpStContrlProcVenda_PedidoCancelado == $processo_type)
              ? $canceled_status_list
              : ($this->config->get('processo_venda_order_status_started') ? $this->config->get('processo_venda_order_status_started') : 0);

          $sql = "
            select
              ots.tipo,
              ots.status,
              ots.proccess_status,
              ots.data_hora,
              oh.comment,
              os.name
            from oc_order_to_situation ots
            left join oc_order_status os on (os.order_status_id in ($status_verificacao) )
            LEFT JOIN oc_order_history oh ON (oh.order_id = $order_id  and oh.order_status_id in ($status_verificacao) )
            where ots.tipo = $tipo and ots.order_id = $order_id and ots.status = $processo_type
            order by ots.data_hora desc, oh.date_added desc
            limit 1";
        }else{
          $sql = "
            select
              ots.tipo,
              ots.status,
              ots.proccess_status,
              ots.data_hora,
              oh.comment,
              os.name
            from oc_order_to_situation ots
            inner join oc_proccess_control_item pci on (
            (pci.order_situation_ini_id = ots.order_situation_id and ots.proccess_status = $processo_iniciado) or
            (pci.order_situation_suc_id = ots.order_situation_id and ots.proccess_status = $processo_finalizado) or
            (pci.order_situation_err_id = ots.order_situation_id and ots.proccess_status = $processo_erro))
            left join oc_proccess_to_status pts on (pts.proccess_control_item_id = pci.proccess_control_item_id)
            left join oc_order_status os on (os.order_status_id = pts.order_status_id)
            LEFT JOIN oc_order_history oh ON (oh.order_id = $order_id and oh.order_status_id = os.order_status_id)
            where ots.tipo = $tipo and ots.order_id = $order_id and ots.status = $processo_type
                  and (pci.utiliza <> $proccess_disabled)
                  and (pts.tipo_status = ots.proccess_status or pts.order_status_id is null)
                  and pci.proccess_control_id = $processo_venda_empresa
            order by ots.data_hora desc, oh.date_added desc
            limit 1";

        }


        return $this->db->query($sql)->row;
    }

    function getProccessStatusAll(){

      $processo_venda_empresa      = $this->config->get('processo_venda_id');

      $select_order_status_aban_id = $this->config->get('select_order_status_aban_id');
      $processo_venda_order_status_started = $this->config->get('processo_venda_order_status_started') ? $this->config->get('processo_venda_order_status_started') : 0;

      $this->load->dmodel('localisation/order_status');
      $this->load->type('tipofuturaserver');

      $canceled_status_list = $this->dmodel_localisation_order_status->getOrderStatusServerList(Type_PedidoStatus::TpPSt_Cancelado,false,true);
      if($canceled_status_list){
        $canceled_status_list = $canceled_status_list.','.$this->config->get('select_order_status_canc_id');
      }else{
        $canceled_status_list = $this->config->get('select_order_status_canc_id');
      }

      $sql = "
        select
          distinct(os.order_status_id) as order_status_id,
          os.name
        from oc_proccess_to_status pts
        left join oc_proccess_control_item pci on (pts.proccess_control_item_id = $processo_venda_empresa)
        left join oc_order_status os on (pts.order_status_id = os.order_status_id or
                                          os.order_status_id  in($canceled_status_list) or";
                                          if($select_order_status_aban_id){
                                            $sql .= " os.order_status_id  = $select_order_status_aban_id or";
                                          }
                                          $sql.= " os.order_status_id  = $processo_venda_order_status_started) ";

      return $this->db->query($sql)->rows;

    }

    public function getOrderStatusByProcessType($type_process, $type_status){

      $processo_venda_id = $this->config->get('processo_venda_id');

      $sql = "select pts.order_status_id
              from oc_proccess_to_status pts
              inner join oc_proccess_control_item pci on (pci.proccess_control_item_id = pts.proccess_control_item_id)
              where pci.tipo = $type_process and pts.tipo_status = $type_status and pci.proccess_control_id = $processo_venda_id";

      return $this->db->query($sql)->rows;

    }

}