This commit is contained in:
@@ -0,0 +1,964 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Almoxarifado;
|
||||
|
||||
use App\Enums\Almoxarifado\RequisicaoRespostaItemMotivo as RequisicaoRespostaItemMotivoEnum;
|
||||
use App\Enums\Almoxarifado\RequisicaoRespostaStatus;
|
||||
use App\Enums\Almoxarifado\RequisicaoStatus;
|
||||
use App\Models\Almoxarifado\EntradaItem;
|
||||
use App\Models\Almoxarifado\ParametrizacaoRequisicao;
|
||||
use App\Models\Almoxarifado\Requisicao;
|
||||
use App\Models\Almoxarifado\RequisicaoItem;
|
||||
use App\Models\Almoxarifado\RequisicaoPermissao;
|
||||
use App\Models\Almoxarifado\RequisicaoRespostaItemMotivo;
|
||||
use App\Models\Cadastro\Estabelecimento\CentroCusto;
|
||||
use App\Models\Cadastro\Estabelecimento\Unidade;
|
||||
use App\Models\Cadastro\Material\Material;
|
||||
use App\Services\Service;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class RequisicaoPendentePermissaoService extends Service
|
||||
{
|
||||
public static function datatable()
|
||||
{
|
||||
$requisicoes = DB::table('almoxarifado_requisicao as requisicao')
|
||||
->join(
|
||||
'cadastro_centro_custo as centro_custo',
|
||||
'centro_custo.id',
|
||||
'requisicao.created_centro_custo_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_infraestrutura as infraestrutura',
|
||||
'infraestrutura.id',
|
||||
'centro_custo.infraestrutura_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_unidade as unidade',
|
||||
'unidade.id',
|
||||
'infraestrutura.unidade_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_setor as setor',
|
||||
'setor.id',
|
||||
'centro_custo.setor_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_lotacao as lotacao',
|
||||
'lotacao.id',
|
||||
'requisicao.created_lotacao_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_usuario as usuario',
|
||||
'usuario.id',
|
||||
'lotacao.usuario_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_cidadao as cidadao',
|
||||
'cidadao.id',
|
||||
'usuario.cidadao_id'
|
||||
)
|
||||
->where('requisicao.status_id', '<>', RequisicaoStatus::FINALIZADA)
|
||||
->where('requisicao.centro_custo_id', self::getCurrentCentroCusto()->id)
|
||||
->where(function ($query) {
|
||||
|
||||
$query->whereNotExists(function ($query) {
|
||||
|
||||
$query->select(DB::raw(1))
|
||||
->from('almoxarifado_requisicao_resposta as resposta')
|
||||
->whereColumn('resposta.requisicao_id', 'requisicao.id')
|
||||
->where('resposta.status_id', RequisicaoRespostaStatus::ENVIADA);
|
||||
})->orWhereRaw("EXISTS (
|
||||
SELECT 1
|
||||
FROM almoxarifado_requisicao_resposta_item as resposta_item
|
||||
WHERE resposta_item.requisicao_resposta_id = (
|
||||
SELECT resposta.id
|
||||
FROM almoxarifado_requisicao_resposta as resposta
|
||||
WHERE resposta.requisicao_id = requisicao.id
|
||||
AND resposta.status_id = " . RequisicaoRespostaStatus::ENVIADA . "
|
||||
ORDER BY resposta.id DESC
|
||||
LIMIT 1
|
||||
)
|
||||
AND resposta_item.motivo_id IN (
|
||||
" . RequisicaoRespostaItemMotivoEnum::ENTREGA_PARCIAL . ",
|
||||
" . RequisicaoRespostaItemMotivoEnum::PENDENTE_DE_ENTREGA . "
|
||||
)
|
||||
)");
|
||||
})
|
||||
->select(
|
||||
'requisicao.id',
|
||||
DB::raw("DATE_FORMAT(requisicao.created_at, '%d/%m/%Y') as data_requisicao"),
|
||||
'unidade.nome_fantasia as unidade_nome_fantasia',
|
||||
DB::raw("COALESCE(infraestrutura.nome, unidade.nome_fantasia) AS infraestrutura_nome"),
|
||||
'setor.nome as setor_nome',
|
||||
'cidadao.nome as usuarioNome',
|
||||
'requisicao.numero',
|
||||
DB::raw("IF(requisicao.status_id = " . RequisicaoStatus::RESPOSTA_INICIADA . ", 1, 0) as iniciou_resposta"),
|
||||
)
|
||||
->addSelect([
|
||||
'possui_envio_pendente' => function ($query) {
|
||||
|
||||
$query->selectRaw("COALESCE((
|
||||
SELECT 1
|
||||
FROM almoxarifado_requisicao_resposta_item as resposta_item
|
||||
WHERE resposta_item.requisicao_resposta_id = (
|
||||
SELECT resposta.id
|
||||
FROM almoxarifado_requisicao_resposta as resposta
|
||||
WHERE resposta.requisicao_id = requisicao.id
|
||||
AND resposta.enviada_em IS NOT NULL
|
||||
ORDER BY resposta.id DESC
|
||||
LIMIT 1
|
||||
)
|
||||
AND resposta_item.motivo_id IN (
|
||||
" . RequisicaoRespostaItemMotivoEnum::ENTREGA_PARCIAL . ",
|
||||
" . RequisicaoRespostaItemMotivoEnum::PENDENTE_DE_ENTREGA . "
|
||||
)
|
||||
LIMIT 1
|
||||
), 0)");
|
||||
}
|
||||
]);
|
||||
|
||||
return datatables()
|
||||
->of($requisicoes)
|
||||
->filterColumn('requisicao.created_at', function ($query, $keyword) {
|
||||
|
||||
$query->whereRaw("DATE_FORMAT(requisicao.created_at, '%d/%m/%Y') like ?", ["%{$keyword}%"])
|
||||
->orWhereRaw(
|
||||
"CONCAT(
|
||||
SUBSTR(requisicao.created_at,9,2),
|
||||
SUBSTR(requisicao.created_at,6,2),
|
||||
SUBSTR(requisicao.created_at,1,4)
|
||||
) like ?",
|
||||
["%{$keyword}%"]
|
||||
);
|
||||
})
|
||||
->filterColumn('infraestrutura.nome', function ($query, $keyword) {
|
||||
|
||||
$query->whereRaw("COALESCE(infraestrutura.nome, unidade.nome_fantasia) like ?", ["%{$keyword}%"]);
|
||||
})
|
||||
->skipTotalRecords()
|
||||
->toJson();
|
||||
}
|
||||
|
||||
public static function datatablePermissao()
|
||||
{
|
||||
$centrosCusto = DB::table('cadastro_centro_custo as centro_custo')
|
||||
->join(
|
||||
'cadastro_infraestrutura as infraestrutura',
|
||||
'infraestrutura.id',
|
||||
'centro_custo.infraestrutura_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_unidade as unidade',
|
||||
'unidade.id',
|
||||
'infraestrutura.unidade_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_setor as setor',
|
||||
'setor.id',
|
||||
'centro_custo.setor_id'
|
||||
)
|
||||
->whereNull('centro_custo.deleted_at')
|
||||
->where('centro_custo.id', '<>', self::getCurrentCentroCusto()->id)
|
||||
->select(
|
||||
'centro_custo.id',
|
||||
'unidade.cnes',
|
||||
'unidade.nome_fantasia as unidade_nome_fantasia',
|
||||
DB::raw("COALESCE(infraestrutura.nome, unidade.nome_fantasia) AS infraestrutura_nome"),
|
||||
'setor.nome as setor_nome',
|
||||
);
|
||||
|
||||
return datatables()
|
||||
->of($centrosCusto)
|
||||
->filterColumn('infraestrutura.nome', function ($query, $keyword) {
|
||||
|
||||
$query->whereRaw("COALESCE(infraestrutura.nome, unidade.nome_fantasia) like ?", ["%{$keyword}%"]);
|
||||
})
|
||||
->skipTotalRecords()
|
||||
->toJson();
|
||||
}
|
||||
|
||||
public static function getMateriais($centroCustoRequisitanteId)
|
||||
{
|
||||
$centroCustoLogadoId = self::getCurrentCentroCusto()->id;
|
||||
|
||||
$grupos = self::getCurrentCentroCusto()
|
||||
->almoxarifadoParametrizacoesControleEstoqueGrupo
|
||||
->map(fn ($parametrizacaoGrupo) => [
|
||||
'id' => $parametrizacaoGrupo->grupo->id,
|
||||
'nome' => $parametrizacaoGrupo->grupo->nome,
|
||||
'materiais' => $parametrizacaoGrupo->grupo->materiais()
|
||||
->where('is_ativo', true)
|
||||
->where(function ($query) use ($parametrizacaoGrupo) {
|
||||
|
||||
$query
|
||||
->whereDoesntHave('subgrupo')
|
||||
->orWhereHas('subgrupo', function ($query) use ($parametrizacaoGrupo) {
|
||||
|
||||
$query->whereHas('almoxarifadoParametrizacoesControleEstoqueSubgrupo',
|
||||
function ($query) use ($parametrizacaoGrupo) {
|
||||
|
||||
$query->where('parametrizacao_controle_estoque_grupo_id', $parametrizacaoGrupo->id);
|
||||
}
|
||||
);
|
||||
});
|
||||
})
|
||||
->get()
|
||||
->map(function ($material) use ($centroCustoLogadoId, $centroCustoRequisitanteId) {
|
||||
|
||||
$permissao = $material->almoxarifadoRequisicaoPermissoes()
|
||||
->where('created_centro_custo_id', $centroCustoLogadoId)
|
||||
->where('centro_custo_requisitante_id', $centroCustoRequisitanteId)
|
||||
->first();
|
||||
|
||||
return [
|
||||
'id' => $material->id,
|
||||
'permite_requisitar' => !is_null($permissao),
|
||||
'codigo' => $material->codigo_material,
|
||||
'descricao_completa' => $material->descricao_completa,
|
||||
'subgrupo_nome' => $material->subgrupo->nome ?? null,
|
||||
'estoque_maximo' => $permissao->estoque_maximo ?? null,
|
||||
];
|
||||
}),
|
||||
])
|
||||
->all();
|
||||
|
||||
foreach ($grupos as &$grupo) {
|
||||
|
||||
$grupo['permite_requisitar'] = collect($grupo['materiais'])
|
||||
->contains('permite_requisitar', true);
|
||||
}
|
||||
|
||||
unset($grupo);
|
||||
|
||||
return $grupos;
|
||||
}
|
||||
|
||||
public static function datatableHistorico()
|
||||
{
|
||||
$requisicoes = DB::table('almoxarifado_requisicao as requisicao')
|
||||
->join(
|
||||
'cadastro_centro_custo as centro_custo',
|
||||
'centro_custo.id',
|
||||
'requisicao.created_centro_custo_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_infraestrutura as infraestrutura',
|
||||
'infraestrutura.id',
|
||||
'centro_custo.infraestrutura_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_unidade as unidade',
|
||||
'unidade.id',
|
||||
'infraestrutura.unidade_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_setor as setor',
|
||||
'setor.id',
|
||||
'centro_custo.setor_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_lotacao as lotacao',
|
||||
'lotacao.id',
|
||||
'requisicao.created_lotacao_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_usuario as usuario',
|
||||
'usuario.id',
|
||||
'lotacao.usuario_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_cidadao as cidadao',
|
||||
'cidadao.id',
|
||||
'usuario.cidadao_id'
|
||||
)
|
||||
->where('requisicao.centro_custo_id', self::getCurrentCentroCusto()->id)
|
||||
->where('unidade.id', request()->unidade_requisitante_id)
|
||||
->whereExists(function ($query) {
|
||||
|
||||
$query->select(DB::raw(1))
|
||||
->from('almoxarifado_requisicao_item as item')
|
||||
->join(
|
||||
'almoxarifado_requisicao_resposta_item as resposta_item',
|
||||
'resposta_item.requisicao_item_id',
|
||||
'item.id'
|
||||
)
|
||||
->whereColumn('item.requisicao_id', 'requisicao.id')
|
||||
->where('item.material_id', request()->material_id)
|
||||
->whereNotNull('saida_item_id');
|
||||
})
|
||||
->select(
|
||||
'requisicao.id',
|
||||
'requisicao.numero',
|
||||
DB::raw("DATE_FORMAT(requisicao.created_at, '%d/%m/%Y') as data_requisicao"),
|
||||
DB::raw("COALESCE(infraestrutura.nome, unidade.nome_fantasia) AS infraestrutura_nome"),
|
||||
'setor.nome as setor_nome',
|
||||
'cidadao.nome as usuario_nome',
|
||||
)
|
||||
->addSelect([
|
||||
'concedido' => function ($query) {
|
||||
|
||||
$query->select(DB::raw('SUM(saida_item_entrada_item.quantidade_saida)'))
|
||||
->from('almoxarifado_saida_item_entrada_item as saida_item_entrada_item')
|
||||
->join(
|
||||
'almoxarifado_saida_item as saida_item',
|
||||
'saida_item.id',
|
||||
'saida_item_entrada_item.saida_item_id'
|
||||
)
|
||||
->join(
|
||||
'almoxarifado_requisicao_resposta_item as resposta_item',
|
||||
'resposta_item.saida_item_id',
|
||||
'saida_item.id'
|
||||
)
|
||||
->join(
|
||||
'almoxarifado_requisicao_item as requisicao_item',
|
||||
'requisicao_item.id',
|
||||
'resposta_item.requisicao_item_id'
|
||||
)
|
||||
->whereColumn('requisicao_item.requisicao_id', 'requisicao.id')
|
||||
->where('requisicao_item.material_id', request()->material_id);
|
||||
}
|
||||
]);
|
||||
|
||||
return datatables()
|
||||
->of($requisicoes)
|
||||
->filterColumn('requisicao.created_at', function ($query, $keyword) {
|
||||
|
||||
$query->whereRaw("DATE_FORMAT(requisicao.created_at, '%d/%m/%Y') like ?", ["%{$keyword}%"]);
|
||||
})
|
||||
->filterColumn('infraestrutura.nome', function ($query, $keyword) {
|
||||
|
||||
$query->whereRaw("COALESCE(infraestrutura.nome, unidade.nome_fantasia) like ?", ["%{$keyword}%"]);
|
||||
})
|
||||
->toJson();
|
||||
}
|
||||
|
||||
public static function storePermissoes()
|
||||
{
|
||||
self::validatePermissao();
|
||||
|
||||
DB::transaction(function () {
|
||||
|
||||
RequisicaoPermissao::where('created_centro_custo_id', self::getCurrentCentroCusto()->id)
|
||||
->where('centro_custo_requisitante_id', request()->centro_custo_requisitante_id)
|
||||
->whereNotIn('material_id', collect(request()->materiais)->pluck('id'))
|
||||
->delete();
|
||||
|
||||
foreach (request()->materiais as $material) {
|
||||
|
||||
RequisicaoPermissao::updateOrCreate(
|
||||
[
|
||||
'created_centro_custo_id' => self::getCurrentCentroCusto()->id,
|
||||
'centro_custo_requisitante_id' => request()->centro_custo_requisitante_id,
|
||||
'material_id' => $material['id'],
|
||||
],
|
||||
[
|
||||
'estoque_maximo' => $material['estoque_maximo'],
|
||||
]
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static function validatePermissao()
|
||||
{
|
||||
$rules = [
|
||||
'centro_custo_requisitante_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(CentroCusto::class, 'id'),
|
||||
],
|
||||
'materiais' => [
|
||||
'present',
|
||||
'array',
|
||||
],
|
||||
'materiais.*.id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(Material::class, 'id'),
|
||||
],
|
||||
'materiais.*.estoque_maximo' => [
|
||||
'nullable',
|
||||
'integer',
|
||||
'max:99999999',
|
||||
]
|
||||
];
|
||||
|
||||
$messages = [];
|
||||
|
||||
request()->validate($rules, $messages);
|
||||
}
|
||||
|
||||
public static function createImportacao($centroCustoDestinoId)
|
||||
{
|
||||
$centroCustoLogadoId = self::getCurrentCentroCusto()->id;
|
||||
|
||||
return [
|
||||
'form' => [
|
||||
'unidades' => Unidade::orderBy('nome_fantasia')
|
||||
->whereHas('infraestruturas', function ($query) use ($centroCustoDestinoId, $centroCustoLogadoId) {
|
||||
|
||||
$query->whereHas('centrosCusto', function ($query) use ($centroCustoDestinoId, $centroCustoLogadoId) {
|
||||
|
||||
$query
|
||||
->where('id', '<>', $centroCustoDestinoId)
|
||||
->whereHas('almoxarifadoRequisicaoPermissoesRequisitante', function ($query) use ($centroCustoLogadoId) {
|
||||
|
||||
$query->where('created_centro_custo_id', $centroCustoLogadoId);
|
||||
});
|
||||
});
|
||||
})
|
||||
->get()
|
||||
->map(fn ($unidade) => [
|
||||
'id' => $unidade->id,
|
||||
'nome_fantasia' => $unidade->nome_fantasia,
|
||||
'infraestruturas' => $unidade->infraestruturas()
|
||||
->whereHas('centrosCusto', function ($query) use ($centroCustoDestinoId, $centroCustoLogadoId) {
|
||||
|
||||
$query
|
||||
->where('id', '<>', $centroCustoDestinoId)
|
||||
->whereHas('almoxarifadoRequisicaoPermissoesRequisitante', function ($query) use ($centroCustoLogadoId) {
|
||||
|
||||
$query->where('created_centro_custo_id', $centroCustoLogadoId);
|
||||
});
|
||||
})
|
||||
->get()
|
||||
->sortBy('nome')
|
||||
->map(fn ($infraestrutura) => [
|
||||
'id' => $infraestrutura->id,
|
||||
'nome' => $infraestrutura->nome,
|
||||
'centros_custo' => $infraestrutura->centrosCusto()
|
||||
->where('id', '<>', $centroCustoDestinoId)
|
||||
->whereHas('almoxarifadoRequisicaoPermissoesRequisitante', function ($query) use ($centroCustoLogadoId) {
|
||||
|
||||
$query->where('created_centro_custo_id', $centroCustoLogadoId);
|
||||
})
|
||||
->get()
|
||||
->map(fn ($centroCusto) => [
|
||||
'id' => $centroCusto->id,
|
||||
'setor_nome' => $centroCusto->setor->nome,
|
||||
])
|
||||
->sortBy('setor_nome')
|
||||
->values()
|
||||
])
|
||||
->values()
|
||||
]),
|
||||
'unidade_id' => null,
|
||||
'infraestrutura_id' => null,
|
||||
],
|
||||
'model' => [
|
||||
'centro_custo_origem_id' => null,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public static function storeImportacao()
|
||||
{
|
||||
self::validateImportacao();
|
||||
|
||||
DB::transaction(function () {
|
||||
|
||||
RequisicaoPermissao::where('created_centro_custo_id', self::getCurrentCentroCusto()->id)
|
||||
->where('centro_custo_requisitante_id', request()->centro_custo_destino_id)
|
||||
->delete();
|
||||
|
||||
RequisicaoPermissao::where('created_centro_custo_id', self::getCurrentCentroCusto()->id)
|
||||
->where('centro_custo_requisitante_id', request()->centro_custo_origem_id)
|
||||
->get()
|
||||
->each(function ($permissao) {
|
||||
|
||||
if ($permissao->material->is_ativo) {
|
||||
|
||||
RequisicaoPermissao::create([
|
||||
'centro_custo_requisitante_id' => request()->centro_custo_destino_id,
|
||||
'material_id' => $permissao->material_id,
|
||||
'estoque_maximo' => request()->importar_estoque_maximo ? $permissao->estoque_maximo : null,
|
||||
]);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static function validateImportacao()
|
||||
{
|
||||
$rules = [
|
||||
'centro_custo_origem_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(CentroCusto::class, 'id'),
|
||||
],
|
||||
'centro_custo_destino_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(CentroCusto::class, 'id'),
|
||||
],
|
||||
'importar_estoque_maximo' => [
|
||||
'required',
|
||||
'boolean',
|
||||
]
|
||||
];
|
||||
|
||||
$messages = [];
|
||||
|
||||
request()->validate($rules, $messages);
|
||||
}
|
||||
|
||||
public static function edit($id)
|
||||
{
|
||||
$requisicao = Requisicao::findOrFail($id);
|
||||
|
||||
$ultimoEnvio = $requisicao->respostas()
|
||||
->whereNotNull('enviada_em')
|
||||
->orderByDesc('id')
|
||||
->first();
|
||||
|
||||
$respostaIniciada = $requisicao->respostas()
|
||||
->where('status_id', RequisicaoRespostaStatus::INICIADA)
|
||||
->first();
|
||||
|
||||
$itens = $requisicao->itens()->withAggregate('material', 'descricao')
|
||||
->when(request()->has('sort') && request()->sort !== 'null', function ($query) {
|
||||
return $query->orderBy('material_descricao', request()->sort);
|
||||
})
|
||||
->get();
|
||||
|
||||
if ($ultimoEnvio) {
|
||||
|
||||
$itens = $itens->filter(function ($item) use ($ultimoEnvio) {
|
||||
|
||||
$ultimoEnvioItem = $ultimoEnvio->itens()->where('requisicao_item_id', $item->id)->first();
|
||||
|
||||
return !is_null($ultimoEnvioItem) && collect([
|
||||
RequisicaoRespostaItemMotivoEnum::ENTREGA_PARCIAL,
|
||||
RequisicaoRespostaItemMotivoEnum::PENDENTE_DE_ENTREGA,
|
||||
])->contains($ultimoEnvioItem->motivo_id);
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
'form' => self::getFormData($requisicao),
|
||||
'model' => [
|
||||
'itens' => $itens->map(function ($item) use ($respostaIniciada) {
|
||||
|
||||
$respostaItemIniciada = $respostaIniciada
|
||||
? $respostaIniciada->itens()->where('requisicao_item_id', $item->id)->first()
|
||||
: null;
|
||||
|
||||
$estoque = AlmoxarifadoService::getEstoque(
|
||||
$item->material->id,
|
||||
null,
|
||||
$respostaItemIniciada->reserva_item_id ?? null
|
||||
);
|
||||
|
||||
$estoqueTotal = $estoque['total'];
|
||||
$reservas = AlmoxarifadoService::getReservas($item->material->id)['agrupadas'];
|
||||
|
||||
$estoqueTotalRequisitante = AlmoxarifadoService::getEstoque(
|
||||
$item->material->id,
|
||||
$item->requisicao->created_centro_custo_id
|
||||
)['total'];
|
||||
|
||||
$respostaItemEnviadas = $item->respostaItens()
|
||||
->whereHas('requisicaoResposta', function ($query) {
|
||||
|
||||
$query->whereNotNull('enviada_em');
|
||||
})
|
||||
->get();
|
||||
|
||||
$entregue = $respostaItemEnviadas ? $respostaItemEnviadas
|
||||
->map(fn ($respostaItemEnviada) => $respostaItemEnviada->saidaItem->quantidade ?? 0)
|
||||
->sum() : 0;
|
||||
|
||||
$restanteRequisitado = $item->quantidade - $entregue;
|
||||
$concedido = 0;
|
||||
$escolheuEntradaItemManualmente = false;
|
||||
$entradaItens = [];
|
||||
$motivoId = null;
|
||||
|
||||
if ($respostaItemIniciada) {
|
||||
|
||||
$entradaItensReservados = [];
|
||||
|
||||
if ($respostaItemIniciada->reservaItem) {
|
||||
|
||||
$concedido = $respostaItemIniciada->reservaItem->quantidade;
|
||||
|
||||
$escolheuEntradaItemManualmente = $respostaItemIniciada->reservaItem
|
||||
->escolheu_entrada_item_manualmente;
|
||||
|
||||
$entradaItensReservados = $respostaItemIniciada->reservaItem->entradaItens
|
||||
->map(fn ($entradaItem) => [
|
||||
'entrada_item_id' => $entradaItem->id,
|
||||
'quantidade_saida' => $entradaItem->pivotReservaItemEntradaItem->quantidade_saida,
|
||||
]);
|
||||
}
|
||||
|
||||
$entradaItens = collect($estoque['por_entrada'])
|
||||
->map(function ($entradaItem) use ($entradaItensReservados) {
|
||||
|
||||
$entradaItem['quantidade_saida'] = collect($entradaItensReservados)
|
||||
->where('entrada_item_id', $entradaItem['entrada_item_id'])
|
||||
->first()['quantidade_saida'] ?? 0;
|
||||
|
||||
return $entradaItem;
|
||||
});
|
||||
|
||||
$motivoId = $respostaItemIniciada->motivo_id;
|
||||
}
|
||||
else {
|
||||
|
||||
$quantidade = $respostaItemEnviadas->isEmpty() ? $item->quantidade : $restanteRequisitado;
|
||||
$concedido = $quantidade > $estoqueTotal ? $estoqueTotal : $quantidade;
|
||||
|
||||
$entradaItensData = AlmoxarifadoService::getEntradaItensData(
|
||||
$item->material->id,
|
||||
[
|
||||
'escolheu_entrada_item_manualmente' => false,
|
||||
'quantidade' => $concedido,
|
||||
]
|
||||
);
|
||||
|
||||
$entradaItensAutomaticos = [];
|
||||
|
||||
foreach ($entradaItensData as $entradaItemId => $entradaItemData) {
|
||||
|
||||
$entradaItensAutomaticos[] = [
|
||||
'entrada_item_id' => $entradaItemId,
|
||||
'quantidade_saida' => $entradaItemData['quantidade_saida'],
|
||||
];
|
||||
}
|
||||
|
||||
$entradaItens = collect($estoque['por_entrada'])
|
||||
->map(function ($entradaItem) use ($entradaItensAutomaticos) {
|
||||
|
||||
$entradaItem['quantidade_saida'] = collect($entradaItensAutomaticos)
|
||||
->where('entrada_item_id', $entradaItem['entrada_item_id'])
|
||||
->first()['quantidade_saida'] ?? 0;
|
||||
|
||||
return $entradaItem;
|
||||
});
|
||||
|
||||
$motivoId = $estoqueTotal === 0 ? RequisicaoRespostaItemMotivoEnum::SEM_ESTOQUE : null;
|
||||
}
|
||||
|
||||
$possuiEntradaComLote = !is_null(collect($entradaItens)->whereNotNull('lote')->first());
|
||||
|
||||
$data = [
|
||||
'requisicao_item_id' => $item->id,
|
||||
'unidade_requisitante' => [
|
||||
'id' => $item->requisicao->createdCentroCusto->infraestrutura->unidade->id,
|
||||
'nome_fantasia' => $item->requisicao->createdCentroCusto->infraestrutura->unidade->nome_fantasia
|
||||
],
|
||||
'material' => [
|
||||
'id' => $item->material->id,
|
||||
'codigo' => $item->material->codigo_material,
|
||||
'descricao_completa' => $item->material->descricao_completa,
|
||||
],
|
||||
'possui_entrada_com_lote' => $possuiEntradaComLote,
|
||||
'estoque_disponivel' => $estoqueTotal,
|
||||
'reservas' => $reservas,
|
||||
'estoque_requisitante' => $estoqueTotalRequisitante,
|
||||
'concedido' => $concedido,
|
||||
'escolheu_entrada_item_manualmente' => $escolheuEntradaItemManualmente,
|
||||
'entrada_itens' => $entradaItens,
|
||||
'motivo_id' => $motivoId,
|
||||
'motivo_outro' => $respostaItemIniciada->motivo_outro ?? null,
|
||||
];
|
||||
|
||||
if ($respostaItemEnviadas->isEmpty()) {
|
||||
|
||||
$data['requisitado'] = $item->quantidade;
|
||||
}
|
||||
else {
|
||||
|
||||
$data['entregue'] = $entregue;
|
||||
$data['restante_requisitado'] = $restanteRequisitado;
|
||||
}
|
||||
|
||||
return $data;
|
||||
})->values(),
|
||||
'observacoes' => $respostaIniciada->observacoes ?? null,
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
private static function getFormData($requisicao)
|
||||
{
|
||||
$parametrizacao = ParametrizacaoRequisicao::first();
|
||||
|
||||
return [
|
||||
'data_requisicao' => (new Carbon($requisicao->created_at))->format('d/m/Y'),
|
||||
'numero' => $requisicao->numero,
|
||||
'requisitante' => [
|
||||
'unidade_nome_fantasia' => $requisicao->createdCentroCusto->infraestrutura->unidade->nome_fantasia,
|
||||
'infraestrutura_nome' => $requisicao->createdCentroCusto->infraestrutura->nome,
|
||||
'setor_nome' => $requisicao->createdCentroCusto->setor->nome,
|
||||
'usuario_nome' => $requisicao->createdLotacao->usuario->cidadao->nome,
|
||||
],
|
||||
'envios' => self::getEnvios($requisicao),
|
||||
'motivos' => RequisicaoRespostaItemMotivo::orderBy('nome')->get(['id', 'nome']),
|
||||
'motivo_obrigatorio' => $parametrizacao->motivo_obrigatorio ?? false
|
||||
];
|
||||
}
|
||||
|
||||
private static function getEnvios($requisicao)
|
||||
{
|
||||
$envios = $requisicao->respostas()
|
||||
->whereNotNull('enviada_em')
|
||||
->orderBy('enviada_em')
|
||||
->get();
|
||||
|
||||
$entregue = [];
|
||||
|
||||
$envios = $envios->map(function ($resposta, $i) use (&$entregue) {
|
||||
|
||||
$numeroEnvio = $i + 1;
|
||||
|
||||
$itens = $resposta->itens->map(function ($respostaItem) use ($numeroEnvio, &$entregue) {
|
||||
|
||||
$material = $respostaItem->requisicaoItem->material;
|
||||
|
||||
if (!isset($entregue[$material->id])) {
|
||||
|
||||
$entregue[$material->id] = 0;
|
||||
}
|
||||
|
||||
$item = [
|
||||
'material' => [
|
||||
'codigo' => $material->codigo_material,
|
||||
'descricao_completa' => $material->descricao_completa,
|
||||
],
|
||||
'motivo_nome' => $respostaItem->motivo->nome ?? null,
|
||||
'motivo_outro' => $respostaItem->motivo_outro,
|
||||
];
|
||||
|
||||
if ($numeroEnvio === 1) {
|
||||
|
||||
$item['requisitado'] = $respostaItem->requisicaoItem->quantidade;
|
||||
}
|
||||
else {
|
||||
|
||||
$item['entregue'] = $entregue[$material->id];
|
||||
$item['restante_requisitado'] = $respostaItem->requisicaoItem->quantidade - $entregue[$material->id];
|
||||
}
|
||||
|
||||
$item['possui_entrada_com_lote'] = is_null($respostaItem->saidaItem) ? false
|
||||
: $respostaItem->saidaItem->entradaItens()->whereNotNull('lote')->exists();
|
||||
|
||||
if ($item['possui_entrada_com_lote']) {
|
||||
|
||||
$item['entrada_itens'] = $respostaItem->saidaItem
|
||||
? $respostaItem->saidaItem->entradaItens->map(fn ($entradaItem) => [
|
||||
'concedido' => $entradaItem->pivotSaidaItemEntradaItem->quantidade_saida,
|
||||
'lote' => $entradaItem->lote,
|
||||
'validade_lote' => $entradaItem->validade_lote
|
||||
? $entradaItem->validade_lote->format('d/m/Y')
|
||||
: null,
|
||||
]) : [];
|
||||
|
||||
$entregue[$material->id] += collect($item['entrada_itens'])->sum('concedido');
|
||||
}
|
||||
else {
|
||||
|
||||
$item['concedido'] = $respostaItem->saidaItem ? $respostaItem->saidaItem->quantidade : 0;
|
||||
|
||||
$entregue[$material->id] += $item['concedido'];
|
||||
}
|
||||
|
||||
return $item;
|
||||
});
|
||||
|
||||
return [
|
||||
'numero_envio' => $numeroEnvio,
|
||||
'data_hora' => $resposta->enviada_em->format('d/m/Y H:i'),
|
||||
'usuario' => $resposta->enviadaLotacao->usuario->cidadao->nome ?? null,
|
||||
'itens' => $itens,
|
||||
'observacoes' => $resposta->observacoes,
|
||||
];
|
||||
});
|
||||
|
||||
return collect($envios)->sortByDesc('numero_envio')->values();
|
||||
}
|
||||
|
||||
public static function update($id)
|
||||
{
|
||||
self::validate();
|
||||
|
||||
$requisicao = Requisicao::findOrFail($id);
|
||||
|
||||
DB::transaction(function () use ($requisicao) {
|
||||
|
||||
$resposta = $requisicao->respostas()->updateOrCreate(
|
||||
['status_id' => RequisicaoRespostaStatus::INICIADA],
|
||||
['observacoes' => request()->observacoes]
|
||||
);
|
||||
|
||||
$reservaAnteriorId = $resposta->reserva_id;
|
||||
|
||||
$resposta->update(['reserva_id' => null]);
|
||||
$resposta->itens->each(fn ($i) => $i->update(['reserva_item_id' => null]));
|
||||
|
||||
$itens = request()->itens;
|
||||
|
||||
foreach ($itens as &$item) {
|
||||
|
||||
$requisicaoItem = RequisicaoItem::findOrFail($item['requisicao_item_id']);
|
||||
|
||||
$item['material_id'] = $requisicaoItem->material_id;
|
||||
}
|
||||
|
||||
unset($item);
|
||||
|
||||
$itensComQuantidadeConcedida = collect($itens)
|
||||
->filter(fn ($i) => $i['concedido'] > 0)
|
||||
->map(fn ($item) => [
|
||||
'material_id' => $item['material_id'],
|
||||
'quantidade' => $item['concedido'],
|
||||
'escolheu_entrada_item_manualmente' => $item['escolheu_entrada_item_manualmente'],
|
||||
'entrada_itens' => $item['entrada_itens'],
|
||||
]);
|
||||
|
||||
if (request()->enviar_resposta) {
|
||||
|
||||
$saida = AlmoxarifadoService::saveSaidaDeRequisicao(
|
||||
$itensComQuantidadeConcedida,
|
||||
$reservaAnteriorId
|
||||
);
|
||||
|
||||
$resposta->update([
|
||||
'saida_id' => $saida->id ?? null,
|
||||
'status_id' => RequisicaoRespostaStatus::ENVIADA,
|
||||
'enviada_em' => Carbon::now(),
|
||||
'enviada_lotacao_id' => self::getCurrentLotacao()->id,
|
||||
]);
|
||||
|
||||
foreach ($itens as $item) {
|
||||
|
||||
$saidaItemId = null;
|
||||
|
||||
if ($saida) {
|
||||
|
||||
$saidaItemId = $saida->itens()
|
||||
->where('material_id', $item['material_id'])
|
||||
->first()->id ?? null;
|
||||
}
|
||||
|
||||
$resposta->itens()->updateOrCreate(
|
||||
['requisicao_item_id' => $item['requisicao_item_id']],
|
||||
array_merge(self::getItemData($item), [
|
||||
'saida_item_id' => $saidaItemId,
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
$reserva = AlmoxarifadoService::saveReservaDeRequisicao(
|
||||
$itensComQuantidadeConcedida,
|
||||
$reservaAnteriorId
|
||||
);
|
||||
|
||||
if ($reserva) {
|
||||
|
||||
$resposta->update(['reserva_id' => $reserva->id]);
|
||||
}
|
||||
|
||||
foreach ($itens as $item) {
|
||||
|
||||
$reservaItemId = null;
|
||||
|
||||
if ($reserva) {
|
||||
|
||||
$reservaItemId = $reserva->itens()
|
||||
->where('material_id', $item['material_id'])
|
||||
->first()->id ?? null;
|
||||
}
|
||||
|
||||
$resposta->itens()->updateOrCreate(
|
||||
['requisicao_item_id' => $item['requisicao_item_id']],
|
||||
array_merge(self::getItemData($item), [
|
||||
'reserva_item_id' => $reservaItemId,
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($requisicao->status_id !== RequisicaoStatus::RESPOSTA_INICIADA) {
|
||||
|
||||
$requisicao->update(['status_id' => RequisicaoStatus::RESPOSTA_INICIADA]);
|
||||
}
|
||||
});
|
||||
|
||||
return $requisicao->fresh();
|
||||
}
|
||||
|
||||
private static function getItemData($item)
|
||||
{
|
||||
return [
|
||||
'motivo_id' => $item['motivo_id'],
|
||||
'motivo_outro' => $item['motivo_id'] === RequisicaoRespostaItemMotivoEnum::OUTRO
|
||||
? $item['motivo_outro'] : null,
|
||||
];
|
||||
}
|
||||
|
||||
public static function validate()
|
||||
{
|
||||
$rules = [
|
||||
'enviar_resposta' => [
|
||||
'required',
|
||||
'boolean',
|
||||
],
|
||||
'observacoes' => [
|
||||
'nullable',
|
||||
'string',
|
||||
'max:1000',
|
||||
],
|
||||
'itens' => [
|
||||
'required',
|
||||
'array',
|
||||
],
|
||||
'itens.*.requisicao_item_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(RequisicaoItem::class, 'id'),
|
||||
],
|
||||
'itens.*.concedido' => [
|
||||
'required',
|
||||
'integer',
|
||||
],
|
||||
'itens.*.escolheu_entrada_item_manualmente' => [
|
||||
'required',
|
||||
'boolean',
|
||||
],
|
||||
'itens.*.entrada_itens' => [
|
||||
'present',
|
||||
'array',
|
||||
],
|
||||
'itens.*.entrada_itens.*.entrada_item_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(EntradaItem::class, 'id'),
|
||||
],
|
||||
'itens.*.entrada_itens.*.quantidade_saida' => [
|
||||
'required',
|
||||
'integer',
|
||||
'min:1',
|
||||
],
|
||||
'itens.*.motivo_id' => [
|
||||
'nullable',
|
||||
'integer',
|
||||
Rule::exists(RequisicaoRespostaItemMotivo::class, 'id'),
|
||||
],
|
||||
'itens.*.motivo_outro' => [
|
||||
'nullable',
|
||||
'string',
|
||||
'max:300',
|
||||
],
|
||||
];
|
||||
|
||||
$messages = [];
|
||||
|
||||
request()->validate($rules, $messages);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user