Crie o model Tributacao
para criar o model Tributacao use o comando: php artisan make:model Tributacao -m
adicione os seguintes campos:
Schema::create('tributacaos', function (Blueprint $table) {
$table->id();
$table->string('nome_tributacao',90)->nullable();
//Ipi
$table->string('cstIPI',20);
$table->string('clEnq',150)->nullable();
$table->string('CNPJProd',25)->nullable();
$table->string('cSelo',25)->nullable();
$table->string('qSelo',25)->nullable();
$table->string('cEnq',25)->nullable();
$table->integer('tipo_calc_ipi')->nullable();
$table->decimal('pIPI',15,2)->nullable();
$table->decimal('vUnidIPI',15,2)->nullable();
$table->decimal('qUnidIPI',15,2)->nullable();
//PIS
$table->string('cstPIS',10);
$table->integer('tipo_calc_pis')->nullable();
$table->decimal('pPIS',10,2)->nullable();
$table->decimal('vAliqProd_pis',10,2)->nullable();
$table->decimal('qBCProd_pis',10,2)->nullable();
$table->integer('tipo_calc_pisst')->nullable();
$table->decimal('pPISST',10,2)->nullable();
$table->decimal('vAliqProd_pisst',10,2)->nullable();
$table->string('insere_ipi_na_base',1)->nullable();
//Cofins
$table->string('cstCOFINS',25);
$table->integer('tipo_calc_cofins',)->nullable();
$table->decimal('pCOFINS',15,2)->nullable();
$table->decimal('vAliqProd_cofins',15,2)->nullable();
$table->decimal('qBCProd_cofins',15,2)->nullable();
$table->integer('tipo_calc_cofinsst',)->nullable();
$table->decimal('pCOFINSST',10,2)->nullable();
$table->decimal('vAliqProd_cofinsst',15,2)->nullable();
//ICMS
$table->string('cstICMS',20);
$table->integer('modBC')->nullable();
$table->decimal('vBCICMS',10,2)->nullable();
$table->decimal('pICMS',15,2)->nullable();
$table->integer('modBCST')->nullable();
$table->decimal('pMVAST',15,2)->nullable();
$table->decimal('pRedBCST',15,2)->nullable();
$table->string('preco_unit_Pauta_ST',15,2)->nullable();
$table->decimal('pICMSST',15,2)->nullable();
$table->decimal('pRedBC',15,2)->nullable();
$table->integer('motDesICMS')->nullable();
$table->decimal('pBCOp',15,2)->nullable();
$table->string('UFST',20)->nullable();
$table->decimal('pCredSN',15,2)->nullable();
$table->decimal('pFCP',15,2)->nullable();
$table->decimal('vICMSSubstituto',15,2)->nullable();
$table->decimal('pFCPST',15,2)->nullable();
$table->decimal('pFCPSTRet',15,2)->nullable();
$table->decimal('pDif',15,2)->nullable();
//vBCSTRet
$table->decimal('vBCSTRet',10,2)->nullable();
$table->decimal('vICMSSTRet',10,2)->nullable();
$table->decimal('vBCSTDest',10,2)->nullable();
$table->decimal('vICMSSTDest',10,2)->nullable();
$table->decimal('vBCFCPSTRet',10,2)->nullable();
$table->decimal('vFCPSTRet',10,2)->nullable();
$table->timestamps();
});
Configure os fillables do Model Tributacao
protected $fillable =[
'nome_tributacao',
'padrao',
'cfop',
'cfop_fora',
'cfop_fora_consumidor_final',
'cfop_exportacao',
'tipo',
'indPres',
'finNFe',
'cstICMS',
'vBCICMS',
'modBC',
'pICMS',
'pRedBC',
'modBCST',
'vBCST',
'pICMSST',
'pMVAST',
'pRedBCST',
'vICMSSubstituto',
'pFCP',
'pFCPST',
'vFCP',
'pFCPSTRet',
'pDif',
'cstIPI',
'pIPI',
'vBCIPI',
'tipo_calc_ipi',
'CNPJProd',
'cSelo',
'qSelo',
'qUnidIPI',
'vUnidIPI',
'pCOFINS',
'pCOFINSST',
'preco_unit_Pauta_ST',
'motDesICMS',
'pBCOp',
'cEnq',
'vIPI',
'cstPIS',
'tipo_calc_pis',
'pPIS',
'vAliqProd_pis',
'pPISST',
'vAliqProd_pisst',
'vPIS',
'vPISST',
'cstCOFINS',
'pFCPSTRet',
'tipo_calc_cofins',
'pCofins',
'vAliqProd_cofins',
'tipo_calc_cofinsst',
'pCofinsst',
'vAliqProd_cofinsst',
'vCofins',
'uso_consumo',
'vbc_somente_produto','vbc_frete','vbc_ipi','vbc_outros', 'vbc_seguro','vbc_desconto',
'ipi_somente_produto','ipi_frete','ipi_outros','ipi_seguro','ipi_desconto',
'pis_somente_produto','pis_frete','pis_ipi','pis_outros','pis_seguro','pis_desconto',
'cofins_somente_produto','cofins_frete','cofins_ipi','cofins_outros','cofins_seguro','cofins_desconto',
'cst900_icms','cst900_redbc','cst900_credisn','cst900_st','cst900_redbcst',
];
Crie a seed Tributacao
Tributacao::create([
'natureza_operacao_id' => 1,
'descricao' => 'Tributação Padrão - Simples Nacional',
'cstCOFINS' => '07',
'cstPIS' => '07',
'cstIPI' => '53',
'cstICMS' => '103',
'cfop' => '5102',
]);
para criar a seed Tributacao use o comando: php artisan make:seed TributacaoSeeder
Crie um controller de recursos chamado Tributacao, para que o projeto fique mais organizado salve o controller numa pasta chamada NotaFiscal
Crie a view para a listagem de produto
Dentro da pasta resources/view crie uma pasta chamada de NotaFiscal e dentro de NotaFiscal crie uma outra chamada de Tributacao e dentro da pasta Tributacao crie um arquivo chamado Index.blade.php
Copie o conteúdo do arquivo lst_tributacao para o arquivo NotaFiscal/Tributacao/Index.blade.php, não esqueça envolvê-lo pelos comandos:
@extends('template')
@section('conteudo')
//aqui fica o conteúdo do arquivo
@endsection
Na view Index, faça os seguintes procedimentos:
- Faça o loop para receber os dados do banco e listar na tabela
- Configure o link para fazer a edição de um registro
- Configure o link para fazer a exclusão de um registro
@foreach ($lista as $l)
<tr>
<td align="center">{{ $l->id }}</td>
<td align="center">{{ $l->nome_tributacao }}</td>
<td align="center">{{ $l->cstICMS }}</td>
<td align="center">{{ $l->cstIPI }}</td>
<td align="center">{{ $l->cstPIS }}</td>
<td align="center">{{ $l->cstCOFINS }}</td>
<td align="center" width="400">
<a href="javascript:;"
onclick="abrirTelaProduto({{ $l->id }})"
class="btn btn-azul btn-pequeno d-inline-block">Produtos</a>
<a href="javascript:;" onclick="abrirTelaIva({{ $l->id }})"
class="btn btn-azul btn-pequeno d-inline-block">IVA</a>
<a href="javascript:;"
onclick="confirm('Tem Certeza?') ? document.getElementById('apagar{{ $l->id }}').submit() : '';"
class="btn btn-vermelho btn-pequeno d-inline-block">
<form action="{{ route('tributacao.destroy', $l->id) }}"
method="POST" id="apagar{{ $l->id }}">
@method('DELETE')
{{ csrf_field() }}
</form>
Excluir
</a>
<a href="{{ route('tributacao.edit', $l->id) }}"
class="btn btn-verde btn-pequeno d-inline-block">Editar</a>
</td>
</tr>
@endforeach
Implemente o método create do controller ProdutoController com as seguintes ações:
- no array $dados liste as natureza de Operação
- no array $dados liste as cstIcms
- no array $dados liste os cstPis
- no array $dados liste os cstCofins
- no array $dados liste as desoneracoes
- no array dados sete a variável TributacaoJs para true
- chame a view Produto/Create passando o array $dados
public function create()
{
$dados["lista_cstIcms"] = CstIcms::get();
$dados["lista_cstIpi"] = CstIpi::get();
$dados["lista_cstPis"] = CstPis::get();
$dados["lista_cstCofins"] = CstCofins::get();
$dados["desoneracoes"] = IcmsDesoneracao::get();
$dados["tributacaoJs"] = true;
return view("NotaFiscal.Tributacao.Create", $dados);
}
Para fazer o cadastro de produto será necessário criar uma nova view, Dentro da pasta NotaFiscal/Tributacao faça o seguinte:
- Crie uma view chamada Create.blade.php
Copie o conteúdo do arquivo frm_tributacao para o arquivo NotaFiscal/Tributacao/Create.blade.php, não esqueça envolvê-lo pelos comandos:
@extends('template')
@section('conteudo')
//aqui fica o conteúdo do arquivo
@endsection
Configure o elemento form da view Create, com as seguintes ações:
- Setar a rota tributacao.store na propriedade action do form
- Setar o método post na propriedade method do form
- setar a propriedade enctype para multipart/form-data
- implementar o helper @csrf dentro do form
<form action="{{ route('tributacao.store') }}" method="POST" enctype="multipart/form-data">
@csrf
configure os input atribuindo a eles na propriedade name o nome igual ao que foi definido na criação da tabela,
também observe os tipos de dados específicos e os que são obrigatórios atribua a propriedade required
<div class="col-3 mb-3">
<label class="text-label">CFOP Fora do Estado</label>
<input type="text" name="cfop_fora" id="cfop_fora" maxlength="4"
value="{{ $tributacao->cfop_fora ?? old('cfop_fora') }}" class="form-campo">
</div>
Configure os combos: Natureza Operação, CstIcms, CstIpi, CstPis e CstCofins e motivodesoneração
Faça o loop da lista de Cst Icms, Ipi, Pis, Cofins
ICMS
<select class="form-campo" name="cstICMS" id="cstICMS">
@foreach ($lista_cstIcms as $cstIcms)
<option value="{{ $cstIcms->cst }}"
{{ ($tributacao->cstICMS ?? '103') == $cstIcms->cst ? 'selected' : null }}>
{{ $cstIcms->descricao }}
</option>
@endforeach
</select>
IPI
<select class="form-campo" name="cstIPI" id="cstIPI">
@foreach ($lista_cstIpi as $cstIpi)
<option value="{{ $cstIpi->cst }}"
{{ ($tributacao->cstIPI ?? '53') == $cstIpi->cst ? 'selected' : null }}>
{{ $cstIpi->descricao }}
</option>
@endforeach
</select>
Pis
<select class="form-campo" name="cstPIS" id="cstPIS">
@foreach ($lista_cstPis as $cstPis)
<option value="{{ $cstPis->cst }}"
{{ ($tributacao->cstPIS ?? '07') == $cstPis->cst ? 'selected' : null }}>
{{ $cstPis->descricao }}
</option>
@endforeach
</select>
Faça o loop da lista de Motivo desoneracao
<select class="form-campo" name="motDesICMS" id="motDesICMS">
@foreach ($desoneracoes as $d)
<option value="{{ $d->codigo }}"
{{ ($tributacao->motDesICMS ?? null) == $d->codigo ? 'selected' : null }}>
{{ $d->codigo }}-{{ $d->descricao }}
</option>
@endforeach
</select>
implemente o método store para receber e salvar os dados do formulário no Banco de dados
No metodo store valide os dados do tipo decimal que vieram do formulário usando máscaras, para isso use a função getFloat implementado no helper
//Icms
$req["pICMS"] = ($req["pICMS"] ?? null ) != null ? getFloat($req["pICMS"] ) : null;
$req["pRedBC"] = ($req["pRedBC"] ?? null ) != null ? getFloat($req["pRedBC"] ) : null;
$req["vICMSSubstituto"] = ($req["vICMSSubstituto"] ?? null ) != null ? getFloat($req["vICMSSubstituto"] ) : null;
$req["pFCP"] = ($req["pFCP"] ?? null ) != null ? getFloat($req["pFCP"] ) : null;
$req["pDif"] = ($req["pDif"] ?? null ) != null ? getFloat($req["pDif"] ) : null;
$req["pBCOp"] = ($req["pBCOp"]?? null ) != null ? getFloat($req["pBCOp"]) : null;
//IPI
$req["CNPJProd"] = ($req["CNPJProd"] ?? null) != null ? tira_mascara($req["CNPJProd"]) :null ;
$req["pIPI"] = ($req["pIPI"] ?? null ) != null ? getFloat($req["pIPI"] ) : null;
$req["qUnidIPI"] = ($req["qUnidIPI"] ?? null ) != null ? getFloat($req["qUnidIPI"] ) : null;
$req["vUnidIPI"] = ($req["vUnidIPI"] ?? null ) != null ? getFloat($req["vUnidIPI"] ) : null;
$req["tipo_calc_ipi"] = $req["tipo_calc_ipi"] ?? 1;
//PIS
$req["pPIS"] = ($req["pPIS"] ?? null ) != null ? getFloat($req["pPIS"] ) : null;
$req["pPISST"] = ($req["pPISST"] ?? null ) != null ? getFloat($req["pPISST"] ) : null;
$req["qBCProd_pis"] = ($req["qBCProd_pis"] ?? null ) != null ? getFloat($req["qBCProd_pis"] ) : null;
$req["vAliqProd_pis"] = ($req["vAliqProd_pis"] ?? null ) != null ? getFloat($req["vAliqProd_pis"] ) : null;
//Cofins
$req["pCOFINS"] = ($req["pCOFINS"] ?? null ) != null ? getFloat($req["pCOFINS"] ) : null;
$req["pCOFINSST"] = ($req["pCOFINSST"] ?? null ) != null ? getFloat($req["pCOFINSST"] ) : null;
$req["qBCProd_cofins"] = ($req["qBCProd_cofins"]?? null ) != null ? getFloat($req["qBCProd_cofins"]) : null;
$req["vAliqProd_cofins"] = ($req["vAliqProd_cofins"]?? null ) != null ? getFloat($req["vAliqProd_cofins"] ) : null;
Caso não tenha conseguido fazer, segue o código completo
public function store(TributacaoRequest $request)
{
$req = $request->except(["_token"]);
try {
//Icms
$req["pICMS"] = ($req["pICMS"] ?? null ) != null ? getFloat($req["pICMS"] ) : null;
$req["pRedBC"] = ($req["pRedBC"] ?? null ) != null ? getFloat($req["pRedBC"] ) : null;
$req["vICMSSubstituto"] = ($req["vICMSSubstituto"] ?? null ) != null ? getFloat($req["vICMSSubstituto"] ) : null;
$req["pFCP"] = ($req["pFCP"] ?? null ) != null ? getFloat($req["pFCP"] ) : null;
$req["pDif"] = ($req["pDif"] ?? null ) != null ? getFloat($req["pDif"] ) : null;
$req["pBCOp"] = ($req["pBCOp"]?? null ) != null ? getFloat($req["pBCOp"]) : null;
//IPI
$req["CNPJProd"] = ($req["CNPJProd"] ?? null) != null ? tira_mascara($req["CNPJProd"]) :null ;
$req["pIPI"] = ($req["pIPI"] ?? null ) != null ? getFloat($req["pIPI"] ) : null;
$req["qUnidIPI"] = ($req["qUnidIPI"] ?? null ) != null ? getFloat($req["qUnidIPI"] ) : null;
$req["vUnidIPI"] = ($req["vUnidIPI"] ?? null ) != null ? getFloat($req["vUnidIPI"] ) : null;
$req["tipo_calc_ipi"] = $req["tipo_calc_ipi"] ?? 1;
//PIS
$req["pPIS"] = ($req["pPIS"] ?? null ) != null ? getFloat($req["pPIS"] ) : null;
$req["pPISST"] = ($req["pPISST"] ?? null ) != null ? getFloat($req["pPISST"] ) : null;
$req["qBCProd_pis"] = ($req["qBCProd_pis"] ?? null ) != null ? getFloat($req["qBCProd_pis"] ) : null;
$req["vAliqProd_pis"] = ($req["vAliqProd_pis"] ?? null ) != null ? getFloat($req["vAliqProd_pis"] ) : null;
//Cofins
$req["pCOFINS"] = ($req["pCOFINS"] ?? null ) != null ? getFloat($req["pCOFINS"] ) : null;
$req["pCOFINSST"] = ($req["pCOFINSST"] ?? null ) != null ? getFloat($req["pCOFINSST"] ) : null;
$req["qBCProd_cofins"] = ($req["qBCProd_cofins"]?? null ) != null ? getFloat($req["qBCProd_cofins"]) : null;
$req["vAliqProd_cofins"] = ($req["vAliqProd_cofins"]?? null ) != null ? getFloat($req["vAliqProd_cofins"] ) : null;
Tributacao::Create($req);
return redirect()->route("tributacao.index")->with("msg_sucesso", "Registro inserido com sucesso");
//code...
} catch (\Throwable $th) {
return redirect()->route("tributacao.index")->with("msg_sucesso","Registro alterado com sucesso");
}
}
Uma boa prática de programação é validar os dados antes de enviá-los para o banco de dados e uma bom recurso que o laravel oferece são os requests.
implemente um request de forma que faça todas as validações necessárias para salvar a informações no banco
Teste o sistema fazendo cadastros
Configure o método edit do Controller, com as seguinte ações:
- Busque o produto pelo id passado no parâmetro e guarde a informação em um array $dados
- no array $dados liste as categorias
- no array $dados liste as unidades
- no array dados sete a variável projetoJs para true
- no array dados sete a variável categoriaJs para true
- chame a view Produto/Edit passando o array $dados
public function edit(string $id)
{
$dados["tributacao"] = Tributacao::find($id);
$dados["lista_cstIcms"] = CstIcms::get();
$dados["lista_cstIpi"] = CstIpi::get();
$dados["lista_cstPis"] = CstPis::get();
$dados["lista_cstCofins"] = CstCofins::get();
$dados["desoneracoes"] = IcmsDesoneracao::get();
$dados["tributacaoJs"] = true;
return view("NotaFiscal.Tributacao.Create", $dados);
}
Na view edit, copie e cole o conteúdo contido no arquivo edit_produto.html, este arquivo já está com todas as configurações necessárias, mas caso queira fazer do zero, siga os passo abaixo:
- Copie os dados da view Create
- Configure o elemento form, sistema deve verificar se o objeto produto existe,
- caso ele exista, no formulário deve ser configurada a rota produto.update
- caso não exista, no formulário deve ser configurada a rota produto.store
- Na propriedade value de cada input, faça uma verificação se existe o objeto produto, se existir imprimir o valor do campo correspondente, senão existe imprimir o objeto old()
Implemente o método update de forma que o mesmo receba os dados do formulário e salve no banco de dados, caso ache necessário use um bloco try/catch
public function update(Request $request, string $id)
{
$req = $request->except(["_token"]);
try {
//Icms
$req["pICMS"] = getFloat($req["pICMS"]) ;
$req["pRedBC"] = getFloat($req["pRedBC"]) ;
$req["vICMSSubstituto"] = getFloat($req["vICMSSubstituto"]) ;
$req["pFCP"] = getFloat($req["pFCP"]) ;
$req["pDif"] = getFloat($req["pDif"]) ;
$req["pBCOp"] = getFloat($req["pBCOp"]);
//IPI
$req["CNPJProd"] = tira_mascara($req["CNPJProd"]) ;
$req["pIPI"] = getFloat($req["pIPI"]) ;
$req["qUnidIPI"] = getFloat($req["qUnidIPI"]) ;
$req["vUnidIPI"] = getFloat($req["vUnidIPI"]) ;
$req["tipo_calc_ipi"] = $req["tipo_calc_ipi"] ?? 1;
//PIS
$req["pPIS"] = getFloat($req["pPIS"]) ;
$req["pPISST"] = getFloat($req["pPISST"]) ;
$req["qBCProd_pis"] = getFloat($req["qBCProd_pis"]) ;
$req["vAliqProd_pis"] = getFloat($req["vAliqProd_pis"]) ;
//Cofins
$req["pCOFINS"] = getFloat($req["pCOFINS"]) ;
$req["pCOFINSST"] = getFloat($req["pCOFINSST"]) ;
$req["qBCProd_cofins"] = getFloat($req["qBCProd_cofins"]);
$req["vAliqProd_cofins"] = getFloat($req["vAliqProd_cofins"]) ;
Tributacao::find($id)->update($req);
return redirect()->route("tributacao.index")->with("msg_sucesso", "Registro inserido com sucesso");
} catch (\Throwable $th) {
return redirect()->back()->with('msg_erro', $th->getMessage());
}
}
Faça o teste do seu sistema de forma que o mesmo consiga criar um novo registro e também alterá-lo
implemente o método destroy do Controller, com as seguinte ações:
- Busque a tributação pelo id passado no parâmetro
- Caso encontre, exclua a mesma do banco, coloque esta instrução em um bloco try/catch
- Verifique se o campo imagem está preenchido e se tiver, verifique se a imagem existe e caso exista exclua-a
- redirecione para a rota index
try {
$tributacao = Tributacao::find($id);
if($tributacao){
$tributacao->delete();
}
return redirect()->route("tributacao.index")->with("msg_sucesso", "excluido com sucesso");
} catch (\Throwable $th) {
return redirect()->back()->with("msg_erro", "Erro: " . $th->getMessage());
}
Teste o seu sistema, para que você tenha certeza que está tudo o ok, o sistema deverá:
- Listar todos os produtos
- Criar um produto novo
- Editar um produto selecionado
- Excluir um produto selecionado