join( 'cadastro_infraestrutura as infraestrutura', 'infraestrutura.id', 'jornada_bloqueio.infraestrutura_id' ) ->join( 'cadastro_unidade as unidade', 'unidade.id', 'infraestrutura.unidade_id' ) ->select(DB::raw(" jornada_bloqueio.id, unidade.nome_fantasia as unidade_nome_fantasia, COALESCE(infraestrutura.nome, unidade.nome_fantasia) as infraestrutura_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); } } } public static function create() { return [ 'form' => [ 'unidades' => self::getUnidades(), 'infraestruturas' => [], ], 'model' => [ 'id' => null, 'unidade_id' => null, 'infraestrutura_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), ], 'model' => [ 'id' => $bloqueio->id, 'unidade_id' => $bloqueio->infraestrutura->unidade_id, 'infraestrutura_id' => $bloqueio->infraestrutura_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') ->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)) ->get(['id', 'nome', 'principal', 'unidade_id']) ->map(fn ($infraestrutura) => [ 'id' => $infraestrutura->id, 'nome' => $infraestrutura->nome, ]) ->sortBy('nome') ->values(); } 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'), ], '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(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(); } }