self::getAdditionalsData(), ]; } public static function create() { $entrada = null; if (request()->get('tipo_movimentacao') === 'estorno') { $entrada = Entrada::findOrFail(request()->get('entrada_id')); } return [ 'additionals' => self::getAdditionalsData(), 'form' => self::getFormData($entrada), 'model' => self::getModelData($entrada), ]; } public static function store($request) { self::validate($request); DB::transaction(function() use ($request) { $saida = Saida::create([ 'tipo_id' => SaidaTipo::DISTRIBUICAO, 'sala_vacinacao_id' => $request['sala_vacinacao_id_de'], 'data_saida' => Carbon::createFromFormat('d/m/Y', $request['data']), ]); $entrada = Entrada::create([ 'tipo_id' => EntradaTipo::DISTRIBUICAO, 'sala_vacinacao_id' => $request['sala_vacinacao_id_para'], 'data_entrada' => Carbon::createFromFormat('d/m/Y', $request['data']), ]); foreach ($request['vacinas'] as $vacina) { $quantidade = $vacina['quantidade']; while ((int) $quantidade > 0) { $entradaVacina = self::getEntradaVacina($request['sala_vacinacao_id_de'], $vacina['vacina_id'], $vacina['lote'], $vacina['data_validade_lote']); if ($entradaVacina->quantidade >= $quantidade) { $saidaVacina = SaidaVacina::create([ 'saida_id' => $saida->id, 'entrada_vacina_id' => $entradaVacina->id, 'vacina_id' => $entradaVacina->vacina_id, 'quantidade' => $quantidade, ]); $entrada->vacinas()->create([ 'saida_vacina_id' => $saidaVacina->id, 'vacina_id' => $saidaVacina->vacina_id, 'produtor_id' => $entradaVacina->produtor_id, 'apresentacao_id' => $entradaVacina->apresentacao_id, 'quantidade' => $saidaVacina->quantidade, 'lote' => $entradaVacina->lote, 'data_validade_lote' => $entradaVacina->data_validade_lote, ]); $quantidade = 0; } else { $saidaVacina = SaidaVacina::create([ 'saida_id' => $saida->id, 'entrada_vacina_id' => $entradaVacina->id, 'vacina_id' => $entradaVacina->vacina_id, 'quantidade' => $entradaVacina->quantidade, ]); $entrada->vacinas()->create([ 'saida_vacina_id' => $saidaVacina->id, 'vacina_id' => $saidaVacina->vacina_id, 'produtor_id' => $entradaVacina->produtor_id, 'apresentacao_id' => $entradaVacina->apresentacao_id, 'quantidade' => $saidaVacina->quantidade, 'lote' => $entradaVacina->lote, 'data_validade_lote' => $entradaVacina->data_validade_lote, ]); $quantidade = $quantidade - $entradaVacina->quantidade; } } } }); } public static function destroy($request) { self::validate($request); DB::transaction(function() use ($request) { $saida = Saida::create([ 'tipo_id' => SaidaTipo::ESTORNO, 'sala_vacinacao_id' => $request['sala_vacinacao_id_para'], 'data_saida' => Carbon::now()->format('Y-m-d'), ]); $entrada = Entrada::create([ 'tipo_id' => EntradaTipo::ESTORNO, 'sala_vacinacao_id' => $request['sala_vacinacao_id_de'], 'data_entrada' => Carbon::now()->format('Y-m-d'), ]); foreach ($request['vacinas'] as $value) { $entradaVacina = EntradaVacina::findOrFail($value); $saidaVacina = SaidaVacina::create([ 'saida_id' => $saida->id, 'entrada_vacina_id' => $entradaVacina->id, 'vacina_id' => $entradaVacina->vacina_id, 'quantidade' => $entradaVacina->quantidade, ]); $entrada->vacinas()->create([ 'saida_vacina_id' => $saidaVacina->id, 'vacina_id' => $saidaVacina->vacina_id, 'produtor_id' => $entradaVacina->produtor_id, 'apresentacao_id' => $entradaVacina->apresentacao_id, 'quantidade' => $saidaVacina->quantidade, 'lote' => $entradaVacina->lote, 'data_validade_lote' => $entradaVacina->data_validade_lote, ]); } }); } public static function datatable() { $salaVacinacaoLogada = self::getSalaVacinacaoLogada(); $datatable = DB::table('imunizacao_entrada_vacina') ->select([ 'imunizacao_entrada.id AS entrada_id', 'imunizacao_saida.id AS saida_id', 'cadastro_unidade_de.nome_fantasia AS unidade_nome_de', DB::raw("CASE WHEN cadastro_infraestrutura_de.principal THEN cadastro_unidade_de.nome_fantasia ELSE cadastro_infraestrutura_de.nome END AS infraestrutura_nome_de"), 'cadastro_unidade_para.nome_fantasia AS unidade_nome_para', DB::raw("CASE WHEN cadastro_infraestrutura_para.principal THEN cadastro_unidade_para.nome_fantasia ELSE cadastro_infraestrutura_para.nome END AS infraestrutura_nome_para"), DB::raw("DATE_FORMAT(imunizacao_saida.data_saida, '%d/%m/%Y') AS data"), ]) ->join('imunizacao_entrada', 'imunizacao_entrada.id', 'imunizacao_entrada_vacina.entrada_id') ->join('imunizacao_sala_vacinacao AS imunizacao_sala_vacinacao_para', 'imunizacao_sala_vacinacao_para.id', 'imunizacao_entrada.sala_vacinacao_id') ->join('cadastro_infraestrutura AS cadastro_infraestrutura_para', 'cadastro_infraestrutura_para.id', 'imunizacao_sala_vacinacao_para.infraestrutura_id') ->join('cadastro_unidade AS cadastro_unidade_para', 'cadastro_unidade_para.id', 'cadastro_infraestrutura_para.unidade_id') ->join('imunizacao_saida_vacina', 'imunizacao_saida_vacina.id', 'imunizacao_entrada_vacina.saida_vacina_id') ->join('imunizacao_saida', 'imunizacao_saida.id', 'imunizacao_saida_vacina.saida_id') ->join('imunizacao_sala_vacinacao AS imunizacao_sala_vacinacao_de', 'imunizacao_sala_vacinacao_de.id', 'imunizacao_saida.sala_vacinacao_id') ->join('cadastro_infraestrutura AS cadastro_infraestrutura_de', 'cadastro_infraestrutura_de.id', 'imunizacao_sala_vacinacao_de.infraestrutura_id') ->join('cadastro_unidade AS cadastro_unidade_de', 'cadastro_unidade_de.id', 'cadastro_infraestrutura_de.unidade_id') ->where('imunizacao_saida.tipo_id', SaidaTipo::DISTRIBUICAO); if ($salaVacinacaoLogada && $salaVacinacaoLogada->responsavel == false) { $datatable->where('imunizacao_sala_vacinacao_de.id', $salaVacinacaoLogada->id); } return $datatable->groupBy([ 'imunizacao_entrada.id', 'cadastro_unidade_de.nome_fantasia', DB::raw("CASE WHEN cadastro_infraestrutura_de.principal THEN cadastro_unidade_de.nome_fantasia ELSE cadastro_infraestrutura_de.nome END"), 'cadastro_unidade_para.nome_fantasia', DB::raw("CASE WHEN cadastro_infraestrutura_para.principal THEN cadastro_unidade_para.nome_fantasia ELSE cadastro_infraestrutura_para.nome END"), DB::raw("DATE_FORMAT(imunizacao_saida.data_saida, '%d/%m/%Y')"), ]); } public static function list() { switch (request()->get('listar')) { case 'salas_vacinacao_de': return self::getSalasVacinacaoDe(request()->get('unidade_id_de')); break; case 'salas_vacinacao_para': return self::getSalasVacinacaoPara(request()->get('unidade_id_para')); break; case 'lotes': return self::getLotes(request()->get('sala_vacinacao_id'), request()->get('vacina_id')); break; 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; } } private static function validate($request) { $rules = []; switch (request()->get('tipo_movimentacao')) { case 'estorno': $rules = [ 'sala_vacinacao_id_de' => [ 'required', 'integer', 'exists:\App\Models\Imunizacao\SalaVacinacao,id', ], 'sala_vacinacao_id_para' => [ 'required', 'integer', 'exists:\App\Models\Imunizacao\SalaVacinacao,id', ], 'vacinas' => [ function ($_, $value, $fail) { foreach ($value as $value) { $movimentacao = EntradaVacina::where('id', $value)->has('saidasVacina')->exists(); if ($movimentacao === true) { $fail('Um ou mais itens selecionados possui movimentação e não pode ser estornado.'); } } }, ], ]; break; default: foreach ($request['vacinas'] as $key => $value) { $rules["vacinas.$key.vacina_id"] = [ 'required', 'integer', 'exists:\App\Models\Cadastro\Vacina,id', ]; $rules["vacinas.$key.lote"] = [ 'required', 'string', ]; $rules["vacinas.$key.data_validade_lote"] = [ 'required', 'date', ]; $rules["vacinas.$key.quantidade"] = [ 'required', 'integer', 'between:1,99999999', 'max:' . self::getEstoque(request()->get('sala_vacinacao_id_de'), $value['vacina_id'], $value['lote'], $value['data_validade_lote']), ]; } $rules = array_merge([ 'sala_vacinacao_id_de' => [ 'required', 'integer', 'exists:\App\Models\Imunizacao\SalaVacinacao,id', ], 'sala_vacinacao_id_para' => [ 'required', 'integer', 'exists:\App\Models\Imunizacao\SalaVacinacao,id', ], 'data' => [ 'required', 'date_format:d/m/Y', 'before_or_equal:today', ], ], $rules); break; } return $request->validate($rules); } private static function getAdditionalsData() { return [ 'data_atual' => Carbon::now()->format('Y-m-d'), 'parametrizacao' => self::getParametrizacao(), 'sala_vacinacao_logada' => self::getSalaVacinacaoLogada(), ]; } private static function getFormData($entrada = null) { $response = []; switch (request()->get('tipo_movimentacao')) { case 'estorno': $response = [ 'unidades_de' => self::getUnidadesDe(), 'salas_vacinacao_de' => self::getSalasVacinacaoDe($entrada->vacinas()->first()->saidaVacina->saida->salaVacinacao->infraestrutura->unidade_id), 'unidades_para' => self::getUnidadesPara(), 'salas_vacinacao_para' => self::getSalasVacinacaoPara($entrada->salaVacinacao->infraestrutura->unidade_id), ]; break; default: $salaVacinacaoLogada = self::getSalaVacinacaoLogada(); $response = [ 'unidades_de' => self::getUnidadesDe(), 'salas_vacinacao_de' => self::getSalasVacinacaoDe($salaVacinacaoLogada->unidade_id ?? null), 'unidades_para' => self::getUnidadesPara(), 'salas_vacinacao_para' => [], 'lotes' => [], ]; break; } return $response; } private static function getModelData($entrada) { $response = []; switch (request()->get('tipo_movimentacao')) { case 'estorno': $response = [ 'unidade_id_de' => $entrada->vacinas()->first()->saidaVacina->saida->salaVacinacao->infraestrutura->unidade_id, 'sala_vacinacao_id_de' => $entrada->vacinas()->first()->saidaVacina->saida->sala_vacinacao_id, 'unidade_id_para' => $entrada->salaVacinacao->infraestrutura->unidade_id, 'sala_vacinacao_id_para' => $entrada->sala_vacinacao_id, 'data' => $entrada->data_entrada, 'vacinas' => self::getEntradasVacina($entrada->id)->map(function($query) { return [ 'id' => $query->id, 'disabled' => (bool) $query->existe_saida, 'checked' => false, 'vacina_nome' => $query->vacina_nome, 'vacina_abreviacao' => $query->vacina_abreviacao, 'vacina_sigla' => $query->vacina_sigla, 'vacina_sigla_nome' => $query->vacina_sigla . ' - ' . $query->vacina_nome, 'vacina_sigla_abreviacao' => $query->vacina_sigla . ' - ' . $query->vacina_abreviacao, 'vacina_abreviacao_nome' => $query->vacina_abreviacao . ' - ' . $query->vacina_nome, 'vacina_sigla_abreviacao_nome' => $query->vacina_sigla . ' - ' . $query->vacina_abreviacao . ' - ' . $query->vacina_nome, 'quantidade' => $query->quantidade, 'lote' => $query->lote . ' - Val: ' . $query->data_validade_lote, ]; }), ]; break; default: $salaVacinacaoLogada = self::getSalaVacinacaoLogada(); $response = [ 'unidade_id_de' => $salaVacinacaoLogada->unidade_id ?? null, 'sala_vacinacao_id_de' => $salaVacinacaoLogada->id ?? null, 'unidade_id_para' => null, 'sala_vacinacao_id_para' => null, 'data' => Carbon::now()->format('Y-m-d'), 'vacinas' => [], ]; 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 getUnidadesDe() { $salaVacinacaoLogada = self::getSalaVacinacaoLogada(); $unidades = DB::table('cadastro_unidade') ->select([ 'id', 'nome_fantasia', ]) ->when($salaVacinacaoLogada && $salaVacinacaoLogada->responsavel == false, function ($query) use ($salaVacinacaoLogada) { $query->where('id', $salaVacinacaoLogada->unidade_id); }) ->whereExists(function ($query) { $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.ativo', true); }); return $unidades->orderBy('nome_fantasia')->get(); } private static function getUnidadesPara() { return DB::table('cadastro_unidade') ->select([ 'id', 'nome_fantasia', ]) ->whereExists(function ($query) { $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.ativo', true); }) ->orderBy('nome_fantasia') ->get(); } private static function getSalasVacinacaoDe($unidadeId) { 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.ativo', true) ->where('cadastro_infraestrutura.unidade_id', $unidadeId) ->orderByRaw('CASE WHEN cadastro_infraestrutura.principal THEN cadastro_unidade.nome_fantasia ELSE cadastro_infraestrutura.nome END') ->get(); } private static function getSalasVacinacaoPara($unidadeIdPara) { 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.ativo', true) ->where('cadastro_infraestrutura.unidade_id', $unidadeIdPara) ->orderByRaw('CASE WHEN cadastro_infraestrutura.principal THEN cadastro_unidade.nome_fantasia ELSE cadastro_infraestrutura.nome END') ->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 (int) 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() ?? 0; } private static function getEntradaVacina($salaVacinacaoId, $vacinaId, $lote, $dataValidadeLote) { return DB::table('imunizacao_entrada_vacina') ->select([ 'imunizacao_entrada_vacina.id', 'imunizacao_entrada_vacina.vacina_id', 'imunizacao_entrada_vacina.produtor_id', 'imunizacao_entrada_vacina.apresentacao_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 '), '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) ->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 getEntradasVacina($entradaId) { return DB::table('imunizacao_entrada_vacina') ->select([ 'imunizacao_entrada_vacina.id', 'cadastro_vacina.nome AS vacina_nome', 'cadastro_vacina.abreviacao AS vacina_abreviacao', 'cadastro_vacina.sigla AS vacina_sigla', 'imunizacao_entrada_vacina.quantidade', 'imunizacao_entrada_vacina.lote', DB::raw("DATE_FORMAT(imunizacao_entrada_vacina.data_validade_lote, '%d/%m/%Y') AS data_validade_lote"), DB::raw(' ( SELECT TRUE FROM imunizacao_saida_vacina WHERE imunizacao_saida_vacina.entrada_vacina_id = imunizacao_entrada_vacina.id LIMIT 1 ) AS existe_saida '), ]) ->join('cadastro_vacina', 'cadastro_vacina.id', 'imunizacao_entrada_vacina.vacina_id') ->where('entrada_id', $entradaId) ->get(); } public static function getPrintData($id) { $saida = Saida::find($id); $parametrizacao = Parametrizacao::first()->parametrizacao_descricao_vacina_id; return [ 'entrada' => [ 'unidade_distribuidora' => $saida->salaVacinacao->infraestrutura->unidade->nome_fantasia, 'local_distribuidor' => $saida->salaVacinacao->infraestrutura->nome, 'unidade_recebedora' => $saida->vacinas[0]->entradaVacinaDestino->entrada->salaVacinacao->infraestrutura->unidade->nome_fantasia, 'local_recebedor' => $saida->vacinas[0]->entradaVacinaDestino->entrada->salaVacinacao->infraestrutura->nome, 'data' => Carbon::parse($saida->data_saida)->format('d/m/Y') ], 'vacinas' => $saida->vacinas->map(function($saida_vacina) use($parametrizacao) { return [ 'nome' => self::getNomeParametrizado($parametrizacao, $saida_vacina->vacina), 'quantidade' => $saida_vacina->quantidade, 'lote' => $saida_vacina->entradaVacinaDestino->lote, 'validade' => Carbon::parse($saida_vacina->entradaVacinaDestino->data_validade_lote)->format('d/m/Y'), ]; }) ]; } private static function getNomeParametrizado($parametrizacao, $vacina) { switch ($parametrizacao) { case ParametrizacaoDescricaoVacina::DESCRICAO: return $vacina->nome; case ParametrizacaoDescricaoVacina::DESCRICAO_ABREVIADA: return $vacina->abreviacao; case ParametrizacaoDescricaoVacina::SIGLA: return $vacina->sigla; case ParametrizacaoDescricaoVacina::SIGLA_DESCRICAO: return "$vacina->sigla - $vacina->nome"; case ParametrizacaoDescricaoVacina::SIGLA_DESCRICAO_ABREVIADA: return "$vacina->sigla - $vacina->abreviacao"; case ParametrizacaoDescricaoVacina::DESCRICAO_ABREVIADA_DESCRICAO: return "$vacina->abreviacao - $vacina->nome"; case ParametrizacaoDescricaoVacina::SIGLA_DESCRICAO_ABREVIADA_DESCRICAO: return "$vacina->sigla - $vacina->abreviacao - $vacina->nome"; } } }