join( 'almoxarifado_saida_requisicao', 'almoxarifado_saida_requisicao.saida_id', 'almoxarifado_saida.id' ) ->join( 'cadastro_centro_custo', 'cadastro_centro_custo.id', 'almoxarifado_saida_requisicao.centro_custo_id' ) ->join( 'cadastro_setor', 'cadastro_setor.id', 'cadastro_centro_custo.setor_id' ) ->join( 'cadastro_infraestrutura', 'cadastro_infraestrutura.id', 'cadastro_centro_custo.infraestrutura_id' ) ->join( 'cadastro_unidade', 'cadastro_unidade.id', 'cadastro_infraestrutura.unidade_id' ) ->join( 'cadastro_usuario', 'cadastro_usuario.id', 'almoxarifado_saida_requisicao.usuario_id' ) ->join( 'cadastro_cidadao', 'cadastro_cidadao.id', 'cadastro_usuario.cidadao_id' ) ->select( 'almoxarifado_saida.id', DB::raw("DATE_FORMAT(almoxarifado_saida_requisicao.data, '%d/%m/%Y') as data_requisicao"), DB::raw("cadastro_unidade.nome_fantasia AS unidade_nome_fantasia"), DB::raw("COALESCE(cadastro_infraestrutura.nome, cadastro_unidade.nome_fantasia) AS infraestrutura_nome"), 'cadastro_setor.nome as setor_nome', 'cadastro_cidadao.nome AS usuario_nome', 'almoxarifado_saida_requisicao.numero', DB::raw("DATE_FORMAT(almoxarifado_saida.created_at, '%d/%m/%Y') as data_saida"), 'almoxarifado_saida.finalizada', ) ->where('almoxarifado_saida.tipo_id', SaidaTipo::MANUAL) ->where('almoxarifado_saida.centro_custo_id', self::getCurrentCentroCusto()->id); return datatables() ->of($saidas) ->filterColumn('almoxarifado_saida_requisicao.data', function ($query, $keyword) { $query->whereRaw("DATE_FORMAT(almoxarifado_saida_requisicao.data, '%d/%m/%Y') like ?", ["%{$keyword}%"]) ->orWhereRaw( "CONCAT( SUBSTR(almoxarifado_saida_requisicao.data,9,2), SUBSTR(almoxarifado_saida_requisicao.data,6,2), SUBSTR(almoxarifado_saida_requisicao.data,1,4) ) like ?", ["%{$keyword}%"] ); }) ->filterColumn('almoxarifado_saida.created_at', function ($query, $keyword) { $query->whereRaw("DATE_FORMAT(almoxarifado_saida.created_at, '%d/%m/%Y') like ?", ["%{$keyword}%"]) ->orWhereRaw( "CONCAT( SUBSTR(almoxarifado_saida.created_at,9,2), SUBSTR(almoxarifado_saida.created_at,6,2), SUBSTR(almoxarifado_saida.created_at,1,4) ) like ?", ["%{$keyword}%"] ); }) ->filterColumn('cadastro_infraestrutura.nome', function ($query, $keyword) { $query->whereRaw("COALESCE(cadastro_infraestrutura.nome, cadastro_unidade.nome_fantasia) like ?", ["%{$keyword}%"]); }) ->skipTotalRecords() ->toJson(); } public static function create() { return [ 'additionals' => self::getAdditionalsData(), 'form' => self::getFormData(), 'model' => [ 'finalizada' => false, 'requisicao' => [ 'centro_custo_id' => null, 'usuario' => null, 'numero' => ParametrizacaoService::getParametrizacaoRequisicao()['numero_requisicao_automatico'] ? ParametrizacaoService::getNovoNumeroRequisicao() : null, 'data' => null, ], 'itens' => [], ] ]; } public static function store() { self::validate(); $saida = null; DB::transaction(function () use (&$saida) { $saida = AlmoxarifadoService::saveSaidaManual(self::getParams()); }); return $saida; } public static function edit($id) { $saida = Saida::findOrFail($id); return [ 'additionals' => self::getAdditionalsData(), 'form' => self::getFormData($saida), 'model' => [ 'finalizada' => $saida->finalizada, 'requisicao' => [ 'centro_custo_id' => $saida->requisicao->centroCusto->id, 'usuario' => [ 'id' => $saida->requisicao->usuario->id, 'cidadao_nome' => $saida->requisicao->usuario->cidadao->nome, ], 'numero' => $saida->requisicao->numero, 'data' => $saida->requisicao->data->format('d/m/Y'), ], 'itens' => $saida->itens->map(fn ($item) => [ 'id' => $item->id, 'material' => [ 'id' => $item->material->id, 'codigo_material' => $item->material->codigo_material, 'descricao_completa' => $item->material->descricao_completa, ], 'quantidade' => $item->quantidade, 'estorno_salvo' => $item->estornado, 'estornado' => $item->estornado, 'entrada_itens' => $item->entradaItens->map(fn ($entradaItem) => [ 'entrada_item_id' => $entradaItem->id, 'quantidade_saida' => $entradaItem->pivotSaidaItemEntradaItem->quantidade_saida, 'lote' => $entradaItem->lote, 'validade_lote' => $entradaItem->validade_lote, ]), 'escolheu_entrada_item_manualmente' => $item->escolheu_entrada_item_manualmente, ]) ] ]; } private static function getFormData($saida = null) { $centroCustoLogadoId = self::getCurrentCentroCusto()->id; return [ 'requisicao' => [ 'unidades' => Unidade::orderBy('nome_fantasia') ->whereHas('infraestruturas', function ($query) use ($centroCustoLogadoId) { $query->whereHas('centrosCusto', function ($query) use ($centroCustoLogadoId) { $query->where('id', '<>', $centroCustoLogadoId) ->whereDoesntHave('almoxarifadoParametrizacoesControleEstoqueGrupo'); }); }) ->get() ->map(fn ($unidade) => [ 'id' => $unidade->id, 'nome_fantasia' => $unidade->nome_fantasia, 'infraestruturas' => $unidade->infraestruturas() ->whereHas('centrosCusto', function ($query) use ($centroCustoLogadoId) { $query->where('id', '<>', $centroCustoLogadoId) ->whereDoesntHave('almoxarifadoParametrizacoesControleEstoqueGrupo'); }) ->get() ->sortBy('nome') ->map(fn ($infraestrutura) => [ 'id' => $infraestrutura->id, 'nome' => $infraestrutura->nome, 'centros_custo' => $infraestrutura->centrosCusto() ->where('id', '<>', $centroCustoLogadoId) ->whereDoesntHave('almoxarifadoParametrizacoesControleEstoqueGrupo') ->get() ->map(fn ($centroCusto) => [ 'id' => $centroCusto->id, 'setor_nome' => $centroCusto->setor->nome, ]) ->sortBy('setor_nome') ->values() ]) ->values() ]), 'unidade_id' => $saida ? $saida->requisicao->centroCusto->infraestrutura->unidade_id : null, 'infraestrutura_id' => $saida ? $saida->requisicao->centroCusto->infraestrutura->id : null, 'balancete_lastest' => BalanceteFechamento::select('id','mes','ano')->orderBy('id','desc')->first() ?? null, ] ]; } private static function getAdditionalsData() { return [ 'data_atual' => Carbon::now()->format('d/m/Y'), 'is_numero_requisicao_automatico' => ParametrizacaoService::getParametrizacaoRequisicao() ['numero_requisicao_automatico'], ]; } public static function update($id) { self::validate(); $saida = Saida::findOrFail($id); DB::transaction(function () use (&$saida) { $saida = AlmoxarifadoService::saveSaidaManual(self::getParams(), $saida->id); }); return $saida; } private static function getParams() { return [ 'finalizada' => request()->finalizada, 'requisicao' => [ 'centro_custo_id' => request()->requisicao['centro_custo_id'], 'usuario_id' => request()->requisicao['usuario_id'], 'numero' => request()->requisicao['numero'], 'data' => Carbon::createFromFormat('d/m/Y', request()->requisicao['data']), ], 'itens' => collect(request()->itens)->map(fn ($item) => [ 'id' => $item['id'], 'material_id' => $item['material_id'], 'quantidade' => (int) $item['quantidade'], 'estornado' => $item['estornado'], 'entrada_itens' => collect($item['entrada_itens'])->map(fn ($entradaItem) => [ 'entrada_item_id' => $entradaItem['entrada_item_id'], 'quantidade_saida' => (int) $entradaItem['quantidade_saida'], ]), 'escolheu_entrada_item_manualmente' => $item['escolheu_entrada_item_manualmente'], ]) ]; } public static function validate() { $rules = [ 'finalizada' => [ 'required', 'boolean', ], 'requisicao.centro_custo_id' => [ 'required', 'integer', Rule::exists(CentroCusto::class, 'id'), ], 'requisicao.usuario_id' => [ 'required', 'integer', Rule::exists(Usuario::class, 'id'), ], 'requisicao.numero' => [ 'required', 'digits_between:1,20', Rule::unique(SaidaRequisicao::class, 'numero')->ignore(request()->route('saida'), 'saida_id'), ], 'requisicao.data' => [ 'required', 'date_format:d/m/Y', 'before_or_equal:now', ], 'itens' => [ 'required', 'array', ], 'itens.*.id' => [ 'nullable', 'integer', Rule::exists(SaidaItem::class, 'id'), ], 'itens.*.material_id' => [ 'required', 'integer', Rule::exists(Material::class, 'id'), ], 'itens.*.quantidade' => [ 'required', 'integer', 'min:1', ], 'itens.*.escolheu_entrada_item_manualmente' => [ 'required', 'boolean', ], 'itens.*.estornado' => [ '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', ], ]; $messages = [ 'requisicao.numero.unique' => 'O número da requisição já foi inserido anteriormente.', ]; request()->validate($rules, $messages); } public static function destroy($id) { $saida = Saida::findOrFail($id); DB::transaction(function () use ($saida) { $saida->itens->each(fn ($i) => $i->entradaItens()->detach()); $saida->delete(); }); return null; } }