init commit
All checks were successful
build-api-image / build (push) Successful in 51s

This commit is contained in:
Antonio Lopes dos Santos
2026-08-04 16:52:02 -03:00
commit afec302c3e
11594 changed files with 1636728 additions and 0 deletions

View File

@@ -0,0 +1,397 @@
<?php
namespace App\Services\Cadastro\Fornecedor;
use App\Models\Cadastro\Fornecedor\Categoria;
use App\Models\Cadastro\Fornecedor\Fornecedor;
use App\Models\Cadastro\Localizacao\Logradouro;
use App\Models\Cns\TermoInvalido;
use App\Rules\Cnpj;
use App\Rules\CnsTermoValido;
use App\Services\Cadastro\Localizacao\EnderecoSaveService;
use App\Services\Service;
use App\Utils\ImportacaoCns;
use App\Utils\MaskUtil;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
class FornecedorService extends Service
{
public static function autocomplete()
{
$fornecedores = DB::table('cadastro_fornecedor')
->leftJoin(
'cadastro_fornecedor_categoria',
'cadastro_fornecedor_categoria.id',
'cadastro_fornecedor.categoria_id'
)
->select(
'cadastro_fornecedor.id',
'cadastro_fornecedor.cnpj',
'cadastro_fornecedor.inscricao_estadual',
'cadastro_fornecedor.nome_fantasia',
'cadastro_fornecedor.razao_social',
'cadastro_fornecedor.categoria_id',
'cadastro_fornecedor_categoria.nome AS categoria_nome',
'cadastro_fornecedor.site',
);
return datatables()
->of($fornecedores)
->filterColumn('cadastro_fornecedor.cnpj', function ($query, $keyword) {
$query
->whereRaw("cadastro_fornecedor.cnpj like ?", ["%{$keyword}%"])
->orWhereRaw(
"CONCAT(
SUBSTR(cadastro_fornecedor.cnpj,1,2),
'.',
SUBSTR(cadastro_fornecedor.cnpj,3,3),
'.',
SUBSTR(cadastro_fornecedor.cnpj,6,3),
'/',
SUBSTR(cadastro_fornecedor.cnpj,9,4),
'-',
SUBSTR(cadastro_fornecedor.cnpj,13,2)
) like ?",
["%{$keyword}%"]
);
})
->toJson();
}
public static function datatable()
{
$fornecedores = DB::table('cadastro_fornecedor')
->leftJoin(
'cadastro_fornecedor_categoria',
'cadastro_fornecedor_categoria.id',
'cadastro_fornecedor.categoria_id'
)
->leftJoin(
'cadastro_endereco',
'cadastro_endereco.id',
'cadastro_fornecedor.endereco_id'
)
->leftJoin(
'cadastro_logradouro',
'cadastro_logradouro.id',
'cadastro_endereco.logradouro_id'
)
->leftJoin(
'cadastro_fornecedor_telefone',
'cadastro_fornecedor_telefone.fornecedor_id',
'cadastro_fornecedor.id'
)
->leftJoin(
'intranet.cadastro_municipio',
'intranet.cadastro_municipio.id',
'cadastro_logradouro.municipio_id'
)
->select(
'cadastro_fornecedor.id',
'cadastro_fornecedor_categoria.nome AS categoria_nome',
'cadastro_fornecedor.nome_fantasia',
'cadastro_fornecedor.cnpj',
'intranet.cadastro_municipio.nome AS municipio_nome',
DB::raw("(SELECT GROUP_CONCAT(numero LIMIT 1) FROM cadastro_fornecedor_telefone WHERE fornecedor_id = cadastro_fornecedor.id) as telefone")
)
->groupBy('cadastro_fornecedor.id');
return datatables()
->of($fornecedores)
->filterColumn('cadastro_fornecedor.cnpj', function ($query, $keyword) {
$query
->whereRaw("cadastro_fornecedor.cnpj like ?", ["%{$keyword}%"])
->orWhereRaw(
"CONCAT(
SUBSTR(cadastro_fornecedor.cnpj,1,2),
'.',
SUBSTR(cadastro_fornecedor.cnpj,3,3),
'.',
SUBSTR(cadastro_fornecedor.cnpj,6,3),
'/',
SUBSTR(cadastro_fornecedor.cnpj,9,4),
'-',
SUBSTR(cadastro_fornecedor.cnpj,13,2)
) like ?",
["%{$keyword}%"]
);
})
->toJson();
}
public static function create()
{
$fornecedor = new Fornecedor;
$fornecedor->fill(array_fill_keys($fornecedor->getFillable(), null));
$fornecedor->telefones = [];
$fornecedor->contatos = [];
$fornecedor->endereco = self::getEmptyEndereco();
return [
'additionals' => self::getAdditionalsData(),
'form' => self::getFormData(),
'model' => $fornecedor->makeHidden('endereco_id'),
];
}
public static function store()
{
self::validate();
return self::save(new Fornecedor);
}
public static function edit($id)
{
$fornecedor = Fornecedor::findOrFail($id);
return [
'additionals' => self::getAdditionalsData(),
'form' => self::getFormData(),
'model' => [
'categoria_id' => $fornecedor->categoria_id,
'cnpj' => $fornecedor->cnpj ? MaskUtil::getCnpjMasked($fornecedor->cnpj) : null,
'inscricao_estadual' => $fornecedor->inscricao_estadual,
'nome_fantasia' => $fornecedor->nome_fantasia,
'razao_social' => $fornecedor->razao_social,
'site' => $fornecedor->site,
'telefones' => $fornecedor->telefones->map(fn ($telefone) => [
'numero' => MaskUtil::getPhoneMasked($telefone->numero),
'observacao' => $telefone->observacao,
]),
'contatos' => $fornecedor->contatos->map(fn ($contato) => [
'nome' => $contato->nome,
'departamento' => $contato->departamento,
'cargo' => $contato->cargo,
'telefone' => $contato->telefone ? MaskUtil::getPhoneMasked($contato->telefone) : null,
'email' => $contato->email,
]),
'endereco' => $fornecedor->endereco ? [
'cep' => MaskUtil::getCepMasked($fornecedor->endereco->logradouro->cep),
'logradouro' => $fornecedor->endereco->logradouro,
'numero' => $fornecedor->endereco->numero,
'sem_numero' => $fornecedor->endereco->sem_numero,
'complemento' => $fornecedor->endereco->complemento,
'referencia' => $fornecedor->endereco->referencia,
] : self::getEmptyEndereco()
]
];
}
private static function getFormData()
{
return [
'categorias' => Categoria::orderBy('nome')->get(['id', 'nome']),
];
}
private static function getEmptyEndereco()
{
return [
'cep' => null,
'logradouro' => null,
'numero' => null,
'sem_numero' => false,
'complemento' => null,
'referencia' => null,
];
}
private static function getAdditionalsData()
{
return [
'termos_invalidos' => TermoInvalido::all()->pluck('descricao'),
];
}
public static function update($id)
{
self::validate();
$fornecedor = Fornecedor::findOrFail($id);
return self::save($fornecedor);
}
private static function save($fornecedor)
{
DB::transaction(function () use ($fornecedor) {
$data = self::getData();
$data['endereco_id'] = is_null($data['endereco']) ? null
: (new EnderecoSaveService($data['endereco']))->save()->id;
$fornecedor->fill($data);
$fornecedor->save();
$fornecedor->telefones->each(fn ($t) => $t->delete());
$fornecedor->telefones()->createMany($data['telefones']);
$fornecedor->contatos->each(fn ($c) => $c->delete());
$fornecedor->contatos()->createMany($data['contatos']);
});
return $fornecedor->fresh();
}
private static function getData()
{
return [
'cnpj' => request()->cnpj,
'inscricao_estadual' => request()->inscricao_estadual,
'nome_fantasia' => Str::upper(request()->nome_fantasia),
'razao_social' => Str::upper(request()->razao_social),
'categoria_id' => request()->categoria_id,
'site' => request()->site,
'telefones' => collect(request()->telefones)->map(fn ($telefone) => [
'numero' => $telefone['numero'],
'observacao' => Str::upper($telefone['observacao']),
]),
'contatos' => collect(request()->contatos)->map(fn ($contato) => [
'nome' => Str::upper($contato['nome']),
'departamento' => $contato['departamento'] ? Str::upper($contato['departamento']) : null,
'cargo' => $contato['cargo'] ? Str::upper($contato['cargo']) : null,
'telefone' => $contato['telefone'],
'email' => $contato['email'],
]),
'endereco' => empty(request()->endereco) ? null : [
'logradouro_id' => request()->endereco['logradouro_id'],
'numero' => request()->endereco['numero'],
'complemento' => request()->endereco['complemento']
? Str::upper(request()->endereco['complemento']) : null,
'referencia' => request()->endereco['referencia']
? Str::upper(request()->endereco['referencia']) : null,
],
];
}
public static function validate()
{
$rules = [
'cnpj' => [
'nullable',
'digits:14',
new Cnpj,
Rule::unique(Fornecedor::class)->ignore(request()->route('fornecedor'))
],
'inscricao_estadual' => [
'nullable',
'digits_between:8,14',
Rule::unique(Fornecedor::class)->ignore(request()->route('fornecedor'))
],
'nome_fantasia' => [
'required',
'string',
'between:3,255',
Rule::unique(Fornecedor::class)->ignore(request()->route('fornecedor'))
],
'razao_social' => [
'required',
'string',
'between:3,255',
Rule::unique(Fornecedor::class)->ignore(request()->route('fornecedor'))
],
'categoria_id' => [
'nullable',
'integer',
Rule::exists(Categoria::class, 'id')
],
'site' => [
'nullable',
'string',
'max:180',
],
'endereco' => [
'nullable',
'array',
],
'endereco.logradouro_id' => [
'nullable',
'integer',
Rule::exists(Logradouro::class, 'id')
],
'endereco.numero' => [
'nullable',
'digits_between:1,6',
],
'endereco.complemento' => [
'nullable',
'string',
'between:3,180',
'not_regex:' . ImportacaoCns::regexValidacao(),
new CnsTermoValido(['attribute' => 'Complemento']),
],
'endereco.referencia' => [
'nullable',
'string',
'max:150',
'not_regex:' . ImportacaoCns::regexValidacao(),
new CnsTermoValido(['attribute' => 'Referência']),
],
'telefones' => [
'required',
'array',
],
'telefones.*.numero' => [
'required',
'digits_between:10,11',
],
'telefones.*.observacao' => [
'nullable',
'string',
'max:50',
],
'contatos' => [
'present',
'array',
],
'contatos.*.nome' => [
'required',
'string',
'between:6,150',
],
'contatos.*.departamento' => [
'nullable',
'string',
'max:50',
],
'contatos.*.cargo' => [
'nullable',
'string',
'max:50',
],
'contatos.*.telefone' => [
'nullable',
'required_without:contatos.*.email',
'digits_between:10,11',
],
'contatos.*.email' => [
'nullable',
'required_without:contatos.*.telefone',
'max:180',
'email:rfc,dns',
],
];
$messages = [
'cnpj.unique' => 'O CNPJ do fornecedor já foi inserido anteriormente.',
'inscricao_estadual.unique' => 'A inscrição estadual do fornecedor já foi inserido anteriormente.',
'nome_fantasia.unique' => 'O nome fantasia do fornecedor já foi inserido anteriormente.',
'razao_social.unique' => 'A razão social do fornecedor já foi inserido anteriormente.',
];
request()->validate($rules, $messages);
}
public static function destroy($id)
{
Fornecedor::findOrFail($id)->delete();
return null;
}
}