This commit is contained in:
431
api/app/Services/Almoxarifado/EntradaService.php
Normal file
431
api/app/Services/Almoxarifado/EntradaService.php
Normal file
@@ -0,0 +1,431 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Almoxarifado;
|
||||
|
||||
use App\Enums\Almoxarifado\DocumentoTipo as AlmoxarifadoDocumentoTipo;
|
||||
use App\Enums\Almoxarifado\EntradaTipo;
|
||||
use App\Models\Almoxarifado\DocumentoTipo;
|
||||
use App\Models\Almoxarifado\Entrada;
|
||||
use App\Models\Almoxarifado\EntradaItem;
|
||||
use App\Models\Cadastro\Fabricante\Fabricante;
|
||||
use App\Models\Cadastro\Fornecedor\Fornecedor;
|
||||
use App\Models\Cadastro\Material\Material;
|
||||
use App\Models\Cadastro\OrigemProgramatica;
|
||||
use App\Services\Service;
|
||||
use App\Utils\MaskUtil;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class EntradaService extends Service
|
||||
{
|
||||
public static function datatable()
|
||||
{
|
||||
$entradas = DB::table('almoxarifado_entrada')
|
||||
->join(
|
||||
'almoxarifado_entrada_documento',
|
||||
'almoxarifado_entrada_documento.entrada_id',
|
||||
'almoxarifado_entrada.id'
|
||||
)
|
||||
->join(
|
||||
'almoxarifado_documento_tipo',
|
||||
'almoxarifado_documento_tipo.id',
|
||||
'almoxarifado_entrada_documento.tipo_id'
|
||||
)
|
||||
->join(
|
||||
'cadastro_fornecedor',
|
||||
'cadastro_fornecedor.id',
|
||||
'almoxarifado_entrada_documento.fornecedor_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'cadastro_origem_programatica',
|
||||
'cadastro_origem_programatica.id',
|
||||
'almoxarifado_entrada_documento.origem_programatica_id'
|
||||
)
|
||||
->select(
|
||||
'almoxarifado_entrada.id',
|
||||
DB::raw("DATE_FORMAT(almoxarifado_entrada_documento.data, '%d/%m/%Y') as data_documento"),
|
||||
'cadastro_fornecedor.nome_fantasia AS fornecedor_nome_fantasia',
|
||||
'cadastro_origem_programatica.nome AS origem_programatica_nome',
|
||||
'almoxarifado_entrada_documento.numero',
|
||||
'almoxarifado_entrada_documento.numero_pedido',
|
||||
DB::raw("(
|
||||
SELECT SUM(item.valor_total)
|
||||
FROM almoxarifado_entrada_item item
|
||||
WHERE item.entrada_id = almoxarifado_entrada.id
|
||||
) AS valor"),
|
||||
'almoxarifado_documento_tipo.nome AS tipo_nome',
|
||||
DB::raw("DATE_FORMAT(almoxarifado_entrada.created_at, '%d/%m/%Y') as data_entrada"),
|
||||
'almoxarifado_entrada.finalizada',
|
||||
)
|
||||
->where('almoxarifado_entrada.tipo_id', EntradaTipo::MANUAL)
|
||||
->where('almoxarifado_entrada.centro_custo_id', self::getCurrentCentroCusto()->id);
|
||||
|
||||
return datatables()
|
||||
->of($entradas)
|
||||
->filterColumn('almoxarifado_entrada_documento.data', function ($query, $keyword) {
|
||||
|
||||
$query->whereRaw("DATE_FORMAT(almoxarifado_entrada_documento.data, '%d/%m/%Y') like ?", ["%{$keyword}%"])
|
||||
->orWhereRaw(
|
||||
"CONCAT(
|
||||
SUBSTR(almoxarifado_entrada_documento.data,9,2),
|
||||
SUBSTR(almoxarifado_entrada_documento.data,6,2),
|
||||
SUBSTR(almoxarifado_entrada_documento.data,1,4)
|
||||
) like ?",
|
||||
["%{$keyword}%"]
|
||||
);
|
||||
})
|
||||
->filterColumn('almoxarifado_entrada.created_at', function ($query, $keyword) {
|
||||
|
||||
$query->whereRaw("DATE_FORMAT(almoxarifado_entrada.created_at, '%d/%m/%Y') like ?", ["%{$keyword}%"])
|
||||
->orWhereRaw(
|
||||
"CONCAT(
|
||||
SUBSTR(almoxarifado_entrada.created_at,9,2),
|
||||
SUBSTR(almoxarifado_entrada.created_at,6,2),
|
||||
SUBSTR(almoxarifado_entrada.created_at,1,4)
|
||||
) like ?",
|
||||
["%{$keyword}%"]
|
||||
);
|
||||
})
|
||||
->skipTotalRecords()
|
||||
->toJson();
|
||||
}
|
||||
|
||||
public static function create()
|
||||
{
|
||||
return [
|
||||
'additionals' => self::getAdditionalsData(),
|
||||
'form' => self::getFormData(),
|
||||
'model' => [
|
||||
'finalizada' => false,
|
||||
'documento' => [
|
||||
'tipo_id' => null,
|
||||
'numero_pedido' => null,
|
||||
'numero' => null,
|
||||
'data' => null,
|
||||
'fornecedor' => null,
|
||||
'origem_programatica' => null,
|
||||
],
|
||||
'itens' => [],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function store()
|
||||
{
|
||||
self::validate();
|
||||
|
||||
$entrada = null;
|
||||
|
||||
DB::transaction(function () use (&$entrada) {
|
||||
|
||||
$entrada = AlmoxarifadoService::saveEntradaManual(self::getParams());
|
||||
});
|
||||
|
||||
return $entrada;
|
||||
}
|
||||
|
||||
public static function edit($id)
|
||||
{
|
||||
$entrada = Entrada::findOrFail($id);
|
||||
|
||||
return [
|
||||
'additionals' => self::getAdditionalsData(),
|
||||
'form' => self::getFormData(),
|
||||
'model' => [
|
||||
'finalizada' => $entrada->finalizada,
|
||||
'documento' => [
|
||||
'tipo_id' => $entrada->documento->tipo_id,
|
||||
'numero_pedido' => $entrada->documento->numero_pedido,
|
||||
'numero' => $entrada->documento->numero,
|
||||
'data' => $entrada->documento->data->format('d/m/Y'),
|
||||
'fornecedor' => $entrada->documento->fornecedor,
|
||||
'origem_programatica' => $entrada->documento->origemProgramatica,
|
||||
],
|
||||
'itens' => $entrada->itens->map(function($item) {
|
||||
$hasMovimentacao = false;
|
||||
|
||||
$hasMovimentacao = DB::table('almoxarifado_saida_item_entrada_item')
|
||||
->where('entrada_item_id', $item->id)
|
||||
->exists();
|
||||
|
||||
if (!$hasMovimentacao) {
|
||||
$hasMovimentacao = DB::table('almoxarifado_reserva_item_entrada_item')
|
||||
->where('entrada_item_id', $item->id)
|
||||
->exists();
|
||||
}
|
||||
|
||||
if (!$hasMovimentacao) {
|
||||
$hasMovimentacao = DB::table('integracao_bnafar_posicao_estoque_item')
|
||||
->where('material_id', $item->material->id)
|
||||
->exists();
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'material' => [
|
||||
'id' => $item->material->id,
|
||||
'grupo_tipo_id' => $item->material->grupo->grupo_tipo_id ?? null,
|
||||
'possui_lote' => $item->material->possui_lote,
|
||||
'codigo_material' => $item->material->codigo_material,
|
||||
'descricao_completa' => $item->material->descricao_completa,
|
||||
'material_bnafar_id' => $item->material->materialBnafar->id ?? null,
|
||||
'material_bnafar_codigo' => $item->material->materialBnafar->codigo ?? null,
|
||||
'material_bnafar_descricao' => $item->material->materialBnafar->descricao ?? null,
|
||||
'material_bnafar_tipo' => $item->material->materialBnafar->tipo ?? null,
|
||||
],
|
||||
'quantidade' => $item->quantidade,
|
||||
'lote' => $item->lote,
|
||||
'validade_lote' => $item->validade_lote ? $item->validade_lote->format('d/m/Y') : null,
|
||||
'valor_unitario' => $item->valor_unitario_formatted,
|
||||
'valor_total' => $item->valor_total_formatted,
|
||||
'numero_empenho' => $item->numero_empenho,
|
||||
'despesas' => $item->despesas_formatted,
|
||||
'numero_autorizacao_fornecimento' => MaskUtil::getNumeroAutorizacaoFornecimentoMasked(
|
||||
$item->numero_autorizacao_fornecimento
|
||||
),
|
||||
'fabricante' => $item->fabricante,
|
||||
'codigo_barras' => $item->codigo_barras,
|
||||
'estorno_salvo' => $item->estornado,
|
||||
'estornado' => $item->estornado,
|
||||
'integracao_bnafar_medicamento' => $item->integracaoBnafarMedicamento ? [
|
||||
'medicamento_descricao_id' => $item->integracaoBnafarMedicamento->id,
|
||||
'medicamento_descricao' => $item->integracaoBnafarMedicamento->descricao,
|
||||
] : null,
|
||||
'integracao_bnafar_medicamento_id' => $item->integracaoBnafarMedicamento->id ?? null,
|
||||
'has_movimentacao' => $hasMovimentacao,
|
||||
];
|
||||
})
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
private static function getAdditionalsData()
|
||||
{
|
||||
return [
|
||||
'data_atual' => Carbon::now()->format('d/m/Y'),
|
||||
];
|
||||
}
|
||||
|
||||
private static function getFormData()
|
||||
{
|
||||
return [
|
||||
'tipos_documento' => DocumentoTipo::orderBy('nome')->get(['id', 'nome']),
|
||||
];
|
||||
}
|
||||
|
||||
public static function update($id)
|
||||
{
|
||||
self::validate();
|
||||
|
||||
$entrada = Entrada::findOrFail($id);
|
||||
|
||||
DB::transaction(function () use (&$entrada) {
|
||||
|
||||
$entrada = AlmoxarifadoService::saveEntradaManual(self::getParams(), $entrada->id);
|
||||
});
|
||||
|
||||
return $entrada;
|
||||
}
|
||||
|
||||
private static function getParams()
|
||||
{
|
||||
return [
|
||||
'finalizada' => request()->finalizada,
|
||||
'documento' => [
|
||||
'fornecedor_id' => request()->documento['fornecedor_id'],
|
||||
'origem_programatica_id' => request()->documento['origem_programatica_id'],
|
||||
'tipo_id' => request()->documento['tipo_id'],
|
||||
'numero_pedido' => request()->documento['numero_pedido'],
|
||||
'numero' => request()->documento['numero'],
|
||||
'data' => Carbon::createFromFormat('d/m/Y', request()->documento['data']),
|
||||
],
|
||||
'itens' => collect(request()->itens)->map(fn ($item) => [
|
||||
'id' => $item['id'],
|
||||
'material_id' => $item['material_id'],
|
||||
'integracao_bnafar_medicamento_id' => $item['integracao_bnafar_medicamento_id'],
|
||||
'quantidade' => $item['quantidade'],
|
||||
'lote' => $item['lote'] ? Str::upper($item['lote']) : null,
|
||||
'validade_lote' => $item['validade_lote']
|
||||
? Carbon::createFromFormat('d/m/Y', $item['validade_lote']) : null,
|
||||
'valor_unitario' => $item['valor_unitario'],
|
||||
'valor_total' => $item['valor_total'],
|
||||
'numero_empenho' => $item['numero_empenho'],
|
||||
'despesas' => $item['despesas'],
|
||||
'numero_autorizacao_fornecimento' => $item['numero_autorizacao_fornecimento'],
|
||||
'fabricante_id' => $item['fabricante_id'],
|
||||
'codigo_barras' => $item['codigo_barras'],
|
||||
'estornado' => $item['estornado'],
|
||||
])
|
||||
];
|
||||
}
|
||||
|
||||
public static function validate()
|
||||
{
|
||||
$rules = [
|
||||
'finalizada' => [
|
||||
'required',
|
||||
'boolean',
|
||||
],
|
||||
'documento.fornecedor_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(Fornecedor::class, 'id'),
|
||||
],
|
||||
'documento.origem_programatica_id' => [
|
||||
'nullable',
|
||||
'integer',
|
||||
Rule::exists(OrigemProgramatica::class, 'id'),
|
||||
],
|
||||
'documento.tipo_id' => [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(DocumentoTipo::class, 'id'),
|
||||
],
|
||||
'documento.numero_pedido' => [
|
||||
'required',
|
||||
'digits_between:1,20',
|
||||
],
|
||||
'documento.numero' => [
|
||||
'required',
|
||||
'digits_between:1,10',
|
||||
],
|
||||
'documento.data' => [
|
||||
'required',
|
||||
'date_format:d/m/Y',
|
||||
'before_or_equal:now',
|
||||
],
|
||||
'itens' => [
|
||||
'required',
|
||||
'array',
|
||||
],
|
||||
];
|
||||
|
||||
$isDocumentoDoacao = (request()->documento['tipo_id'] ?? null) == AlmoxarifadoDocumentoTipo::DOACAO;
|
||||
|
||||
foreach ((request()->itens ?? []) as $i => $item) {
|
||||
|
||||
$material = is_null($item['material_id']) ? null : Material::find($item['material_id']);
|
||||
$possuiLote = $material->possui_lote ?? null;
|
||||
$hasVinculoBnafar = !is_null($material->material_bnafar_id ?? null);
|
||||
|
||||
$rules["itens.{$i}.id"] = [
|
||||
'nullable',
|
||||
'integer',
|
||||
Rule::exists(EntradaItem::class, 'id'),
|
||||
];
|
||||
|
||||
$rules["itens.{$i}.material_id"] = [
|
||||
'bail',
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(Material::class, 'id'),
|
||||
];
|
||||
|
||||
$rules["itens.{$i}.quantidade"] = [
|
||||
'required',
|
||||
'integer',
|
||||
'between:1,99999999'
|
||||
];
|
||||
|
||||
$rules["itens.{$i}.lote"] = [
|
||||
'nullable',
|
||||
Rule::requiredIf(fn () => is_null($item['id']) && $possuiLote),
|
||||
'string',
|
||||
'max:15',
|
||||
];
|
||||
|
||||
$rules["itens.{$i}.validade_lote"] = [
|
||||
'nullable',
|
||||
Rule::requiredIf(fn () => is_null($item['id']) && $possuiLote),
|
||||
'date_format:d/m/Y',
|
||||
'after_or_equal:documento.data',
|
||||
];
|
||||
|
||||
$rules["itens.{$i}.valor_total"] = [
|
||||
'required',
|
||||
'numeric',
|
||||
'min:' . ($isDocumentoDoacao ? '0.000000' : '0.000001'),
|
||||
'max:99999999.999999'
|
||||
];
|
||||
|
||||
$rules["itens.{$i}.valor_unitario"] = [
|
||||
'required',
|
||||
'numeric',
|
||||
'min:' . ($isDocumentoDoacao ? '0.000000' : '0.000001'),
|
||||
'max:99999999.999999'
|
||||
];
|
||||
|
||||
$rules["itens.{$i}.numero_empenho"] = [
|
||||
'nullable',
|
||||
'digits_between:1,20',
|
||||
];
|
||||
|
||||
$rules["itens.{$i}.despesas"] = [
|
||||
'nullable',
|
||||
'numeric',
|
||||
'max:99999999.999999'
|
||||
];
|
||||
|
||||
$rules["itens.{$i}.numero_autorizacao_fornecimento"] = [
|
||||
'nullable',
|
||||
'digits:9',
|
||||
];
|
||||
|
||||
$rules["itens.{$i}.fabricante_id"] = [
|
||||
'nullable',
|
||||
Rule::requiredIf(fn () => $hasVinculoBnafar),
|
||||
'integer',
|
||||
Rule::exists(Fabricante::class, 'id'),
|
||||
];
|
||||
|
||||
$rules["itens.{$i}.codigo_barras"] = [
|
||||
'nullable',
|
||||
'digits:13',
|
||||
];
|
||||
|
||||
$rules["itens.{$i}.estornado"] = [
|
||||
'required',
|
||||
'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
$messages = [];
|
||||
|
||||
request()->validate($rules, $messages);
|
||||
}
|
||||
|
||||
public static function destroy($id)
|
||||
{
|
||||
Entrada::findOrFail($id)->delete();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function list()
|
||||
{
|
||||
switch (request()->listar) {
|
||||
case 'integracao-bnafar-medicamentos':
|
||||
return self::getIntegracaoBnafarMedicamentos(request()->material_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static function getIntegracaoBnafarMedicamentos($materialId)
|
||||
{
|
||||
return DB::table('integracao_bnafar_medicamento')
|
||||
->select([
|
||||
'integracao_bnafar_medicamento.id AS medicamento_id',
|
||||
'integracao_bnafar_medicamento.codigo AS medicamento_codigo',
|
||||
'integracao_bnafar_medicamento.descricao AS medicamento_descricao',
|
||||
])
|
||||
->whereExists(function ($query) use ($materialId) {
|
||||
$query->select(DB::raw(1))
|
||||
->from('cadastro_material_integracao_bnafar_medicamento')
|
||||
->where('cadastro_material_integracao_bnafar_medicamento.material_id', $materialId)
|
||||
->whereColumn('cadastro_material_integracao_bnafar_medicamento.medicamento_id', 'integracao_bnafar_medicamento.id');
|
||||
})
|
||||
->get();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user