self::getAdditionalsData(), ]; } public static function create() { return [ 'additionals' => self::getAdditionalsData(), 'form' => self::getFormData(), 'model' => self::getModelData(), ]; } public static function store($request) { self::validate($request); $saidaVacinaId = null; if ($request['tipo_movimentacao'] === 'baixa') { DB::transaction(function() use ($request, &$saidaVacinaId) { $saida = Saida::create([ 'sala_vacinacao_id' => $request['sala_vacinacao_id'], 'tipo_id' => $request['tipo_id'], 'motivo_id' => $request['motivo_id'], 'motivo_indisponibilidade' => $request['motivo_indisponibilidade'], 'observacao' => $request['observacao'], 'data_saida' => Carbon::createFromFormat('d/m/Y', $request['data_saida']), ]); $quantidade = $request['quantidade']; while ((int) $quantidade > 0) { $entradaVacina = self::getEntradaVacina($request['sala_vacinacao_id'], $request['vacina_id'], $request['lote'], $request['data_validade_lote']); if ($entradaVacina->quantidade >= $quantidade) { $saidaVacina = $saida->vacinas()->create([ 'entrada_vacina_id' => $entradaVacina->id, 'vacina_id' => $entradaVacina->vacina_id, 'quantidade' => $quantidade, ]); $saidaVacinaId = $saidaVacina->id; $quantidade = 0; } else { $saidaVacina = $saida->vacinas()->create([ 'entrada_vacina_id' => $entradaVacina->id, 'vacina_id' => $entradaVacina->vacina_id, 'quantidade' => $entradaVacina->quantidade, ]); $saidaVacinaId = $saidaVacina->id; $quantidade = $quantidade - $entradaVacina->quantidade; } } }); } else if ($request['tipo_movimentacao'] === 'estorno') { DB::transaction(function() use ($request, &$saidaVacinaId) { foreach ($request['saidas'] as $saidaId) { $saidaVacina = SaidaVacina::findOrFail($saidaId); $saidaVacinaId = $saidaVacina->id; $entrada = Entrada::create([ 'tipo_id' => EntradaTipo::ESTORNO, 'sala_vacinacao_id' => $saidaVacina->entradaVacinaOrigem->entrada->sala_vacinacao_id, 'data_entrada' => $saidaVacina->entradaVacinaOrigem->entrada->data_entrada, 'origem' => $saidaVacina->entradaVacinaOrigem->entrada->origem, ]); $entrada->vacinas()->create([ 'saida_vacina_id' => $saidaVacina->id, 'vacina_id' => $saidaVacina->entradaVacinaOrigem->vacina_id, 'produtor_id' => $saidaVacina->entradaVacinaOrigem->produtor_id, 'apresentacao_id' => $saidaVacina->entradaVacinaOrigem->apresentacao_id, 'quantidade' => $saidaVacina->quantidade, 'lote' => $saidaVacina->entradaVacinaOrigem->lote, 'data_validade_lote' => $saidaVacina->entradaVacinaOrigem->data_validade_lote, ]); } }); } else if ($request['tipo_movimentacao'] === 'indisponibilidade') { DB::transaction(function() use ($request, &$saidaVacinaId) { foreach ($request['saidas'] as $saida) { $saidaVacina = SaidaVacina::findOrFail($saida); $saidaVacinaId = $saidaVacina->id; $entrada = Entrada::create([ 'tipo_id' => EntradaTipo::ESTORNO, 'sala_vacinacao_id' => $saidaVacina->entradaVacinaOrigem->entrada->sala_vacinacao_id, 'data_entrada' => $saidaVacina->entradaVacinaOrigem->entrada->data_entrada, 'origem' => $saidaVacina->entradaVacinaOrigem->entrada->origem, ]); $entrada->vacinas()->create([ 'saida_vacina_id' => $saidaVacina->id, 'vacina_id' => $saidaVacina->entradaVacinaOrigem->vacina_id, 'produtor_id' => $saidaVacina->entradaVacinaOrigem->produtor_id, 'apresentacao_id' => $saidaVacina->entradaVacinaOrigem->apresentacao_id, 'quantidade' => $saidaVacina->quantidade, 'lote' => $saidaVacina->entradaVacinaOrigem->lote, 'data_validade_lote' => $saidaVacina->entradaVacinaOrigem->data_validade_lote, ]); } }); } return $saidaVacinaId; } public static function datatable() { $salaVacinacaoLogada = self::getSalaVacinacaoLogada(); $sub = DB::table('imunizacao_entrada_vacina') ->select([ 'cadastro_unidade.id AS unidade_id', 'imunizacao_sala_vacinacao.id AS sala_vacinacao_id', 'cadastro_unidade.nome_fantasia AS unidade_nome_fantasia', DB::raw(" CASE WHEN cadastro_infraestrutura.principal THEN cadastro_unidade.nome_fantasia ELSE cadastro_infraestrutura.nome END AS infraestrutura_nome "), 'cadastro_vacina.id AS vacina_id', 'cadastro_vacina.nome AS vacina_nome', 'cadastro_vacina.abreviacao AS vacina_abreviacao', 'cadastro_vacina.sigla AS vacina_sigla', 'imunizacao_entrada_vacina.lote', DB::raw(' SUM(imunizacao_entrada_vacina.quantidade - COALESCE(( SELECT SUM(imunizacao_saida_vacina.quantidade) FROM imunizacao_saida_vacina WHERE imunizacao_saida_vacina.entrada_vacina_id = imunizacao_entrada_vacina.id ), 0)) AS estoque ') ]) ->join('imunizacao_entrada', 'imunizacao_entrada.id', 'imunizacao_entrada_vacina.entrada_id') ->join('imunizacao_sala_vacinacao', 'imunizacao_sala_vacinacao.id', 'imunizacao_entrada.sala_vacinacao_id') ->join('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'imunizacao_sala_vacinacao.infraestrutura_id') ->join('cadastro_unidade', 'cadastro_unidade.id', 'cadastro_infraestrutura.unidade_id') ->join('cadastro_vacina', 'cadastro_vacina.id', 'imunizacao_entrada_vacina.vacina_id') ->when($salaVacinacaoLogada && $salaVacinacaoLogada->responsavel == false, function ($query) use ($salaVacinacaoLogada) { $query->where('imunizacao_sala_vacinacao.id', $salaVacinacaoLogada->id); }) ->groupBy([ 'cadastro_unidade.id', 'imunizacao_sala_vacinacao.id', 'cadastro_vacina.id', 'imunizacao_entrada_vacina.lote' ]) ->havingRaw('estoque > 0'); return DB::query() ->fromSub($sub, 'estoque_por_lote') ->select([ 'unidade_id', 'sala_vacinacao_id', 'unidade_nome_fantasia', 'infraestrutura_nome', 'vacina_id', 'vacina_nome', 'vacina_abreviacao', 'vacina_sigla', DB::raw("CONCAT(vacina_sigla, ' - ', vacina_nome) AS vacina_sigla_nome"), DB::raw("CONCAT(vacina_sigla, ' - ', vacina_abreviacao) AS vacina_sigla_abreviacao"), DB::raw("CONCAT(vacina_abreviacao, ' - ', vacina_nome) AS vacina_abreviacao_nome"), DB::raw("CONCAT(vacina_sigla, ' - ', vacina_abreviacao, ' - ', vacina_nome) AS vacina_sigla_abreviacao_nome"), DB::raw('SUM(estoque) AS estoque') ]) ->groupBy([ 'unidade_id', 'sala_vacinacao_id', 'vacina_id' ]); } public static function list() { switch (request()->get('listar')) { case 'estoque': return self::getEstoque(request()->get('sala_vacinacao_id'), request()->get('vacina_id'), request()->get('lote'), request()->get('data_validade_lote')); break; default: return []; break; } } public static function historico() { if (empty(request()->get('sala_vacinacao_id'))) { return SaidaVacina::where('vacina_id', request()->get('vacina_id')) ->latest() ->get() ->map(fn($vacina) => [ 'id' => $vacina->id, 'data_saida' => $vacina->saida->data_saida, 'motivo' => self::getMotivos()->firstWhere('id', $vacina->saida->motivo_id) ? self::getMotivos()->firstWhere('id', $vacina->saida->motivo_id)->nome : '', 'quantidade' => $vacina->quantidade, 'usuario' => $vacina->lotacao->usuario->nome ?? 'NÃO INFORMADO', 'observacao' => $vacina->saida->observacao, ]); } else { return self::getSaidasVacina(request()->get('sala_vacinacao_id'), request()->get('vacina_id')) ->map(fn($vacina) => [ 'id' => $vacina->id, 'data_saida' => $vacina->data_saida, 'motivo' => $vacina->saida_vacina_motivo, 'quantidade' => $vacina->quantidade, 'usuario' => SaidaVacina::where('id', $vacina->id) ->get() ->pluck('lotacao.usuario.nome') ->filter() ->first() ?? 'NÃO INFORMADO', 'observacao' => $vacina->observacao, ]); } } private static function validate($request) { $rules = []; switch ($request['tipo_movimentacao']) { case 'baixa': $rules = [ 'tipo_id' => [ 'required', 'integer', 'exists:\App\Models\Imunizacao\SaidaTipo,id', ], 'motivo_id' => [ 'nullable', 'integer', 'exists:\App\Models\Imunizacao\SaidaMotivo,id', ], 'motivo_indisponibilidade' => [ 'nullable', 'string', 'between:3,100', ], 'observacao' => [ 'nullable', 'string', 'between:3,300', ], 'lote' => [ 'required', 'string', ], 'data_validade_lote' => [ 'required', 'date', ], 'quantidade' => [ 'required', 'integer', 'between:1,99999999', 'max:' . self::getEstoque(request()->get('sala_vacinacao_id'), request()->get('vacina_id'), request()->get('lote'), request()->get('data_validade_lote')), ], ]; break; case 'estorno': $rules = [ 'saidas' => [ 'required', 'array', ], ]; break; case 'indisponibilidade': $rules = [ 'saidas' => [ 'required', 'array', ], ]; break; } return $request->validate($rules); } private static function getAdditionalsData() { return [ 'parametrizacao' => self::getParametrizacao(), 'sala_vacinacao_logada' => self::getSalaVacinacaoLogada(), ]; } private static function getFormData() { $response = []; switch (request()->get('tipo_movimentacao')) { case 'baixa': $response = [ 'unidades' => self::getUnidades(request()->get('sala_vacinacao_id')), 'salas_vacinacao' => self::getSalasVacinacao(request()->get('sala_vacinacao_id')), 'tipos' => self::getTipos(), 'motivos' => self::getMotivos(), 'lotes' => self::getLotes(request()->get('sala_vacinacao_id'), request()->get('vacina_id')), ]; break; case 'estorno': $response = [ 'unidades' => self::getUnidades(request()->get('sala_vacinacao_id')), 'salas_vacinacao' => self::getSalasVacinacao(request()->get('sala_vacinacao_id')), ]; break; case 'indisponibilidade': $response = [ 'unidades' => self::getUnidades(request()->get('sala_vacinacao_id')), 'salas_vacinacao' => self::getSalasVacinacao(request()->get('sala_vacinacao_id')), ]; break; } return $response; } private static function getModelData() { $response = []; $vacina = Vacina::findOrFail(request()->get('vacina_id')); $salaVacinacao = self::getSalaVacinacao(request()->get('sala_vacinacao_id')); switch (request()->get('tipo_movimentacao')) { case 'baixa': $response = [ 'unidade_id' => $salaVacinacao->unidade_id ?? null, 'sala_vacinacao_id' => request()->get('sala_vacinacao_id'), 'vacina_id' => request()->get('vacina_id'), 'vacina_nome' => $vacina->nome, 'vacina_abreviacao' => $vacina->abreviacao, 'vacina_sigla' => $vacina->sigla, 'vacina_sigla_nome' => $vacina->sigla . ' - ' . $vacina->nome, 'vacina_sigla_abreviacao' => $vacina->sigla . ' - ' . $vacina->abreviacao, 'vacina_abreviacao_nome' => $vacina->abreviacao . ' - ' . $vacina->nome, 'vacina_sigla_abreviacao_nome' => $vacina->sigla . ' - ' . $vacina->abreviacao . ' - ' . $vacina->nome, 'tipo_id' => null, 'motivo_id' => null, 'motivo_indisponibilidade' => null, 'observacao' => null, 'data_saida' => Carbon::now()->format('Y-m-d'), 'estoque' => null, 'quantidade' => null, 'lote' => null, ]; break; case 'estorno': $response = [ 'unidade_id' => $salaVacinacao->unidade_id ?? null, 'sala_vacinacao_id' => request()->get('sala_vacinacao_id'), 'vacina_id' => request()->get('vacina_id'), 'vacina_nome' => $vacina->nome, 'vacina_abreviacao' => $vacina->abreviacao, 'vacina_sigla' => $vacina->sigla, 'vacina_sigla_nome' => $vacina->sigla . ' - ' . $vacina->nome, 'vacina_sigla_abreviacao' => $vacina->sigla . ' - ' . $vacina->abreviacao, 'vacina_abreviacao_nome' => $vacina->abreviacao . ' - ' . $vacina->nome, 'vacina_sigla_abreviacao_nome' => $vacina->sigla . ' - ' . $vacina->abreviacao . ' - ' . $vacina->nome, 'saidas' => self::getSaidasVacina(request()->get('sala_vacinacao_id'), request()->get('vacina_id'))->map(function($query) { return [ 'id' => $query->id, 'selecionada' => false, 'quantidade' => $query->quantidade, 'lote' => $query->lote, 'data_validade_lote' => $query->data_validade_lote, 'saida_vacina_motivo' => $query->saida_vacina_motivo, ]; }), ]; break; case 'indisponibilidade': $response = [ 'unidade_id' => $salaVacinacao->unidade_id ?? null, 'sala_vacinacao_id' => request()->get('sala_vacinacao_id'), 'vacina_id' => request()->get('vacina_id'), 'vacina_nome' => $vacina->nome, 'vacina_abreviacao' => $vacina->abreviacao, 'vacina_sigla' => $vacina->sigla, 'vacina_sigla_nome' => $vacina->sigla . ' - ' . $vacina->nome, 'vacina_sigla_abreviacao' => $vacina->sigla . ' - ' . $vacina->abreviacao, 'vacina_abreviacao_nome' => $vacina->abreviacao . ' - ' . $vacina->nome, 'vacina_sigla_abreviacao_nome' => $vacina->sigla . ' - ' . $vacina->abreviacao . ' - ' . $vacina->nome, 'saidas' => self::getEstoquesIndisponiveis(request()->get('sala_vacinacao_id'), request()->get('vacina_id'))->map(function($query) { return [ 'id' => $query->id, 'selecionado' => false, 'quantidade' => $query->quantidade, 'lote' => $query->lote, 'data_validade_lote' => $query->data_validade_lote, 'motivo_indisponibilidade' => $query->motivo_indisponibilidade, ]; }), ]; break; } return $response; } private static function getSalaVacinacaoLogada() { return DB::table('imunizacao_sala_vacinacao') ->select([ 'imunizacao_sala_vacinacao.id', 'cadastro_infraestrutura.unidade_id', 'imunizacao_sala_vacinacao.responsavel', ]) ->join('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'imunizacao_sala_vacinacao.infraestrutura_id') ->where('imunizacao_sala_vacinacao.ativo', true) ->where('cadastro_infraestrutura.id', auth()->payload()->get('infraestrutura_id')) ->first(); } private static function getParametrizacao() { return DB::table('imunizacao_parametrizacao') ->select([ 'parametrizacao_descricao_vacina_id', ]) ->first(); } private static function getSalaVacinacao($salaVacinacaoId) { return DB::table('imunizacao_sala_vacinacao') ->select([ 'imunizacao_sala_vacinacao.id', 'cadastro_infraestrutura.unidade_id', 'imunizacao_sala_vacinacao.responsavel', ]) ->join('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'imunizacao_sala_vacinacao.infraestrutura_id') ->where('imunizacao_sala_vacinacao.id', $salaVacinacaoId) ->first(); } private static function getUnidades($salaVacinacaoId) { return DB::table('cadastro_unidade') ->select([ 'id', 'nome_fantasia', ]) ->whereExists(function ($query) use ($salaVacinacaoId) { $query->select(DB::raw(1)) ->from('imunizacao_sala_vacinacao') ->join('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'imunizacao_sala_vacinacao.infraestrutura_id') ->whereColumn('cadastro_infraestrutura.unidade_id', 'cadastro_unidade.id') ->where('imunizacao_sala_vacinacao.id', $salaVacinacaoId); }) ->orderBy('nome_fantasia') ->get(); } private static function getSalasVacinacao($salaVacinacaoId) { return DB::table('imunizacao_sala_vacinacao') ->select([ 'imunizacao_sala_vacinacao.id', DB::raw("CASE WHEN cadastro_infraestrutura.principal THEN cadastro_unidade.nome_fantasia ELSE cadastro_infraestrutura.nome END AS nome"), ]) ->join('cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'imunizacao_sala_vacinacao.infraestrutura_id') ->join('cadastro_unidade', 'cadastro_unidade.id', 'cadastro_infraestrutura.unidade_id') ->where('imunizacao_sala_vacinacao.id', $salaVacinacaoId) ->orderByRaw('CASE WHEN cadastro_infraestrutura.principal THEN cadastro_unidade.nome_fantasia ELSE cadastro_infraestrutura.nome END') ->get(); } private static function getTipos() { return DB::table('imunizacao_saida_tipo') ->select([ 'id', 'nome', ]) ->whereIn('id', [SaidaTipo::BAIXA, SaidaTipo::INDISPONIBILIDADE]) ->orderBy('nome') ->get(); } private static function getMotivos() { return DB::table('imunizacao_saida_motivo') ->select([ 'id', 'nome', ]) ->orderBy('nome') ->get(); } private static function getLotes($salaVacinacaoId, $vacinaId) { return DB::table('imunizacao_entrada_vacina') ->select([ 'imunizacao_entrada_vacina.lote', 'imunizacao_entrada_vacina.data_validade_lote', ]) ->join('imunizacao_entrada', 'imunizacao_entrada.id', 'imunizacao_entrada_vacina.entrada_id') ->where('imunizacao_entrada.sala_vacinacao_id', $salaVacinacaoId) ->where('imunizacao_entrada_vacina.vacina_id', $vacinaId) ->groupBy([ 'imunizacao_entrada_vacina.lote', 'imunizacao_entrada_vacina.data_validade_lote', ]) ->havingRaw(' SUM(imunizacao_entrada_vacina.quantidade - COALESCE(( SELECT SUM(imunizacao_saida_vacina.quantidade) FROM imunizacao_saida_vacina WHERE imunizacao_saida_vacina.entrada_vacina_id = imunizacao_entrada_vacina.id ), 0)) > 0 ') ->orderBy('imunizacao_entrada_vacina.data_validade_lote') ->get(); } private static function getEstoque($salaVacinacaoId, $vacinaId, $lote, $dataValidadeLote) { return DB::table('imunizacao_entrada_vacina') ->select([ DB::raw(' SUM(imunizacao_entrada_vacina.quantidade - COALESCE(( SELECT SUM(imunizacao_saida_vacina.quantidade) FROM imunizacao_saida_vacina WHERE imunizacao_saida_vacina.entrada_vacina_id = imunizacao_entrada_vacina.id ), 0)) AS estoque ') ]) ->join('imunizacao_entrada', 'imunizacao_entrada.id', 'imunizacao_entrada_vacina.entrada_id') ->where('imunizacao_entrada.sala_vacinacao_id', $salaVacinacaoId) ->where('imunizacao_entrada_vacina.vacina_id', $vacinaId) ->where('imunizacao_entrada_vacina.lote', $lote) ->where('imunizacao_entrada_vacina.data_validade_lote', $dataValidadeLote) ->pluck('estoque') ->first(); } private static function getEntradaVacina($salaVacinacaoId, $vacinaId, $lote, $dataValidadeLote) { return DB::table('imunizacao_entrada_vacina') ->select([ 'imunizacao_entrada_vacina.id', 'imunizacao_entrada_vacina.vacina_id', DB::raw(' imunizacao_entrada_vacina.quantidade - COALESCE(( SELECT SUM(imunizacao_saida_vacina.quantidade) FROM imunizacao_saida_vacina WHERE imunizacao_saida_vacina.entrada_vacina_id = imunizacao_entrada_vacina.id ), 0) AS quantidade '), ]) ->join('imunizacao_entrada', 'imunizacao_entrada.id', 'imunizacao_entrada_vacina.entrada_id') ->where('imunizacao_entrada.sala_vacinacao_id', $salaVacinacaoId) ->where('imunizacao_entrada_vacina.vacina_id', $vacinaId) ->where('imunizacao_entrada_vacina.lote', $lote) ->where('imunizacao_entrada_vacina.data_validade_lote', $dataValidadeLote) ->whereRaw(' imunizacao_entrada_vacina.quantidade > COALESCE(( SELECT SUM(imunizacao_saida_vacina.quantidade) FROM imunizacao_saida_vacina WHERE imunizacao_saida_vacina.entrada_vacina_id = imunizacao_entrada_vacina.id ), 0) ') ->orderBy('imunizacao_entrada_vacina.id') ->first(); } private static function getSaidasVacina($salaVacinacaoId, $vacinaId) { return DB::table('imunizacao_saida_vacina') ->select([ 'imunizacao_saida_vacina.id', 'imunizacao_saida_vacina.quantidade', 'imunizacao_entrada_vacina.lote', 'imunizacao_saida.data_saida', 'imunizacao_saida.observacao', DB::raw("DATE_FORMAT(imunizacao_entrada_vacina.data_validade_lote, '%d/%m/%Y') AS data_validade_lote"), 'imunizacao_saida_motivo.nome AS saida_vacina_motivo', ]) ->join('imunizacao_saida', 'imunizacao_saida.id', 'imunizacao_saida_vacina.saida_id') ->join('imunizacao_entrada_vacina', 'imunizacao_entrada_vacina.id', 'imunizacao_saida_vacina.entrada_vacina_id') ->join('imunizacao_saida_motivo', 'imunizacao_saida_motivo.id', 'imunizacao_saida.motivo_id') ->whereNotExists(function ($query) { $query->select(DB::raw(1)) ->from('imunizacao_entrada_vacina') ->whereColumn('imunizacao_entrada_vacina.saida_vacina_id', 'imunizacao_saida_vacina.id'); }) ->where('imunizacao_saida.tipo_id', SaidaTipo::BAIXA) ->where('imunizacao_saida.sala_vacinacao_id', $salaVacinacaoId) ->where('imunizacao_saida_vacina.vacina_id', $vacinaId) ->get(); } private static function getEstoquesIndisponiveis($salaVacinacaoId, $vacinaId) { return DB::table('imunizacao_saida_vacina') ->select([ 'imunizacao_saida_vacina.id', 'imunizacao_saida_vacina.quantidade', 'imunizacao_entrada_vacina.lote', DB::raw("DATE_FORMAT(imunizacao_entrada_vacina.data_validade_lote, '%d/%m/%Y') AS data_validade_lote"), 'imunizacao_saida.motivo_indisponibilidade', ]) ->join('imunizacao_saida', 'imunizacao_saida.id', 'imunizacao_saida_vacina.saida_id') ->join('imunizacao_entrada_vacina', 'imunizacao_entrada_vacina.id', 'imunizacao_saida_vacina.entrada_vacina_id') ->join('imunizacao_entrada', 'imunizacao_entrada.id', 'imunizacao_entrada_vacina.entrada_id') ->whereNotExists(function ($query) { $query->select(DB::raw(1)) ->from('imunizacao_entrada_vacina') ->whereColumn('imunizacao_entrada_vacina.saida_vacina_id', 'imunizacao_saida_vacina.id'); }) ->where('imunizacao_saida.tipo_id', SaidaTipo::INDISPONIBILIDADE) ->where('imunizacao_entrada.sala_vacinacao_id', $salaVacinacaoId) ->where('imunizacao_entrada_vacina.vacina_id', $vacinaId) ->get(); } }