403Webshell
Server IP : 54.94.228.101  /  Your IP : 172.28.1.13
Web Server : Apache
System : Linux ip-172-28-29-189 6.5.0-1014-aws #14~22.04.1-Ubuntu SMP Thu Feb 15 15:27:06 UTC 2024 x86_64
User : www-data ( 33)
PHP Version : 7.2.34-43+ubuntu22.04.1+deb.sury.org+1
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/www/html/vinumday2_0/app/Services/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/vinumday2_0/app/Services/GeralService.php
<?php

namespace App\Services;

use App\Modules\AdegaVirada\Services\AdegaViradaService;
use DB;
use Cart;
use Sentinel;
use Illuminate\Support\Facades\Log;

use App\BasicInfo;
use App\Modules\Confraria\Models\Confraria;
use App\Modules\ConfrariaConvite\Models\ConfrariaConvite;
use App\Modules\AdegaViradaParticipante\Models\AdegaViradaParticipante;
use App\Modules\AdegaViradaParticipanteIndicacao\Models\AdegaViradaParticipanteIndicacao;
use App\Modules\Cadastro\Models\Cadastro;
use App\Modules\CadastroConsumo\Models\CadastroConsumo;
use App\Modules\Cupom\Models\Cupom;
use App\Modules\CupomIndicacao\Models\CupomIndicacao;
use App\Modules\CupomCadastro\Models\CupomCadastro;
use App\Modules\Empresa\Models\Empresa;
use App\Modules\Contato\Models\Contato;

use App\Modules\TipoDeProduto\Models\TipoDeProduto;
use App\Modules\Produto\Models\Produto;
use App\Modules\Oferta\Models\Oferta;
use App\Modules\OfertaReserva\Models\OfertaReserva;
use App\Modules\OfertaHasProduto\Models\OfertaHasProduto;
use App\Modules\Adega\Models\Adega;
use App\Modules\Pais\Models\Pais;
use App\Modules\ProdutoCaracteristica\Models\ProdutoCaracteristica;
use App\Modules\ProdutoVariacao\Models\ProdutoVariacao;
use App\Modules\ProdutoVariacaoAtributo\Models\ProdutoVariacaoAtributo;

use App\Modules\PedidoEntrega\Models\PedidoEntrega;
use App\Modules\PedidoEntregaExpedicao\Models\PedidoEntregaExpedicao;
use App\Modules\AcaoUsuario\Models\AcaoUsuario;
use App\Modules\PedidoVenda\Models\PedidoVenda;
use App\Modules\AdegaHasPedidoVenda\Models\AdegaHasPedidoVenda;
use App\Modules\PedidoVendaHasProduto\Models\PedidoVendaHasProduto;
use App\Modules\Regiao\Models\Regiao;
use App\Modules\CadastroEndereco\Models\CadastroEndereco;
use App\Modules\EstoqueLog\Models\EstoqueLog;
use App\Modules\CanalHasOferta\Models\CanalHasOferta;
use App\Modules\CanalAcessoAutenticado\Models\CanalAcessoAutenticado;
use App\Modules\Canal\Models\Canal;
use App\Modules\QuantidadeReserva\Models\QuantidadeReserva;

use App\Modules\PlanoFinanceiroLancamento\Models\PlanoFinanceiroLancamento;
use App\Modules\ContaFinanceiraLancamento\Models\ContaFinanceiraLancamento;

use App\Services\ErpService;
use App\Services\DashService;
use App\Services\OfertaService;
use App\Modules\Confraria\Services\ConfrariaService;

use Notification;
use App\Notifications\NotificacaoContato;
use App\User;

class GeralService {

    private static $imageCreateFunc = [
        'png' => 'imagecreatefrompng',
        'gd' => 'imagecreatefromgd',
        'gif' => 'imagecreatefromgif',
        'jpg' => 'imagecreatefromjpeg',
        'jpeg' => 'imagecreatefromjpeg',
    ];

    private static $imageSaveFunc = [
        'png' => 'imagepng',
        'jpg' => 'imagejpeg',
        'jpeg' => 'imagejpeg',
    ];

    private static $createExt = [
        'image/png' => 'png',
        'image/jpg' => 'jpg',
        'image/jpeg' => 'jpeg',
    ];

     public static function getClientIp()  
     {  
        $ipaddress = '';
        if (isset($_SERVER['HTTP_CLIENT_IP']))
            $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
        else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
            $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
        else if(isset($_SERVER['HTTP_X_FORWARDED']))
            $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
        else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
            $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
        else if(isset($_SERVER['HTTP_FORWARDED']))
            $ipaddress = $_SERVER['HTTP_FORWARDED'];
        else if(isset($_SERVER['REMOTE_ADDR']))
            $ipaddress = $_SERVER['REMOTE_ADDR'];
        else
            $ipaddress = 'UNKNOWN';
        return $ipaddress;  
     }  

    public static function ultimosMeses(){
        $meses = [];
        //Atual
        for($i=1;$i<=date('m');$i++){
            $meses[] = ['mes' => $i, 'ano' => date('Y')];
        }
        //Anterior
        for($i=12;$i>date('m');$i--){
            $meses[] = ['mes' => $i, 'ano' => (date('Y') - 1)];
        }
        return $meses;
    }

    public static function mesesAno(){

        $mesesLabel = [
            1 => 'Janeiro',
            2 => 'Fevereiro',
            3 => 'Março',
            4 => 'Abril',
            5 => 'Maio',
            6 => 'Junho',
            7 => 'Julho',
            8 => 'Agosto',
            9 => 'Setembro',
            10 => 'Outubro',
            11 => 'Novembro',
            12 => 'Dezembro'
        ];

        return $mesesLabel;
    }

    public static function getUsersRH(){
        return [29391, 36210, 29398, 29394, 29393, 29574];
    }

    public static function montarMeses($qtde, $afterCurrentMonth = TRUE){

        $mesesLabel = [
            1 => 'Janeiro',
            '01' => 'Janeiro',
            2 => 'Fevereiro',
            '02' => 'Fevereiro',
            3 => 'Março',
            '03' => 'Março',
            4 => 'Abril',
            '04' => 'Abril',
            5 => 'Maio',
            '05' => 'Maio',
            6 => 'Junho',
            '06' => 'Junho',
            7 => 'Julho',
            '07' => 'Julho',
            8 => 'Agosto',
            '08' => 'Agosto',
            9 => 'Setembro',
            '09' => 'Setembro',
            10 => 'Outubro',
            11 => 'Novembro',
            12 => 'Dezembro'
        ];

        $date       = date('Y-m').'-01';
        $firstMonth = date('m', strtotime("-{$qtde} months", strtotime($date)));
        $firstYear  = date('Y', strtotime("-{$qtde} months", strtotime($date)));
        $lastMonth  = date('m', strtotime("+{$qtde} months", strtotime($date)));
        $lastYear   = date('Y', strtotime("+{$qtde} months", strtotime($date)));
        $months     = [];
        $ano        = date('Y');
        $mes        = date('m');

        if($firstYear < date('Y')){
            for($i=$firstMonth;$i<=12;$i++){
                $months[] = ['mes' => $i, 'ano' => $firstYear, 'mes_label' => $mesesLabel[$i]];
            }
        }

        if($firstYear < date('Y') && $lastYear > date('Y')){
            for($i=1;$i<=12;$i++){
                if($i > date('m') && !$afterCurrentMonth){
                    break;
                }
                $months[] = ['mes' => $i, 'ano' => date('Y'), 'mes_label' => $mesesLabel[$i]];
            }
        }elseif($firstYear == date('Y') && $lastYear == date('Y')){
            for($i=$firstMonth;$i<=$lastMonth;$i++){
                $months[] = ['mes' => $i, 'ano' => date('Y'), 'mes_label' => $mesesLabel[$i]];
            }
        }

        if($afterCurrentMonth){
            if($lastYear > date('Y')){
                for($i=1;$i<=$lastMonth;$i++){
                    $months[] = ['mes' => $i, 'ano' => $lastYear, 'mes_label' => $mesesLabel[$i]];
                }
            }
        }

        return $months;
    }

    public static function sequenceEstoque(){
        $produto = Produto::select(DB::raw('MAX(id_estoque) + 1 AS id_estoque'))->first();
        return $produto->id_estoque;
    }

    public static function sequenceSKU($count = 1){

        $info          = \App\BasicInfo::find(1);
        $skuInit       = $info->mascara_sku;
        $sequencia_sku = $info->sequencia_sku;

        if($sequencia_sku == 0){
            $produto = Produto::select('sku')->whereRaw("sku LIKE '{$skuInit}%' AND LENGTH(REPLACE(sku, ' ', '')) > 11")->orderBy('sku', 'desc')->first();
            if(!$produto){
                $produto = Produto::select('sku')->whereRaw("sku LIKE '{$skuInit}%'")->orderBy('sku', 'desc')->first();
            }
            $result        = explode($skuInit, $produto->sku);
            $sequencia_sku = $result[1];

            $sql = "UPDATE sis_basic_info SET sequencia_sku = {$sequencia_sku} WHERE id = 1";
            DB::update($sql);
        }

        $sku = $sequencia_sku + $count;

        return "{$skuInit}" . str_pad($sku, 3, "0", STR_PAD_LEFT);
    }

    public static function buscarProfissionalLogado(){
        $user = Sentinel::getUser();
        $profissional = Profissional::where('user_id', $user->id)->first();
        return $profissional;
    }

    public static function buscarCanalHasOferta($filtros = []){

        $query = Oferta::select(array('oferta.*', 'canal_has_oferta.quantidade', 'canal_has_oferta.ordenacao', 'canal_has_oferta.data_inicial', 'canal_has_oferta.data_final'))
        ->join('canal_has_oferta','oferta.id','=','canal_has_oferta.id_oferta')->whereRaw('canal_has_oferta.deleted_at IS NULL');

        if(isset($filtros['id_canal']))
            $query->where('id_canal', $filtros['id_canal']);

         $order = (isset($filtros['order']) ? $filtros['order'] : 'ASC');
         $by    = (isset($filtros['by']) ? $filtros['by'] : 'oferta.titulo');

        $listaOfertas = $query->orderBy($by, $order)->get();

        return $listaOfertas;
    }

    public static function buscarOfertaDia(){
        $oferta = Oferta::where('data', date('Y-m-d'))->where('tipo', 'D')->with('produtos.produto')->first();
        return $oferta;
    }

    public static function buscarOfertaDaSemana(){
        $data_oferta = GeralService::dataOfertaSemana();
        $oferta      = Oferta::where('data', $data_oferta)->where('tipo', 'S')->with('produtos.produto')->first();
        return $oferta;
    }

    public static function buscarOfertaSolidaria(){
        $oferta = Oferta::whereMonth('data', date('m'))->where('tipo', 'L')->with('produtos.produto')->orderBy('data', 'DESC')->first();
        return $oferta;
    }

    public static function buscarOfertaCasada(){
        $oferta = Oferta::where('data', date('Y-m-d'))->where('tipo', 'CS')->with('produtos.produto')->first();
        return $oferta;
    }

    
    public static function buscarOfertasCasadas(){
        $ofertas = Oferta::where('data', date('Y-m-d'))->where('tipo', 'CS')->with('produtos.produto')->orderBy('oferta.id', 'DESC')->get();
        return $ofertas;
    }

    
    // Busca a do mês atual: Coleção ou Kit Brinde
    public static function buscarOfertaConfraria($dataOferta=FALSE){
        $dataOferta = $dataOferta ? $dataOferta : self::dataOfertaConfraria();
        $ofertas = Oferta::where('data', $dataOferta)
        ->where('tipo', 'CF')
        ->with('produtos.produto')
        ->with('tema')
        ->orderBy('oferta.id', 'DESC')
        ->first();

        return $ofertas;
    }

    // Busca as dos meses anteriores
    public static function buscarOfertasConfrariaAnteriores(){
        // whereYear('data', date('Y'))
        $ofertas = Oferta::where('tipo', 'CF')
        ->whereMonth('data', '!=', date('m'))
        ->whereYear('data', '!=', date('Y'))
        ->with('produtos.produto')
        ->orderBy('oferta.data', 'DESC')
        ->limit(12)
        ->get();

        return $ofertas;
    }

    public static function buscarOfertaDaSemanaCliente($oferta, $cadastro){
        $pedidoOferta = false;
        if(isset($cadastro->id)){
            $pedidoOferta = PedidoVenda::select(DB::raw('pedido_venda.id'))
            ->join('pedido_venda_has_produto','pedido_venda_has_produto.id_pedido_venda','=','pedido_venda.id')
            ->where('pedido_venda.id_cliente', $cadastro->id)
            ->whereRaw('pedido_venda.confraria_id IS NULL')
            ->where('pedido_venda_has_produto.id_oferta', $oferta->id)
            ->first();
        }
        return $pedidoOferta;
    }

    /**
    * Retorna um inteiro do dia da semana
    * 0 - Sunday ...
    * @param Date $date 0000-00-00 00:00:00
    * @return Int 0-6
    */
    public static function DayOfWeek($date){
        $result = explode(" ", $date);
        $d = explode("-", $result[0]);
        $h = explode(":", $result[1]);
        $day_of_week = date("w", mktime($h[0], $h[1], $h[2], $d[1], $d[2], $d[0]));
        return $day_of_week;
    }

    public static function variacoesProdutoOferta($oferta){
        $variacoes = [];
        if($oferta->produtos && count($oferta->produtos) == 1){
            $variacoes = !empty($oferta->produtos[0]->produto->tipo) ? $oferta->produtos[0]->produto->tipo->variacoes : [];
        }
        return $variacoes;
    }

    public static function variacaoNome($variacao_id){
        $nome = ProdutoVariacao::select('nome')->where('id', $variacao_id)->value('nome');
        return $nome;
    }

    public static function variacaoAtributo($atributo_id){
        $atributo = ProdutoVariacaoAtributo::where('id', $atributo_id)->first();
        return $atributo;
    }

    public static function tiposOfertasProdutos($oferta){
        $tipos = [];
        if($oferta->tipo == 'CS'){
            foreach ($oferta->produtos as $item) {
                $OfertaHasProduto = OfertaHasProduto::select('oferta.tipo')->join('oferta', 'oferta.id', '=', 'oferta_has_produto.id_oferta')->where('id_produto', $item->id_produto)->whereIn('oferta.tipo', ['D','S'])->first();
                if($OfertaHasProduto){
                    $tipos[] = $OfertaHasProduto->tipo;
                }
            }
        }
        return $tipos;
    }

    public static function ultimaOfertaProduto($produto_id){

        //Oferta Diária
        $ultima_oferta = Oferta::select('oferta.*')->join('oferta_has_produto', 'oferta.id', '=', 'oferta_has_produto.id_oferta')->where('oferta.data' ,'<', date('Y-m-d'))->where('oferta.tipo', 'D')->where('oferta_has_produto.id_produto', $produto_id)->orderBy('data', 'DESC')->first();

        //Oferta Semana
        if(!$ultima_oferta){
            $ultima_oferta = Oferta::select('oferta.*')->join('oferta_has_produto', 'oferta.id', '=', 'oferta_has_produto.id_oferta')->where('oferta.data' ,'<', date('Y-m-d'))->where('oferta.tipo', 'S')->where('oferta_has_produto.id_produto', $produto_id)->orderBy('data', 'DESC')->first();
        }

        //Oferta Canal
        if(!$ultima_oferta){
            $ultima_oferta = Oferta::select('oferta.*', 'canal_has_oferta.data_final')
            ->join('oferta_has_produto', 'oferta.id', '=', 'oferta_has_produto.id_oferta')
            ->join('canal_has_oferta', 'oferta.id', '=', 'canal_has_oferta.id_oferta')
            ->where('canal_has_oferta.data_final' ,'<', date('Y-m-d'))->where('oferta.tipo', 'C')->whereRaw('canal_has_oferta.deleted_at IS NULL')->where('oferta_has_produto.id_produto', $produto_id)->orderBy('data', 'DESC')->first();
        }

        return $ultima_oferta;
        
    }

    public static function countPedidosPreVendaOferta($id_oferta){

        $pedidos = PedidoVenda::select('pedido_venda.id')
        ->join('pedido_venda_has_produto', 'pedido_venda_has_produto.id_pedido_venda', '=', 'pedido_venda.id')
        ->join('oferta', 'oferta.id', '=', 'pedido_venda_has_produto.id_oferta')
        ->where('pedido_venda.id_status_pedido_venda', 9)->where('pedido_venda_has_produto.id_oferta', $id_oferta)
        ->get();

        return $pedidos;

    }

    public static function dataOfertaSemana($date = FALSE){
        //quarta - 3
        $date       = ($date ? $date : date('Y-m-d'));
        $dia_semana = GeralService::DayOfWeek("{$date} 00:00:00");
        if($dia_semana == 3){
            $data_oferta_semana = $date;
        }elseif($dia_semana > 3){
            $days = $dia_semana - 3;
            $data_oferta_semana = date('Y-m-d', strtotime("-{$days} days",strtotime($date)));
        }else{
            $dias_semana = [0 => 4, 1 => 5, 2 => 6];
            $data_oferta_semana = date('Y-m-d', strtotime("-{$dias_semana[$dia_semana]} days",strtotime($date)));
        }
        return $data_oferta_semana;
    }

    public static function dataOfertaSolidaria($date = FALSE){
        
        $date      = ($date ? $date : date('Y-m-d'));
        $dataAtual = "{$date} 00:00:00";
        $data_oferta_solidaria = date('Y-m', strtotime($dataAtual)) . "-01";
        
        return $data_oferta_solidaria;
    }

    public static function dataOfertaConfraria($date = FALSE){
        
        $date      = ($date ? $date : date('Y-m-d'));
        $dataAtual = "{$date} 00:00:00";
        $data_oferta_confraria = date('Y-m', strtotime($dataAtual)) . "-01";
        
        return $data_oferta_confraria;
    }

    public static function buscarFretesPorRegiao(){

        $regioes = Regiao::select('regiao.*', 'f.valor_inicial as valor_maximo_frete')

        ->leftJoin('frete as f', function ($join) {
            $join->on('regiao.id', '=', 'f.regiao_id')
            ->where('f.custo', '=', 0);
        })
        ->orderBy('regiao.id', 'ASC')
        ->get();

        return $regioes;

    }

    public static function buscarOfertasRelacionadasCanal($filtro, $total = FALSE){

        $limit             = (isset($filtro['limit']) ? $filtro['limit'] : 4);
        $random            = (isset($filtro['random']) ? $filtro['random'] : true);
        $oferta_semana     = (isset($filtro['oferta_semana']) ? $filtro['oferta_semana'] : false);
        $oferta_dia        = (isset($filtro['oferta_dia']) ? $filtro['oferta_dia'] : false);
        $oferta_solidaria  = (isset($filtro['oferta_solidaria']) ? $filtro['oferta_solidaria'] : false);
        $oferta_individual = (isset($filtro['oferta_individual']) ? $filtro['oferta_individual'] : false);
        $totalOfertasCanal = (isset($filtro['totalOfertasCanal']) ? $filtro['totalOfertasCanal'] : 0);
        $canalIndividual   = (isset($filtro['canalIndividual']) ? $filtro['canalIndividual'] : false);

        if(!$total){
            $oferta_da_semana = (isset($filtro['ofertaDaSemana']) ? $filtro['ofertaDaSemana'] : false);
            if($oferta_da_semana){
                $limit -= 1;
            }
            $oferta_do_dia = (isset($filtro['ofertaDoDia']) ? $filtro['ofertaDoDia'] : false);
            if($oferta_do_dia){
                $limit -= 1;
            }
            $oferta_solidaria = (isset($filtro['ofertaSolidaria']) ? $filtro['ofertaSolidaria'] : false);
            if($oferta_solidaria){
                $limit -= 1;
            }
        }

        if($total){
            $query = Oferta::select('oferta.id');
        }else{
            $query = Oferta::select('oferta.*', 'tipo_de_produto.nome as nome_tipo_produto', 'tipo_de_produto.grupo as grupo_tipo_produto', 'tipo_de_produto.thumbnail_principal as thumbnail_tipo_produto', 'pais.thumbnail_principal as thumbnail_pais', 'pais.nome as nome_pais');
        }

        $query->join('oferta_has_produto','oferta_has_produto.id_oferta','=','oferta.id')
            ->join('produto','produto.id','=','oferta_has_produto.id_produto')
            ->join('tipo_de_produto','tipo_de_produto.id','=','produto.id_tipo_produto')
            ->leftJoin('pais','pais.id','=','produto.id_pais_origem')
            ->join('canal_has_oferta as cho', 'cho.id_oferta', '=', 'oferta.id')
            ->join('canal as c', 'c.id', '=', 'cho.id_canal')
            ->whereRaw('cho.deleted_at IS NULL')
            ->where('c.data_inicio', '<', date('Y-m-d H:i:s'))
            ->where('c.data_fim', '>', date('Y-m-d H:i:s'))
            ->where('cho.data_inicial', '<=', date('Y-m-d'))
            ->where('cho.data_final', '>=', date('Y-m-d'))
            ->where('oferta.estoque' , '>', 0)
            ->whereRaw("(c.id = 35 OR c.ativar_url = 0)"); //@marcoskubas melhorar condition canal = ofertas-de-ocasiao

        if($total){
            $query->whereRaw("((c.tipo <> 'IN' AND oferta.destaque = 1) OR (c.tipo = 'IN'))");
        }else{
            if(!$canalIndividual){
                $query->where('c.tipo', '<>', 'IN')->where('oferta.destaque' , 1);
            }else{
                $query->where('c.tipo', 'IN');
            }
        }

        if($random && isset($_COOKIE['ofertasCheckout']) && !$total){
            $ofertasCheckout = json_decode($_COOKIE['ofertasCheckout']);
            if(count($ofertasCheckout) >= $totalOfertasCanal){
                \Cookie::queue(\Cookie::forget('ofertasCheckout'));
            }else{
                $query->whereNotIn('oferta.id', $ofertasCheckout);
            }
        }
            
        $query->groupBy('oferta.id')->with('canalHasOferta.canal','produtos.produto.paisDeOrigem','produtos.produto.tipoDeProduto');

        if(!$total){
            $query->orderBy('cho.ordenacao', 'ASC')->limit($limit);
        }

        $listaOfertas             = $query->get();
        $listaOfertasRelacionadas = [];
        foreach ($listaOfertas as $oferta) {
            $listaOfertasRelacionadas[] = $oferta;
        }

        return $listaOfertasRelacionadas;
    }

    public static function buscarOfertasRelacionadas($filtro = []){
        try {

            $limit             = (isset($filtro['limit']) ? $filtro['limit'] : 4);
            $random            = (isset($filtro['random']) ? $filtro['random'] : true);
            $oferta_semana     = (isset($filtro['oferta_semana']) ? $filtro['oferta_semana'] : false);
            $oferta_dia        = (isset($filtro['oferta_dia']) ? $filtro['oferta_dia'] : false);
            $oferta_individual = (isset($filtro['oferta_individual']) ? $filtro['oferta_individual'] : false);
            $oferta_solidaria  = (isset($filtro['oferta_solidaria']) ? $filtro['oferta_solidaria'] : false);
            $oferta_equipe     = (isset($filtro['oferta_equipe']) ? $filtro['oferta_equipe'] : false);

            $cartItems   = Cart::content();
            $ofertasCart = [];
            foreach ($cartItems as $item) {
                $ofertasCart[] = $item->options->id;
            }

            //OFERTA DA SEMANA
            if($oferta_semana){

                $data_oferta  = GeralService::dataOfertaSemana();
                $OfertaSemana = Oferta::select('oferta.*', 'tipo_de_produto.nome as nome_tipo_produto', 'tipo_de_produto.grupo as grupo_tipo_produto', 'tipo_de_produto.thumbnail_principal as thumbnail_tipo_produto', 'pais.thumbnail_principal as thumbnail_pais', 'pais.nome as nome_pais')
                ->join('oferta_has_produto','oferta_has_produto.id_oferta','=','oferta.id')
                ->join('produto','produto.id','=','oferta_has_produto.id_produto')
                ->join('tipo_de_produto','tipo_de_produto.id','=','produto.id_tipo_produto')
                ->join('pais','pais.id','=','produto.id_pais_origem')
                ->where('oferta.data', '=', $data_oferta)
                ->where('oferta.tipo', '=', 'S')
                ->where('oferta.estoque' , '>', 0)
                ->with('produtos.produto.paisDeOrigem','produtos.produto.tipoDeProduto')->first();
                
                if($OfertaSemana && !in_array($OfertaSemana->id, $ofertasCart)){
                    $OfertaDaSemana = $OfertaSemana;
                }else{
                    $OfertaDaSemana = FALSE;
                }

            }else{
                $OfertaDaSemana = FALSE;
            }

            //OFERTA DO DIA
            if($oferta_dia){

                $OfertaDia = Oferta::select('oferta.*', 'tipo_de_produto.nome as nome_tipo_produto', 'tipo_de_produto.grupo as grupo_tipo_produto', 'tipo_de_produto.thumbnail_principal as thumbnail_tipo_produto', 'pais.thumbnail_principal as thumbnail_pais', 'pais.nome as nome_pais')
                ->join('oferta_has_produto','oferta_has_produto.id_oferta','=','oferta.id')
                ->join('produto','produto.id','=','oferta_has_produto.id_produto')
                ->join('tipo_de_produto','tipo_de_produto.id','=','produto.id_tipo_produto')
                ->join('pais','pais.id','=','produto.id_pais_origem')
                ->where('oferta.data', '=', date('Y-m-d'))
                ->where('oferta.tipo', '=', 'D')
                ->where('oferta.estoque' , '>', 0)
                ->with('produtos.produto.paisDeOrigem','produtos.produto.tipoDeProduto')->first();

                if($OfertaDia && !in_array($OfertaDia->id, $ofertasCart)){
                    $OfertaDoDia = $OfertaDia;
                }else{
                    $OfertaDoDia = FALSE;
                }

            }else{
                $OfertaDoDia = FALSE;
            }

            //OFERTA DA EQUIPE
            if($oferta_equipe){

                $OfertaDaEquipe = Oferta::select('oferta.*', 'tipo_de_produto.nome as nome_tipo_produto', 'tipo_de_produto.grupo as grupo_tipo_produto', 'tipo_de_produto.thumbnail_principal as thumbnail_tipo_produto', 'pais.thumbnail_principal as thumbnail_pais', 'pais.nome as nome_pais')
                ->join('oferta_has_produto','oferta_has_produto.id_oferta','=','oferta.id')
                ->join('produto','produto.id','=','oferta_has_produto.id_produto')
                ->join('tipo_de_produto','tipo_de_produto.id','=','produto.id_tipo_produto')
                ->join('pais','pais.id','=','produto.id_pais_origem')
                ->whereMonth('oferta.data', '=', date('m'))
                ->whereYear('oferta.data', '=', date('Y'))
                ->where('oferta.tipo', '=', 'EQ')
                ->where('oferta.estoque' , '>', 0)
                ->with('produtos.produto.paisDeOrigem','produtos.produto.tipoDeProduto')->first();

                if($OfertaDaEquipe && !in_array($OfertaDaEquipe->id, $ofertasCart)){
                    $OfertaDaEquipe = $OfertaDaEquipe;
                }else{
                    $OfertaDaEquipe = FALSE;
                }

            }else{
                $OfertaDaEquipe = FALSE;
            }

            //OFERTA SOLIDÁRIA
            if($oferta_solidaria){

                $OfertaSolidaria = Oferta::select('oferta.*', 'tipo_de_produto.nome as nome_tipo_produto', 'tipo_de_produto.grupo as grupo_tipo_produto', 'tipo_de_produto.thumbnail_principal as thumbnail_tipo_produto', 'pais.thumbnail_principal as thumbnail_pais', 'pais.nome as nome_pais')
                ->join('oferta_has_produto','oferta_has_produto.id_oferta','=','oferta.id')
                ->join('produto','produto.id','=','oferta_has_produto.id_produto')
                ->join('tipo_de_produto','tipo_de_produto.id','=','produto.id_tipo_produto')
                ->join('pais','pais.id','=','produto.id_pais_origem')
                ->whereMonth('oferta.data', '=', date('m'))
                ->where('oferta.tipo', '=', 'L')
                ->where('oferta.estoque' , '>', 0)
                ->with('produtos.produto.paisDeOrigem','produtos.produto.tipoDeProduto')->first();

                if($OfertaSolidaria && !in_array($OfertaSolidaria->id, $ofertasCart)){
                    $OfertaSolidaria = $OfertaSolidaria;
                }else{
                    $OfertaSolidaria = FALSE;
                }

            }else{
                $OfertaSolidaria = FALSE;
            }
            
            //OFERTAS CANAIS
            $totalOfertasCanal           = GeralService::buscarOfertasRelacionadasCanal($filtro, TRUE);
            $filtro['totalOfertasCanal'] = count($totalOfertasCanal);
            $filtro['ofertaDaSemana']    = $OfertaDaSemana;
            $filtro['ofertaDoDia']       = $OfertaDoDia;
            $filtro['ofertaDaEquipe']    = $OfertaDaEquipe;
            $filtro['ofertaSolidaria']   = $OfertaSolidaria;
            $listaOfertasRelacionadas    = GeralService::buscarOfertasRelacionadasCanal($filtro);
            if($oferta_individual && count($listaOfertasRelacionadas) <= 3){
                $filtro['canalIndividual']          = TRUE;
                $filtro['limit']                    = 3 - count($listaOfertasRelacionadas);
                $listaOfertasRelacionadasIndividual = GeralService::buscarOfertasRelacionadasCanal($filtro);
                if(count($listaOfertasRelacionadasIndividual) > 0){
                    $listaOfertasRelacionadas = array_merge($listaOfertasRelacionadas, $listaOfertasRelacionadasIndividual);
                }
            }

            if($random){
                $ofertas = [];
                foreach ($listaOfertasRelacionadas as $oferta) {
                    $ofertas[] = $oferta->id;
                }

                if(!isset($_COOKIE['ofertasCheckout'])){
                    setcookie('ofertasCheckout', json_encode($ofertas));
                }else{
                    $ofertasCheckout = json_decode($_COOKIE['ofertasCheckout']);
                    $ofertas         = array_merge($ofertas, $ofertasCheckout);
                    setcookie('ofertasCheckout', json_encode($ofertas));
                }
            }

            $ofertasCheckout = [];
            if(isset($_COOKIE['ofertasCheckout']) && $_COOKIE['ofertasCheckout']){
                $ofertasCheckout = json_decode($_COOKIE['ofertasCheckout']);
            }

            //OFERTA SEMANA
            if($oferta_semana){

                if($OfertaSemana && !in_array($OfertaSemana->id, $ofertasCart)){
                    if($limit == 3 || count($listaOfertasRelacionadas) < 3){
                        if(isset($listaOfertasRelacionadas[1])){
                            $listaOfertasRelacionadas[2] = $listaOfertasRelacionadas[1];
                            $listaOfertasRelacionadas[1] = $OfertaSemana;
                        }else{
                            $listaOfertasRelacionadas[] = $OfertaSemana;
                        }
                    }else{
                        if(isset($listaOfertasRelacionadas[2])){
                            $listaOfertasRelacionadas[3] = $listaOfertasRelacionadas[2];
                            $listaOfertasRelacionadas[2] = $OfertaSemana;
                        }else{
                            $listaOfertasRelacionadas[] = $OfertaSemana;
                        }
                    }
                }

            }

            //OFERTA DIA
            if($oferta_dia){

                if($OfertaDia && !in_array($OfertaDia->id, $ofertasCart)){
                    if($limit == 3 || count($listaOfertasRelacionadas) < 3){
                        if(isset($listaOfertasRelacionadas[1])){
                            $listaOfertasRelacionadas[2] = $listaOfertasRelacionadas[1];
                            $listaOfertasRelacionadas[1] = $OfertaDia;
                        }else{
                            $listaOfertasRelacionadas[] = $OfertaDia;
                        }
                    }else{
                        if(isset($listaOfertasRelacionadas[2])){
                            $listaOfertasRelacionadas[3] = $listaOfertasRelacionadas[2];
                            $listaOfertasRelacionadas[2] = $OfertaDia;
                        }else{
                            $listaOfertasRelacionadas[] = $OfertaDia;
                        }
                    }
                }

            }

            //OFERTA DA EQUIPE
            if($oferta_equipe){

                if($OfertaDaEquipe && !in_array($OfertaDaEquipe->id, $ofertasCart) && !in_array($OfertaDaEquipe->id, $ofertasCheckout)){

                    if(isset($_COOKIE['ofertasCheckout']) && $_COOKIE['ofertasCheckout']){
                        $ofertasCheckout = json_decode($_COOKIE['ofertasCheckout']);
                        $ofertas[] = $OfertaDaEquipe->id;
                        $ofertas         = array_merge($ofertas, $ofertasCheckout);
                        setcookie('ofertasCheckout', json_encode($ofertas));
                    }

                    if($limit == 3 || count($listaOfertasRelacionadas) < 3){
                        if(isset($listaOfertasRelacionadas[1])){
                            $listaOfertasRelacionadas[2] = $listaOfertasRelacionadas[1];
                            $listaOfertasRelacionadas[1] = $OfertaDaEquipe;
                        }else{
                            $listaOfertasRelacionadas[] = $OfertaDaEquipe;
                        }
                    }else{
                        if(isset($listaOfertasRelacionadas[2])){
                            $listaOfertasRelacionadas[3] = $listaOfertasRelacionadas[2];
                            $listaOfertasRelacionadas[2] = $OfertaDaEquipe;
                        }else{
                            $listaOfertasRelacionadas[] = $OfertaDaEquipe;
                        }
                    }
                }

            }

            //OFERTA SOLIDÁRIA
            if($oferta_solidaria){

                if($OfertaSolidaria && !in_array($OfertaSolidaria->id, $ofertasCart)){
                    if($limit == 3 || count($listaOfertasRelacionadas) < 3){
                        if(isset($listaOfertasRelacionadas[1])){
                            $listaOfertasRelacionadas[2] = $listaOfertasRelacionadas[1];
                            $listaOfertasRelacionadas[1] = $OfertaSolidaria;
                        }else{
                            $listaOfertasRelacionadas[] = $OfertaSolidaria;
                        }
                    }else{
                        if(isset($listaOfertasRelacionadas[2])){
                            $listaOfertasRelacionadas[3] = $listaOfertasRelacionadas[2];
                            $listaOfertasRelacionadas[2] = $OfertaSolidaria;
                        }else{
                            $listaOfertasRelacionadas[] = $OfertaSolidaria;
                        }
                    }
                }

            }

            return $listaOfertasRelacionadas;

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

    public static function buscarPedidosCotacao($filtro, $paginate = FALSE, $excel=FALSE){

            $query = PedidoEntrega::select('pedido_entrega.*')->join('adega','adega.id','=','pedido_entrega.id_adega')
                                    ->join('cadastro','cadastro.id','=','adega.id_cliente')
                                    ->join('sis_users','sis_users.id','=','cadastro.user_id');

            $query->join('pedido_entrega_status', 'pedido_entrega.id_pedido_entrega_status', '=', 'pedido_entrega_status.id');    

            $query->where('pedido_entrega.retirada_local', 0);

            //Empresa
            if(isset($filtro['filtro_empresa']) && !empty($filtro['filtro_empresa'])){
                $query->where('pedido_entrega.empresa_id', '=', $filtro['filtro_empresa']);
            }

            //Data Solicitação
            if(isset($filtro['data_inicial']) && $filtro['data_inicial']){
                $query->where('pedido_entrega.data_solicitacao', '>=', $filtro['data_inicial'] . ' 00:00:00');
            }
            if(isset($filtro['data_final']) && $filtro['data_final']){
                $query->where('pedido_entrega.data_solicitacao', '<=', $filtro['data_final'].' 23:59:59');
            }

            //Status Pedidos
            if(isset($filtro['filtro_status']) && $filtro['filtro_status']){
                $query->where('pedido_entrega.id_pedido_entrega_status', '=', $filtro['filtro_status']);
            }

            //Pedido Entrega
            if(isset($filtro['pedido_entrega']) && !empty($filtro['pedido_entrega'])){
                $query->where('pedido_entrega.id', '=', $filtro['pedido_entrega']);
            }

            //Cliente
            if(isset($filtro['cliente']) && $filtro['cliente']){
                $query->where(function ($query) use ($filtro) {
                    $query->where('cadastro.nome', 'like', '%'.$filtro['cliente'].'%')
                          ->OrWhere('cadastro.sobrenome', 'like', '%'.$filtro['cliente'].'%')
                          ->OrWhere('sis_users.email', 'like', '%'.$filtro['cliente'].'%');
                });
            }

            //Transportadora
            if(isset($filtro['filtro_transportadora']) && $filtro['filtro_transportadora']){
                $query->whereRaw("pedido_entrega.id_cotacao_valor IS NOT NULL AND EXISTS (SELECT 1 FROM cotacao_valor WHERE cotacao_valor.id = pedido_entrega.id_cotacao_valor AND cotacao_valor.transportadora_id = {$filtro['filtro_transportadora']})");
            }

            //Status Cotação
            if(!$excel){
                if(isset($filtro['status_cotacao']) && $filtro['status_cotacao']){
                    if($filtro['status_cotacao'] == 'A'){
                        $query->where(function ($query) use ($filtro) {
                            $query->whereRaw('pedido_entrega.id_cotacao_valor IS NULL')
                                  ->OrWhereRaw("pedido_entrega.id_cotacao_valor IS NOT NULL AND EXISTS (SELECT 1 FROM cotacao WHERE cotacao.pedido_entrega_id = pedido_entrega.id AND cotacao.status = 'A')");
                        });
                    }elseif($filtro['status_cotacao'] == 'F'){
                        $query->whereRaw("pedido_entrega.id_cotacao_valor IS NOT NULL AND EXISTS (SELECT 1 FROM cotacao WHERE cotacao.pedido_entrega_id = pedido_entrega.id AND cotacao.status = 'F')");
                    }
                }
            }

            //Nota Fiscal
            if(isset($filtro['nota_fiscal']) && !empty($filtro['nota_fiscal'])){
                $query->where('pedido_entrega.nota_fiscal_erp', '=', $filtro['nota_fiscal']);
            }

            if($paginate){
                $pedidos = $query->orderBy('pedido_entrega.data_solicitacao', 'desc')->paginate($paginate);
            }else{
                $pedidos = $query->orderBy('pedido_entrega.data_solicitacao', 'desc')->get();
            }

            return $pedidos;
    }

    public static function listaOfertasPedidoVenda(){

        $time               = strtotime(date('Y-m-d') . " -10 days");
        $data_filtro_oferta = date('Y-m-d', $time);
        $data_oferta_semana = GeralService::dataOfertaSemana();

        $listaOfertas = Oferta::select('oferta.*', 'cho.data_inicial as data_inicial_canal', 'cho.data_final as data_final_canal', 'c.nome as nome_canal', 'c.subtitulo as subtitulo_canal')
        ->leftJoin('canal_has_oferta as cho', 'oferta.id', '=', 'cho.id_oferta')
        ->leftJoin('canal as c', 'cho.id_canal', '=', 'c.id')
        ->where(function($query) use($data_filtro_oferta){
            $query->where('oferta.tipo', '<>', 'S')->where('oferta.agrupamento_produtos', 0)
            ->where(function($query) use($data_filtro_oferta){
                $query->where('oferta.data', '>=', $data_filtro_oferta)
                ->orWhere('cho.data_final','>=', $data_filtro_oferta);
            });
        })
        ->orWhere(function($query) use($data_oferta_semana){

            $query->where('oferta.tipo', 'S')
            ->where(function($query) use($data_oferta_semana){

                $ultima_oferta_semana = strtotime($data_oferta_semana . "-7 days");
                $ultima_oferta_semana = date('Y-m-d', $ultima_oferta_semana);

                $query->where('oferta.data', '>=', $data_oferta_semana)
                ->orWhere('oferta.data','>=', $ultima_oferta_semana);

            });
        })
        ->whereRaw('cho.deleted_at IS NULL')
        ->where('oferta.agrupamento_produtos', 0)
        ->orderBy('titulo', 'ASC')
        ->orderBy('sub_titulo', 'ASC')->get();

        return $listaOfertas;
    }

    public static function buscarTipoProdutoCanal($canal, $checkEstoque = FALSE){

        $query = TipoDeProduto::select(DB::raw('count(produto.id_tipo_produto) as qtde_tipo_produto, tipo_de_produto.*'))
        ->join('produto','tipo_de_produto.id','=','produto.id_tipo_produto')
        ->join('oferta_has_produto', 'oferta_has_produto.id_produto', '=', 'produto.id')
        ->join('oferta','oferta.id','=','oferta_has_produto.id_oferta')
        ->join('canal_has_oferta', 'canal_has_oferta.id_oferta', '=', 'oferta_has_produto.id_oferta')
        ->where('canal_has_oferta.id_canal', $canal->id)
        ->groupBy('tipo_de_produto.id')
        ->where('canal_has_oferta.data_inicial' , '<=', date('Y-m-d'))
        ->where('canal_has_oferta.data_final' , '>=', date('Y-m-d'))
        ->whereRaw('canal_has_oferta.deleted_at IS NULL');

        if($checkEstoque){
            $query->where('oferta.estoque', '>', 0);
        }

        $listaTipoDeProduto = $query->get();

        return $listaTipoDeProduto;
    }

    public static function buscarPaisesCanal($canal, $checkEstoque = FALSE){

        $query = Pais::select(DB::raw('count(produto.id_pais_origem) as qtde_paises, pais.*'))
        ->join('produto','pais.id','=','produto.id_pais_origem')
        ->join('oferta_has_produto', 'oferta_has_produto.id_produto', '=', 'produto.id')
        ->join('oferta','oferta.id','=','oferta_has_produto.id_oferta')
        ->join('canal_has_oferta', 'canal_has_oferta.id_oferta', '=', 'oferta_has_produto.id_oferta')
        ->where('canal_has_oferta.id_canal', $canal->id)
        ->groupBy('pais.id')
        ->where('canal_has_oferta.data_inicial' , '<=', date('Y-m-d'))
        ->where('canal_has_oferta.data_final' , '>=', date('Y-m-d'))
        ->whereRaw('canal_has_oferta.deleted_at IS NULL');

        if($checkEstoque){
            $query->where('oferta.estoque', '>', 0);
        }

        //Possui uma oferta com 3 produtos. oferta.id = 10132

        $listaPaises = $query->orderBy('pais.nome', 'ASC')->get();

        return $listaPaises;
    }

    public static function buscarRegioesCanal($canal, $pais_id = FALSE){

        $query = Pais::select(DB::raw('count(DISTINCT produto_caracteristica.id_produto) as qtde_produtos, produto_regiao.*'))
        ->join('produto','pais.id','=','produto.id_pais_origem')
        ->join('produto_caracteristica','produto.id','=','produto_caracteristica.id_produto')
        ->join('produto_regiao','produto_regiao.id','=','produto_caracteristica.produto_regiao_id')
        ->join('oferta_has_produto', 'oferta_has_produto.id_produto', '=', 'produto.id')
        ->join('oferta','oferta.id','=','oferta_has_produto.id_oferta')
        ->join('canal_has_oferta', 'canal_has_oferta.id_oferta', '=', 'oferta_has_produto.id_oferta')
        ->where('canal_has_oferta.id_canal', $canal->id)
        ->groupBy('produto_regiao.id')
        ->where('canal_has_oferta.data_inicial' , '<=', date('Y-m-d'))
        ->where('canal_has_oferta.data_final' , '>=', date('Y-m-d'))
        ->whereRaw('canal_has_oferta.deleted_at IS NULL')
        ->where('oferta.estoque', '>', 0);

        if($pais_id){
            $query->where('produto_regiao.pais_id', $pais_id);
        }

        $listaRegioes = $query->get();

        return $listaRegioes;
    }

    public static function buscarRegioesPais($listaRegioes){

        $Regioes = [];

        foreach ($listaRegioes as $regiao) {
            $Regioes[$regiao->pais_id][] = $regiao->id;
        }

        return $Regioes;

    }

    public static function buscarAnosCanal($canal, $checkEstoque = FALSE){

        $query = ProdutoCaracteristica::select(DB::raw('count(produto.id) as qtde_anos, produto_caracteristica.safra'))
        ->join('produto', 'produto_caracteristica.id_produto', '=', 'produto.id')
        ->join('oferta_has_produto', 'oferta_has_produto.id_produto', '=', 'produto.id')
        ->join('oferta','oferta.id','=','oferta_has_produto.id_oferta')
        ->join('canal_has_oferta', 'canal_has_oferta.id_oferta', '=', 'oferta_has_produto.id_oferta')
        ->where('canal_has_oferta.id_canal', $canal->id)
        ->groupBy('produto_caracteristica.safra')
        ->where('canal_has_oferta.data_inicial' , '<=', date('Y-m-d'))
        ->where('canal_has_oferta.data_final' , '>=', date('Y-m-d'))
        ->whereRaw('canal_has_oferta.deleted_at IS NULL');

        if($checkEstoque){
            $query->where('oferta.estoque', '>', 0);
        }
        
        $listaAnos = $query->get();

        return $listaAnos;
    }

    public static function buscarOfertasCanal($canal, $filtros = FALSE, $checkEstoque = FALSE){

        $tempo_reserva = OfertaReserva::dataAtual();

        $query = Oferta::select(
            'oferta.*',
            'tipo_de_produto.nome as nome_tipo_produto', 
            'tipo_de_produto.grupo as grupo_tipo_produto', 
            'tipo_de_produto.thumbnail_principal as thumbnail_tipo_produto', 
            'pais.thumbnail_principal as thumbnail_pais', 'pais.nome as nome_pais',
            'oferta_has_produto.valor_caixa_status as valor_caixa_status',
            'oferta_has_produto.qtd_produtos_caixa',
            DB::raw("(SELECT 1 FROM oferta_reserva WHERE oferta.id = oferta_reserva.oferta_id AND oferta_reserva.data_expiracao >= '{$tempo_reserva}' LIMIT 1) AS 'oferta_reserva'")
        )
        ->join('oferta_has_produto','oferta_has_produto.id_oferta','=','oferta.id')
        ->join('produto','produto.id','=','oferta_has_produto.id_produto')
        ->join('produto_caracteristica','produto.id','=','produto_caracteristica.id_produto')
        ->join('tipo_de_produto','tipo_de_produto.id','=','produto.id_tipo_produto')
        ->leftJoin('pais','pais.id','=','produto.id_pais_origem')
        ->leftJoin('produto_regiao','produto_regiao.id','=','produto_caracteristica.produto_regiao_id')
        ->join('canal_has_oferta','canal_has_oferta.id_oferta','=','oferta.id')
        ->join('canal','canal_has_oferta.id_canal','=','canal.id')
        ->where('canal_has_oferta.data_inicial' , '<=', date('Y-m-d'))
        ->where('canal_has_oferta.data_final' , '>=', date('Y-m-d'))
        ->whereRaw('canal_has_oferta.deleted_at IS NULL')
        ->where('canal.slug',$canal->slug);

        if($filtros){


            if(isset($filtros['removerAcessorios'])){
                $query->whereIn('produto.id_tipo_produto', [3, 9, 4, 7, 8, 5]);
            }   

            //Pesquisa by Texto
            if(isset($filtros['pesquisa'])){
                $query->where(function($q) use($filtros){
                    $q->orwhere('oferta.titulo', 'LIKE', '%' . $filtros['pesquisa'] . '%');
                    $q->orwhere('oferta.sub_titulo', 'LIKE', '%' . $filtros['pesquisa'] . '%');
                });
            }

            //Filtro País
            if(isset($filtros['pais']) && $filtros['pais']){
                if(is_numeric($filtros['pais'])){
                    $query->where('produto.id_pais_origem', $filtros['pais']);
                }else{
                    $query->where('pais.slug', $filtros['pais']);
                }
            }

            //Filtro Região
            if(isset($filtros['regiao']) && $filtros['regiao']){
                if(is_numeric($filtros['regiao'])){
                    $query->where('produto_caracteristica.produto_regiao_id', $filtros['regiao']);
                }else{
                    $query->where('produto_regiao.slug', $filtros['regiao']);
                }
            }

        }

        if($checkEstoque){
            $query->where('oferta.estoque', '>', 0);
        }

        $query->groupBy('oferta.id')
            ->with('produtos.produto.paisDeOrigem','produtos.produto.tipoDeProduto')
            ->orderBy('canal_has_oferta.ordenacao', 'asc');


        if(isset($filtros['limitar'])){
            $listaOfertas = $query->limit(12)->get();
        } else{
            if($canal->tipo == 'BF'){
                $listaOfertas = $query->paginate(15);
            }else{
                $listaOfertas = $query->get();
            }
        }

        return $listaOfertas;
    }

    public static function checkOfertasEsgotadas($listaOfertas, $ofertas_esgotadas = 0){
        foreach ($listaOfertas as $objOferta) {
            if($objOferta->estoque <= 0 && empty($objOferta->oferta_reserva)){ 
                $ofertas_esgotadas++;
            }
        }
        return $ofertas_esgotadas;
    }

    public static function buscarMaxPercentualDescontoCanal($canal, $filtros = FALSE){

        $tempo_reserva = OfertaReserva::dataAtual();

        $query = Oferta::select(
            DB::raw('oferta.percentual_desconto AS percentual_desconto')
        )
        ->join('oferta_has_produto','oferta_has_produto.id_oferta','=','oferta.id')
        ->join('produto','produto.id','=','oferta_has_produto.id_produto')
        ->join('produto_caracteristica','produto.id','=','produto_caracteristica.id_produto')
        ->join('tipo_de_produto','tipo_de_produto.id','=','produto.id_tipo_produto')
        ->leftJoin('pais','pais.id','=','produto.id_pais_origem')
        ->leftJoin('produto_regiao','produto_regiao.id','=','produto_caracteristica.produto_regiao_id')
        ->join('canal_has_oferta','canal_has_oferta.id_oferta','=','oferta.id')
        ->join('canal','canal_has_oferta.id_canal','=','canal.id')
        ->where('canal_has_oferta.data_inicial' , '<=', date('Y-m-d'))
        ->where('canal_has_oferta.data_final' , '>=', date('Y-m-d'))
        ->whereRaw('canal_has_oferta.deleted_at IS NULL')
        ->where('canal.slug',$canal->slug);

        if($filtros){
            if(isset($filtros['pesquisa'])){
                $query->where(function($q) use($filtros){
                    $q->orwhere('oferta.titulo', 'LIKE', '%' . $filtros['pesquisa'] . '%');
                    $q->orwhere('oferta.sub_titulo', 'LIKE', '%' . $filtros['pesquisa'] . '%');
                });
            }
        }

        $query->groupBy('oferta.id')->orderBy('oferta.percentual_desconto', 'desc');

        $oferta = $query->first();

        return $oferta;
    }

    public static function buscarFaixasOfertas($canal, $checkEstoque = FALSE){

        $query = Oferta::select(
            DB::raw("SUM(CASE WHEN oferta.preco_oferta BETWEEN 0 AND 60 THEN 1 ELSE 0 END) AS 'ZERO_SESSENTA',
                    SUM(CASE WHEN oferta.preco_oferta BETWEEN 60 AND 100 THEN 1 ELSE 0 END) AS 'SESSENTA_CEM',
                    SUM(CASE WHEN oferta.preco_oferta BETWEEN 100 AND 200 THEN 1 ELSE 0 END) AS 'CEM_DUZENTOS',
                    SUM(CASE WHEN oferta.preco_oferta BETWEEN 200 AND 500 THEN 1 ELSE 0 END) AS 'DUZENTOS_QUINHENTOS',
                    SUM(CASE WHEN oferta.preco_oferta > 500 THEN 1 ELSE 0 END) AS 'ACIMA'")
        )
        ->join('oferta_has_produto','oferta_has_produto.id_oferta','=','oferta.id')
        ->join('produto','produto.id','=','oferta_has_produto.id_produto')
        ->join('tipo_de_produto','tipo_de_produto.id','=','produto.id_tipo_produto')
        ->join('pais','pais.id','=','produto.id_pais_origem')
        ->join('canal_has_oferta','canal_has_oferta.id_oferta','=','oferta.id')
        ->join('canal','canal_has_oferta.id_canal','=','canal.id')
        ->where('canal_has_oferta.data_inicial' , '<=', date('Y-m-d'))
        ->where('canal_has_oferta.data_final' , '>=', date('Y-m-d'))
        ->whereRaw('canal_has_oferta.deleted_at IS NULL')
        ->where('canal.slug',$canal->slug)
        ->with('produtos.produto.paisDeOrigem','produtos.produto.tipoDeProduto');

        if($checkEstoque){
            $query->where('oferta.estoque', '>', 0);
        }

        $listaFaixas = $query->first();

        return $listaFaixas;

    }

    public static function alteraOrdenacaoOferta($Oferta){

        Log::info("ALTERAR ORDENAÇÃO OFERTA: {$Oferta->estoque}");

        if($Oferta->estoque == 0){

            $canaisOferta = CanalHasOferta::where('id_oferta', $Oferta->id)
                ->where('data_inicial', '<=', date('Y-m-d'))
                ->where('data_final', '>=', date('Y-m-d'))
                ->whereRaw("NOT EXISTS (SELECT 1 FROM oferta_reserva reserva WHERE reserva.oferta_id = canal_has_oferta.id_oferta AND reserva.oferta_id = {$Oferta->id})")
                ->get();

            Log::info("ALTERAR ORDENAÇÃO OFERTA COUNT: " . count($canaisOferta));

            foreach ($canaisOferta as $canalOferta) {
                $canalOferta->ordenacao = 999;
                if(!$canalOferta->save()){
                    Log::info("ALTERAR ORDENAÇÃO OFERTA ERRO");
                }
            }
            
        }

        return true;
    }

    public static function montarDadosFluxoCaixaDre($filtro){

        $sumCase  = [];
        $aliases  = [];
        $meses    = [
            1  => 'jan',
            2  => 'fev',
            3  => 'mar',
            4  => 'abr',
            5  => 'mai',
            6  => 'jun',
            7  => 'jul',
            8  => 'ago',
            9  => 'set',
            10 => 'out',
            11 => 'nov',
            12 => 'dez'
        ];

        if($filtro['periodicidade'] == 'D'){
            $resultStart = explode('-', $filtro['data_inicial']);
            $resultEnd   = explode('-', $filtro['data_final']);
            $diaStart    = $resultStart[2];
            $mesStart    = $resultStart[1];
            $anoStart    = $resultStart[0];
            $diaEnd      = $resultEnd[2];
            $mesEnd      = $resultEnd[1];
            $anoEnd      = $resultEnd[0];
        }elseif($filtro['periodicidade'] == 'Y'){
            $anoStart = $filtro['ano_inicial'];
            $anoEnd   = $filtro['ano_final'];
            $diaStart = 01;
            $diaEnd   = 31;
            $mesStart = 1;
            $mesEnd   = 12;
        }else{
            $resultStart = explode('-', $filtro['mes_inicial']);
            $resultEnd   = explode('-', $filtro['mes_final']);
            $diaStart    = "01";
            $diaEnd      = "01";
            if(count($resultStart) > 1){
                $anoStart = $resultStart[0];
                $anoEnd   = $resultEnd[0];
                $mesStart = $resultStart[1];
                $mesEnd   = $resultEnd[1];
            }else{
                $anoStart = $filtro['ano_inicial'];
                $anoEnd   = $filtro['ano_final'];
                $mesStart = $filtro['mes_inicial'];
                $mesEnd   = $filtro['mes_final'];  
            }
        }

        $ano       = $anoStart;
        $dataStart = "{$ano}-{$mesStart}-{$diaStart}";
        $dataEnd   = ($filtro['periodicidade'] == 'D' ? $filtro['data_final'] : GeralService::retornaData($mesEnd, $anoEnd));
        $mes       = $mesStart;
        $dataSaldo = $dataStart;

        if($mesStart == date('m')){
            $dataSaldo = date('Y-m-d');
        }

        if($filtro['periodicidade'] == 'D'){
            if($mesStart == $mesEnd){
                for($i=$diaStart;$i<=$diaEnd;$i++){
                    $dia       = str_pad($i, 2, "0", STR_PAD_LEFT);
                    $mes       = (int) $mesStart;
                    $alias     = $meses[$mes] . $ano . $dia;
                    $sumCase[] = "SUM(CASE WHEN data = '{$ano}-{$mesStart}-{$dia}' THEN valor ELSE 0 END) AS '{$alias}'";
                    $aliases[] = (object) ['alias' => $alias, 'data' => "{$ano}-{$mesStart}-{$dia}", 'dia' => $dia, 'mes' => $mesStart, 'ano' => $ano];
                }
            }else{
                //MÊS START
                $dataEndStart = GeralService::retornaData($mesStart, $ano);
                $result       = explode("-", $dataEndStart);
                for($i=$diaStart;$i<=$result[2];$i++){
                    $dia       = str_pad($i, 2, "0", STR_PAD_LEFT);
                    $mes       = (int) $mesStart;
                    $alias     = $meses[$mes] . $ano . $dia;
                    $sumCase[] = "SUM(CASE WHEN data = '{$ano}-{$mesStart}-{$dia}' THEN valor ELSE 0 END) AS '{$alias}'";
                    $aliases[] = (object) ['alias' => $alias, 'data' => "{$ano}-{$mesStart}-{$dia}", 'dia' => $dia, 'mes' => $mesStart, 'ano' => $ano];
                }
                //MÊS END
                for($i=1;$i<=$diaEnd;$i++){
                    $dia       = str_pad($i, 2, "0", STR_PAD_LEFT);
                    $mes       = (int) $mesEnd;
                    $alias     = $meses[$mes] . $anoEnd . $dia;
                    $sumCase[] = "SUM(CASE WHEN data = '{$anoEnd}-{$mesEnd}-{$dia}' THEN valor ELSE 0 END) AS '{$alias}'";
                    $aliases[] = (object) ['alias' => $alias, 'data' => "{$anoEnd}-{$mesEnd}-{$dia}", 'dia' => $dia, 'mes' => $mesEnd, 'ano' => $anoEnd];
                }
            }
        }elseif($filtro['periodicidade'] == 'Y'){
            for($i=$anoStart;$i<=$anoEnd;$i++){
                $alias     = $i;
                $sumCase[] = "SUM(CASE WHEN YEAR(data) = {$i} THEN valor ELSE 0 END) AS '{$alias}'";
                $aliases[] = (object) ['alias' => $alias, 'data' => "{$i}-01-01", 'dia' => 1, 'mes' => 1, 'ano' => $i];
            }
        }else{
            if($ano == $anoEnd){
                for($i=$mesStart;$i<=$mesEnd;$i++){
                    $i         = (int) $i;
                    $mes       = str_pad($i, 2, "0", STR_PAD_LEFT);
                    $alias     = $meses[$i] . $ano;
                    if(isset($filtro['dre'])){
                        $data_fim    = GeralService::retornaData($i, $ano);
                        $sumCase[] = "SUM(CASE WHEN data BETWEEN '{$ano}-{$mes}-01' AND '{$data_fim}' THEN valor ELSE 0 END) AS '{$alias}'";
                    }else{
                        $sumCase[] = "SUM(CASE WHEN data = '{$ano}-{$mes}-01' THEN valor ELSE 0 END) AS '{$alias}'";
                    }
                    $aliases[] = (object) ['alias' => $alias, 'data' => "{$ano}-{$mes}-01", 'mes' => $mes, 'ano' => $ano];
                }
            }else{

                //ANO START
                for($i=$mesStart;$i<=12;$i++){
                    $i         = (int) $i;
                    $mes       = str_pad($i, 2, "0", STR_PAD_LEFT);
                    $alias     = $meses[$i] . $ano;
                    if(isset($filtro['dre'])){
                        $data_fim  = GeralService::retornaData($i, $ano);
                        $sumCase[] = "SUM(CASE WHEN data BETWEEN '{$ano}-{$mes}-01' AND '{$data_fim}' THEN valor ELSE 0 END) AS '{$alias}'";
                    }else{
                        $sumCase[] = "SUM(CASE WHEN data = '{$ano}-{$mes}-01' THEN valor ELSE 0 END) AS '{$alias}'";
                    }
                    $aliases[] = (object) ['alias' => $alias, 'data' => "{$ano}-{$mes}-01", 'mes' => $mes, 'ano' => $ano];
                }

                //ANO END
                for($i=1;$i<=$mesEnd;$i++){
                    $i         = (int) $i;
                    $mes       = str_pad($i, 2, "0", STR_PAD_LEFT);
                    $alias     = $meses[$i] . $anoEnd;
                    if(isset($filtro['dre'])){
                        $data_fim  = GeralService::retornaData($i, $anoEnd);
                        $sumCase[] = "SUM(CASE WHEN data BETWEEN '{$anoEnd}-{$mes}-01' AND '{$data_fim}' THEN valor ELSE 0 END) AS '{$alias}'";
                    }else{
                        $sumCase[] = "SUM(CASE WHEN data = '{$anoEnd}-{$mes}-01' THEN valor ELSE 0 END) AS '{$alias}'";
                    }
                    $aliases[] = (object) ['alias' => $alias, 'data' => "{$anoEnd}-{$mes}-01", 'mes' => $mes, 'ano' => $anoEnd];
                }

            }
        }

        $resultado            = new \stdClass();
        $resultado->aliases   = $aliases;
        $resultado->sumCase   = $sumCase;
        $resultado->dataStart = $dataStart;
        $resultado->dataEnd   = $dataEnd;
        $resultado->dataSaldo = $dataSaldo;
        $resultado->mesStart  = $mesStart;
        $resultado->mesEnd    = $mesEnd;
        $resultado->meses     = $meses;
        $resultado->ano       = $ano;
        $resultado->anoStart  = $anoStart;
        $resultado->anoEnd    = $anoEnd;

        return $resultado;
    }

    public static function buscarLancamentosPeriodoDre($sumCase, $dataStart, $dataEnd, $filtro, $aliases){

        $totais      = [];
        $lancamentos = [];

        $query = ContaFinanceiraLancamento::select(
            DB::raw(implode(",", $sumCase)),
            'id_plano_financeiro_conta',
            'plano_financeiro_conta.receita_despesa'
        )
        ->join('plano_financeiro_conta','plano_financeiro_conta.id','=','id_plano_financeiro_conta')
        ->whereBetween('data', [$dataStart, $dataEnd])
        ->where('plano_financeiro_conta.id_plano_financeiro', $filtro['id_plano_financeiro'])
        ->where('plano_financeiro_conta.desconsiderar_dre', 'N');

        if(isset($filtro['empresa_id']) && is_numeric($filtro['empresa_id'])){
            $query->where('id_empresa', $filtro['empresa_id']);
        }

        if(isset($filtro['unidade_negocio_id']) && is_numeric($filtro['unidade_negocio_id'])){
            $query->where('unidade_negocio_id', $filtro['unidade_negocio_id']);
        }

        if(isset($filtro['tipo_id']) && is_numeric($filtro['tipo_id'])){
            $query->where('conta_financeira_lancamento.id_conta_receber_tipo', $filtro['tipo_id']);
        }

        $lancamentosContas = $query->groupBy('id_plano_financeiro_conta')
                                    ->groupBy('plano_financeiro_conta.receita_despesa')
                                    ->get();

        //Lançamentos e Totais
        foreach ($lancamentosContas as $Lancamento) {
            
            $totalLancamento = 0;

            foreach ($aliases as $alias) {

                $alias           = $alias->alias;
                $totalLancamento += $Lancamento->$alias;

                $rc    = ($Lancamento->receita_despesa == 'D' ? 'despesas' : 'receitas');
                if(!isset($totais[$rc][$alias])){
                    $totais[$rc][$alias] = $Lancamento->$alias;
                    continue;
                }
                $totais[$rc][$alias] += $Lancamento->$alias;
            }

            if($totalLancamento > 0){
                $lancamentos[$Lancamento->id_plano_financeiro_conta] = $Lancamento;
            }

        }

        $resultado              = new \stdClass();
        $resultado->totais      = $totais;
        $resultado->lancamentos = $lancamentos;

        return $resultado;
    }

    public static function buscarLancamentosPeriodo($sumCase, $dataStart, $dataEnd, $filtro, $aliases){

        $totais      = [];
        $lancamentos = [];

        $query = PlanoFinanceiroLancamento::select(
            DB::raw(implode(",", $sumCase)),
            'id_plano_financeiro_conta',
            'plano_financeiro_conta.receita_despesa'
        )
        ->join('plano_financeiro_conta','plano_financeiro_conta.id','=','id_plano_financeiro_conta')
        ->whereBetween('data', [$dataStart, $dataEnd])
        ->where('plano_financeiro_conta.id_plano_financeiro', $filtro['id_plano_financeiro']);

        if($filtro['periodicidade'] != 'Y'){
            $query->where('periodicidade', $filtro['periodicidade']);
        }

        if(is_numeric($filtro['empresa_id'])){
            $query->where('id_empresa', $filtro['empresa_id']);
        }

        $lancamentosContas = $query->groupBy('id_plano_financeiro_conta')
                                    ->groupBy('plano_financeiro_conta.receita_despesa')
                                    ->get();

        //Lançamentos e Totais
        foreach ($lancamentosContas as $Lancamento) {
            
            $totalLancamento = 0;

            foreach ($aliases as $alias) {

                $alias           = $alias->alias;
                $totalLancamento += $Lancamento->$alias;

                $rc    = ($Lancamento->receita_despesa == 'D' ? 'despesas' : 'receitas');
                if(!isset($totais[$rc][$alias])){
                    $totais[$rc][$alias] = $Lancamento->$alias;
                    continue;
                }
                $totais[$rc][$alias] += $Lancamento->$alias;
            }

            if($totalLancamento > 0){
                $lancamentos[$Lancamento->id_plano_financeiro_conta] = $Lancamento;
            }

        }

        $resultado              = new \stdClass();
        $resultado->totais      = $totais;
        $resultado->lancamentos = $lancamentos;

        return $resultado;
    }

    public static function atualizarEstoqueOfertasProduto($produto_id){

        $Produto = Produto::where('id', $produto_id)->first();

        if(count($Produto->ofertas) > 0){
            foreach ($Produto->ofertas as $item) {

                $Oferta    = $item->oferta;
                $dataAtual = date('Y-m-d');

                $data_fim_oferta_semana = date('Y-m-d', strtotime("+6 days",strtotime($Oferta->data)));
                $data_fim_data_atual    = date('Y-m-d', strtotime("+6 days",strtotime($dataAtual)));

                Log::info("Oferta: {$Oferta->id} | Data Atual: {$dataAtual} | Data Fim Atual: {$data_fim_data_atual} | Data Fim Oferta Semana: {$data_fim_oferta_semana}");

                if($Oferta->tipo == 'C'){
                    continue;
                }elseif(($Oferta->tipo == 'D' || $Oferta->tipo == 'E') && date('Y-m-d') <= $Oferta->data){
                    continue;
                }elseif($Oferta->tipo == 'S' && $dataAtual <= $data_fim_oferta_semana){
                    continue;
                }

                $Oferta->estoque = 0;
                $Oferta->qtde_vendida = 0;
                $Oferta->save();
            }
        }

        return true;

    }

    public static function zerarEstoqueOfertasProduto($produto_id){

        $Produto = Produto::where('id', $produto_id)->first();

        if(count($Produto->ofertas) > 0){
            foreach ($Produto->ofertas as $item) {

                $Oferta = $item->oferta;

                $Oferta->estoque = 0;
                $Oferta->save();
            }
        }

        return true;

    }

    public static function buscarVariacoesProduto($produto){

        $variacoes = [];
        
        if(isset($produto->tipo->variacoes)){

            foreach ($produto->tipo->variacoes as $variacao) {
                foreach ($variacao->atributos as $atributo) {
                    $object = (object) ['id' => $atributo->id, 'nome' => $atributo->nome];
                    $variacoes[$variacao->slug][] = $object;
                }
            }

        }

        return $variacoes;

    }

    public static function monitoramentoAjustarEstoqueOfertas($id_canal, $ofertas = []){

        /*$query = PedidoVenda::select(DB::raw("
                            SUM(pvhp.quantidade) qtde_vendida,
                            cho.quantidade,
                            ohp.id_oferta,
                            oferta.estoque,
                            cho.id_canal,
                            cho.ordenacao,
                            (SELECT SUM(quantidade) FROM oferta_reserva r WHERE r.oferta_id = oferta.id) 'reserva',
                            CONCAT(oferta.titulo, ' ', oferta.sub_titulo) 'nome_oferta',
                            cho.quantidade - (SUM(pvhp.quantidade) + oferta.estoque) 'diferenca'"
                        ))
                    ->join('pedido_venda_has_produto AS pvhp', 'pvhp.id_pedido_venda', '=', 'pedido_venda.id')
                    ->join('oferta_has_produto as ohp', function($q)
                    {
                        $q->on('pvhp.id_oferta', 'ohp.id_oferta')->on('ohp.id_produto', 'pvhp.id_produto');
                    })
                    ->join('oferta', 'oferta.id', '=', 'ohp.id_oferta')
                    ->join('canal_has_oferta AS cho', 'cho.id_oferta', '=', 'oferta.id')
                    ->join('canal', 'canal.id', '=', 'cho.id_canal')
                    ->where('cho.id_canal', $id_canal)
                    ->whereRaw("CONCAT(oferta.titulo, ' ', oferta.sub_titulo) NOT LIKE '%Coleção%'");*/

        $query = PedidoVenda::select(DB::raw("
                            SUM(pvho.quantidade) qtde_vendida, 
                            cho.quantidade, 
                            pvho.oferta_id id_oferta, 
                            oferta.estoque, 
                            cho.id_canal, 
                            cho.ordenacao,
                            (SELECT SUM(quantidade) FROM oferta_reserva r WHERE r.oferta_id = oferta.id) 'reserva', 
                            CONCAT(oferta.titulo, ' ', oferta.sub_titulo) 'nome_oferta',
                            cho.quantidade - (SUM(pvho.quantidade) + oferta.estoque) 'diferenca'"
                        ))
                    ->join('pedido_venda_has_oferta AS pvho', 'pvho.pedido_venda_id', '=', 'pedido_venda.id')
                    ->join('oferta', 'oferta.id', '=', 'pvho.oferta_id')
                    ->join('canal_has_oferta AS cho', 'cho.id_oferta', '=', 'oferta.id')
                    ->join('canal', 'canal.id', '=', 'cho.id_canal')
                    ->where('cho.id_canal', $id_canal);

        if(count($ofertas) > 0){
            $query->whereIn('pvho.oferta_id', $ofertas);
        }

        $listaOfertas = $query->groupBy('pvho.oferta_id')
                    ->orderBy('diferenca', 'ASC')
                    ->get();

        foreach ($listaOfertas as $oferta) {
            
            $id_oferta = $oferta->id_oferta;

            $reserva   = !empty($oferta->reserva) ? $oferta->reserva : 0;
            $diferenca = $oferta->quantidade - ($oferta->qtde_vendida + $reserva + $oferta->estoque);
            $estoque   = $oferta->estoque;

            $reservas = OfertaReserva::select('id', 'quantidade')->where('oferta_id', $id_oferta)->orderBy('id', 'DESC')->get();

            if($diferenca == 0){

                if($oferta->estoque == 0 && count($reservas) == 0 && $oferta->ordenacao <> 999){
                    $sqlCanalHasOferta = "UPDATE canal_has_oferta SET ordenacao=999 WHERE deleted_at IS NULL AND id_oferta={$id_oferta} AND id_canal={$id_canal}";
                    DB::update($sqlCanalHasOferta);
                }

                continue;

            }elseif($diferenca < 0){
                if($oferta->estoque == 0){
                    $estoque = 0;
                }else{
                    $estoque = ($oferta->estoque) - abs($diferenca);
                    if($estoque < 0){
                        $estoque = 0;
                    }
                }
            }elseif($diferenca > 0){
                $estoque = $oferta->estoque + $diferenca;
            }

            $diferenca_reserva = $reserva - abs($oferta->quantidade - $oferta->qtde_vendida);

            if($oferta->qtde_vendida >= $oferta->quantidade){
                DB::table('oferta_reserva')->where('oferta_id', '=', $id_oferta)->delete();
            }elseif($diferenca_reserva > 0){
                $quantidade = 0;
                foreach ($reservas as $reserva) {
                    $quantidade += $reserva->quantidade;
                    DB::table('oferta_reserva')->where('id', '=', $reserva->id)->delete();
                    if($quantidade >= $diferenca_reserva){
                        break;
                    }
                }
            }

            $sqlOferta = "UPDATE oferta SET estoque={$estoque} WHERE id={$id_oferta}";
            Log::info($sqlOferta);
            DB::update($sqlOferta);

            $sqlCanalHasOferta = "UPDATE canal_has_oferta SET disponibilidade_canal={$estoque} WHERE deleted_at IS NULL AND id_oferta={$id_oferta} AND id_canal={$id_canal}";
            Log::info($sqlCanalHasOferta);
            DB::update($sqlCanalHasOferta);

            $CanalHasOferta = CanalHasOferta::where('id_oferta', $id_oferta)->where('id_canal', $id_canal)->whereRaw('deleted_at IS NULL')->first();
            GeralService::logCanalHasOferta($CanalHasOferta);

            $reservas = OfertaReserva::select('id')->where('oferta_id', $id_oferta)->orderBy('id', 'DESC')->get();

            if($estoque == 0 && count($reservas) == 0 && $oferta->ordenacao <> 999){
                $sqlCanalHasOferta = "UPDATE canal_has_oferta SET ordenacao=999 WHERE deleted_at IS NULL AND id_oferta={$id_oferta} AND id_canal={$id_canal}";
                DB::update($sqlCanalHasOferta);
            }
            
        }

        //AJUSTA ORDENAÇÃO OFERTAS DISPONÍVEIS
        $query = CanalHasOferta::where('id_canal', $id_canal)->where('ordenacao', 999)->where('disponibilidade_canal', '>', 0);

        if(count($ofertas) > 0){
            $query->whereIn('canal_has_oferta.id_oferta', $ofertas);
        }

        $listaOfertas = $query->get();

        foreach ($listaOfertas as $ofertaCanal) {
            $sqlCanalHasOferta = "UPDATE canal_has_oferta SET ordenacao={$ofertaCanal->ordenacao_original} WHERE deleted_at IS NULL AND id_oferta={$ofertaCanal->id_oferta} AND id_canal={$ofertaCanal->id_canal}";
            DB::update($sqlCanalHasOferta);
        }

        //ATUALIZA ORDENAÇÃO OFERTAS EM RESERVA COM ORDENAÇÃO 999
        $tempo_reserva = OfertaReserva::dataAtual();

        $query = Oferta::select(
            'oferta.id', 'canal_has_oferta.ordenacao_original', 'canal_has_oferta.ordenacao',
            DB::raw("(SELECT 1 FROM oferta_reserva WHERE oferta.id = oferta_reserva.oferta_id AND oferta_reserva.data_expiracao >= '{$tempo_reserva}' LIMIT 1) AS 'oferta_reserva'")
        )
        ->join('oferta_has_produto','oferta_has_produto.id_oferta','=','oferta.id')
        ->join('produto','produto.id','=','oferta_has_produto.id_produto')
        ->join('tipo_de_produto','tipo_de_produto.id','=','produto.id_tipo_produto')
        ->leftJoin('pais','pais.id','=','produto.id_pais_origem')
        ->join('canal_has_oferta','canal_has_oferta.id_oferta','=','oferta.id')
        ->join('canal','canal_has_oferta.id_canal','=','canal.id')
        ->where('canal_has_oferta.data_inicial' , '<=', date('Y-m-d'))
        ->where('canal_has_oferta.data_final' , '>=', date('Y-m-d'))
        ->whereRaw('canal_has_oferta.deleted_at IS NULL')
        ->havingRaw('oferta_reserva IS NOT NULL AND ordenacao = 999')
        ->where('canal.id', $id_canal);

        if(count($ofertas) > 0){
            $query->whereIn('canal_has_oferta.id_oferta', $ofertas);
        }

        $query->groupBy('oferta.id')->orderBy('canal_has_oferta.ordenacao_original', 'asc');
        
        $listaOfertas = $query->get();

        foreach ($listaOfertas as $oferta) {
            $sqlCanalHasOferta = "UPDATE canal_has_oferta SET ordenacao={$oferta->ordenacao_original} WHERE deleted_at IS NULL AND id_oferta={$oferta->id} AND id_canal={$id_canal}";
            DB::update($sqlCanalHasOferta);
        }

        return true;

    }

    public static function buscarListaCanais($exibir_bloco_home=FALSE){
        $dataAtual   = date('Y-m-d H:i');
        $query = Canal::where('data_inicio', '<=', $dataAtual)->where('data_fim', '>=', $dataAtual)->where('tipo', '<>', 'IN')->where('ativar_url', 0);
        if($exibir_bloco_home){
            $query->where('exibir_bloco_home', 1);
        }
        $listaCanais = $query->orderBy('nome')->get();
        return $listaCanais;
    }

    public static function tipoCanal($tipo){
        return tipo_canal($tipo);
    }

    public static function checkCanal($slug, $post = []){

        $check = new \stdClass;
        $check->status = false;

        $dataAtual = date('Y-m-d H:i');
        $canal     = Canal::where('data_inicio', '<=', $dataAtual)->where('data_fim', '>=', $dataAtual)->where('slug', $slug)->first();

        //CANAL INEXISTENTE OU FORA DA VALIDADE
        if(!$canal){ 
            return $check;
        }

        //CHECK CANAL AUTENTICADO X CLIENTE LOGADO
        $clienteLogado          = FALSE;
        $CanalAcessoAutenticado = FALSE;
        if($canal->acesso_autenticado){
            $clienteLogado = GeralService::buscarClienteLogado();
            if($clienteLogado){
                $CanalAcessoAutenticado = CanalAcessoAutenticado::select('id', 'habilitado')->where('cadastro_id', $clienteLogado->id)->where('canal_id_acesso_autenticado', $canal->id)->first();
                if(!$CanalAcessoAutenticado || ($CanalAcessoAutenticado && $CanalAcessoAutenticado->habilitado != 1)){
                    $CanalAcessoAutenticado = FALSE;
                }
            }else{
                $clienteLogado = FALSE;
            }
        }

        //CANAL ACESSO AUTENTICADO MAS CLIENTE SEM AUTORIZAÇÃO
        if($canal->acesso_autenticado && ($clienteLogado == FALSE || $CanalAcessoAutenticado == FALSE)){
            if($clienteLogado == FALSE){
                $query_string    = http_build_query($post);
                $redirect        = url('/' . GeralService::tipoCanal($canal->tipo) . '/' . $canal->slug . (!empty($query_string) ? "?{$query_string}" : ""));
                $check->redirect = url('login?redirect='.$redirect);
            }else{
                $check->redirect = url('/preparando-ofertas/' . $canal->slug);
            }
            return $check;
        }

        //CANAL ACESSO AUTENTICADO, CLIENTE AUTORIZADO, MAS SEM A CHAVE
        //TRATAR PARA LIBERAR FUNCIONAMENTO 6 HS ANTES - SOMENTE PESSOAL AUTORIZADO
        /*if($canal->acesso_autenticado && $CanalAcessoAutenticado && $CanalAcessoAutenticado->habilitado != 1){
            $check->redirect = url('/preparando-ofertas/' . $canal->slug);
            return $check;
        }*/

        if($canal && $canal->ativar_url && !empty($canal->senha_acesso)){
            $senha_acesso = isset($post['key']) ? $post['key'] : '';
            if($senha_acesso != $canal->senha_acesso){
                return $check;
            }
        }

        $check->status = true;
        $check->canal = $canal;

        return $check;

    }

    public static function checkCanalBlackFriday(){

        $dataAtual = date('Y-m-d H:i');
        $canal     = Canal::where('data_inicio', '<=', $dataAtual)->where('data_fim', '>=', $dataAtual)->where('tipo', 'BF')->first();

        if(!$canal){
            return false;
        }elseif($canal && $canal->ativar_url && !empty($canal->senha_acesso)){
            $senha_acesso = isset($post['key']) ? $post['key'] : '';
            if($senha_acesso != $canal->senha_acesso){
                return false;
            }
        }

        return $canal;

    }

    public static function buscarVinumWear($post){

        $dataAtual = date('Y-m-d H:i');
        $check     = GeralService::checkCanal('vinum-wear', $post);

        if(!$check->status){
            return false;
        }

        $canal = $check->canal;

        $resultado = new \stdClass;
        $resultado->url = url(GeralService::tipoCanal($canal->tipo).'/'.$canal->slug);

        $listaOfertas = GeralService::buscarOfertasCanal($canal);
        $ofertas      = [];
        foreach ($listaOfertas as $oferta) {
            $ofertas[] = (object) [
                'id'                  => $oferta->id,
                'thumbnail_principal' => $oferta->thumbnail_principal,
                'slug'                => $oferta->slug,
                'titulo'              => $oferta->titulo,
                'sub_titulo'          => $oferta->sub_titulo,
                'preco_mercado'       => $oferta->preco_mercado,
                'preco_oferta'        => $oferta->preco_oferta,
                'percentual_desconto' => $oferta->percentual_desconto
            ];
        }

        $resultado->ofertas = $ofertas;

        return $resultado;
    }

    public static function buscarOfertas($filtro)
    {
        try {
            $queryOferta = Oferta::whereBetween('data', [$filtro['data_inicio'], $filtro['data_fim']]);
            //TIPO
            if(isset($filtro['tipo'])){
                $queryOferta->where('tipo', '=', $filtro['tipo']);
            }
            /*
            if (isset($filtro['users'])) {
                $queryOferta->whereIn('user_id',$filtro['users']);
            }
            */

            $listaOfertas = $queryOferta->get();

            return $listaOfertas;
        } catch (\Exception $e) {
            print_r($e->getMessage());
            return false;
        }
    }

    public static function buscarDashToCalendar($filtro)
    {
        $listaEventos = [];
        $listaOfertas = GeralService::buscarOfertas($filtro);
        $datas        = [];
        $cont         = 1;
        $lastDay      = date('Y-m-d');

        foreach ($listaOfertas as $oferta) {
            if($cont == 1){
                $startDay = $oferta->data;
            }elseif($cont == count($listaOfertas)){
                $lastDay  = $oferta->data;
            }
            $key         = str_replace("-", "_", $oferta->data);
            $datas[$key] = $oferta->data;
            $cont++;
        }

        $entregasDia       = DashService::entregasSolicitadasDia($datas, $startDay, $lastDay);
        $statusDashboard   = DashService::statusDashboard($datas, $startDay, $lastDay);
        //Oferta do Dia
        $quantidadeVendida = DashService::quantidadeVendidaDia($datas, $startDay, $lastDay);
        $estoqueOferta     = DashService::estoqueOfertaDia($datas, $startDay, $lastDay);
        $entregaOferta     = DashService::entregaOfertaDia($datas, $startDay, $lastDay);

        $status_dashboard = [
            3 => 'preparando_envio',
            4 => 'faturado',
            5 => 'enviado',
            6 => 'entregue',
            8 => 'pronto_para_envio'
        ];

        foreach($listaOfertas as $oferta){

            $key = str_replace("-", "_", $oferta->data);

            $status_dash = '';
            $status_dash_value = 0;
            foreach ($status_dashboard as $status => $value) {
                if(isset($statusDashboard[$status][$key]) && $statusDashboard[$status][$key] > $status_dash_value){
                    $status_dash       = $status_dashboard[$status];
                    $status_dash_value = $statusDashboard[$status][$key];
                }
            }

            $evento                       = [];
            $evento['title']              = $oferta->titulo;
            $evento['start']              = $oferta->data;
            $evento['end']                = $oferta->data;
            $evento['allDay']             = 'true';
            $evento['subtitulo']          = $oferta->sub_titulo;
            $evento['slug']               = $oferta->slug;
            $evento['preco_inicial']      = number_format($oferta->preco_mercado,2,',','.');
            $evento['preco_total']        = number_format($oferta->preco_oferta,2,',','.');
            $evento['estoque']            = $oferta->estoque ? $oferta->estoque : 0;
            $evento['entregas_dia']       = (isset($entregasDia[$key]) ? (int) $entregasDia[$key] : '');
            $evento['preparando_envio']   = (isset($statusDashboard[3][$key]) ? (int) $statusDashboard[3][$key] : '');
            $evento['faturado']           = (isset($statusDashboard[4][$key]) ? (int) $statusDashboard[4][$key] : '');
            $evento['enviado']            = (isset($statusDashboard[5][$key]) ? (int) $statusDashboard[5][$key] : '');
            $evento['entregue']           = (isset($statusDashboard[6][$key]) ? (int) $statusDashboard[6][$key] : '');
            $evento['status_dash']        = $status_dash;
            $evento['pronto_para_envio']  = (isset($statusDashboard[8][$key]) ? (int) $statusDashboard[8][$key] : '');
            $evento['oferta_dia_venda']   = (isset($quantidadeVendida[$key]) ? (int) $quantidadeVendida[$key] : '');
            $evento['oferta_dia_estoque'] = (isset($estoqueOferta[$key]) ? (int) $estoqueOferta[$key] : '');
            $evento['oferta_dia_entrega'] = (isset($entregaOferta[$key]) ? (int) $entregaOferta[$key] : '');

            $listaEventos[] = $evento;
        }

        return $listaEventos;

    }

    public static function buscarOfertasToCalendar($filtro)
    {
        $listaEventos = array();
        $listaOfertas = GeralService::buscarOfertas($filtro);

        foreach($listaOfertas as $oferta){
            $evento = array();
            $evento['title'] = $oferta->titulo;
            $evento['start'] = $oferta->data;
            $evento['end'] = $oferta->data;
            $evento['allDay']  = 'true';
            $evento['subtitulo'] = $oferta->sub_titulo;
            $evento['slug'] = $oferta->slug;
            $evento['preco_inicial'] = number_format($oferta->preco_mercado,2,',','.');
            $evento['preco_total'] = number_format($oferta->preco_oferta,2,',','.');
            $evento['estoque'] = $oferta->estoque ? $oferta->estoque : 0;
            $evento['imagem'] = $oferta->thumbnail_principal;

            /*
            className: "compromisso-event event-user-<?php echo $evento->getIdUser()->getIdUser(); ?>",
            color:colors["<?php echo $evento->getIdUser()->getIdUser(); ?>"],
            dataIdUser: "<?php echo $evento->getIdUser()->getIdUser(); ?>",
            id: "compromisso-<?php echo $evento->getIdCompromisso(); ?>",
            dataId: "<?php echo $evento->getIdCompromisso(); ?>",
            dataType: "compromisso",
            */
            $listaEventos[] = $evento;
        }

        return $listaEventos;

    }

    public static function buscarEmpresasIntegracao(){
        $empresas = Empresa::whereRaw("api_key_tiny_erp <> ''")->get();
        return $empresas;
    }

    public static function buscarClienteLogado(){
        $user = Sentinel::getUser();

        if(!$user) return null;

        $cliente = Cadastro::where('user_id', $user->id)->with('user')->with('confraria.config')->first();

        return $cliente;
    }

    public static function configMenuLateral(){
        $data = [];
        $data['exibeRetrospectiva'] = GeralService::exibeRetrospectiva();
        $data['info']               = \App\BasicInfo::find(1);
        $anoEdicao = 2022;
        $adegaViradaInfo = AdegaViradaService::buscarAdegaVirada($anoEdicao, TRUE);
        $data['exibeAdegaVirada'] = ($adegaViradaInfo && $adegaViradaInfo->ativo && date('Y-m-d H:i:s') >= $adegaViradaInfo->data_ativacao);
        return (object)$data;
    }

    public static function exibeAdegaVirada($anoEdicao=2022){
        $adegaViradaInfo  = AdegaViradaService::buscarAdegaVirada($anoEdicao);
        $exibeAdegaVirada = ($adegaViradaInfo && $adegaViradaInfo->ativo && date('Y-m-d H:i:s') >= $adegaViradaInfo->data_ativacao);
        if($exibeAdegaVirada){
            return $adegaViradaInfo;
        }
        return $exibeAdegaVirada;
    }   

    public static function validarOfertaAdegaVirada($oferta){

        $valido_adega_virada = false;
        $exibeAdegaVirada    = GeralService::exibeAdegaVirada();

        if($exibeAdegaVirada && isset($oferta) && isset($oferta->id)){
            $teor = OfertaService::getTeorAlcoolico($oferta->id);
            
            if($teor && $teor <= 13)
                $valido_adega_virada = true;
        }
        
        return $valido_adega_virada;
    }

    public static function exibeRetrospectiva(){

        if(env('APP_ENV') == 'production' && date('YmdHi') < '202207101500'){
            return false;
        }

        $cliente = GeralService::buscarClienteLogado();
        if(!$cliente){
            return false;
        }

        $Pedidos = PedidoVenda::where('id_cliente', $cliente->id)->whereRaw('pedido_venda.confraria_id IS NULL')->count();
        $Consumo = CadastroConsumo::where('cadastro_id', $cliente->id)->count();

        if($Pedidos == 0 || $Consumo == 0){
            return false;
        }

        return true;
    }

    public static function cleanString($texto)
    {
        $aFind = array('&','á','à','ã','â','é','ê','í','ó','ô','õ','ú','ü','ç','Á','À','Ã','Â','É','Ê','Í','Ó','Ô','Õ','Ú','Ü','Ç');
        $aSubs = array('e','a','a','a','a','e','e','i','o','o','o','u','u','c','A','A','A','A','E','E','I','O','O','O','U','U','C');
        $novoTexto = str_replace($aFind, $aSubs, $texto);
        $novoTexto = preg_replace("/[^a-zA-Z0-9 @,-.;_\/]/", "", $novoTexto);
        return $novoTexto;
    }

    public static function atualizarSaldoProduto($produto, $data_ultima_atualizacao = ''){

        $data_ultima_atualizacao = (!empty($data_ultima_atualizacao) ? $data_ultima_atualizacao : date('Y-m-d H:i:s'));

        $estoqueerp = ErpService::getEstoqueProduto($produto);

        if($produto->estoque){
            foreach ($produto->estoque as $Estoque){
                if(isset($estoqueerp['saldos'][$Estoque->empresa->sigla])){
                    $Estoque->quantidade = $estoqueerp['saldos'][$Estoque->empresa->sigla];
                    $Estoque->data_ultima_atualizacao = $data_ultima_atualizacao;
                    $Estoque->save();
                }
            }
        }

        $logs = [];
        $log  = [
            'produto_id'              => $produto->id,
            'data_ultima_atualizacao' => $data_ultima_atualizacao,
            'observacao'              => json_encode($estoqueerp['log_empresas'])
        ];
        
        //Registra Disponibilidade no Produto
        if(count($estoqueerp['saldos']) > 0){
            $userLogado = Sentinel::getUser();

            $produto->disponibilidade          = $estoqueerp['disponibilidade'];
            $produto->reserva                  = $estoqueerp['reserva'];
            $produto->qtd_adega                = $estoqueerp['adega'];
            $produto->qtd_em_processamento     = $estoqueerp['em_processamento'];
            $produto->ultima_atualizacao_saldo = $data_ultima_atualizacao;
            $produto->save();

            $log = array_merge($log, [
                'quantidade_empresa' => json_encode($estoqueerp['saldos']),
                'estoque'            => $estoqueerp['estoque'],
                'adega'              => $estoqueerp['adega'],
                'em_processamento'   => $estoqueerp['em_processamento'],
                'disponibilidade'    => $estoqueerp['disponibilidade'],
                'reserva'            => $estoqueerp['reserva'],
                'status'             => 1,
                // 'user_id'            => $userLogado ? $userLogado->id : 1,
            ]);

        }else{
            $log = array_merge($log, ['status' => 0]);
        }

        $logs[] = $log;
        EstoqueLog::insert($logs);

        $saldoProduto = new \stdClass;
        $saldoProduto->estoque = $estoqueerp;
        $saldoProduto->produto = $produto;

        return $saldoProduto;
        
    }

    //CALCULANDO DIAS NORMAIS
    /*Abaixo vamos calcular a diferença entre duas datas. Fazemos uma reversão da maior sobre a menor 
    para não termos um resultado negativo. */
    public static function calculaDias($xDataInicial, $xDataFinal){
       $time1 = GeralService::dataToTimestamp($xDataInicial);
       $time2 = GeralService::dataToTimestamp($xDataFinal);

       $tMaior = $time1>$time2 ? $time1 : $time2;  
       $tMenor = $time1<$time2 ? $time1 : $time2;  

       $diff    = $tMaior-$tMenor;  
       $numDias = $diff/86400; //86400 é o número de segundos que 1 dia possui  
       return $numDias;
    }

    //LISTA DE FERIADOS NO ANO
    /*Abaixo criamos um array para registrar todos os feriados existentes durante o ano.*/
    public static function feriados($ano,$posicao){
       $dia = 86400;
       $datas = array();
       $datas['pascoa'] = easter_date($ano);
       $datas['sexta_santa'] = $datas['pascoa'] - (2 * $dia);
       $datas['carnaval'] = $datas['pascoa'] - (47 * $dia);
       $datas['corpus_cristi'] = $datas['pascoa'] + (60 * $dia);
       $feriados = array (
          '01/01',
          '02/02', // Navegantes
          date('d/m',$datas['carnaval']),
          date('d/m',$datas['sexta_santa']),
          date('d/m',$datas['pascoa']),
          '21/04',
          '01/05',
          date('d/m',$datas['corpus_cristi']),
          '20/09', // Revolução Farroupilha \m/
          '12/10',
          '02/11',
          '15/11',
          '25/12',
       );
       
    return $feriados[$posicao]."/".$ano;
    }      

    //FORMATA COMO TIMESTAMP
    /*Esta função é bem simples, e foi criada somente para nos ajudar a formatar a data já em formato  TimeStamp facilitando nossa soma de dias para uma data qualquer.*/
    public static function dataToTimestamp($data){
        $ano = substr($data, 6,4);
        $mes = substr($data, 3,2);
        $dia = substr($data, 0,2);
        return mktime(0, 0, 0, $mes, $dia, $ano);  
    }

    //SOMA 01 DIA   
    public static function soma1dia($data){   
       $ano = substr($data, 6,4);
       $mes = substr($data, 3,2);
       $dia = substr($data, 0,2);
        return   date("d/m/Y", mktime(0, 0, 0, $mes, $dia+1, $ano));
    }

    //FORMATA VALORES
    public static function formataValor($valor){   
        $valor = preg_replace("/[^0-9,\.]/", "", $valor);
        $valor = str_replace(".", "", $valor);
        $valor = str_replace(",", ".", $valor);
        return $valor;
    }

    //FORMATA DATA
    public static function formataData($data){
        
        $partials = explode(" ", $data);

        //Valida Data
        $partialDate = explode("-", $partials[0]);
        $date        = [];
        for($i=0;$i<count($partialDate);$i++){
            $date[] = str_pad($partialDate[$i], 2, "0", STR_PAD_LEFT);
        }
        $date = implode("-", $date);

        //Valida Hora
        if(isset($partials[1])){
            $partialHour = explode(":", $partials[1]);
            $hour        = [];
            for($i=0;$i<count($partialHour);$i++){
                $hour[] = str_pad($partialHour[$i], 2, "0", STR_PAD_LEFT);
            }
            $hour = implode(":", $hour);

            $date .= " {$hour}";
        }

        return $date;
        
    }

    public static function checkDiasUteis($data){

        $result = true;

        if(empty($data)){
            return $result;
        }

        $diaSemana = date("w", GeralService::dataToTimestamp($data));
        if($diaSemana==0 || $diaSemana==6){
             //se SABADO OU DOMINGO
             $result = false;
        }else{
             //senão vemos se este dia é FERIADO
             for($i=0; $i<=12; $i++){
                if($data==GeralService::feriados(date("Y"),$i)){
                    $result = false;
                    break;
                }
            }
        }

        return $result;

    }

    public static function diasUteis($yDataInicial,$yDataFinal){

        $diaFDS      = 0; //dias não úteis(Sábado=6 Domingo=0)
        $calculoDias = GeralService::calculaDias($yDataInicial, $yDataFinal); //número de dias entre a data inicial e a final
        $diasUteis   = 0;
        
        if($yDataInicial == $yDataFinal){

            $diaSemana = date("w", GeralService::dataToTimestamp($yDataInicial));
              if($diaSemana==0 || $diaSemana==6){
                 //se SABADO OU DOMINGO, SOMA 01
                 $diaFDS++;
              }else{
                 //senão vemos se este dia é FERIADO
                 for($i=0; $i<=12; $i++){
                    if($yDataInicial==GeralService::feriados(date("Y"),$i)){
                       $diaFDS++;
                    }
                 }
              }

        }else{
            while($yDataInicial!=$yDataFinal){
              $diaSemana = date("w", GeralService::dataToTimestamp($yDataInicial));
              if($diaSemana==0 || $diaSemana==6){
                 //se SABADO OU DOMINGO, SOMA 01
                 $diaFDS++;
              }else{
                 //senão vemos se este dia é FERIADO
                 for($i=0; $i<=12; $i++){
                    if($yDataInicial==GeralService::feriados(date("Y"),$i)){
                       $diaFDS++;
                    }
                 }
              }
              $yDataInicial = GeralService::soma1dia($yDataInicial); //dia + 1
            }
        }
        return $calculoDias - $diaFDS;
    }

    public static function calculaDataRetirada(){

        $days          = 10;
        $day           = date('d');
        $month         = date('m');
        $year          = date('Y');
        $data_current  = "{$day}/{$month}/{$year}";
        $data_retirada = date('d/m/Y', strtotime("+{$days} days",strtotime(date("{$year}-{$month}-{$day}"))));
        $dias_uteis    = GeralService::diasUteis($data_current, $data_retirada);
        $data_retirada = date('Y-m-d', strtotime("+{$days} days",strtotime(date("{$year}-{$month}-{$day}"))));
        $diaSemana     = date("w", GeralService::dataToTimestamp($data_current));
        if($diaSemana == 4){
            $dias_uteis++;
        }elseif($diaSemana == 5){
            $dias_uteis = 10;
        }
        $days          = $days - $dias_uteis;
        $ano = date('Y', strtotime("-{$days} days",strtotime($data_retirada)));
        $mes = date('m', strtotime("-{$days} days",strtotime($data_retirada)));
        $dia = date('d', strtotime("-{$days} days",strtotime($data_retirada)));
        $data_retirada = date('Y-m-d', strtotime("-{$days} days",strtotime($data_retirada)));

        $data_retirada = (object) ['ano' => $ano, 'mes' => $mes, 'dia' => $dia, 'data' => $data_retirada];
        return $data_retirada;
    }

    public static function calculaPesoCaixa($quantidade, $volumes){
        $volumes  = $volumes == 0 || empty($volumes) ? 1 : $volumes;
        $garrafas = $quantidade / $volumes;
        if($garrafas <= 4):
            $peso_caixa = 0.754;
        elseif($garrafas <= 6):
            $peso_caixa = 1.076;
        else:
            $peso_caixa = 1.464;
        endif;
        $peso_caixa = $peso_caixa * $volumes;
        return $peso_caixa;
    }

    public static function calculaPesoProdutosAdega($PedidoEntrega){
        $peso_produtos = 0;
        $pedidos = $PedidoEntrega->adega->pedidos;
        $statusPedidoVenda = [2,3,7];
        foreach ($pedidos as $pedido):
            if(!in_array($pedido->pedidoVenda->id_status_pedido_venda, $statusPedidoVenda)){
                continue;
            }
            $produtos = $pedido->pedidoVenda->produtos;
            foreach ($produtos as $produtoPedido):
                $peso_produtos += $produtoPedido->quantidade * $produtoPedido->produto->peso_bruto;
            endforeach;
        endforeach;
        return $peso_produtos;
    }

    public static function getProdutosSKU(){

        $registros = Produto::select('id', 'sku', 'thumbnail_principal')->get();
        $produtos = [];

        foreach ($registros as $registro) {
            $produtos[$registro->sku] = $registro;
        }

        return $produtos;

    }

    public static function getOfertasCanaisProdutos($canal_id){

        $registros = Oferta::select('oferta.*', 'ohp.id_produto')
        ->join('canal_has_oferta AS cho', 'cho.id_oferta', '=', 'oferta.id')
        ->join('oferta_has_produto AS ohp', 'ohp.id_oferta', '=', 'cho.id_oferta')
        ->where('cho.id_canal', $canal_id)->whereRaw('cho.deleted_at IS NULL')
        ->get();
        $produtos  = [];

        foreach ($registros as $registro) {
            $produtos[$registro->id_produto] = $registro;
        }

        return $produtos;

    }

    public static function calcularAdegaProcessamento(){

        try {
                
            //Quantidade Adegas
            $query = PedidoVenda::select(
                DB::raw('SUM(pedido_venda_has_produto.quantidade) AS adega'), 
                'produto.id',
                DB::raw("(SELECT qtde_sugerida FROM quantidade_reserva WHERE qtde_inicial_saldo <= SUM(pedido_venda_has_produto.quantidade) AND qtde_final_saldo >= SUM(pedido_venda_has_produto.quantidade)) AS 'reserva'")
            );

            $query->join('pedido_venda_has_produto','pedido_venda_has_produto.id_pedido_venda','=','pedido_venda.id')
            ->join('produto','pedido_venda_has_produto.id_produto','=','produto.id')
            ->join('empresa','pedido_venda.empresa_id','=','empresa.id')
            ->whereIn('pedido_venda.id_status_pedido_venda', [1,2]);

            $registros = $query->groupBy('produto.id')->get();

            $adegas    = [];
            $reservas  = [];
            foreach ($registros as $item) {
                $adegas[$item->id] = $item->adega;
                $reservas[$item->id] = $item->reserva;
            }

            //Quantidade Em processamento
            $query = PedidoEntrega::select(DB::raw('SUM(pvhp.quantidade) quantidade'), 'p.id');

            $query->join('adega AS a','pedido_entrega.id_adega','=','a.id')
            ->join('adega_has_pedido_venda AS ahpv','ahpv.id_adega','=','a.id')
            ->join('pedido_venda AS pv','ahpv.id_pedido_venda','=','pv.id')
            ->join('pedido_venda_has_produto AS pvhp','pvhp.id_pedido_venda','=','pv.id')
            ->join('produto AS p','pvhp.id_produto','=','p.id')
            ->join('empresa','pedido_entrega.empresa_id','=','empresa.id')
            ->where('pedido_entrega.id_pedido_entrega_status', '=', 3);

            $registros = $query->groupBy('p.id')->get();

            $processamentos = [];
            foreach ($registros as $item) {
                $processamentos[$item->id] = $item->quantidade;
            }

            //Seta Adega; Processamento
            $registros = Produto::all();
            $produtos  = [];
            foreach ($registros as $produto) {

                $adega           = (isset($adegas[$produto->id]) ? $adegas[$produto->id] : 0);
                $processamento   = (isset($processamentos[$produto->id]) ? $processamentos[$produto->id] : 0);
                $reserva         = (isset($reservas[$produto->id]) ? $reservas[$produto->id] : 0);

                $produtos[$produto->id] = [
                    'adega'           => $adega,
                    'processamento'   => $processamento,
                    'reserva'         => $reserva
                ];
            }

            return $produtos;

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

    }
    
    public static function getEstoqueProduto($produto, $analytic = FALSE){

        $data    = [];
        $saldos  = [];
        $estoque = 0;
        $ultima_atualizacao = '';

        $adegas         = GeralService::buscarAdegaProduto($produto, $analytic);
        $processamentos = GeralService::buscarProdutoEmProcessamento($produto, $analytic);

        $adega            = (is_numeric($produto->qtd_adega) ? $produto->qtd_adega : 0);
        if(is_numeric($adegas)){
            $adega = $adegas;
        }
        $em_processamento = (is_numeric($produto->qtd_em_processamento) ? $produto->qtd_em_processamento : 0);
        if(is_numeric($processamentos)){
            $em_processamento = $processamentos;
        }

        if(count($produto->estoque) > 0){
            foreach ($produto->estoque as $estoque_empresa){
                $saldos[$estoque_empresa->empresa->sigla] = $estoque_empresa->quantidade;
                $estoque += $saldos[$estoque_empresa->empresa->sigla];
                if(!empty($estoque_empresa->data_ultima_atualizacao)){
                    $ultima_atualizacao = $estoque_empresa->data_ultima_atualizacao;
                }
            }
        }

        $adega             = (!empty($adega) ? $adega : 0);
        $em_processamento  = (!empty($em_processamento) ? $em_processamento : 0);
        $QuantidadeReserva = QuantidadeReserva::select('qtde_sugerida')->where('qtde_inicial_saldo', '<=', $adega)->where('qtde_final_saldo', '>=', $adega)->first();
        $reserva           = ($QuantidadeReserva ? $QuantidadeReserva->qtde_sugerida : 0);
        $disponibilidade   = $estoque - $adega - $em_processamento - $reserva;

        $data['saldos']             = $saldos;
        $data['estoque']            = $estoque;
        $data['adega']              = number_format($adega, 0);
        $data['adegas']             = $adegas;
        $data['em_processamento']   = number_format($em_processamento, 0);
        $data['processamentos']     = $processamentos;
        $data['reserva']            = $reserva;
        $data['disponibilidade']    = $disponibilidade;
        $data['ultima_atualizacao'] = $ultima_atualizacao;

        return $data;
    }

    public static function buscarAdegaProduto($produto, $analytic = FALSE){
        
        $query = PedidoVenda::select(DB::raw('SUM(pedido_venda_has_produto.quantidade) AS adega'));
        if($analytic){
            $query = PedidoVenda::select(DB::raw('SUM(pedido_venda_has_produto.quantidade) AS adega'), 'empresa.sigla');
        }

        $query->join('pedido_venda_has_produto','pedido_venda_has_produto.id_pedido_venda','=','pedido_venda.id')
        ->join('produto','pedido_venda_has_produto.id_produto','=','produto.id')
        ->join('cadastro','pedido_venda.id_cliente','=','cadastro.id')
        ->join('empresa','cadastro.empresa_id','=','empresa.id')
        ->whereIn('pedido_venda.id_status_pedido_venda', [1,2])
        ->where('produto.sku', $produto->sku);

        if($analytic){
            $Adegas = $query->groupBy('cadastro.empresa_id')->get();
            $Adega  = [];
            foreach ($Adegas as $item):
                $Adega[$item->sigla] = $item->adega;
            endforeach;
        }else{
            $Adega = $query->first();
            $Adega = ($Adega ? $Adega->adega : 0);
        }

        return $Adega;
    }

    public static function buscarProdutoEmProcessamento($produto, $analytic = FALSE){

        $query = PedidoEntrega::select(DB::raw('SUM(pvhp.quantidade) quantidade'));

        if($analytic){
            $query = PedidoEntrega::select(DB::raw('SUM(pvhp.quantidade) quantidade'), 'empresa.sigla');
        }

        $query->join('adega AS a','pedido_entrega.id_adega','=','a.id')
        ->join('adega_has_pedido_venda AS ahpv','ahpv.id_adega','=','a.id')
        ->join('pedido_venda AS pv','ahpv.id_pedido_venda','=','pv.id')
        ->join('pedido_venda_has_produto AS pvhp','pvhp.id_pedido_venda','=','pv.id')
        ->join('produto AS p','pvhp.id_produto','=','p.id')
        ->join('empresa','pedido_entrega.empresa_id','=','empresa.id')
        ->where('p.sku', '=', $produto->sku)
        ->whereIn('pedido_entrega.id_pedido_entrega_status', [1,2,3]);

        if($analytic){
            $Pedidos       = $query->groupBy('pedido_entrega.empresa_id')->get();
            $PedidoEntrega = [];
            foreach ($Pedidos as $item):
                $PedidoEntrega[$item->sigla] = $item->quantidade;
            endforeach;
        }else{
            $PedidoEntrega = $query->first();
            $PedidoEntrega = ($PedidoEntrega ? $PedidoEntrega->quantidade : 0);
        }

        return $PedidoEntrega;
    }

    public static function resumoEntregas(){

        $cadastro            = self::buscarClienteLogado();
        $qtde_entregas       = 0;
        $data_ultima_entrega = false;

        if($cadastro){

             $entregas = PedidoEntrega::select('pedido_entrega.id')
            ->join('adega as a', 'pedido_entrega.id_adega', '=', 'a.id')
            ->join('adega_has_pedido_venda as ahpv', 'a.id', '=', 'ahpv.id_adega')
            ->join('pedido_venda as pv', 'pv.id', '=', 'ahpv.id_pedido_venda')
            ->where('a.id_cliente', $cadastro->id)
            ->whereRaw('a.confraria_id IS NULL')
            ->where('pv.id_status_pedido_venda', 7)
            ->groupBy('pedido_entrega.id')->get();

            $qtde_entregas = count($entregas);

            if($qtde_entregas > 0){

                 $ultimaEntrega = PedidoEntrega::select('pedido_entrega.data_solicitacao')
                ->join('adega as a', 'pedido_entrega.id_adega', '=', 'a.id')
                ->join('adega_has_pedido_venda as ahpv', 'a.id', '=', 'ahpv.id_adega')
                ->join('pedido_venda as pv', 'pv.id', '=', 'ahpv.id_pedido_venda')
                ->where('a.id_cliente', $cadastro->id)
                ->whereRaw('a.confraria_id IS NULL')
                ->where('pv.id_status_pedido_venda', 7)
                ->groupBy('pedido_entrega.id')
                ->orderBy('pedido_entrega.data_solicitacao', 'DESC')
                ->first();

                $data_ultima_entrega = $ultimaEntrega->data_solicitacao;

            }

        }

        $resumoEntregas = new \stdClass;
        $resumoEntregas->qtde_entregas       = $qtde_entregas;
        $resumoEntregas->data_ultima_entrega = $data_ultima_entrega;

        return $resumoEntregas;
    }

    public static function buscarAdegaAberta($params = []){
        if(isset($params['id_cliente'])){
            $cadastro = Cadastro::find($params['id_cliente']);
        }else{
            $cadastro = self::buscarClienteLogado();
        }

        if(!$cadastro) return null;

        $adegaAberta = Adega::where('id_cliente', $cadastro->id)->whereRaw('adega.confraria_id IS NULL')->where('status', 'A')->first();

        return $adegaAberta;
    }

    public static function buscarFreteAdegaAberta(){

        $adegaAberta        = GeralService::buscarAdegaAberta();
        $valor_adega        = false;
        $valor_frete_gratis = false;

        if($adegaAberta){

            $valor_adega = $adegaAberta->valor_total;

            $params = [
                'id_cliente' => $adegaAberta->id_cliente,
                'adega'      => $adegaAberta
            ];
            $enderecos = GeralService::buscarEnderecosCliente($params);
            $endereco  = false;
            foreach ($enderecos as $address) {
                if($address->principal){
                    $endereco = $address;
                    break;
                }
            }

            if($endereco){
                $valor_frete_gratis = $endereco->valor_final_frete;
            }
        }

        $dadosAdega = new \stdClass;
        $dadosAdega->valor_adega        = $valor_adega;
        $dadosAdega->valor_frete_gratis = $valor_frete_gratis;

        return $dadosAdega;

    }

    /* Esse método é utilizado para buscar as OFERTAS que foram compradas em determinada adega */
    public static function buscarVinhosAdega($input){

        $adega = Adega::find($input['id_adega']);

        if($adega){

            $status = $input['id_status_pedido_venda'] ?? [2];

            if(!is_array($status)){
                $status = [$status];
            }

            $query = Oferta::select(
                'oferta.*',
                'pv.data_fechamento as data_pedido_venda',
                'pv.total as total_pedido_venda',
                'pv.ajuste as total_desconto_pedido',
                'pv.saldo_usado as saldo_usado',
                'pv.slug as slug_pedido_venda',
                'pv.tipo_deposito',
                'pv.comprovante',
                'pvhp.id_pedido_venda',
                'pvhp.id_produto',
                'cpv.id_pedido_venda as cupom_pedido_venda',
                'pvhp.valor_total as total_no_pedido',
                DB::raw('(SELECT SUM(pdvhp.quantidade) FROM pedido_venda_has_produto pdvhp INNER JOIN pedido_venda ON(pdvhp.id_pedido_venda = pedido_venda.id) INNER JOIN adega_has_pedido_venda as ahpv ON(ahpv.id_pedido_venda = pedido_venda.id) WHERE ahpv.id_adega = '.$adega->id.' AND pdvhp.id_oferta = oferta.id AND pedido_venda.id_status_pedido_venda IN ('.implode(',', $status).'))  as quantidade_na_adega'),
                DB::raw('(SELECT SUM(iohp.quantidade) FROM oferta_has_produto iohp WHERE iohp.id_oferta = oferta.id) as quantidade_na_oferta')
            )
            ->join('oferta_has_produto as ohp', 'oferta.id', '=', 'ohp.id_oferta')
            ->join('produto as p', 'ohp.id_produto', '=', 'p.id')
            ->join('tipo_de_produto', 'tipo_de_produto.id', '=', 'p.id_tipo_produto')
            ->join('pedido_venda_has_produto as pvhp', 'oferta.id', '=', 'pvhp.id_oferta')
            ->join('pedido_venda as pv', 'pvhp.id_pedido_venda', '=', 'pv.id')
            ->leftJoin('cupom_pedido_venda as cpv', 'cpv.id_pedido_venda', '=', 'pv.id')
            ->join('adega_has_pedido_venda as ahpv', 'ahpv.id_pedido_venda', '=', 'pvhp.id_pedido_venda')
            ->where('tipo_de_produto.slug', '!=', 'masterclass')
            ->where('ahpv.id_adega', $adega->id)
            ->with("produtos.produto");

            if(isset($input['id_cliente'])){
                $query->where('pv.id_cliente', $input['id_cliente']);
            }

            if(isset($input['id_confraria'])){
                $query->where('pv.confraria_id', $input['id_confraria']);
            }else{
                $query->whereRaw('pv.confraria_id IS NULL');
            }

            if(isset($input['id_status_pedido_venda'])){
                $query->whereIn('pv.id_status_pedido_venda', $status);
            }else{
                $query->where('pv.id_status_pedido_venda', 2); // Aprovados
            }

            $query->groupBy('oferta.id');

            // $query->groupBy('pvhp.id_pedido_venda');

            if (isset($input['somar']) && $input['somar'] == true) {

                $produtosTotal  = $query->get();

                $total_valor    = 0;
                $total_unidades = 0;
                $lista          = [];

                foreach ($produtosTotal as $produto) {
                    $produto->produtos = PedidoVendaHasProduto::where('id_pedido_venda', $produto->id_pedido_venda)
                        ->where('id_oferta', $produto->id)->get();

                    if($produto->agrupamento_produtos){
                        $quantidades_na_adega = $produto->quantidade_na_adega;
                    }else{
                        $quantidades_na_adega = $produto->quantidade_na_adega / $produto->quantidade_na_oferta;
                    }

                    $total_valor += $produto->preco_oferta * $quantidades_na_adega;
                    if (count($produto->produtos) > 1){
                        foreach ($produto->produtos as $item) {
                            $total_unidades += $produto->quantidade_na_adega * $item->quantidade;
                        }
                    }else{
                        $total_unidades += $produto->quantidade_na_adega;
                    }

                    $lista[] = $produto;
                }

                $listaProdutos = $query->get();
                $listaProduto  = [];
                foreach ($listaProdutos as $item) {

                    if($item->agrupamento_produtos){
                        $item->produtos = PedidoVendaHasProduto::where('id_pedido_venda', $item->id_pedido_venda)->where('id_oferta', $item->id)->get();
                    }
                    $listaProduto[] = $item;
                }

                $produtos = $lista;
                $produtos['produtos']       = $listaProduto;
                $produtos['total_valor']    = $total_valor;
                $produtos['total_unidades'] = $total_unidades;

            }else{
                $produtos = $query->get();
                $lista    = [];
                foreach ($produtos as $item) {
                    if($item->agrupamento_produtos){
                        $item->produtos = PedidoVendaHasProduto::where('id_pedido_venda', $item->id_pedido_venda)->where('id_oferta', $item->id)->get();
                    }
                    $lista[] = $item;
                }
                $produtos = $lista;
            }

        }else{

            if (isset($input['somar']) && $input['somar'] == true) {
                $produtos['produtos'] = [];
            }else{
                $produtos = [];
            }

        }

        return $produtos;
    }

    public static function listarPedidosTransportadora($request){

        $query = PedidoEntrega::selectRaw('pedido_entrega.*, 
                                            cotacao_valor.transportadora_id, 
                                            transportadora.nome AS transportadora_nome, 
                                            cotacao_valor.valor AS cotacao_valor, 
                                            cadastro.nome AS cliente_nome, 
                                            cadastro.sobrenome AS cliente_sobrenome, 
                                            pedido_venda.id_status_pedido_venda as status_frete, 
                                            pedido_venda.total as valor_frete'
                                        )
                ->join('cotacao_valor', 'cotacao_valor.id', '=', 'pedido_entrega.id_cotacao_valor')
                ->join('transportadora', 'transportadora.id', '=', 'cotacao_valor.transportadora_id')
                ->join('adega', 'adega.id', '=', 'pedido_entrega.id_adega')
                ->join('cadastro', 'cadastro.id', '=', 'adega.id_cliente')
                ->leftJoin('pedido_venda', 'pedido_entrega.id_pedido_venda_frete', '=', 'pedido_venda.id')
                // ->whereRaw('pedido_entrega.id_transportadora IS NOT NULL')
                ->whereDate('pedido_entrega.data_solicitacao', $request->input('data_romaneio'))
                ->where('pedido_entrega.id_pedido_entrega_status', $request->input('id_pedido_entrega_status'));

        if($request->input('transportadora_id')){
            $query->where('cotacao_valor.transportadora_id', $request->input('transportadora_id'));
        }

        if($request->input('empresa_id')){
            $query->where('pedido_entrega.empresa_id', $request->input('empresa_id'));
        }

        $registros       = $query->orderBy('cotacao_valor.transportadora_id', 'ASC')->orderBy('pedido_entrega.data_solicitacao', 'ASC')->get();
        $pedidos         = [];
        $transportadoras = [];
        $listaItens      = [];

        foreach ($registros as $registro) {

            if(!isset($pedidos[$registro->transportadora_id])){

                $transportadoras[] = $registro->transportadora_id;

                $PedidoEntregaExpedicao = PedidoEntregaExpedicao::where('empresa_id', $request->input('empresa_id'))
                ->where('data_romaneio', $request->input('data_romaneio'))
                ->where('transportadora_id', $registro->transportadora_id)
                ->where('pedido_entrega_status_id', $request->input('id_pedido_entrega_status'))
                ->first();

                if($PedidoEntregaExpedicao){
                    foreach ($PedidoEntregaExpedicao->itens as $item) {
                        $key              = "{$item->expedicao->transportadora_id}_{$item->pedido_entrega_id}_{$item->objeto}";
                        $listaItens[$key] = $item;
                    }
                }
            }

            $pedidos[$registro->transportadora_id][] = $registro;

        }

        return (object) ['pedidos' => $pedidos, 'transportadoras' => $transportadoras, 'itens' => $listaItens];

    }

    public static function listarProdutosCompra($request){

        //Verifica Filtro Última Compra
        $filtro_ultimas_compras = "";
        if($request->input('periodo_compra')){

            $data_inicio_compra = date('Y-m-d', strtotime("-".$request->input('periodo_compra')." day",strtotime(date('Y-m-d'))));
            $data_fim_compra    = date('Y-m-d');

            $filtro_ultimas_compras = " AND oc.data_inclusao BETWEEN '{$data_inicio_compra}' AND '{$data_fim_compra} 23:59:59'";

        }

        $query = Produto::select(
            'produto.*', 
            DB::raw("(SELECT SUM(rc.quantidade) FROM requisicao_compra rc WHERE rc.produto_id = produto.id AND rc.`status` = 'P' AND rc.tipo = 'P') AS 'pedidos_extras'"),
            DB::raw("(SELECT SUM(rc.quantidade) FROM requisicao_compra rc WHERE rc.produto_id = produto.id AND rc.`status` = 'P' AND rc.tipo = 'R') AS 'requisicoes'"),
            DB::raw("(SELECT SUM(oci.quantidade) FROM ordem_compra_item oci WHERE oci.produto_id = produto.id AND EXISTS(
                        SELECT 1 FROM ordem_compra oc WHERE oc.id = oci.ordem_compra_id AND oc.status IN ('P','AR','EN') {$filtro_ultimas_compras}
                    )) AS 'ultimas_compras'"),
            DB::raw("(SELECT SUM(oci.quantidade) FROM ordem_compra_item oci WHERE oci.produto_id = produto.id AND EXISTS(
                        SELECT 1 FROM ordem_compra oc WHERE oc.id = oci.ordem_compra_id AND oc.status IN ('AP') {$filtro_ultimas_compras}
                    )) AS 'ultimas_compras_parcial'")
        );

        //FILTROS
        $query->where('produto.listar_compras', 1);

        //fornecedor
        if($request->input('fornecedor_id')){
            $query->where('produto.id_fornecedor', $request->input('fornecedor_id'));
        }

        //canal
        if($request->input('canal_id')){
            $query->whereRaw(DB::raw('EXISTS (SELECT 1 FROM oferta_has_produto ohp, canal_has_oferta cho WHERE cho.deleted_at IS NULL AND ohp.id_produto = produto.id AND cho.id_oferta = ohp.id_oferta AND cho.id_canal = ' . $request->input('canal_id') . ')'));
        }

        //tipo oferta
        if($request->input('tipo_oferta')){
            $query->whereRaw(DB::raw("EXISTS (SELECT 1 FROM oferta_has_produto ohp, oferta o WHERE ohp.id_produto = produto.id AND o.id = ohp.id_oferta AND o.tipo = '" . $request->input('tipo_oferta') . "')"));
        }

        //período oferta
        if($request->input('periodo_oferta')){

            $data_inicio_oferta = date('Y-m-d', strtotime("-".$request->input('periodo_oferta')." day",strtotime(date('Y-m-d'))));
            $data_fim_oferta    = date('Y-m-d');
            
            $query->whereRaw(DB::raw("EXISTS (SELECT 1 FROM oferta_has_produto ohp, oferta o WHERE ohp.id_produto = produto.id AND o.id = ohp.id_oferta AND o.data BETWEEN '{$data_inicio_oferta}' AND '{$data_fim_oferta}')"));
        }

        //período compra
        if($request->input('periodo_compra')){

            $data_inicio_compra = date('Y-m-d', strtotime("-".$request->input('periodo_compra')." day",strtotime(date('Y-m-d'))));
            $data_fim_compra    = date('Y-m-d');
            
            $query->whereRaw(DB::raw("EXISTS (SELECT 1 FROM ordem_compra_item oci, ordem_compra o WHERE oci.produto_id = produto.id AND o.id = oci.ordem_compra_id AND o.data_inclusao BETWEEN '{$data_inicio_compra}' AND '{$data_fim_compra} 23:59:59')"));
        }

        //produto
        if($request->input('produto_id')){
            $query->where('produto.id', $request->input('produto_id'));
        }

        //produto
        if($request->input('item_id')){
            $query->where('produto.id', $request->input('item_id'));
        }

        //Novos Produtos
        if($request->input('produtos_novos') && $request->input('produtos_novos') == 'S'){
            $query->whereRaw(DB::raw('NOT EXISTS (SELECT 1 FROM oferta_has_produto ofp_new WHERE ofp_new.id_produto = produto.id)'));
            $query->whereRaw(DB::raw('NOT EXISTS (SELECT 1 FROM pedido_venda_has_produto pvhp WHERE pvhp.id_produto = produto.id)'));
        }

        $produtos = $query->get();

        foreach ($produtos as $produto) {

            $produto->percentual_desconto = (!empty($produto->preco_mercado) && $produto->preco_mercado != '0' ? (1 - ($produto->preco_de_venda  / $produto->preco_mercado)) * 100 : 0);
            $produto->percentual_markup   = (!empty($produto->preco_custo) && $produto->preco_custo != '0' ? (($produto->preco_de_venda  / $produto->preco_custo) - 1) * 100 : 0);

            //Ofertas x Canal
            foreach ($produto->ofertas as $oferta){

                if(isset($oferta->oferta) && $oferta->oferta->tipo == 'C'){
                    $CanalHasOferta = CanalHasOferta::where('id_oferta', $oferta->id_oferta)->orderBy('id', 'desc')->first();
                    if($CanalHasOferta){
                        $oferta->oferta->canal = $CanalHasOferta->canal;
                    }
                }

                $PedidoVendaHasProduto = PedidoVendaHasProduto::select(DB::raw("SUM(quantidade) AS 'quantidade'"))
                ->where('id_oferta', $oferta->id_oferta)
                ->where('id_produto', $produto->id)
                ->whereRaw(DB::raw("EXISTS (SELECT 1 FROM pedido_venda pv WHERE pv.id = pedido_venda_has_produto.id_pedido_venda AND pv.id_status_pedido_venda IN (1,2,7,9))"))
                ->groupBy('id_oferta')
                ->first();

                $oferta->quantidade = ($PedidoVendaHasProduto ? $PedidoVendaHasProduto->quantidade : 0);

            }

            //Estoque
            $produto->estoque = GeralService::getEstoqueProduto($produto);

            $adega            = str_replace(['.', ','], "", $produto->estoque['adega']);
            $em_processamento = str_replace(['.', ','], "", $produto->estoque['em_processamento']);
            $disponibilidade  = str_replace(['.', ','], "", $produto->estoque['disponibilidade']);

            //VALIDAÇÃO VALORES ACIMA DE 1 MIL
            $estoque = ['adega' => $adega, 'em_processamento' => $em_processamento, 'disponibilidade' => $disponibilidade];
            $produto->estoque = array_merge($produto->estoque, $estoque);

            // $produto->saldo   = abs($produto->estoque['disponibilidade']) - ($produto->pedidos_extras + $produto->requisicoes + $produto->ultimas_compras);
            $produto->saldo = ($produto->estoque['estoque'] - $produto->estoque['adega'] - $produto->estoque['em_processamento'] - $produto->pedidos_extras - $produto->requisicoes) + $produto->ultimas_compras + $produto->ultimas_compras_parcial;
            $saldo          = $produto->saldo;

            $QuantidadeReserva      = QuantidadeReserva::select('qtde_sugerida')->where('qtde_inicial_saldo', '<=', abs($produto->saldo))->where('qtde_final_saldo', '>=', abs($produto->saldo))->first();
            // $produto->reserva       = ($QuantidadeReserva ? $QuantidadeReserva->qtde_sugerida : 0);
            $produto->reserva         = $produto->estoque['reserva'];
            $produto->qtde_sugerida   = $produto->saldo > 0 ? 0 : abs($produto->saldo) + $produto->reserva;
            $produto->saldo_final     = ($saldo > 0 ? (abs($produto->saldo) - $produto->reserva) : abs($produto->saldo) + $produto->reserva);
            if($saldo < 0){
                $produto->saldo_final = -abs($produto->saldo_final);
            }
            $produto->saldo           = abs($produto->saldo);
            $produto->saldo           = ($saldo >= 0 ? $produto->saldo : -abs($produto->saldo));
            $produto->disponibilidade = ($produto->estoque['disponibilidade'] > 0 ? $produto->estoque['disponibilidade'] : $produto->estoque['disponibilidade'] + $produto->reserva);

        }

        return $produtos;

    }

    /* Esse método é utilizado para buscar os PRODUTOS que foram compradas em determinada adega */
    public static function buscarProdutosAdega($input, $id_status_pedido_venda = 7, $request = false){

        $adega = Adega::find($input['id_adega']);

        if($adega){


            $query = Produto::select('produto.*', 'pvhp.id_pedido_venda', 'pv.data_fechamento as data_pedido_venda', 'pvhp.id_oferta', DB::raw('SUM(pvhp.quantidade) AS quantidade_na_adega'), DB::raw('SUM(pvhp.valor_total) as valor_total_produto'), DB::raw('SUM(pvhp.quantidade) as quantidade_produto'))

            ->join('pedido_venda_has_produto as pvhp', 'produto.id', '=', 'pvhp.id_produto')
            ->join('pedido_venda as pv', 'pvhp.id_pedido_venda', '=', 'pv.id')
            ->join('adega_has_pedido_venda as ahpv', 'ahpv.id_pedido_venda', '=', 'pvhp.id_pedido_venda')
            ->where('ahpv.id_adega', $adega->id);

            if(isset($input['id_status_pedido_venda'])){
                if(is_array($input['id_status_pedido_venda'])){
                    $query->whereIn('pv.id_status_pedido_venda', $input['id_status_pedido_venda']);
                }else{
                    $query->where('pv.id_status_pedido_venda', $input['id_status_pedido_venda']);
                }
            }else{
                $query->where('pv.id_status_pedido_venda', $id_status_pedido_venda); // Entrega solicitada by Default = 7
            }

            if($request && $request->input('produtos')){
                $produtos = $request->input('produtos');
                $produtos = explode("-", $produtos);
                $pedidos  = [];
                foreach ($produtos as $produtoPedido) {
                    $result = explode("_", $produtoPedido);
                    $pedido = count($result) == 1 ? $result[0] : $result[1];
                    $pedidos[] = $pedido;
                }
                $query->whereIn('pv.id', $pedidos);
            }

            $query->groupBy('produto.id');

            if($request && $request->input('order_by_produtos')){
                $query->orderBy($request->input('order_by_produtos'), 'ASC');
            }

            $produtos = $query->get();

            foreach ($produtos as $produto) {
                $Oferta = Oferta::where('id', $produto->id_oferta)->first();
                if($Oferta){
                    $produto->oferta = $Oferta;
                    if($Oferta->tipo == 'C'){
                        $CanalHasOferta = CanalHasOferta::where('id_oferta', $Oferta->id)->orderBy('id', 'desc')->first();
                        if($CanalHasOferta){
                            $produto->oferta->canal = $CanalHasOferta->canal;
                        }
                    }
                }
            }

        }else{
            $produtos = [];
        }

        return $produtos;
    }

    public static function buscarOfertasPagamento($input){

        $id_pedido_venda = $input['id_pedido_venda'];

        $query = Oferta::select(
            'oferta.*', 
            'pvhp.id_pedido_venda',
            DB::raw('(SELECT SUM(pdvhp.quantidade) FROM pedido_venda_has_produto pdvhp WHERE pdvhp.id_produto = p.id AND pdvhp.id_pedido_venda = pv.id AND pdvhp.id_oferta = oferta.id) DIV ohp.quantidade as quantidade_no_pedido'),
            DB::raw('(SELECT SUM(pdvhp.valor_total) FROM pedido_venda_has_produto pdvhp WHERE pdvhp.id_produto = p.id AND pdvhp.id_pedido_venda = pv.id AND pdvhp.id_oferta = oferta.id) as total_no_pedido')
        )

        ->join('pedido_venda_has_produto as pvhp', 'oferta.id', '=', 'pvhp.id_oferta')
        ->join('pedido_venda as pv', 'pvhp.id_pedido_venda', '=', 'pv.id')

        // ->join('oferta_has_produto as ohp', 'oferta.id', '=', 'ohp.id_oferta')
        ->join('oferta_has_produto as ohp', function($q)
        {
            $q->on('oferta.id', 'ohp.id_oferta')->on('ohp.id_produto', 'pvhp.id_produto');
        })
        ->join('produto as p', 'ohp.id_produto', '=', 'p.id')

        ->where('pv.id', $id_pedido_venda);

        $query->groupBy('oferta.id');

        $ofertas = $query->get();

        $lista    = [];
        foreach ($ofertas as $item) {
            if($item->agrupamento_produtos){
                $item->produtos = PedidoVendaHasProduto::where('id_pedido_venda', $item->id_pedido_venda)->where('id_oferta', $item->id)->get();
            }
            $lista[] = $item;
        }
        $ofertas = $lista;

        return $ofertas;
    }

    public static function buscarMeusVinhos($params = []){
        $adegaAberta = self::buscarAdegaAberta();

        if($adegaAberta){
            $produtos = self::buscarVinhosAdega(['id_adega'=> $adegaAberta->id ,'somar' => $params['somar'] ?? false]);
        }else{
            $produtos = isset($params['somar']) ? ['produtos' => []] : [];
        }

        return $produtos;
    }

    public static function buscarMeusVinhosPendentes(){
        $adegaAberta = self::buscarAdegaAberta();

        if($adegaAberta){
            $produtos = self::buscarVinhosAdega(['id_adega'=>$adegaAberta->id, 'id_status_pedido_venda' => 1]);
        }else{
            $produtos = [];
        }

        return $produtos;
    }

    public static function buscarMeusVinhosPreVenda(){
        $adegaAberta = self::buscarAdegaAberta();

        if($adegaAberta){
            $produtos = self::buscarVinhosAdega(['id_adega'=>$adegaAberta->id, 'id_status_pedido_venda' => 9]);
        }else{
            $produtos = [];
        }

        return $produtos;
    }

    public static function buscarAdegaPorCliente($idCadastro){
        $adegaAberta = self::buscarAdegaAberta(['id_cliente' => $idCadastro]);

        if($adegaAberta){
            $produtos = self::buscarVinhosAdega(['id_adega'=>$adegaAberta->id]);
        }else{
            $produtos = [];
        }

        return $produtos;
    }


    public static function buscarAdegaPendentePorCliente($idCadastro){
        $adegaAberta = self::buscarAdegaAberta(['id_cliente' => $idCadastro]);

        if($adegaAberta){
            $produtos = self::buscarVinhosAdega(['id_adega'=>$adegaAberta->id, 'id_status_pedido_venda' => 1]);
        }else{
            $produtos = [];
        }

        return $produtos;
    }


    public static function buscarInformacoesBasicasAdegaAberta($idCadastro = null){

        if ($idCadastro != null){
            $vinhos = self::buscarAdegaPorCliente($idCadastro);
        } else {
            $vinhos = self::buscarMeusVinhos();
        }

        $idTipoMasterclass = DB::table('tipo_de_produto')
            ->where('slug', 'masterclass')
            ->value('id');

        $data = [];

        $valor_total = 0;
        $valor_economizado = 0;
        $quantidade_vinhos_adega = 0;
        foreach ($vinhos as $vinho) {
            $vinho->quantidade_na_adega = $vinho->agrupamento_produtos ? $vinho->quantidade_na_adega : ($vinho->quantidade_na_oferta != 0 ? $vinho->quantidade_na_adega / $vinho->quantidade_na_oferta : 0);
            $valor_total += $vinho->preco_oferta * $vinho->quantidade_na_adega;
            $valor_economizado += ($vinho->preco_mercado - $vinho->preco_oferta) * $vinho->quantidade_na_adega;
            if(count($vinho->produtos) > 1){
                foreach ($vinho->produtos as $produto) {
                    if($produto->produto->id_tipo_produto != $idTipoMasterclass){
                        $quantidade_vinhos_adega += $vinho->quantidade_na_adega * $produto->quantidade;
                    }
                }
            }else{
                $quantidade_vinhos_adega += $vinho->quantidade_na_adega;
            }
        }

        $data['valorTotal']            = $valor_total;
        $data['valorEconomizado']      = $valor_economizado;
        $data['quantidadeVinhosAdega'] = $quantidade_vinhos_adega;

        return $data;
    }

    public static function buscarMinhasEntregas($tipo = 'entregas'){
        $cadastro = self::buscarClienteLogado();
        if(!$cadastro){
            return [];
        }
        $entregas = self::buscarEntregasPorCliente($cadastro->id, $tipo);

        return $entregas;
    }

    public static function buscarEntregasPorCliente($idCadastro, $tipo = 'entregas'){

        $query = PedidoEntrega::select('pedido_entrega.*', DB::raw('SUM(pvhp.quantidade) as quantidade_produtos'), DB::raw('SUM(pvhp.valor_total) as valor_total'), 'pvf.total as valor_frete')
        ->join('adega as a', 'pedido_entrega.id_adega', '=', 'a.id')
        ->join('adega_has_pedido_venda as ahpv', 'a.id', '=', 'ahpv.id_adega')
        ->join('pedido_venda as pv', 'pv.id', '=', 'ahpv.id_pedido_venda')
        ->join('pedido_venda_has_produto as pvhp', 'pvhp.id_pedido_venda', '=', 'pv.id')

        ->leftJoin('pedido_venda as pvf', 'pvf.id', '=', 'pedido_entrega.id_pedido_venda_frete')

        ->where('a.id_cliente', $idCadastro)
        ->whereRaw('pedido_entrega.confraria_id IS NULL')
        ->where('pv.id_status_pedido_venda', 7);

        if($tipo == 'resumo'){
            $query->whereNotIn('pedido_entrega.id_pedido_entrega_status', [6,7]); //Entregue, Cancelado
        }

        $query->orderBy('data_solicitacao', 'DESC')->with('endereco', 'adega')->groupBy('pedido_entrega.id');

        if($tipo == 'resumo'){
            $entregas = $query->get();
        }else{
            $entregas = $query->paginate(15);
        }

        return $entregas;
    }

    public static function buscarQtdeIndicacoesAdegaVirada($codigo, $indicacao = 'id_indicador'){

        $clienteLogado = GeralService::buscarClienteLogado();

        $query = CupomIndicacao::select(DB::raw("COUNT(id) AS qtde_cupons"))
                                            ->where($indicacao, $clienteLogado->id)
                                            ->where('id_cupom', $cupom_id);

        if($indicacao == 'id_indicador'){
            $query->whereRaw("EXISTS (SELECT 1 FROM cupom_pedido_indicacao cpi WHERE cpi.cupom_indicacao_id = cupom_indicacao.id)")
                    ->whereRaw("NOT EXISTS (
                        SELECT 1 FROM 
                        cupom_pedido_indicacao cpi INNER JOIN pedido_venda pv ON pv.id = cpi.pedido_venda_id 
                        WHERE cpi.cupom_indicacao_id = cupom_indicacao.id AND pv.id_cliente = {$clienteLogado->id}
                    )");
        }else{
            $query->whereRaw("NOT EXISTS (
                SELECT 1 FROM 
                cupom_pedido_indicacao cpi INNER JOIN pedido_venda pv ON pv.id = cpi.pedido_venda_id 
                WHERE cpi.cupom_indicacao_id = cupom_indicacao.id AND pv.id_cliente = {$clienteLogado->id}
            )");
        }

        $indicacoes = $query->first();

        return $indicacoes;
    }

    public static function buscarCuponsIndicacoesAdegaVirada($cupom_id, $all = false){

        $clienteLogado = GeralService::buscarClienteLogado();
        $indicacoes    = [];

        $registros = CupomIndicacao::where('id_indicador', $clienteLogado->id)
                                        ->where('id_cupom', $cupom_id)
                                        ->whereRaw("EXISTS (SELECT 1 FROM cupom_pedido_indicacao cpi WHERE cpi.cupom_indicacao_id = cupom_indicacao.id)")
                                        ->whereRaw("NOT EXISTS (
                                            SELECT 1 FROM 
                                            cupom_pedido_indicacao cpi INNER JOIN pedido_venda pv ON pv.id = cpi.pedido_venda_id 
                                            WHERE cpi.cupom_indicacao_id = cupom_indicacao.id AND pv.id_cliente = {$clienteLogado->id}
                                        )")
                                        ->get();

        foreach ($registros as $registro) {
            $registro->indicacao = $registro->indicado;
            $indicacoes[] = $registro;
        }

        if($all){

            $registros = CupomIndicacao::where('id_indicado', $clienteLogado->id)
                                        ->where('id_cupom', $cupom_id)
                                        ->whereRaw("NOT EXISTS (
                                            SELECT 1 FROM 
                                            cupom_pedido_indicacao cpi INNER JOIN pedido_venda pv ON pv.id = cpi.pedido_venda_id 
                                            WHERE cpi.cupom_indicacao_id = cupom_indicacao.id AND pv.id_cliente = {$clienteLogado->id}
                                        )")
                                        ->get();

            foreach ($registros as $registro) {
                $registro->indicacao = $registro->indicador;
                $indicacoes[] = $registro;
            }

        }

        return $indicacoes;
    }

    public static function buscarQtdeIndicacoes($cupom_id, $indicacao = 'id_indicador'){

        $clienteLogado = GeralService::buscarClienteLogado();

        $query = CupomIndicacao::select(DB::raw("COUNT(id) AS qtde_cupons"))
                                            ->where($indicacao, $clienteLogado->id)
                                            ->where('id_cupom', $cupom_id);

        if($indicacao == 'id_indicador'){
            $query->whereRaw("EXISTS (SELECT 1 FROM cupom_pedido_indicacao cpi WHERE cpi.cupom_indicacao_id = cupom_indicacao.id)")
                    ->whereRaw("NOT EXISTS (
                        SELECT 1 FROM 
                        cupom_pedido_indicacao cpi INNER JOIN pedido_venda pv ON pv.id = cpi.pedido_venda_id 
                        WHERE cpi.cupom_indicacao_id = cupom_indicacao.id AND pv.id_cliente = {$clienteLogado->id}
                    )");
        }else{
            $query->whereRaw("NOT EXISTS (
                SELECT 1 FROM 
                cupom_pedido_indicacao cpi INNER JOIN pedido_venda pv ON pv.id = cpi.pedido_venda_id 
                WHERE cpi.cupom_indicacao_id = cupom_indicacao.id AND pv.id_cliente = {$clienteLogado->id}
            )");
        }

        $indicacoes = $query->first();

        return $indicacoes;
    }

    public static function buscarCuponsIndicacoes($cupom_id, $all = false){

        $clienteLogado = GeralService::buscarClienteLogado();
        $indicacoes    = [];

        $registros = CupomIndicacao::where('id_indicador', $clienteLogado->id)
                                        ->where('id_cupom', $cupom_id)
                                        ->whereRaw("EXISTS (SELECT 1 FROM cupom_pedido_indicacao cpi WHERE cpi.cupom_indicacao_id = cupom_indicacao.id)")
                                        ->whereRaw("NOT EXISTS (
                                            SELECT 1 FROM 
                                            cupom_pedido_indicacao cpi INNER JOIN pedido_venda pv ON pv.id = cpi.pedido_venda_id 
                                            WHERE cpi.cupom_indicacao_id = cupom_indicacao.id AND pv.id_cliente = {$clienteLogado->id}
                                        )")
                                        ->get();

        foreach ($registros as $registro) {
            $registro->indicacao = $registro->indicado;
            $indicacoes[] = $registro;
        }

        if($all){

            $registros = CupomIndicacao::where('id_indicado', $clienteLogado->id)
                                        ->where('id_cupom', $cupom_id)
                                        ->whereRaw("NOT EXISTS (
                                            SELECT 1 FROM 
                                            cupom_pedido_indicacao cpi INNER JOIN pedido_venda pv ON pv.id = cpi.pedido_venda_id 
                                            WHERE cpi.cupom_indicacao_id = cupom_indicacao.id AND pv.id_cliente = {$clienteLogado->id}
                                        )")
                                        ->get();

            foreach ($registros as $registro) {
                $registro->indicacao = $registro->indicador;
                $indicacoes[] = $registro;
            }

        }

        return $indicacoes;
    }

    public static function associarConviteConfraria($codigo, $ClienteConvite){

        try {
            
            $Confraria = Confraria::where('codigo', $codigo)->first();
            if(!$Confraria){
                return false;
            }

            $ConfrariaConvite = ConfrariaConvite::where('confraria_id', $Confraria->id)->where('email', $ClienteConvite->user->email)->first();

            if($Confraria){

                if($ConfrariaConvite && empty($ConfrariaConvite->cadastro_id)){
                    
                    $sql = "UPDATE confraria_convite SET cadastro_id = {$ClienteConvite->id} WHERE id = {$ConfrariaConvite->id}";
                    DB::update($sql);

                }elseif(!$ConfrariaConvite){
                    DB::table('confraria_convite')->insert([
                        [
                            'confraria_id' => $Confraria->id,
                            'cadastro_id'  => $ClienteConvite->id,
                            'email'        => $ClienteConvite->user->email,
                            'data_convite' => date('Y-m-d H:i:s'),
                            'elegivel_kit' => 1,
                            'origem'       => 'LINK',
                            'situacao'     => 'P'
                        ]
                    ]);
                }

            }else{
                return false;
            }

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

        return true;
    }

    public static function associarConviteAdegaVirada($codigo, $ClienteConvite){

        try {
            
            $Participante = AdegaViradaParticipante::where('codigo', $codigo)->where('participando', 1)->first();
            if(!$Participante){
                return false;
            }

            $ParticipanteIndicacao = AdegaViradaParticipanteIndicacao::where('adega_virada_participante_id', $Participante->id)->where('email', $ClienteConvite->user->email)->first();

            if($Participante){

                if($ParticipanteIndicacao){
                    
                    $sql = "UPDATE adega_virada_participante_indicacao SET cadastro_id = {$ClienteConvite->id}, situacao = 'A', cpf = '{$ClienteConvite->cpf}', telefone = '{$ClienteConvite->telefone}' WHERE id = {$ParticipanteIndicacao->id}";
                    DB::update($sql);

                }elseif(!$ParticipanteIndicacao){
                    DB::table('adega_virada_participante_indicacao')->insert([
                        [
                            'adega_virada_participante_id' => $Participante->id,
                            'cadastro_id'                  => $ClienteConvite->id,
                            'nome_completo'                => $ClienteConvite->nome_completo(),
                            'email'                        => $ClienteConvite->user->email,
                            'cpf'                          => $ClienteConvite->cpf,
                            'telefone'                     => $ClienteConvite->telefone,
                            'data_cadastro'                => date('Y-m-d H:i:s'),
                            'situacao'                     => 'A'
                        ]
                    ]);
                }

            }else{
                return false;
            }

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

        return true;
    }

    public static function associarCupomIndicacao($codigo_indicacao, $ClienteIndicado){

        try {
            
            $ClienteIndicador = Cadastro::where('codigo_cliente', $codigo_indicacao)->first();
            $Cupom            = Cupom::where('tipo', 'I')->first();

            if($ClienteIndicador && $Cupom){

                //Cadastro Indicação
                $CupomIndicacao = new CupomIndicacao;
                $CupomIndicacao->id_cupom     = $Cupom->id;
                $CupomIndicacao->id_indicador = $ClienteIndicador->id;
                $CupomIndicacao->id_indicado  = $ClienteIndicado->id;
                $CupomIndicacao->save();

                //Cadastro Cupom
                $CupomCadastro = new CupomCadastro;
                $CupomCadastro->id_cupom    = $Cupom->id;
                $CupomCadastro->id_cadastro = $ClienteIndicado->id;
                $CupomCadastro->id_cupom_indicacao = $CupomIndicacao->id;
                $CupomCadastro->save();

            }else{
                return false;
            }

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

        return true;
    }

    public static function buscarMeusCupons(){

        $clienteLogado = GeralService::buscarClienteLogado();

        $first = Cupom::select(
            'cupom.codigo',
            'cupom.data_de_expiracao',
            'cupom.percentual_desconto',
            'cupom.valor_desconto',
            DB::raw('(SELECT pedido_venda.id FROM pedido_venda, cupom_pedido_venda WHERE pedido_venda.id = cupom_pedido_venda.id_pedido_venda AND cupom_pedido_venda.id_cupom = cupom.id AND pedido_venda.id_cliente = ' . $clienteLogado->id . ' LIMIT 1) as uso')
        );
        $first->join('cupom_cadastro', 'cupom.id', '=', 'cupom_cadastro.id_cupom');
        $first->where('cupom_cadastro.id_cadastro', '=', $clienteLogado->id);

        $cupons = $first->orderBy('data_de_expiracao', 'DESC')->orderBy('codigo', 'ASC')->paginate(15);

        return $cupons;
    }


    public static function buscarMeusPagamentos($idPedido = false){
        $cadastro = self::buscarClienteLogado();

        $pedidos = self::buscarPagamentosPorCliente($cadastro->id, $idPedido);

        return $pedidos;
    }

    public static function buscarPagamentosPorCliente($idCadastro, $idPedido = false){
        
        $pedidos = PedidoVenda::select('pedido_venda.*')->where('id_cliente', $idCadastro);

        if($idPedido){
            $pedidos->where('id', $idPedido);
        }else{
            $pedidos->whereRaw('pedido_venda.confraria_id IS NULL');
        }
        
        $pedidos->orderBy('data_fechamento', 'DESC')
        ->with('status', 'produtos')
        ->groupBy('pedido_venda.id');

        return $pedidos->paginate(15);
    }

    public static function buscarPrimeiraAdegaCliente($idCadastro){
        $adega = Adega::where('id_cliente', $idCadastro)->whereRaw('adega.confraria_id IS NULL')->with('pedidoEntrega')->orderBy('data_abertura','asc')->first();
        return $adega;
    }

    public static function buscarTotalAdegasCliente($idCadastro){
        $adega = Adega::select(DB::raw('SUM(adega.valor_total) AS total, SUM(adega.quantidade_produtos) AS quantidade'))->whereRaw('adega.confraria_id IS NULL')->where('id_cliente', $idCadastro)->with('pedidoEntrega')->first();
        return $adega;
    }

    public static function buscarPrimeiroPedidoCliente($idCadastro){
        $pedido = PedidoVenda::select('pedido_venda.*')->where('id_cliente', $idCadastro)->whereRaw('pedido_venda.confraria_id IS NULL')->whereIn('id_status_pedido_venda', [2,7])->orderBy('data_fechamento', 'asc')->first();
        return $pedido;
    }

    public static function buscarTotalPedidosCliente($idCadastro){

        $pedido = PedidoVenda::select(DB::raw('SUM(pedido_venda_has_produto.quantidade) AS quantidade, SUM(pedido_venda_has_produto.valor_total) AS total'))
        ->join('pedido_venda_has_produto','pedido_venda_has_produto.id_pedido_venda','=','pedido_venda.id')
        ->where('pedido_venda.id_cliente', $idCadastro)
        ->whereRaw('pedido_venda.confraria_id IS NULL')
        ->whereIn('pedido_venda.id_status_pedido_venda', [2,7])
        ->first();

        return $pedido;
    }

    public static function buscarPassouAqui($slugTipoDeProduto = ''){
        $data = array();

        $data['listaTipoProduto'] = TipoDeProduto::select('tipo_de_produto.*')->join('produto', function($q)
        {
            $q->on('tipo_de_produto.id', 'produto.id_tipo_produto')
            ->where('produto.destaque', 1);
        })->where('tipo_de_produto.destaque', 1)->groupBy('tipo_de_produto.id')->limit(4)->get();

        if ((!isset($slugTipoDeProduto)) || $slugTipoDeProduto == '') {
            $slugTipoDeProduto = $data['listaTipoProduto'][0]->slug;
        }


        $data['produtoPassouAqui'] = Produto::select('produto.*')->join('tipo_de_produto','produto.id_tipo_produto','=','tipo_de_produto.id')->where('tipo_de_produto.slug',$slugTipoDeProduto)->where('produto.destaque',1)->inRandomOrder()->first();

        $data['outrosProdutos'] = Produto::select('produto.*')->join('tipo_de_produto','produto.id_tipo_produto','=','tipo_de_produto.id')->where('tipo_de_produto.slug',$slugTipoDeProduto)->where('produto.destaque',1)->where('produto.id','!=', $data['produtoPassouAqui']->id)->inRandomOrder()->limit(3)->get();

        $data['slugTipoDeProduto'] = $slugTipoDeProduto;

        return response()->json(array(
            'status' => true,
            'html' => view('site.passou-aqui', $data)->render()
        ));

    }

    public static function buscarPassouAquiCarousel($id_produto,$slug_tipo_produto){
        $data = array();

        $data['listaTipoProduto'] = TipoDeProduto::select('tipo_de_produto.*')->join('produto', function($q)
        {
            $q->on('tipo_de_produto.id', 'produto.id_tipo_produto')
            ->where('produto.destaque', 1);
        })->where('tipo_de_produto.destaque', 1)->groupBy('tipo_de_produto.id')->limit(4)->get();

        $data['produtoPassouAqui'] = Produto::select('produto.*')->join('tipo_de_produto','produto.id_tipo_produto','=','tipo_de_produto.id')->where('produto.id',$id_produto)->first();

        $data['outrosProdutos'] = Produto::select('produto.*')->join('tipo_de_produto','produto.id_tipo_produto','=','tipo_de_produto.id')->where('tipo_de_produto.slug',$slug_tipo_produto)->where('produto.destaque', 1)->where('produto.id','!=', $data['produtoPassouAqui']->id)->inRandomOrder()->limit(3)->get();

        $data['slugTipoDeProduto'] = $slug_tipo_produto;

        return response()->json(array(
            'status' => true,
            'html' => view('site.passou-aqui', $data)->render()
        ));

    }

    /**
    * @param $file Request $file
    * @param $subFolder String 'pedido-venda/comprovante','produtos', 'etc'
    * @return $url Object URL Armazenamento
    * @return $filename Object Filename
    */
    public static function uploadFile($file, $subFolder, $options = [], $nome = false){

        try {
            $subFolderLocal = (isset($options['subFolderLocal']) ? $options['subFolderLocal'] : $subFolder);
            
            $tmpFilePath = '/uploads/' . $subFolderLocal;
            if($file){
                $tmpFileName = time() . '-' . ($nome ? $nome : $file->getClientOriginalName());
                $file = $file->move(public_path() . $tmpFilePath . '/', $tmpFileName);
            }else{
                $tmpFileName       = ($options['filename']);
                $options['delete'] = false;
            }

            $s3       = \Storage::disk('s3');
            $filePath = '/images/' . $subFolder . '/' . $tmpFileName;
            $content  = @file_get_contents(public_path() . $tmpFilePath . '/' . $tmpFileName);
            if($content === false){
                return (object) ['url' => '', 'filename' => ''];
            }

            $options = ['visibility' => 'public'];
            if($file && $file->getExtension() == 'svg'){
                $options = array_merge($options, ['ContentType' => 'image/svg+xml']);
            }
            $s3->put($filePath, $content, $options);
            $url = config('filesystems.disks.s3.url').$filePath;

            if(!isset($options['delete']) || (isset($options['delete']) && $options['delete'] == true)){
                @unlink($file);
                @unlink(public_path() . $tmpFilePath . '/' . $tmpFileName);
            }

        } catch (Exception $e) {
            return (object) ['url' => '', 'filename' => ''];
        }

        return (object) ['url' => $url, 'filename' => $tmpFileName];
    }

    public static function clean_str($string) {
		$string = str_replace(' ', '-', $string);
		return preg_replace('/[^A-Za-z0-9\-]/', '', $string);
	}

    public static function deleteFile($filename, $subFolder){
        @unlink('uploads/' . $subFolder . '/' . $filename);
        $s3 = \Storage::disk('s3')->delete($subFolder . '/' . $filename);
        return $s3;
    }

    public static function deleteFileImages($filename, $subFolder, $subFolderLocal = ''){
        @unlink('uploads/' . (!empty($subFolderLocal) ? $subFolderLocal : $subFolder) . '/' . $filename);
        $subFolder = ($subFolder == 'produto' ? "{$subFolder}s" : $subFolder);
        $s3        = \Storage::disk('s3')->delete('/images/' . $subFolder . '/' . $filename);
        return $s3;
    }

    public static function getApiKeyPagarMe($cliente = FALSE){
        try {

            if(!$cliente){
                $cliente = self::buscarClienteLogado();
            }

            $empresa = ($cliente ? $cliente->empresa : FALSE);

            return Empresa::getApiKeyPagarMe($empresa);

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

    public static function getApiKeyTinyErp($cliente = FALSE, $cliente_id = FALSE){
        try {

            if($cliente_id){
                $cliente = Cadastro::where('id', $cliente_id)->first();
            }

            if(!$cliente){
                $cliente = self::buscarClienteLogado();
            }
            
            return Empresa::getApiKeyTinyErp($cliente->empresa);

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

    public static function getFile($filename, $subFolder){
        return config('filesystems.path') . "/{$subFolder}/{$filename}";
    }

    public static function buscarEnderecosCliente($input){

       $queryEnderecos = CadastroEndereco::select('cadastro_endereco.*', 'f.valor_inicial as valor_final_frete')
        ->join('estado as e', 'e.id', '=', 'cadastro_endereco.estado_id')
        ->join('regiao as r', 'e.regiao_id', '=', 'r.id')
        ->leftJoin('frete as f', function ($join) {
            $join->on('r.id', '=', 'f.regiao_id')
            ->where('f.custo', '=', 0);
        });

        if(isset($input['adega']) && $input['adega']){

            $adegaAberta = $input['adega'];

            $adegaValorTotal = 0;
            if(isset($input['total_adega']) && (!empty($input['total_adega']) && $input['total_adega'] != '0')){
                $adegaValorTotal = $input['total_adega'];
            }elseif ($adegaAberta->valor_total){
                $adegaValorTotal = $adegaAberta->valor_total;
            }

            $queryEnderecos->addSelect('fa.custo as custo_frete');
            $queryEnderecos->leftJoin('frete as fa', function ($join) use($adegaAberta, $adegaValorTotal) {
                $join->on('r.id', '=', 'fa.regiao_id')
                ->where('fa.valor_inicial', '<=', $adegaValorTotal)

                ->where(function($q) use ($adegaValorTotal){
                    $q->where('fa.valor_final', '>=', $adegaValorTotal);
                    $q->orWhere('fa.valor_final', '=', 0);
                });


            });

            //print_r($queryEnderecos->toSql());die();
        }

        if(isset($input['id_cadastro_endereco'])){

            if($input['id_cadastro_endereco']){
                $queryEnderecos->where('cadastro_endereco.id', $input['id_cadastro_endereco']);
            }else{
                $queryEnderecos->where('cadastro_id', $input['id_cliente']);
            }

            $queryEnderecos->groupBy('cadastro_endereco.id')
            ->with('cidade', 'estado')
            ->orderBy('principal', 'DESC')->orderBy('id', 'ASC');

            return $queryEnderecos->first();
        }

        $queryEnderecos->where('cadastro_id', $input['id_cliente'])
            ->where('cadastro_endereco.deletado', 0)
        ->groupBy('cadastro_endereco.id')
        ->with('cidade', 'estado')
        ->orderBy('principal', 'DESC')->orderBy('id', 'ASC');

        return $queryEnderecos->get();
    }

    public static function buscarHtmlOfertasDestaqueAdmin(){
        $data = array();

        $data['ofertasDestaque'] = Oferta::where('destaque', 1)->get();

        return array(
            'status' => true,
            'message' => 'Registros buscados com sucesso!',
            'html' => view('Oferta::admin/lista-ofertas-destaque', $data)->render()
        );

    }

    public static function buscarHtmlTiposProdutoPassouAquiAdmin(){
        $data = array();

        $data['tiposProduto'] = TipoDeProduto::where('destaque', 1)->get();

        return array(
            'status' => true,
            'message' => 'Registros buscados com sucesso!',
            'html' => view('Produto::admin/lista-tipos-produto-passou-aqui', $data)->render(),
        );

    }

    public static function buscarHtmlProdutosPassouAquiAdmin(){
        $data = array();

        $data['produtos'] = Produto::where('destaque', 1)->get();

        return array(
            'status' => true,
            'message' => 'Registros buscados com sucesso!',
            'html' => view('Produto::admin/lista-produtos-passou-aqui', $data)->render(),
        );

    }

    public static function enviarMensagem($cadastro, $pedidoEntrega){

        $email    = trim($cadastro->user->email);
        $nome     = trim($cadastro->nome) . ' ' . trim($cadastro->sobrenome);
        $telefone = trim($cadastro->telefone);
        $assunto  = 'Separação pedido de entrega ' . $pedidoEntrega->id;
        $mensagem = 'Separação pedido de entrega ' . $pedidoEntrega->id;

        $id_cliente   = hexdec( substr(sha1($email), 0, 15) );
        $errorMessage = 'Não foi possível enviar a mensagem. Favor enviar um e-mail para contato@vinumday.com.br';

        if(env('APP_ENV') == 'local'){
            return array(
                'status'  => false,
                'message' => 'Desabilitado no dev'
            );
        }

        try {

            $pessoa = [
               'id'           => $id_cliente,
               "isActive"     => 'true',
               "personType"   => 1,
               "profileType"  => 2,
               "businessName" => $nome,
               "emails" => [
                    0 => [
                        'emailType' => 'Pessoal',
                        'email'     => $email,
                        'isDefault' => true,
                    ]
                ],
               "phone"         => $telefone,
               "accessProfile" => "Clientes",
            ];

            $result = json_decode(GeralService::callMovideskAPI('persons', $pessoa, 'POST'));

            $data = [
                'type'      => 2,
                'subject'   => $assunto,
                'status'    => 'Novo',
                'createdBy' => [
                   'id'           => $id_cliente,
                   "personType"   => 1,
                   "profileType"  => 2,
                   "businessName" => $nome,
                   "email"        => $email,
                   "phone"        => $telefone
                ],
                'clients' => [
                    0 => [
                       'id'           => $id_cliente,
                       "personType"   => 1,
                       "profileType"  => 2,
                       "businessName" => $nome,
                       "email"        => $email,
                       "phone"        => $telefone
                    ]
                  
                ],
                'actions' => [
                    0 => [
                        'type'        => 2,
                        'origin'      => 8,
                        'description' => $mensagem
                    ]
                ]
            ];

            $resultTicket = json_decode(GeralService::callMovideskAPI('tickets', $data, 'POST'));

            if(is_object($resultTicket) && isset($resultTicket->id)){
                $json = array(
                    'status'  => true,
                    'message' => 'E-mail enviado com sucesso! Em breve entraremos em contato.'
                );
            }else{
                $json = array(
                    'status'  => false,
                    'message' => $errorMessage
                );
            }

            $cliente = GeralService::buscarClienteLogado();

            $post = [
                'nome'     => $nome,
                'email'    => $email,
                'telefone' => $telefone,
                'assunto'  => $assunto,
                'mensagem' => $mensagem
            ];

            $contato = new Contato();
            $contato->fill($post);
            if ($cliente) {
                $contato->id_cliente = $cliente->id;
            }
            $contato->save();
            
        } catch (\Exception $e) {
            $json = array(
                'status'  => false,
                'message' => $e->getMessage()
            );
        }

        //envia email alertando em caso de falhas
        if($json['status'] == false){

            $user = User::where('email', 'contato@vinumday.com.br')->first();

            Notification::send(
                $user, 
                new NotificacaoContato(
                    $post,
                    'Verificação estoque solicitação entrega',
                    url('contato')
                )
            );
        }

        Log::info('GeralService::enviarMensagem - ' . json_encode($json));

        return $json;
    }

    public static function enviarREST($url, $data, $optional_headers = null) {

        $params = array('http' => array(
            'method' => 'POST',
            'content' => $data
        ));

        if ($optional_headers !== null) {
            $params['http']['header'] = $optional_headers;
        }

        $ctx = stream_context_create($params);

        $fp = @fopen($url, 'rb', false, $ctx);
        if (!$fp) {
            throw new \Exception("Problema com $url, $php_errormsg");
        }
        $response = stream_get_contents($fp);
        if ($response === false) {
            throw new \Exception("Problema obtendo retorno de $url, $php_errormsg");
        }

        return $response;
    }

    public static function callBitlyAPI($url, $data, $method)
    {
        $token = env('BITLY_TOKEN');
        if(empty($token)){
            return false;
        }
        $curl  = curl_init();
        $url   = 'https://api-ssl.bitly.com/v3/'.$url.'?access_token=' . $token;

        switch ($method)
        {
            case "POST":
                curl_setopt($curl, CURLOPT_POST, 1);

                if ($data)
                    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
                break;
            case "PUT":
                curl_setopt($curl, CURLOPT_PUT, 1);
                break;
            default:
                if ($data)
                    $url = sprintf("%s&%s", $url, http_build_query($data));
        }

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

        $result = curl_exec($curl);

        curl_close($curl);

        return $result;
    }

    public static function callIpAPI($ip, $method = 'GET', $data = []){

        $curl = curl_init();
        $url  = "http://api.ipstack.com/{$ip}?access_key=57f79ba8afcaa223d88b75f72d2fe6e8";

        switch ($method)
        {
            case "POST":
                curl_setopt($curl, CURLOPT_POST, 1);

                if ($data)
                    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
                break;
            case "PUT":
                curl_setopt($curl, CURLOPT_PUT, 1);
                break;
            default:
                if ($data)
                    $url = sprintf("%s?%s", $url, http_build_query($data));
        }

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

        $result = curl_exec($curl);
        $err    = curl_error($curl);

        if($err):
            $err = json_encode(['error' => $err]);
        endif;

        curl_close($curl);

        return $err ? $err : $result;

    }

    public static function callPagarMeAPI($endpoint, $data, $method = 'GET'){

        $curl = curl_init();
        $url  = 'https://api.pagar.me/1/' . $endpoint;

        switch ($method)
        {
            case "POST":
                curl_setopt($curl, CURLOPT_POST, 1);

                if ($data)
                    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
                break;
            case "PUT":
                curl_setopt($curl, CURLOPT_PUT, 1);
                break;
            default:
                if ($data)
                    $url = sprintf("%s?%s", $url, http_build_query($data));
        }

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

        $result = curl_exec($curl);
        $err    = curl_error($curl);

        if($err):
            $err = json_encode(['error' => $err]);
        endif;

        curl_close($curl);

        return $err ? $err : $result;

    }

    public static function callWhatsappAPI($endpoint, $number, $content){

        $custom_id = md5(uniqid(rand(), true));
        $token     = env('WHATSAPP_TOKEN');
        $uid       = env('WHATSAPP_PHONE');

        if(empty($token) || empty($uid)){
            return false;
        }

        $curl    = curl_init();
        $url     = 'https://www.waboxapp.com/api/send/' . $endpoint;
        $content = "token={$token}&uid={$uid}&custom_id={$custom_id}&to=55{$number}&{$content}";
        $method  = 'POST';

        switch ($method)
        {
            case "POST":
                curl_setopt($curl, CURLOPT_POST, 1);

                if ($content)
                    curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
                break;
            case "PUT":
                curl_setopt($curl, CURLOPT_PUT, 1);
                break;
            default:
                if ($content)
                    $url = sprintf("%s&%s", $url, $content);
        }

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

        $result = curl_exec($curl);
        $err    = curl_error($curl);

        if($err):
            $err = json_encode(['error' => $err]);
        endif;

        curl_close($curl);

        return $err ? $err : $result;

    }

    public static function callApiLognex($nfe, $cnpj){

        $nfe  = preg_replace("/[^0-9]/", "", $nfe);
        $nfe  = (int) $nfe;
        $cnpj = preg_replace("/[^0-9]/", "", $cnpj);

        $curl     = curl_init();
        $url      = "https://tms.lognex.com.br/api/v1/lognex/integrations/nfes/{$nfe}/1/occurrences?businessUnit={$cnpj}";
        
        $accountid  = '20bd18e2b42b';
        $accountkey = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhY2NvdW50aTE3NzIzODQ0MDAwMTYzIn0.CgXoqH1Gn0HWaeJetYN7QwIp3j7MdKkEhocEf-ydMLw';
        $company    = '17723844000163';

        $headers = [
            "Content-Type: application/json",
            "accountid: {$accountid}",
            "accountkey: {$accountkey}",
            "company: {$company}"
        ];

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

        $result = curl_exec($curl);
        $err    = curl_error($curl);

        if($err):
            $err = json_encode(['error' => $err]);
        else:
            $result = json_decode($result);
        endif;

        curl_close($curl);

        return $err ? $err : $result;

    }

    public static function callMailchimpAPI($endpoint, $data = [], $method = 'GET', $store = TRUE){

        $curl     = curl_init();
        $store_id = 'SVD_001';
        $url      = "https://us8.api.mailchimp.com/3.0/";
        if($store){
            $url .= "ecommerce/stores/{$store_id}/";
        }
        $url    .= $endpoint;
        // $apikey = 'a3c022ffb57a098910821ad233bf7622-us8';
        $apikey = 'a321caed05b84336fd39270cd3799b3d-us8';

        switch ($method)
        {
            case "POST":
            case "PATH":
                curl_setopt($curl, CURLOPT_POST, 1);
                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
                break;
            case "PUT":
                curl_setopt($curl, CURLOPT_PUT, 1);
                break;
            default:
                if ($data)
                    $url = sprintf("%s?%s", $url, http_build_query($data));
        }

        $headers = [
            'Content-Type: application/json',
            'Authorization: apikey ' . $apikey
        ];

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

        $result = curl_exec($curl);
        $err    = curl_error($curl);

        if($err):
            $err = json_encode(['error' => $err]);
        endif;

        curl_close($curl);

        return $err ? $err : $result;

    }

    public static function callMovideskAPI($url, $data, $method)
    {
        $curl = curl_init();

        $url = 'https://api.movidesk.com/public/v1/'.$url.'?token=351b2833-a790-46e6-b9ca-77c1a95cbc3d&returnAllProperties=false';

        switch ($method)
        {
            case "POST":
                curl_setopt($curl, CURLOPT_POST, 1);

                if ($data)
                    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
                break;
            case "PUT":
                curl_setopt($curl, CURLOPT_PUT, 1);
                break;
            default:
                if ($data)
                    $url = sprintf("%s?%s", $url, http_build_query($data));
        }

        // Optional Authentication:
        //curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        //curl_setopt($curl, CURLOPT_USERPWD, "username:password");

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

        $result = curl_exec($curl);

        curl_close($curl);

        return $result;
    }


    public static function mergeImages($img1_path, $img1_ext){
        $img1_path = substr($img1_path,1);
        $img2_path = 'img/quadrado-branco.jpg';

        list($img1_width, $img1_height) = getimagesize($img1_path);
        list($img2_width, $img2_height) = getimagesize($img2_path);


        if($img1_height > $img2_height){

            if($img1_height >= $img1_width){
                $newImg1_height = $img2_height;
                $newImg1_width = $newImg1_height * $img1_width / $img1_height;
            }else{
                $newImg1_width = $img2_width;
                $newImg1_height = $newImg1_width * $img1_height / $img1_width;
            }

            $path_resized = 'uploads/resized-'.time().'.'.$img1_ext;

            $image_resize = \Image::make($img1_path);
            $image_resize->resize($newImg1_width, $newImg1_height);
            $image_resize->save($path_resized);

            $newImg1 = call_user_func(self::$imageCreateFunc[$img1_ext], $path_resized);


            $merged_width  = $img2_width;
            //get highest
            $merged_height = $img2_height;

            $merged_image = imagecreatetruecolor($merged_width, $merged_height);

            imagealphablending($merged_image, true);
            imagesavealpha($merged_image, true);


            $img2 = imagecreatefromjpeg($img2_path);

            $positionX = ($img2_width - $newImg1_width) / 2;
            $positionY = ($img2_height - $newImg1_height) / 2;

            imagecopy($merged_image, $img2, 0, 0, 0, 0, $img2_width, $img2_height);
            imagecopy($merged_image, $newImg1, $positionX, $positionY, 0, 0, $newImg1_width, $newImg1_height);

            @unlink($path_resized);


        }else{

            $newImg1 = call_user_func(self::$imageCreateFunc[$img1_ext], $img1_path);

            $merged_width  = $img2_width;
            //get highest
            $merged_height = $img2_height;

            $merged_image = imagecreatetruecolor($merged_width, $merged_height);

            imagealphablending($merged_image, true);
            imagesavealpha($merged_image, true);


            $img2 = imagecreatefromjpeg($img2_path);

            $positionX = ($img2_width - $img1_width) / 2;
            $positionY = ($img2_height - $img1_height) / 2;

            imagecopy($merged_image, $img2, 0, 0, 0, 0, $img2_width, $img2_height);
            imagecopy($merged_image, $newImg1, $positionX, $positionY, 0, 0, $img1_width, $img1_height);
        }



        //$save_path = "merged.png";
        //imagepng($merged_image,$save_path);

        return $merged_image;
    }

    public static function buscarPrimeiraCompra(){
        $cadastro = self::buscarClienteLogado();
        if(!$cadastro) return false;
        $pedido   = PedidoVenda::select('pedido_venda.id')->where('id_cliente', '=', $cadastro->id)->where('frete', 0)->whereRaw('pedido_venda.confraria_id IS NULL')->first();
        return ($pedido ? false : true);
    }

    public static function buscarComprasPais(){
        $cadastro = self::buscarClienteLogado();
        $pedidos = PedidoVenda::select('pais.*','pedido_venda_has_produto.quantidade','oferta.preco_oferta','oferta.preco_mercado')

            ->join('pedido_venda_has_produto','pedido_venda.id','=','pedido_venda_has_produto.id_pedido_venda')
            ->join('oferta','oferta.id','=','pedido_venda_has_produto.id_oferta')
            ->join('produto','produto.id','=','pedido_venda_has_produto.id_produto')
            ->join('pais','pais.id','=','produto.id_pais_origem')
            ->join('adega_has_pedido_venda as ahpv', 'pedido_venda_has_produto.id_pedido_venda', '=', 'ahpv.id_pedido_venda')
            ->join('adega as a', 'ahpv.id_adega', '=', 'a.id')
            ->join('pedido_entrega as pe', 'pe.id_adega', '=', 'a.id')
            ->where('pe.id_pedido_entrega_status', 6)
            ->where('a.id_cliente', $cadastro->id)
            ->whereRaw('a.confraria_id IS NULL')
            ->where('a.status', 'F')

            ->get()->groupBy('nome');

        $quantidadeTotalPorPais = 0;
        $valorTotalPorPais = 0;
        $valorTotalEconomizadoPorPais = 0;
        foreach ($pedidos as $pais => $listaProdutos) {
            $quantidadePorPais = 0;
            foreach ($listaProdutos as $produto) {
                $quantidadePorPais += $produto->quantidade;
                $quantidadeTotalPorPais += $produto->quantidade;
                $valorTotalPorPais += $produto->preco_oferta * $produto->quantidade;
                $valorTotalEconomizadoPorPais += ($produto->preco_mercado - $produto->preco_oferta) *  $produto->quantidade;
            }

            $pedidos[$pais]->quantidadeTotal = $quantidadePorPais;
            $pedidos[$pais]->thumbnail_principal = $listaProdutos[0]->thumbnail_principal;
        }

        return array(
            "pedidos" => $pedidos,
            "quantidadeTotalPorPais" => $quantidadeTotalPorPais,
            "valorTotalPorPais" => $valorTotalPorPais,
            "valorTotalEconomizadoPorPais" => $valorTotalEconomizadoPorPais,

        );
    }

    public static function buscarComprasTipo(){
        $cadastro = self::buscarClienteLogado();
        $pedidos = PedidoVenda::select('tipo_de_produto.*','pedido_venda_has_produto.quantidade','produto.preco_de_venda','produto.preco_mercado')->join('pedido_venda_has_produto','pedido_venda.id','=','pedido_venda_has_produto.id_pedido_venda')
        ->join('produto','produto.id','=','pedido_venda_has_produto.id_produto')
        ->join('tipo_de_produto','produto.id_tipo_produto','=','tipo_de_produto.id')
        ->join('adega_has_pedido_venda as ahpv', 'pedido_venda_has_produto.id_pedido_venda', '=', 'ahpv.id_pedido_venda')
        ->join('adega as a', 'ahpv.id_adega', '=', 'a.id')
        ->join('pedido_entrega as pe', 'pe.id_adega', '=', 'a.id')
        ->where('pe.id_pedido_entrega_status', 6)
        ->where('a.id_cliente', $cadastro->id)
        ->whereRaw('a.confraria_id IS NULL')
            ->where('a.status', 'F')

            ->get()->groupBy('nome');

        $quantidadeTotalPorTipo = 0;
        $valorTotalPorTipo = 0;
        foreach ($pedidos as $tipo => $listaProdutos) {
            $quantidadePorTipo = 0;
            foreach ($listaProdutos as $produto) {
                $quantidadePorTipo += $produto->quantidade;
                $quantidadeTotalPorTipo += $produto->quantidade;
                $valorTotalPorTipo += $produto->preco_de_venda * $produto->quantidade;
            }
            $pedidos[$tipo]->quantidadeTotal = $quantidadePorTipo;
            $pedidos[$tipo]->thumbnail_principal = $listaProdutos[0]->thumbnail_principal;
        }

        return array(
            "pedidos" => $pedidos,
            "quantidadeTotalPorTipo" => $quantidadeTotalPorTipo,
            "valorTotalPorTipo" => $valorTotalPorTipo,
        );
    }

    public static function buscarComprasSafra(){
        $cadastro = self::buscarClienteLogado();
        $pedidos = PedidoVenda::select('produto_caracteristica.*','pedido_venda_has_produto.quantidade','produto.preco_de_venda','produto.preco_mercado')

            ->join('pedido_venda_has_produto','pedido_venda.id','=','pedido_venda_has_produto.id_pedido_venda')->join('produto','produto.id','=','pedido_venda_has_produto.id_produto')->join('produto_caracteristica','produto.id','=','produto_caracteristica.id_produto')
            ->join('adega_has_pedido_venda as ahpv', 'pedido_venda_has_produto.id_pedido_venda', '=', 'ahpv.id_pedido_venda')
            ->join('adega as a', 'ahpv.id_adega', '=', 'a.id')
            ->join('pedido_entrega as pe', 'pe.id_adega', '=', 'a.id')
            ->where('pe.id_pedido_entrega_status', 6)
            ->where('a.id_cliente', $cadastro->id)
            ->whereRaw('a.confraria_id IS NULL')
            ->where('a.status', 'F')

            ->get()->groupBy('safra');

        $quantidadeTotalPorSafra = 0;
        $valorTotalPorSafra = 0;

        foreach ($pedidos as $safra => $listaProdutos) {
            $quantidadePorSafra = 0;
            foreach ($listaProdutos as $produto) {
                $quantidadePorSafra += $produto->quantidade;
                $quantidadeTotalPorSafra += $produto->quantidade;
                $valorTotalPorSafra += $produto->preco_de_venda * $produto->quantidade;
            }
            $pedidos[$safra]->quantidadeTotal = $quantidadePorSafra;
        }

        return array(
            "pedidos" => $pedidos,
            "quantidadeTotalPorSafra" => $quantidadeTotalPorSafra,
            "valorTotalPorSafra" => $valorTotalPorSafra,
        );
    }

    public static function buscarProdutosCompradosPorCliente($idCadastro, $query = null){
        $entregas = Produto::select('produto.*', 'pa.valor as avaliacaoValor', 'pa.experiencia as avaliacaoExperiencia')
        ->join('pedido_venda_has_produto as pvhp', 'pvhp.id_produto', '=', 'produto.id')
        ->join('pedido_venda as pv', 'pv.id', '=', 'pvhp.id_pedido_venda')
        ->join('adega_has_pedido_venda as ahpv', 'pv.id', '=', 'ahpv.id_pedido_venda')
        ->join('adega as a', 'ahpv.id_adega', '=', 'a.id')
        ->join('pedido_entrega as pe', 'pe.id_adega', '=', 'a.id')

        ->leftJoin('produto_avaliacao as pa', function($join) use ($idCadastro)
        {
            $join->on('pa.id_produto', '=', 'produto.id');
            $join->on('pa.id_cadastro','=', DB::raw($idCadastro));
        })

        ->where('pe.id_pedido_entrega_status', 6)
        ->where('a.id_cliente', $idCadastro)
        ->where('a.status', 'F');


        if ($query != null){
            $entregas->join('pais', 'pais.id', '=', 'produto.id_pais_origem');
            $entregas->join('tipo_de_produto', 'tipo_de_produto.id', '=', 'produto.id_tipo_produto');

            $entregas->where(function($q) use($query){
                $q->orwhere('produto.nome', 'LIKE', '%'.$query.'%');
                $q->orwhere('pais.nome', 'LIKE', '%'.$query.'%');
                $q->orwhere('tipo_de_produto.nome', 'LIKE', '%'.$query.'%');
            });


            //$entregas->where('produto', 'LIKE', '%'.$query.'%');
        }



        $listaEntregas = $entregas->orderBy('pv.data_fechamento', 'DESC')
        ->with('tipo', 'paisOrigem')
        ->groupBy('produto.id')->get();

        return $listaEntregas;
    }

     public static function buscarMeuHistorico($query = null){
        $cadastro = self::buscarClienteLogado();
        $entregas = self::buscarProdutosCompradosPorCliente($cadastro->id, $query);

        return $entregas;
    }

    public static function buscarListaAdegas($id_cliente = FALSE, $id_pedido_venda = FALSE, $id_adega = FALSE, $confraria_id = FALSE){

        $query = Adega::select(
                DB::raw('DISTINCT adega.id'),
                DB::raw('adega.quantidade_pedidos, adega.quantidade_produtos, adega.valor_total'),
                DB::raw('(
                    SELECT 
                        count(ahpv.id) 
                    FROM 
                        adega_has_pedido_venda ahpv, 
                        pedido_venda pv 
                    WHERE 
                        ahpv.id_pedido_venda = pv.id 
                        AND ahpv.id_adega = adega.id
                        AND pv.id_status_pedido_venda = 5 AND pv.frete = 0
                ) pedidos_cancelados'),
                DB::raw('(
                    SELECT 
                        count(ahpv.id) 
                    FROM 
                        adega_has_pedido_venda ahpv, 
                        pedido_venda pv 
                    WHERE 
                        ahpv.id_pedido_venda = pv.id 
                        AND ahpv.id_adega = adega.id
                        AND pv.id_status_pedido_venda = 4 AND pv.frete = 0
                ) pedidos_estornados'),
                DB::raw('(
                    SELECT 
                        count(ahpv.id) 
                    FROM 
                        adega_has_pedido_venda ahpv, 
                        pedido_venda pv 
                    WHERE 
                        ahpv.id_pedido_venda = pv.id 
                        AND ahpv.id_adega = adega.id
                        AND pv.id_status_pedido_venda IN (2,7) AND pv.frete = 0
                ) qtde_pedidos'),
                DB::raw('(
                    SELECT 
                        sum(pvhp.valor_total)
                    FROM 
                        adega_has_pedido_venda ahpv, 
                        pedido_venda pv,
                        pedido_venda_has_produto pvhp 
                    WHERE 
                        ahpv.id_pedido_venda = pv.id 
                        AND pv.id = pvhp.id_pedido_venda
                        AND ahpv.id_adega = adega.id
                        AND pv.id_status_pedido_venda IN (2,7) AND pv.frete = 0
                ) total_pedidos'),
                DB::raw("(
                    SELECT 
                        sum(pvhp.quantidade) 
                    FROM 
                        adega_has_pedido_venda ahpv, 
                        pedido_venda pv,
                        pedido_venda_has_produto pvhp,
                        oferta
                    WHERE 
                        ahpv.id_pedido_venda = pv.id 
                        AND ahpv.id_adega = adega.id
                        AND pvhp.id_pedido_venda = pv.id 
                        AND pvhp.id_oferta = oferta.id
                        AND pv.id_status_pedido_venda IN (2,7) AND pv.frete = 0 AND oferta.titulo NOT LIKE '%combo%'
                ) qtde_produtos"),
                DB::raw("(
                    SELECT 
                        sum(pvhp.quantidade) / (
                            SELECT 
                                (COUNT(DISTINCT ohp.id_produto) / COUNT(DISTINCT ohp.id_oferta)) produtos_ofertas
                            FROM 
                                adega_has_pedido_venda ahpv
                                INNER JOIN pedido_venda pv ON pv.id = ahpv.id_pedido_venda
                                INNER JOIN pedido_venda_has_produto pvhp ON pvhp.id_pedido_venda = pv.id
                                INNER JOIN oferta ON oferta.id = pvhp.id_oferta
                                INNER JOIN oferta_has_produto ohp ON ohp.id_oferta = oferta.id 
                            WHERE adega.id = ahpv.id_adega AND pv.id_status_pedido_venda IN (2,7) AND pv.frete = 0 AND oferta.titulo LIKE '%combo%'
                        )
                    FROM 
                        adega_has_pedido_venda ahpv, 
                        pedido_venda pv,
                        pedido_venda_has_produto pvhp,
                        oferta
                    WHERE 
                        ahpv.id_pedido_venda = pv.id 
                        AND ahpv.id_adega = adega.id
                        AND pvhp.id_pedido_venda = pv.id 
                        AND pvhp.id_oferta = oferta.id 
                        AND pv.id_status_pedido_venda IN (2,7) AND pv.frete = 0 AND oferta.titulo LIKE '%combo%'
                ) qtde_produtos_combo")
        );
    
        if(!$confraria_id){
            if($id_cliente){
                $query->where('id_cliente', $id_cliente);
            }else{
                $query->havingRaw('pedidos_estornados > 0 OR pedidos_cancelados > 0');
            }
        }

        if($confraria_id && !empty($confraria_id)){
            $query->where('adega.confraria_id', $confraria_id);
        }

        if($id_pedido_venda){
            $query->whereRaw('EXISTS (SELECT 1 FROM adega_has_pedido_venda ahpv WHERE ahpv.id_adega = adega.id AND ahpv.id_pedido_venda = ' . $id_pedido_venda . ')');
        }

        if($id_adega){
            $query->whereRaw('EXISTS (SELECT 1 FROM adega_has_pedido_venda ahpv WHERE ahpv.id_adega = adega.id AND ahpv.id_adega = ' . $id_adega . ')');
        }

        Log::info("FILTROS GeralService::buscarListaAdegas() - id_cliente => {$id_cliente}, id_pedido_venda => {$id_pedido_venda}, id_adega => {$id_adega}, confraria_id => {$confraria_id}");
        // Log::info($query->toSql());

        $listaAdegas = $query->get();

        foreach ($listaAdegas as $listAdega) {
            $listAdega->total_pedidos       = $listAdega->total_pedidos == '' ? 0 : $listAdega->total_pedidos;
            $listAdega->qtde_produtos       = $listAdega->qtde_produtos == '' ? 0 : $listAdega->qtde_produtos;
            $listAdega->qtde_pedidos        = $listAdega->qtde_pedidos == '' ? 0 : $listAdega->qtde_pedidos;
            $listAdega->qtde_produtos_combo = $listAdega->qtde_produtos_combo == '' ? 0 : $listAdega->qtde_produtos_combo;
            $listAdega->quantidade_pedidos  = $listAdega->quantidade_pedidos == '' ? 0 : $listAdega->quantidade_pedidos;
            $listAdega->quantidade_produtos = $listAdega->quantidade_produtos == '' ? 0 : $listAdega->quantidade_produtos;
        }

        return $listaAdegas;
    }

    public static function mascaraCpf($cpf){
        $cpf = preg_replace("/[^0-9]/", "", $cpf);
        $cpf = str_pad($cpf, 11, '0', STR_PAD_LEFT);
        $cpf = substr($cpf, 0, 3).'.'.substr($cpf, 3, 3).'.'.substr($cpf, 6, 3).'-'.substr($cpf, 9, 2);
        return $cpf;
    }

    public static function mascararCnpj($mask, $str){
        if(strlen($str) > 14){
            return '';
        }

        $str = str_replace(" ","",$str);
    
        for($i=0;$i<strlen($str);$i++){
            $mask[strpos($mask,"#")] = $str[$i];
        }
    
        return $mask;
    
    }

    public static function checkUnidadeNegocio($obj, $tipo, $adega_id = FALSE){

        $unidade_negocio_id = 1;

        try {
            
            switch ($tipo) {
                case 'pedido-venda':
                    //Verifica Produtos
                    $pedidoVendaHasProduto = PedidoVendaHasProduto::select('produto.unidade_negocio_id')
                    ->join('produto', 'produto.id', '=', 'pedido_venda_has_produto.id_produto')
                    ->where('pedido_venda_has_produto.id_pedido_venda', $obj->id)
                    ->where('produto.unidade_negocio_id', '<>', $unidade_negocio_id)
                    ->first();
                    if($pedidoVendaHasProduto){
                        $unidade_negocio_id = $pedidoVendaHasProduto->unidade_negocio_id;
                        Log::info("checkUnidadeNegocio:pedido-venda => {$unidade_negocio_id}");
                    }
                    break;
                case 'pedido-entrega':
                    $adegaHasPedidoVenda = AdegaHasPedidoVenda::select('pedido_venda.unidade_negocio_id')
                    ->join('pedido_venda', 'pedido_venda.id', '=', 'adega_has_pedido_venda.id_pedido_venda')
                    ->where('adega_has_pedido_venda.id_adega', $adega_id)
                    ->where('pedido_venda.unidade_negocio_id', '<>', $unidade_negocio_id)
                    ->first();
                    if($adegaHasPedidoVenda){
                        $unidade_negocio_id = $adegaHasPedidoVenda->unidade_negocio_id;
                        Log::info("checkUnidadeNegocio:pedido-entrega => {$unidade_negocio_id}");
                    }
                    break;
                default:
                    $unidade_negocio_id = 1;
                    break;
            }

        } catch (Exception $e) {
            Log::info('GeralService::checkUnidadeNegocio => Exception: ' . $e->getMessage());
            $unidade_negocio_id = 1;
        }

        return $unidade_negocio_id;

    }

    public static function checkBlockCadastroCliente($pedidoVenda){

        $data_created = date('Y-m-d', strtotime("-30 days",strtotime(date('Y-m-d'))));

        //Bloqueio Cliente por Tentativas de Pagamento sem Cartão Salvo
        $Tentativas = AcaoUsuario::select('acao_usuario.id')->join('cadastro','cadastro.id','=','acao_usuario.id_cliente')
                                ->join('sis_users','sis_users.id','=','cadastro.user_id')
                                ->where('acao_usuario.tipo', 'usuario')->where('acao_usuario.acao', 'compra-cartao')->where('acao_usuario.status', 0)
                                ->whereDate('sis_users.created_at', '>=', $data_created)
                                ->whereDate('acao_usuario.data_acao', '=', date('Y-m-d'))
                                ->where('acao_usuario.id_cliente', $pedidoVenda->id_cliente)
                                ->where('cadastro.cliente_analisado', 'N')
                                ->get();

        if(count($Tentativas) == 3){
            $cadastro = $pedidoVenda->cliente;
            $cadastro->bloqueio_cliente = 1;
            $cadastro->data_bloqueio    = date('Y-m-d H:i:s');
            $cadastro->motivo_bloqueio  = '3ª Tentativa pagamento recusado sem cartão salvo!';
            $cadastro->save();
            return false;
        }

        //Bloqueio por Pedido Novo Cliente com mais de 6 ofertas
        $Pedidos = PedidoVenda::select('pedido_venda.id')->join('cadastro','cadastro.id','=','pedido_venda.id_cliente')
                                ->join('sis_users','sis_users.id','=','cadastro.user_id')
                                ->where('pedido_venda.id_cliente', $pedidoVenda->id_cliente)
                                ->whereRaw('pedido_venda.confraria_id IS NULL')
                                ->where('pedido_venda.frete', 0)
                                ->where('cadastro.cliente_analisado', 'N')
                                ->get();

        if(count($Pedidos) == 1 && $pedidoVenda->nr_ofertas > 6){
            $cadastro = $pedidoVenda->cliente;
            $cadastro->bloqueio_cliente = 1;
            $cadastro->data_bloqueio    = date('Y-m-d H:i:s');
            $cadastro->motivo_bloqueio  = '1º pedido com mais de 6gf';
            $cadastro->save();
            return false;
        }

        Log::info("Pedidos Cliente: {$pedidoVenda->id_cliente} => " . count($Pedidos) . " ({$pedidoVenda->nr_ofertas})");

        // Pedido de venda de frete para quem se cadastrou nos últimos 30 dias
        $Pedidos = PedidoVenda::select('pedido_venda.id')->join('cadastro','cadastro.id','=','pedido_venda.id_cliente')
                                ->join('sis_users','sis_users.id','=','cadastro.user_id')
                                ->whereDate('sis_users.created_at', '>=', $data_created)
                                ->where('pedido_venda.id_cliente', $pedidoVenda->id_cliente)
                                ->whereRaw('pedido_venda.confraria_id IS NULL')
                                ->where('pedido_venda.frete', 1)
                                ->where('cadastro.cliente_analisado', 'N')
                                ->get();

        if(count($Pedidos) > 0){
            $cadastro = $pedidoVenda->cliente;
            $cadastro->bloqueio_cliente = 1;
            $cadastro->data_bloqueio    = date('Y-m-d H:i:s');
            $cadastro->motivo_bloqueio  = 'Pedido de venda de frete para quem se cadastrou nos últimos 30 dias';
            $cadastro->save();
            return false;
        }

        //Bloqueio 2 Pedidos em um intervalo de 1h
        $data_fechamento = date('Y-m-d H:i:s', strtotime("-1 hour",strtotime(date('Y-m-d H:i:s'))));
        $Pedidos         = PedidoVenda::select('pedido_venda.id')->join('cadastro','cadastro.id','=','pedido_venda.id_cliente')
                                ->join('sis_users','sis_users.id','=','cadastro.user_id')
                                ->whereDate('sis_users.created_at', '>=', $data_created)
                                ->where('pedido_venda.id_cliente', $pedidoVenda->id_cliente)
                                ->whereRaw('pedido_venda.confraria_id IS NULL')
                                ->where('pedido_venda.data_fechamento', '>=', $data_fechamento)
                                ->where('pedido_venda.frete', 0)
                                ->where('cadastro.cliente_analisado', 'N')
                                ->get();

        if(count($Pedidos) == 2){
            $cadastro = $pedidoVenda->cliente;
            $cadastro->bloqueio_cliente = 1;
            $cadastro->data_bloqueio    = date('Y-m-d H:i:s');
            $cadastro->motivo_bloqueio  = '2 pedidos em um intervalo de 1h';
            $cadastro->save();
            return false;
        }

        //Bloqueio 3 Pedidos em um intervalo de 12h
        $data_fechamento = date('Y-m-d H:i:s', strtotime("-12 hours",strtotime(date('Y-m-d H:i:s'))));
        $Pedidos         = PedidoVenda::select('pedido_venda.id')->join('cadastro','cadastro.id','=','pedido_venda.id_cliente')
                                ->join('sis_users','sis_users.id','=','cadastro.user_id')
                                ->whereDate('sis_users.created_at', '>=', $data_created)
                                ->where('pedido_venda.id_cliente', $pedidoVenda->id_cliente)
                                ->whereRaw('pedido_venda.confraria_id IS NULL')
                                ->where('pedido_venda.data_fechamento', '>=', $data_fechamento)
                                ->where('pedido_venda.frete', 0)
                                ->where('cadastro.cliente_analisado', 'N')
                                ->get();

        if(count($Pedidos) >= 3){
            $cadastro = $pedidoVenda->cliente;
            $cadastro->bloqueio_cliente = 1;
            $cadastro->data_bloqueio    = date('Y-m-d H:i:s');
            $cadastro->motivo_bloqueio  = '3 pedidos em um intervalo de 12h';
            $cadastro->save();
            return false;
        }

        return true;

    }

    public static function checkoutTracking($tipo, $post){

        try {
            
            if(!session('hash_tracking')){
                $hash_tracking = md5(date('Y-m-d H:i:s').microtime(true));
                session(['hash_tracking' => $hash_tracking]);
            }

            $cadastro   = self::buscarClienteLogado();
            $id_cliente = $cadastro ? $cadastro->id : (isset($post['id_cliente']) ? $post['id_cliente'] : NULL);
            $hash       = session('hash_tracking');
            $acao       = (isset($post['acao']) ? $post['acao'] : 'click');
            $observacao = (isset($post['observacao']) ? $post['observacao'] : '');
            $status     = (isset($post['status']) ? $post['status'] : 1);

            $params = [
                $tipo,
                $post['id_tipo'],
                $id_cliente,
                $hash,
                (isset($post['quantidade']) ? $post['quantidade'] : NULL),
                $acao,
                $status,
                $observacao,
                date('Y-m-d H:i:s')
            ];

            DB::insert('insert into acao_usuario (tipo, id_tipo, id_cliente, hash, quantidade, acao, status, observacao, data_acao) values (?, ?, ?, ?, ?, ?, ?, ?, ?)', $params);

            if($tipo == 'usuario' && $acao == 'compra-cartao' && $status == 0){

                $data_created = date('Y-m-d', strtotime("-30 days",strtotime(date('Y-m-d'))));

                //Bloqueio Cliente por Tentativas de Pagamento sem Cartão Salvo
                $Tentativas = AcaoUsuario::select('acao_usuario.id')->join('cadastro','cadastro.id','=','acao_usuario.id_cliente')
                                        ->join('sis_users','sis_users.id','=','cadastro.user_id')
                                        ->where('acao_usuario.tipo', 'usuario')->where('acao_usuario.acao', 'compra-cartao')->where('acao_usuario.status', 0)
                                        ->whereDate('sis_users.created_at', '>=', $data_created)
                                        ->whereDate('acao_usuario.data_acao', '=', date('Y-m-d'))
                                        ->where('acao_usuario.id_cliente', $id_cliente)
                                        ->where('cadastro.cliente_analisado', 'N')
                                        ->get();

                if(count($Tentativas) == 3){
                    $cadastro = Cadastro::find($id_cliente);
                    $cadastro->bloqueio_cliente = 1;
                    $cadastro->data_bloqueio    = date('Y-m-d H:i:s');
                    $cadastro->motivo_bloqueio  = '3ª Tentativa pagamento recusado sem cartão salvo!';
                    $cadastro->save();
                }

            }

            return true;

        } catch (Exception $e) {
            Log::info('GeralService::checkoutTracking error => ' . $e->getMessage());
            return false;
        }

    }

    public static function recalcularCashback($pedidoVenda){

        if($pedidoVenda->contaCorrente){
            $valor_cashback = $pedidoVenda->contaCorrente->valor;
            $tipo_movimento = $pedidoVenda->contaCorrente->tipo_movimento;
            Log::info('GeralService::recalcularCashback => tipo_movimento: ' . $tipo_movimento);
            Log::info('GeralService::recalcularCashback => valor_cashback: ' . $valor_cashback);
            $pedidoVenda->contaCorrente->delete();
            $cliente = Cadastro::where('id', $pedidoVenda->id_cliente)->first();

            if($cliente->contaCorrente){
                if($tipo_movimento == 'E'){
                    $saldo = $cliente->contaCorrente->saldo - $valor_cashback;
                }else if($tipo_movimento == 'S'){
                    $saldo = $cliente->contaCorrente->saldo + $valor_cashback;
                }else{
                    return false;
                }
                $saldo = number_format($saldo, 2, '.', '');
                Log::info('GeralService::recalcularCashback => saldo: ' . $saldo);
                $cliente->contaCorrente->saldo = $saldo;
                $cliente->contaCorrente->save();
            }
        }

        return true;

    }

    public static function recalcularAdega($id_cliente = FALSE, $id_pedido_venda = FALSE, $id_adega = FALSE, $confraria_id = FALSE){

        $listaAdegas = GeralService::buscarListaAdegas($id_cliente, $id_pedido_venda, $id_adega, $confraria_id);

        //Atualiza Pedidos Cancelados/Estornados x Adega
        foreach ($listaAdegas as $adega) {

            $qtde_produtos = (!empty($adega->qtde_produtos) ? $adega->qtde_produtos : 0) + (!empty($adega->qtde_produtos_combo) ? $adega->qtde_produtos_combo : 0);

            if($adega->quantidade_pedidos != $adega->qtde_pedidos || $adega->quantidade_produtos != $qtde_produtos || $adega->valor_total != $adega->total_pedidos){

                $qtde_pedidos  = (!empty($adega->qtde_pedidos) ? $adega->qtde_pedidos : 0);
                $total_pedidos = (!empty($adega->total_pedidos) ? $adega->total_pedidos : 0);
                $qtde_produtos = number_format($qtde_produtos, 0, '','');

                $sqlUpdateAdega = "UPDATE adega SET quantidade_pedidos = {$qtde_pedidos}, quantidade_produtos = {$qtde_produtos}, valor_total = {$total_pedidos} WHERE id = {$adega->id}";
                DB::update(DB::raw($sqlUpdateAdega));

            }

        }

        if($id_cliente){
            $confraria = ConfrariaService::buscarConfrariaUsuarioLogado($id_cliente);
            if($confraria){
                $confraria_id = $confraria->id;
            }
        }

        if(!empty($confraria_id)){
            ConfrariaService::recalcularConfraria($confraria_id, $id_cliente);
        }

        return true;
    }

    public static function atualizaQtdeVendidaCanal($oferta, $quantidade){

        $dataAtual   = date('Y-m-d H:i');

        $CanalHasOferta = CanalHasOferta::select(DB::raw("canal_has_oferta.*"))
            ->join('oferta', 'canal_has_oferta.id_oferta', '=', 'oferta.id')
            ->join('canal as c', 'c.id', '=', 'canal_has_oferta.id_canal')
            ->whereRaw('canal_has_oferta.deleted_at IS NULL')
            ->where('c.data_inicio', '<=', $dataAtual)
            ->where('c.data_fim', '>=', $dataAtual)
            ->where('oferta.id', $oferta->id)
            ->first();

        if($CanalHasOferta){
            
            $sql = "UPDATE canal_has_oferta SET qtde_vendida = qtde_vendida + {$quantidade}, disponibilidade_canal = {$oferta->estoque} WHERE id = {$CanalHasOferta->id}";
            DB::update(DB::raw($sql));

            $CanalHasOferta->qtde_vendida = $CanalHasOferta->qtde_vendida + $quantidade;
            $CanalHasOferta->disponibilidade_canal = $oferta->estoque;
            GeralService::logCanalHasOferta($CanalHasOferta);

        }

        Log::info("atualizaQtdeVendidaCanal");

        return true;

    }

    public static function atualizarDisponibilidadeCanal($oferta, $origem){

        $basicInfo = BasicInfo::first();

        if($basicInfo->liberar_canais == 1){

            $dataAtual = date('Y-m-d H:i');

            $CanalHasOferta = CanalHasOferta::select(DB::raw("canal_has_oferta.*"))
            ->join('oferta', 'canal_has_oferta.id_oferta', '=', 'oferta.id')
            ->join('canal as c', 'c.id', '=', 'canal_has_oferta.id_canal')
            ->whereRaw('canal_has_oferta.deleted_at IS NULL')
            ->where('c.data_inicio', '<=', $dataAtual)
            ->where('c.data_fim', '>=', $dataAtual)
            ->where('oferta.id', $oferta->id)
            ->first();

            if($CanalHasOferta){
                $sql = "UPDATE canal_has_oferta SET disponibilidade_canal = {$oferta->estoque} WHERE id = {$CanalHasOferta->id}";
                DB::update(DB::raw($sql));
                Log::info($sql);
                $CanalHasOferta->disponibilidade_canal = $oferta->estoque;
                GeralService::logCanalHasOferta($CanalHasOferta);
            }

            Log::info("GeralService::atualizarDisponibilidadeCanal from {$origem} => {$oferta->id} - {$oferta->estoque}");

        }

        return true;

    }

    public static function logCanalHasOferta($CanalHasOferta){

        $quantidade            = !empty($CanalHasOferta->quantidade) ? $CanalHasOferta->quantidade : 0;
        $ordenacao             = !empty($CanalHasOferta->ordenacao) ? $CanalHasOferta->ordenacao : 1;
        $qtde_vendida          = !empty($CanalHasOferta->qtde_vendida) ? $CanalHasOferta->qtde_vendida : 0;
        $disponibilidade_canal = !empty($CanalHasOferta->disponibilidade_canal) ? $CanalHasOferta->disponibilidade_canal : 0;
        $oferta                = $CanalHasOferta->oferta ? json_encode($CanalHasOferta->oferta) : '';
        $oferta                = str_replace("'", "\'", $oferta);

        $sql = "INSERT INTO canal_has_oferta_log (quantidade, qtde_vendida, disponibilidade_canal, id_oferta, id_canal, ordenacao, oferta, created_at) VALUES 
        ({$quantidade},{$qtde_vendida},{$disponibilidade_canal},{$CanalHasOferta->id_oferta},{$CanalHasOferta->id_canal},{$ordenacao},'{$oferta}','".date('Y-m-d H:i:s')."')";
        
        DB::insert($sql);

        return true;
    }

    public static function logPedidoVendaTransacao($pedidoVendaTransacao){

        $id = DB::table('pedido_venda_transacao')->insertGetId(
            [
                'empresa_id'      => isset($pedidoVendaTransacao->empresa_id) ? $pedidoVendaTransacao->empresa_id : NULL,
                'pedido_venda_id' => isset($pedidoVendaTransacao->pedido_venda_id) ? $pedidoVendaTransacao->pedido_venda_id : NULL,
                'cadastro_id'     => isset($pedidoVendaTransacao->cadastro_id) ? $pedidoVendaTransacao->cadastro_id : NULL,
                'customer_id'     => isset($pedidoVendaTransacao->customer_id) ? $pedidoVendaTransacao->customer_id : NULL,
                'transacao_id'    => isset($pedidoVendaTransacao->transacao_id) ? $pedidoVendaTransacao->transacao_id : NULL,
                'valor'           => isset($pedidoVendaTransacao->valor) ? $pedidoVendaTransacao->valor : 0,
                'status'          => $pedidoVendaTransacao->status,
                'observacao'      => $pedidoVendaTransacao->observacao,
                'created_at'      => date('Y-m-d H:i:s')
            ]
        );

        return $id;

    }

    public static function atualizarPedidoAdega($pedidoVenda, $adega = FALSE){

        if(!$adega){
            $adega = Adega::select('adega.*')->join('adega_has_pedido_venda', 'adega.id', '=', 'adega_has_pedido_venda.id_adega')->where('adega_has_pedido_venda.id_pedido_venda', $pedidoVenda->id)->first();
        }

        if($adega){

            if($pedidoVenda->id_status_pedido_venda == 4 || $pedidoVenda->id_status_pedido_venda == 5){

                Log::info('GeralService::atualizarPedidoAdega - ' . $pedidoVenda->id_status_pedido_venda);

                $adega->quantidade_pedidos--;
                foreach ($pedidoVenda->produtos as $pdvHasProduto) {
                    $adega->quantidade_produtos -= $pdvHasProduto->quantidade;
                }
                $adega->valor_total -= $pedidoVenda->total;
                $adega->save();

            }elseif($pedidoVenda->id_status_pedido_venda == 2){

                Log::info('GeralService::atualizarPedidoAdega - ' . $pedidoVenda->id_status_pedido_venda);

                $adega->quantidade_pedidos = $adega->quantidade_pedidos + 1;
                foreach ($pedidoVenda->produtos as $produto) {
                     $adega->quantidade_produtos += $produto->quantidade;
                }
                $adega->valor_total = $adega->valor_total + $pedidoVenda->subtotal;

                $adega->save();

            }
        }else{
            Log::info('GeralService::atualizarPedidoAdega - ' . $pedidoVenda->id_status_pedido_venda);
            Log::info('GeralService::atualizarPedidoAdega - Adega não encontrada - ' . $pedidoVenda->id);
        }

        return $adega;
    }

    public static function buscarAdegasCliente($params){

        $query = Adega::where('id_cliente', $params['id_cadastro'])->whereRaw('adega.confraria_id IS NULL')->orderBy('data_abertura', 'DESC')->with('pedidoEntrega');

        $adegas = $query->get();

        return $adegas;
    }

    public static function buscarHtmlMailchimpCadastro(){

        $data                = [];
        $BasicInfo           = BasicInfo::first();
        $modal_image_desktop = $BasicInfo->modal_image_desktop;
        $modal_image_mobile  = $BasicInfo->modal_image_mobile;
        $modal_text          = $BasicInfo->modal_text;

        if(empty($modal_image_desktop))
            $modal_image_desktop = 'https://vinumdays3.s3.amazonaws.com/images/modal/1538016054-popup_background.png';

        if(empty($modal_image_mobile))
            $modal_image_mobile = 'https://vinumdays3.s3.amazonaws.com/images/modal/1538067581-popup-mobile-background.png';

        if(empty($modal_text))
            $modal_text = "Cadastre-se e tenha acesso a vinhos diferenciados a preços especiais!";

        $data['modal_image_desktop'] = $modal_image_desktop;
        $data['modal_image_mobile']  = $modal_image_mobile;
        $data['modal_text']          = $modal_text;

        $view = view('site/mailchimp-cadastro', $data);

        return $view->render();
    }

    public static function buscarHtmlMeiosPagamentoCliente($params){

        $data = [];

        $data['cadastro'] = Cadastro::find($params['id_cliente']);

        $apiKey  = self::getApiKeyPagarMe($data['cadastro']);
        $pagarMe = new \PagarMe\Sdk\PagarMe($apiKey);

        if(!$data['cadastro']){
            return null;
        }

        foreach ($data['cadastro']->cartoes as $cartao) {
           $cartao->info = $pagarMe->card()->get($cartao->cartao_id);
        }

        $view = view('PedidoEntrega::admin/meios-pagamento-cliente', $data);

        return $view->render();
    }

    public static function buscarCustomerPagarme($cliente){
        $apiKey  = self::getApiKeyPagarMe($cliente);
        $pagarMe = new \PagarMe\Sdk\PagarMe($apiKey);
        try {
            $customer = $pagarMe->customer()->get($cliente->customer_id);

        } catch (\Exception $e) {
            $customer = null;
        }

        return $customer;
    }

	public static function buscarHtmlCupomClientesAdmin($id_cupom){
      $data = array();
		try {
			$data['cadastros'] = Cadastro::select('cadastro.*')->join('cupom_cadastro', 'cadastro.id', '=', 'cupom_cadastro.id_cadastro')->where('cupom_cadastro.id_cupom', $id_cupom)->get();

	      return array(
	         'status' => true,
	         'message' => 'Registros buscados com sucesso!',
	         'html' => view('Cupom::admin/lista-cadastros', $data)->render()
	   	);
		} catch (\Exception $e) {
			return array(
	         'status' => false,
	         'message' => $e->getMessage()
	   	);
		}
   }

   public static function retornaData($mes, $ano) {

        $dia = '01';
        if ( $mes == '8' ) {
            $mes = 9;
        }
        else {
            $mes += 1;
        }

        //PEGO O MES ANTERIOR
        if ( $mes == 1 )
            $mesAnterior = 12;
        else
            $mesAnterior = $mes - 1;

        @$ultimodia = cal_days_in_month(CAL_GREGORIAN, $mesAnterior, $ano);
        if ( $mesAnterior <= 9 )
            $mesAnterior = "0" . $mesAnterior;

        if ( $mes == 3 ) {
            if ( $ano % 4 == 0 ) {
                $ultimodia = 29;
            }
        }

        $data = "{$ano}-{$mesAnterior}-{$ultimodia}";
        return $data;
    }

   public static function gerarPedidoParcial($post){

        try {

            if(count($post['produtos_pedido']) <= 0){
                return true;
            }
            
            DB::beginTransaction();

                $cadastro = Cadastro::find($post['id_cliente']);
                $adega    = Adega::find($post['id_adega']);

                $ProdutosVenda = PedidoVendaHasProduto::select('pedido_venda_has_produto.*')
                ->join('adega_has_pedido_venda AS ahpv','ahpv.id_pedido_venda','=','pedido_venda_has_produto.id_pedido_venda')
                ->join('pedido_venda AS pv','pv.id','=','pedido_venda_has_produto.id_pedido_venda')
                ->where('ahpv.id_adega', $post['id_adega'])
                ->where('pv.id_status_pedido_venda', 2)
                ->get();

                //Verifica Criação Novo Pedido
                $criaNovoPedido  = FALSE;
                $produtos_pedido = $post['produtos_pedido'];
                foreach ($ProdutosVenda as $pedidoVendaProduto) {
                    if($pedidoVendaProduto->valor_total != $pedidoVendaProduto->pedidoVenda->total && in_array("{$pedidoVendaProduto->id_produto}_{$pedidoVendaProduto->id_pedido_venda}", $produtos_pedido)){
                        $criaNovoPedido = TRUE;
                        break;
                    }
                }

                $pedidoVenda = FALSE;
                if($criaNovoPedido){
                    //Cria Pedido Parcial
                    $pedidoVenda = new PedidoVenda();
                    $pedidoVenda->ajuste = 0;
                    $pedidoVenda->data_fechamento = date('Y-m-d H:i:s');
                    $pedidoVenda->nm_referencia = 'Pedido automático para '.$cadastro->nome.' '.$cadastro->sobrenome;
                    $pedidoVenda->assunto = 'Pedido realizado através da plataforma.';
                    $pedidoVenda->id_condicao_comercial = 1; // 1x
                    $pedidoVenda->id_cliente = $cadastro->id;
                    $pedidoVenda->id_status_pedido_venda = 1; // Pendente
                    $pedidoVenda->parcial = 1;
                    $pedidoVenda->save();
                }

                $valor_total = 0;
                $nr_ofertas  = 0;

                //Verificar Descontos
                foreach ($ProdutosVenda as $pedidoVendaProduto){

                    $inProdutosPedido = in_array("{$pedidoVendaProduto->id_produto}_{$pedidoVendaProduto->id_pedido_venda}", $produtos_pedido);

                    if($pedidoVenda && $pedidoVendaProduto->valor_total != $pedidoVendaProduto->pedidoVenda->total && !$inProdutosPedido){

                        $pedidoVendaProduto->pedidoVenda->total      = ($pedidoVendaProduto->pedidoVenda->total - $pedidoVendaProduto->valor_total);
                        $pedidoVendaProduto->pedidoVenda->nr_ofertas = ($pedidoVendaProduto->pedidoVenda->nr_ofertas - $pedidoVendaProduto->quantidade);
                        $pedidoVendaProduto->pedidoVenda->save();

                        $valor_total += $pedidoVendaProduto->valor_total;
                        $nr_ofertas  += $pedidoVendaProduto->quantidade;

                        $pedidoVendaProduto->id_pedido_venda = $pedidoVenda->id;
                        $pedidoVendaProduto->save();

                    }elseif(!$inProdutosPedido){

                        $pedidoVendaProduto->pedidoVenda->id_status_pedido_venda = 1;
                        $pedidoVendaProduto->pedidoVenda->parcial = 1;
                        $pedidoVendaProduto->pedidoVenda->save();
                    }

                }

                //PedidoVenda
                $pedidos  = [];
                foreach ($produtos_pedido as $produtoPedido) {
                    $result = explode("_", $produtoPedido);
                    $pedidos[] = $result[1];
                }

                $updatePedidosSelecionados = "UPDATE pedido_venda SET id_status_pedido_venda = 2, parcial = 0 WHERE id IN (" . implode(",", $pedidos) . ")";
                Log::info('updatePedidosSelecionados: ' . $updatePedidosSelecionados);
                DB::update(DB::raw($updatePedidosSelecionados));

                if($pedidoVenda){
                    //Salva Valores Novo Pedido
                    $pedidoVenda->subtotal   = $valor_total;
                    $pedidoVenda->total      = $valor_total;
                    $pedidoVenda->nr_ofertas = $nr_ofertas;
                    $pedidoVenda->unidade_negocio_id = GeralService::checkUnidadeNegocio($pedidoVenda, 'pedido-venda');
                    $pedidoVenda->save();

                    if($pedidoVenda->total == 0){
                        DB::table('pedido_venda')->where('id', '=', $pedidoVenda->id)->delete();
                        DB::table('adega_has_pedido_venda')->where('id_pedido_venda', '=', $pedidoVenda->id)->delete();
                    }
                }

                GeralService::recalcularAdega($adega->id_cliente, FALSE, $adega->id, $adega->confraria_id);

            DB::commit();

            return true;

        } catch (Exception $e) {
            DB::rollBack();
            Log::info("GeralService::gerarPedidoParcial - " . $e->getMessage());
            return false;
        }
   }

   public static function obterNotaFiscalPedido($pedidoEntrega){

        if(!$pedidoEntrega->disponibilidade || empty($pedidoEntrega->empresa_id) || !isset($pedidoEntrega->empresa)){
            return [
                'status'  => false,
                'message' => 'Pedido não disponível para integração!'
            ];
        }

        $token = $pedidoEntrega->empresa->api_key_tiny_erp;

        if(empty($pedidoEntrega->id_nota_fiscal_erp) && !empty($pedidoEntrega->id_erp)):

            $url          = 'https://api.tiny.com.br/api2/pedido.obter.php';
            $content      = "token={$token}&id={$pedidoEntrega->id_erp}&formato=json";
            $resultPedido = json_decode(GeralService::enviarREST($url, $content));

            if($resultPedido->retorno->status_processamento == 2){
                return [
                    'status' => false,
                    'message' => 'Erro API Pedido: '.$resultPedido->retorno->erros[0]->erro
                ];
            }elseif($resultPedido->retorno->status_processamento == 1){
                return [
                    'status' => false,
                    'message' => 'Erro API Pedido: '.$resultPedido->retorno->erros[0]->erro
                ];
            }

            $pedidoEntrega->id_nota_fiscal_erp = $resultPedido->retorno->pedido->id_nota_fiscal;
            $pedidoEntrega->save();

        endif;

        if(!empty($pedidoEntrega->id_nota_fiscal_erp) && empty($pedidoEntrega->peso_nota_fiscal_erp)):

            $url        = 'https://api.tiny.com.br/api2/nota.fiscal.obter.php';
            $content    = "token={$token}&id={$pedidoEntrega->id_nota_fiscal_erp}&formato=json";
            $resultNota = json_decode(GeralService::enviarREST($url, $content));

            if($resultNota->retorno->status_processamento == 2){
                return [
                    'status' => false,
                    'message' => 'Erro API Nota Fiscal: '.$resultNota->retorno->erros[0]->erro
                ];
            }elseif($resultNota->retorno->status_processamento == 1){
                return [
                    'status' => false,
                    'message' => 'Erro API Nota Fiscal: '.$resultNota->retorno->erros[0]->erro
                ];
            }

            if(empty($pedidoEntrega->nota_fiscal_erp)){
                $pedidoEntrega->nota_fiscal_erp = $resultNota->retorno->nota_fiscal->numero;
            }

            $volumes  = $resultNota->retorno->nota_fiscal->quantidade_volumes;
            $volumes  = $volumes == 0 || empty($volumes) ? 1 : $volumes;

            $pedidoEntrega->peso_nota_fiscal_erp = $resultNota->retorno->nota_fiscal->peso_bruto;
            $pedidoEntrega->valor_nota_erp       = $resultNota->retorno->nota_fiscal->valor_nota;
            $pedidoEntrega->quantidade_volumes_nota_erp = $volumes;

            $pedidoEntrega->save();

        endif;

        return $pedidoEntrega;

   }

   public static function gerarPedidoTiny($pedidoEntrega, $valor_desconto = 0){

        if(env('APP_ENV') != 'production'){
            return [
                'status' => false,
                'message' => 'Desabilitado no DEV'
            ];
        }

        $data = [];

        $nome_completo = $pedidoEntrega->adega->cliente->nome.' '.$pedidoEntrega->adega->cliente->sobrenome;

        $pedido = new \stdClass();
        $pedido->valor_desconto = $valor_desconto;
        $pedido->data_pedido = date('d/m/Y');
        $pedido->forma_envio = 'T';
        $pedido->cliente = new \stdClass();
        $pedido->cliente->codigo = $pedidoEntrega->adega->id_cliente;
        $pedido->cliente->nome = trim($nome_completo);
        $pedido->cliente->tipo = 'F';
        $pedido->cliente->cpf_cnpj = $pedidoEntrega->adega->cliente->cpf;
        $pedido->cliente->fone = $pedidoEntrega->adega->cliente->telefone;
        $pedido->cliente->email = $pedidoEntrega->adega->cliente->user->email;

        $endereco = ($pedidoEntrega->endereco ? $pedidoEntrega->endereco : $pedidoEntrega->adega->cliente->enderecoPrincipal);
        if(!$endereco && count($pedidoEntrega->adega->cliente->enderecos) > 0){
            $endereco = $pedidoEntrega->adega->cliente->enderecos[0];
        }

        if(!$endereco){
            return [
                'status' => false,
                'message' => 'Pedido ou Cliente sem Endereço'
            ];
        }

        $pedido->cliente->endereco    = $endereco->logradouro;
        $pedido->cliente->numero      = $endereco->numero;
        $pedido->cliente->complemento = str_replace(["&"], "E", $endereco->complemento);
        $pedido->cliente->bairro      = $endereco->bairro;
        $pedido->cliente->cep         = $endereco->cep;
        $pedido->cliente->cidade      = $endereco->cidade->nome;
        $pedido->cliente->uf          = $endereco->estado->sigla;
        $pedido->itens = [];

        $produtos        = self::buscarProdutosAdega(['id_adega' => $pedidoEntrega->id_adega, 'id_status_pedido_venda' => 7]);
        $data_fechamento = date('Y-m-d', strtotime("-15 days",strtotime(date('Y-m-d'))));

        //Valida Disponibilidade
        /*
        foreach ($produtos as $produto) {

            //Se Data PedidoVenda for > 15 últimos dias segue adiante
            if($produto->data_pedido_venda > $data_fechamento):
                continue;
            endif;

            if($produto->disponibilidade < 0){
                return [
                    'status'  => false,
                    'message' => "Disponibilidade Produto {$produto->nome} indisponível!"
                ];
                break;
            }
        }
        */

        $quantidadeProdutos = 0;
        foreach ($produtos as $produto) {

            if($produto->quantidade_produto == 0){
                continue;
            }

            $produto_nome = str_replace(["&"], "", $produto->nome);

            $obj = new \stdClass();
            $obj->item = new \stdClass();
            $obj->item->codigo = $produto->sku;
            $obj->item->descricao = trim($produto_nome);
            $obj->item->quantidade = floatval($produto->quantidade_produto);
            $obj->item->unidade = 'gr';
            $obj->item->valor_unitario = floatval(number_format($produto->valor_total_produto / $produto->quantidade_produto,2,'.',''));

            $pedido->itens[] = $obj;

            $quantidadeProdutos += floatval($produto->quantidade_produto);
        }

        $volumes = ceil($quantidadeProdutos / 9);

        if($pedidoEntrega->pedidoVendaFrete){
            $pedido->frete_por_conta = 'R';
            $pedido->valor_frete = $pedidoEntrega->pedidoVendaFrete->total;
        }
        
        $pedido->numero_pedido_ecommerce = $pedidoEntrega->id;
        $pedido->situacao = (!$pedidoEntrega->pedidoVendaFrete || $pedidoEntrega->pedidoVendaFrete->id_status_pedido_venda != 1) ? 'aprovado' : 'aberto';
        $obs = (isset($pedidoEntrega->adega->cliente->obs_nota_fiscal) ? $pedidoEntrega->adega->cliente->obs_nota_fiscal : '');

        //Empresa optante pelo SIMPLES nacionol ou não
        if($pedidoEntrega->empresa->sigla == 'SWC'){
            $obs = "{$obs}";
        }else{
            $obs = "Empresa optante pelo SIMPLES nacional. {$obs}";
        }

        //Observação por Estado
        if($endereco->estado->sigla == 'RJ'){
            if(!empty($obs)){
                $obs = trim($obs) . ". ";
            }
            $obs .= "Para o estado do Rio de Janeiro aplica-se a legislação : Conforme art. 4º, Inc. II do Decreto nº 45.607 de 21 de março de 2016. Benefício fiscal reinstituído por meio do Decreto nº 46.409/2018";
        }

        $pedido->obs = trim($obs);

        $pedido->forma_pagamento = 'credito';

        $data['pedido'] = $pedido;

        // $token = GeralService::getApiKeyTinyErp($pedidoEntrega->adega->cliente);
        $token = Empresa::getApiKeyTinyErp($pedidoEntrega->empresa);

        $pedido = json_encode($data);

        $url = 'https://api.tiny.com.br/api2/pedido.incluir.php';
        $content = "token=$token&pedido=$pedido&formato=json";

        $resultPedido = json_decode(GeralService::enviarREST($url, $content));

        Log::info(json_encode($resultPedido));
        Log::info($pedido);

        if($resultPedido->retorno->status_processamento == 2){
            $result = json_encode($resultPedido);
            if(isset($resultPedido->retorno->registros->registro->erros->erro)){
                $result = $resultPedido->retorno->registros->registro->erros->erro;
            }
            return [
                'status' => false,
                'message' => 'Erro API Pedido 1: '.$result
            ];
        }elseif($resultPedido->retorno->status_processamento == 1){
            return [
                'status' => false,
                'message' => 'Erro API Pedido 2: '.$resultPedido->retorno->erros[0]->erro
            ];
        }

        $id_pedido_tiny = $resultPedido->retorno->registros->registro->id;

        $pedidoEntrega->id_erp = $id_pedido_tiny;


        /*$url = 'https://api.tiny.com.br/api2/cadastrar.codigo.rastreamento.pedido.php';
        $content = "token=$token&id=$id_pedido_tiny&volumes=$volumes&formato=json";

        $resultVolumes = json_decode(GeralService::enviarREST($url, $content));*/



        if(!$pedidoEntrega->pedidoVendaFrete || $pedidoEntrega->pedidoVendaFrete->id_status_pedido_venda != 1){


            $url = 'https://api.tiny.com.br/api2/gerar.nota.fiscal.pedido.php';
            $content = "token=$token&id=$id_pedido_tiny&formato=json&modelo=NFe";

            $resultNota = json_decode(GeralService::enviarREST($url, $content));

            if($resultNota->retorno->status_processamento == 2){
                return [
                    'status' => false,
                    'message' => 'Erro API Nota Fiscal: '.$resultNota->retorno->registros->registro->erros->erro
                ];
            }elseif($resultNota->retorno->status_processamento == 1){
                return [
                    'status' => false,
                    'message' => 'Erro API Nota Fiscal: '.$resultNota->retorno->erros[0]->erro
                ];
            }

            $pedidoEntrega->nota_fiscal_erp    = $resultNota->retorno->registros->registro->numero;
            $pedidoEntrega->id_nota_fiscal_erp = $resultNota->retorno->registros->registro->idNotaFiscal;

        }

        $pedidoEntrega->disponibilidade = 1;
        $pedidoEntrega->save();

        $notafiscal = new \stdClass();
        $notafiscal->notafiscal = new \stdClass();
        $notafiscal->notafiscal->id = $resultNota->retorno->registros->registro->idNotaFiscal; //verificar Undefined variable: resultNota in /var/www/html/vinumday2_0/app/Services/GeralService.php:3991
        $notafiscal->notafiscal->volumes = $volumes;
        $notafiscal->notafiscal->formaEnvio = 'T';

        $url = 'https://api.tiny.com.br/api2/nota.fiscal.cadastrar.codigo.rastreamento.php';
        $content = "token=$token&notafiscal=".json_encode($notafiscal)."&formato=json";

        $resultVolumes = json_decode(GeralService::enviarREST($url, $content));

        if($resultVolumes->retorno->status_processamento == 2){
            return [
                'status' => false,
                'message' => 'Erro API Volumes: '.$resultVolumes->retorno->registros->registro->erros->erro
            ];
        }elseif($resultVolumes->retorno->status_processamento == 1){
            return [
                'status' => false,
                'message' => 'Erro API Volumes: '.$resultVolumes->retorno->erros[0]->erro
            ];
        }

        return [
            'status'        => true,
            'message'       => 'Pedido gerado no Tiny com sucesso!',
            'resultPedido'  => $resultPedido,
            'resultNota'    => $resultNota,
            'resultVolumes' => $resultVolumes
        ];
   }

    public static function gerarCodigoAleatorio($tamanho = 9, $somente_numeros = FALSE){
        $codigo = md5(uniqid(rand(), true));
        if($somente_numeros){
            $codigo = preg_replace("/[^0-9]/", "", $codigo);
        }
        $codigo = str_pad($codigo, $tamanho, 0, STR_PAD_LEFT);
        $codigo = substr($codigo, 0, $tamanho);
        return $codigo;
    }

    public static function buscarOfertaCanalRelampago(){

        $canalRelampago = Canal::select('oferta.thumbnail_principal', 'canal.data_inicio', 'canal.data_fim', 'oferta.preco_mercado', 'oferta.preco_oferta', 'oferta.slug', 'oferta.id as id_oferta', 'oferta.quantidade_maxima_por_cliente')
        ->where('canal.tipo', 'R')
        ->where('canal.data_inicio', '<=', date('Y-m-d H:i'))
        ->where('canal.data_fim', '>=', date('Y-m-d H:i'))
        ->whereRaw('canal_has_oferta.deleted_at IS NULL')
        ->join('canal_has_oferta', 'canal_has_oferta.id_canal', '=', 'canal.id')
        ->join('oferta', 'oferta.id', 'canal_has_oferta.id_oferta')
        ->first();

        return $canalRelampago;
    }

    public static function buscarOfertaRelampago($id){
        $oferta = Oferta::where('id', $id)->with('produtos.produto')->first();
        return $oferta;
    }

    public static function buscarOfertaEquipe($id){
        $oferta = Oferta::where('id', $id)->with('produtos.produto')->first();
        return $oferta;
    }

    public static function buscarTagCliente($cadastroSlug, $tipoTagSlug){
        $tagsCliente = DB::table('cadastro')
        ->select('tag.*', 'tag_tipo.cor', 'tag_tipo.nome as tipoNome', 'tag_tipo.slug as tipoSlug', DB::raw('COUNT(produto_has_tag.tag_id) as qt_tag'))
        ->where('cadastro.slug', $cadastroSlug)
        ->where('tag_tipo.slug', $tipoTagSlug)
        ->join('pedido_venda', 'pedido_venda.id_cliente', '=', 'cadastro.id')
        ->join('pedido_venda_has_produto', 'pedido_venda_has_produto.id_pedido_venda', '=', 'pedido_venda.id')
        ->join('produto_has_tag', 'produto_has_tag.produto_id', '=', 'pedido_venda_has_produto.id_produto')
        ->join('tag', 'tag.id', '=', 'produto_has_tag.tag_id')
        ->join('tag_tipo', 'tag_tipo.id', 'tag.tag_tipo_id')
        ->orderBy('tag_tipo.id', 'asc')
        ->orderBy('qt_tag', 'desc')
        ->groupBy('tag.nome')
        ->take(10)
        ->get();

        return $tagsCliente;
    }


    // Busca sugestões de produto para o cliente conforme
    // os outros produtos já adquiridos
    public static function buscarSugestoesProduto(){
        $clienteLogado = self::buscarClienteLogado();

        if(!$clienteLogado)
            return [];
       $sugestaoProdutos = DB::table('cadastro')
       ->select('produto.nome', 'pais.thumbnail_principal as thumbnail_pais', 'pais.nome as nome_pais', DB::raw('COUNT(produto_has_tag.tag_id) as qt_tag'))
       ->where('cadastro.slug', $clienteLogado->slug)
       ->join('pedido_venda', 'pedido_venda.id_cliente', '=', 'cadastro.id')
       ->join('pedido_venda_has_produto', 'pedido_venda_has_produto.id_pedido_venda', '=', 'pedido_venda.id')
       ->join('produto_has_tag', 'produto_has_tag.produto_id', '=', 'pedido_venda_has_produto.id_produto')
       ->join('produto', 'produto.id', 'produto_has_tag.produto_id')
       ->join('tag', 'tag.id', 'produto_has_tag.tag_id')
       ->join('pais','pais.id','=','produto.id_pais_origem')
       ->orderBy('qt_tag', 'desc')
       ->take(3)
       ->get();

       return $sugestaoProdutos;
    }

    public static function duplicarOferta($oferta_id, $nova_data = false, $duplicar_canal = false){
        $oferta = DB::table('oferta')->where('id', $oferta_id)->first();
        $canalExistente = false;

        if($nova_data){
            if($nova_data == $oferta->data){
                return [
                    'status' => false,
                    'mensagem' => 'Informe uma nova data para essa oferta:'
                ];
            }

            $oferta->data = $nova_data;
        } 
        if($oferta->data == date('Y-m-d')){
            return [
                'status' => false,
                'mensagem' => 'Informe uma nova data para essa oferta:'
            ];
        }

        if($duplicar_canal){
            $canalExistente = DB::table('canal_has_oferta')->where('id_oferta', $oferta->id)->first();
        }

        $oferta->titulo =  'DUPLICADO - ' . $oferta->titulo;
        //$oferta->slug =  $oferta->titulo . '-' . strtotime(date('Y-m-d H:i'));
        $oferta->created_at =  date('Y-m-d H:i:s');
        unset($oferta->id);
        $ofertaArray  = (array) $oferta;

        $novaOfertaId = DB::table('oferta')->insertGetId($ofertaArray);

        if($canalExistente){
            $canalExistente->id_oferta = $novaOfertaId;
            unset($canalExistente->id);
            $canalArray  = (array) $canalExistente;
            DB::table('canal_has_oferta')->insert($canalArray);
        }

        $ofertaHasProdutos = DB::table('oferta_has_produto')->where('id_oferta', $oferta_id)->get();

        foreach($ofertaHasProdutos as $ofertaHasProduto){
            $ofertaHasProduto->id_oferta = $novaOfertaId;
            unset($ofertaHasProduto->id);
            $ofertaHasProdutoArray  = (array) $ofertaHasProduto;
            DB::table('oferta_has_produto')->insert($ofertaHasProdutoArray);
        }

        return [
            'status' => true,
            'mensagem' => 'Oferta duplicada com sucesso!'
        ];
    }

    public static function buscarCupomIndicacaoAtivo(){
        $cupom = DB::table('cupom')
        ->where('tipo', 'I')
        ->where('status', 'A')
        ->whereDate('data_de_expiracao', '>', date('Y-m-d'))
        ->first();

        return $cupom;
    }
/*
    public static function buscarOfertasEmDiscrepancia(){


    $ofertasEmMaisDeUmCanal = DB::table('canal')
    ->select('id_oferta')
    ->join('canal_has_oferta', 'canal.id', '=', 'canal_has_oferta.id_canal')
    ->where('canal.data_fim', '>', date('Y-m-d H:i:s'))
    ->groupBy('id_oferta')
    ->havingRaw('COUNT(DISTINCT canal_has_oferta.id_canal) > 1');
    
    $canaisAtivosComOfertasEmMaisDeUmCanal = Canal::with(['ofertasCanal' => function ($query) use ($ofertasEmMaisDeUmCanal) {
        $query->whereIn('id_oferta', $ofertasEmMaisDeUmCanal);
    }])
    ->whereHas('ofertasCanal', function ($query) use ($ofertasEmMaisDeUmCanal) {
        $query->whereIn('id_oferta', $ofertasEmMaisDeUmCanal);
    })
    ->where('data_fim', '>', date('Y-m-d H:i:s'))
    ->get();


    return $canaisAtivosComOfertasEmMaisDeUmCanal;


        $canaisAtivos = Canal::with('ofertasCanal')
        ->where('canal.data_fim', '>', date('Y-m-d H:i:s'))
        ->get();
        // ->toArray();

        return $canaisAtivos;


        
        $ofertas = Produto::select('produto.*')

        ->join('oferta_has_produto', 'oferta_has_produto.id_produto', 'produto.id')
        ->join('oferta', 'oferta.id', 'oferta_has_produto.id_oferta')

        ->join('canal_has_oferta', 'canal_has_oferta.id_oferta', 'oferta.id')
        ->join('canal', 'canal.id', 'canal_has_oferta.id_canal')

        ->where('canal.data_fim', '>', date('Y-m-d H:i:s'))

        ->groupBy('canal.id')
        ->get();


        return $ofertas;
    }
    */

    public static function buscarOfertasEmDiscrepancia(){ 
        /*
        select `produto`.`id` as `produto_id`, SUM(`oferta`.`estoque`) as `estoqueOferta`, `produto`.`disponibilidade` from `produto` 
        inner join `oferta_has_produto` on `oferta_has_produto`.`id_produto` = `produto`.`id` 
        inner join `oferta` on `oferta_has_produto`.`id_oferta` = `oferta`.`id` 
        inner join `canal_has_oferta` on `canal_has_oferta`.`id_oferta` = `oferta_has_produto`.`id_oferta` 
        inner join `canal` on `canal`.`id` = `canal_has_oferta`.`id_canal` 
        where `canal`.`data_fim` > '2023-08-04'
        and `canal_has_oferta`.`data_final` > '2023-08-04' 
        group by produto.id
        having estoqueOferta <> produto.disponibilidade
        */

        $produtos = DB::table('produto')
        ->select('produto.id as produto_id', 'oferta.id as oferta_id', DB::raw('SUM(oferta.estoque) AS estoqueOferta'), 'produto.disponibilidade')
        ->join('oferta_has_produto', 'oferta_has_produto.id_produto', 'produto.id')
        ->join('oferta', 'oferta_has_produto.id_oferta', 'oferta.id')
        ->join('canal_has_oferta', 'canal_has_oferta.id_oferta', 'oferta_has_produto.id_oferta')
        ->join('canal', 'canal.id', 'canal_has_oferta.id_canal')
        ->where('canal.data_fim', '>', date('Y-m-d'))
        ->where('canal_has_oferta.data_final', '>', date('Y-m-d'))
        ->groupBy('produto.id')
        ->having('estoqueOferta', '<>', 'produto.disponibilidade');


        $produtos = $produtos->get()->filter(function ($value, $key) {
            return $value->estoqueOferta > $value->disponibilidade;
        });  

        return $produtos;

        // print_r($produtos);
        // die();

        /*
        $produtos = DB::table('produto')
        ->select('produto.id as produto_id', 'oferta.id as oferta_id', 'oferta_has_produto.estoque as estoqueOferta')
        ->join('oferta_has_produto', 'oferta_has_produto.id_produto', 'produto.id')
        ->join('oferta', 'oferta.id', 'oferta_has_produto.id_oferta')
        ->join('canal_has_oferta', 'canal_has_oferta.id_oferta', 'oferta.id')
        ->join('canal', 'canal.id', 'canal_has_oferta.id_canal')
        ->join('estoque', 'estoque.produto_id', 'produto.id')
        ->where('canal.data_fim', '>', date('Y-m-d H:i:s'))
        ->toSql();
        */


        $duplicados = [];

        foreach($produtos as $produto){
            $check = collect($produtos)->where('produto_id', $produto->produto_id)
            ->where('oferta_id', '<>', $produto->oferta_id)
            ->first();

            if($check){
                $duplicados[] = $produto;
            }
        }

        $itensAgrupados = [];
        foreach ($duplicados as $item) {
            $produto_id = $item->produto_id;
            $oferta_id = $item->oferta_id;
            $estoqueOferta = $item->estoqueOferta;

            if (!isset($itensAgrupados[$produto_id])) {
                $itensAgrupados[$produto_id] = [];
            }

            $itensAgrupados[$produto_id]['ofertas'][] = ['oferta_id' => $oferta_id, 'estoqueOferta' => $estoqueOferta];
        }
        
        $produtosEstoqueOfertas = [];
        foreach($itensAgrupados as $produtoId => $items){
            $estoqueCount = 0;

            foreach($items['ofertas'] as $item){
                $estoqueCount += $item['estoqueOferta'];
    
                if (!isset($produtosEstoqueOfertas[$produtoId])) {
                    $itensAgrupados[$produtoId] = [];
                }
            }

            $estoque = DB::table('produto')->where('id', $produtoId)->sum('quantidade');
            $produtosEstoqueOfertas[$produtoId] = ['estoqueOferta' => $estoqueCount, 'estoqueTotal' => $estoque];
        }

        print_r($produtosEstoqueOfertas);
        die();

        return $produtosEstoqueOfertas;
    } 

}


Youez - 2016 - github.com/yon3zu
LinuXploit