join( 'cadastro_infraestrutura as infraestrutura', 'infraestrutura.id', 'jornada_bloqueio.infraestrutura_id' ) ->join( 'cadastro_unidade as unidade', 'unidade.id', 'infraestrutura.unidade_id' ) ->join( 'cadastro_especialidade as especialidade', 'especialidade.id', 'jornada_bloqueio.especialidade_id' ) ->join( 'sigtap.ocupacao as ocupacao', 'ocupacao.id', 'especialidade.ocupacao_id' ) ->leftJoin( 'cadastro_usuario as usuario', 'usuario.id', 'jornada_bloqueio.usuario_id' ) ->leftJoin( 'cadastro_cidadao as cidadao', 'cidadao.id', 'usuario.cidadao_id' ) ->select(DB::raw(" jornada_bloqueio.id, unidade.nome_fantasia as unidade_nome_fantasia, COALESCE(infraestrutura.nome, unidade.nome_fantasia) as infraestrutura_nome, CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as ocupacao_descricao, especialidade.nome as especialidade_nome, cidadao.nome as usuario_nome, DATE_FORMAT(jornada_bloqueio.inicio, '%d/%m/%Y') as inicio, DATE_FORMAT(jornada_bloqueio.fim, '%d/%m/%Y') as fim ")); return datatables() ->of($jornadas) ->filterColumn('jornada_bloqueio.inicio', function ($query, $keyword) { $query->whereRaw("DATE_FORMAT(jornada_bloqueio.inicio, '%d/%m/%Y') LIKE ?", ["%{$keyword}%"]) ->orWhereRaw( "CONCAT( SUBSTR(jornada_bloqueio.inicio,9,2), SUBSTR(jornada_bloqueio.inicio,6,2), SUBSTR(jornada_bloqueio.inicio,1,4) ) like ?", ["%{$keyword}%"] ); }) ->filterColumn('jornada_bloqueio.fim', function ($query, $keyword) { $query->whereRaw("DATE_FORMAT(jornada_bloqueio.fim, '%d/%m/%Y') LIKE ?", ["%{$keyword}%"]) ->orWhereRaw( "CONCAT( SUBSTR(jornada_bloqueio.fim,9,2), SUBSTR(jornada_bloqueio.fim,6,2), SUBSTR(jornada_bloqueio.fim,1,4) ) like ?", ["%{$keyword}%"] ); }) ->skipTotalRecords() ->toJson(); } public static function list() { $params = (object) request()->all(); switch (request()->listar) { case 'infraestruturas': { return self::getInfraestruturas($params); } case 'ocupacoes': { return self::getOcupacoes($params); } case 'especialidades': { return self::getEspecialidades($params); } case 'usuarios': { return self::getUsuarios($params); } } } public static function create() { return [ 'form' => [ 'unidades' => self::getUnidades(), 'infraestruturas' => [], 'ocupacoes' => [], 'especialidades' => [], 'usuarios' => [], ], 'model' => [ 'id' => null, 'unidade_id' => null, 'infraestrutura_id' => null, 'ocupacao_id' => null, 'especialidade_id' => null, 'usuario_id' => null, 'periodo' => [ 'start' => null, 'end' => null, ], ] ]; } public static function edit($id) { $bloqueio = JornadaBloqueio::findOrFail($id); return [ 'form' => [ 'unidades' => self::getUnidades($bloqueio->infraestrutura->unidade_id), 'infraestruturas' => self::getInfraestruturas((object) [ 'unidade_id' => $bloqueio->infraestrutura->unidade_id, ], $bloqueio->infraestrutura_id), 'ocupacoes' => self::getOcupacoes((object) [ 'infraestrutura_id' => $bloqueio->infraestrutura_id, ], $bloqueio->especialidade->ocupacao_id), 'especialidades' => self::getEspecialidades((object) [ 'ocupacao_id' => $bloqueio->ocupacao_id, ], $bloqueio->especialidade_id), 'usuarios' => self::getUsuarios((object) [ 'infraestrutura_id' => $bloqueio->infraestrutura_id, 'ocupacao_id' => $bloqueio->especialidade->ocupacao_id, ], $bloqueio->usuario_id), ], 'model' => [ 'id' => $bloqueio->id, 'unidade_id' => $bloqueio->infraestrutura->unidade_id, 'infraestrutura_id' => $bloqueio->infraestrutura_id, 'ocupacao_id' => $bloqueio->especialidade->ocupacao_id, 'especialidade_id' => $bloqueio->especialidade_id, 'usuario_id' => $bloqueio->usuario_id, 'periodo' => [ 'start' => $bloqueio->inicio->format('d/m/Y'), 'end' => $bloqueio->fim->format('d/m/Y'), ], ], ]; } private static function getUnidades($unidadeId = null) { return Unidade::orderBy('nome_fantasia') ->where('id', $unidadeId) ->orWhereHas('infraestruturas', fn ($q) => $q ->whereHas('ambulatorioParametrizacaoJornadaInfraestrutura') ) ->get(['id', 'nome_fantasia']); } private static function getInfraestruturas($params, $infraestruturaId = null) { return Infraestrutura::setEagerLoads([]) ->where('id', $infraestruturaId) ->orWhere(fn ($q) => $q ->where('unidade_id', $params->unidade_id) ->whereHas('ambulatorioParametrizacaoJornadaInfraestrutura') ) ->get(['id', 'nome', 'principal', 'unidade_id']) ->map(fn ($infraestrutura) => [ 'id' => $infraestrutura->id, 'nome' => $infraestrutura->nome, ]) ->sortBy('nome') ->values(); } private static function getOcupacoes($params, $ocupacaoId = null) { return DB::table('sigtap.ocupacao as ocupacao') ->where('ocupacao.id', $ocupacaoId) ->orWhere(function ($query) use ($params) { $query->whereExists(function ($query) use ($params) { $query->select(DB::raw(1)) ->from('cadastro_lotacao as lotacao') ->whereColumn('lotacao.ocupacao_id', 'ocupacao.id') ->where('lotacao.infraestrutura_id', $params->infraestrutura_id); }) ->whereExists(function ($query) { $query->select(DB::raw(1)) ->from('cadastro_especialidade as especialidade') ->whereColumn('especialidade.ocupacao_id', 'ocupacao.id'); }); }) ->orderBy('ocupacao.nome') ->select( 'ocupacao.id', DB::raw("CONCAT(ocupacao.codigo, ' - ', ocupacao.nome) as descricao") ) ->get(); } private static function getEspecialidades($params, $especialidadeId = null) { return Especialidade::where('id', $especialidadeId) ->orWhere('ocupacao_id', $params->ocupacao_id) ->orderBy('nome') ->get(['id', 'nome']); } private static function getUsuarios($params, $usuarioId = null) { return DB::table('cadastro_usuario as usuario') ->join('cadastro_cidadao as cidadao', 'cidadao.id', 'usuario.cidadao_id') ->where('usuario.id', $usuarioId) ->orWhere(function ($query) use ($params) { $query->whereExists(function ($query) use ($params) { $query->select(DB::raw(1)) ->from('cadastro_lotacao as lotacao') ->whereColumn('lotacao.usuario_id', 'usuario.id') ->where('lotacao.infraestrutura_id', $params->infraestrutura_id) ->where('lotacao.ocupacao_id', $params->ocupacao_id); }); }) ->orderBy('cidadao.nome') ->select( 'usuario.id', 'cidadao.nome' ) ->get(); } public static function store() { self::validate(); $params = self::getParams(); self::validateConflito($params); return JornadaBloqueio::create($params)->fresh(); } public static function update($id) { $bloqueio = JornadaBloqueio::findOrFail($id); self::validate(); $params = self::getParams(); self::validateConflito($params, $bloqueio->id); $bloqueio->update($params); return $bloqueio->fresh(); } private static function getParams() { $params = request()->all(); $params['inicio'] = Carbon::createFromFormat('d/m/Y', $params['inicio']); $params['fim'] = Carbon::createFromFormat('d/m/Y', $params['fim']); return $params; } public static function validate() { $rules = [ 'infraestrutura_id' => [ 'required', 'integer', Rule::exists(Infraestrutura::class, 'id'), ], 'especialidade_id' => [ 'required', 'integer', Rule::exists(Especialidade::class, 'id'), ], 'usuario_id' => [ 'nullable', 'integer', Rule::exists(Usuario::class, 'id'), ], 'inicio' => [ 'required', 'date_format:d/m/Y', 'before_or_equal:fim' ], 'fim' => [ 'required', 'date_format:d/m/Y', 'after_or_equal:inicio' ], ]; $messages = []; request()->validate($rules, $messages); } private static function validateConflito($params, $id = null) { $conflito = JornadaBloqueio::when($id, fn ($q) => $q->where('id', '<>', $id)) ->where('infraestrutura_id', $params['infraestrutura_id']) ->where('especialidade_id', $params['especialidade_id']) ->when($params['usuario_id'], fn ($q, $id) => $q->where('usuario_id', $id), fn ($q) => $q->whereNull('usuario_id') ) ->where(fn ($q) => $q ->where(fn ($q) => $q ->whereDate('inicio', '<=', $params['inicio']) ->whereDate('fim', '>=', $params['inicio']) ) ->orWhere(fn ($q) => $q ->whereDate('inicio', '<=', $params['fim']) ->whereDate('fim', '>=', $params['fim']) ) ->orWhere(fn ($q) => $q ->whereDate('inicio', '>=', $params['inicio']) ->whereDate('inicio', '<=', $params['fim']) ) ->orWhere(fn ($q) => $q ->whereDate('fim', '>=', $params['inicio']) ->whereDate('fim', '<=', $params['fim']) ) ) ->exists(); if ($conflito) { throw new ConflitoJornadaBloqueioException(); } } public static function destroy($id) { JornadaBloqueio::findOrFail($id)->delete(); } }