Crie o model Produto
para criar o model Produto use o comando: php artisan make:model Produto -m
adicione os seguintes campos:
- status_id (relacionado com a tabela status)
- categoria_id (relacionado com a tabela categoria)
- nome varchar(100)
- gtin varchar(20) opcional
- sku varcha(80) opcional
- imagem varchar(100) opcional
- codigo_barra varchar(60) opcional
- unidade varchar (20)
- usa_grade varchar(1) padrao 'N'
- eh_produto varchar(1) padrao 'N'
- eh_insumo varchar(1) padrao 'N'
- preco_venda decimal
- preco_custo decimal opcional
- margem_lucro decimal opcional
- estoque_minimo decimal opcional
- estoque_maximo decimal opcional
- estoque_inicial decimal opcional
- estoque_atual decimal opcional
Schema::create('produtos', function (Blueprint $table) {
$table->id();
$table->Biginteger('status_id')->unsigned();
$table->foreign('status_id')->references('id')->on('statuses');
$table->BigInteger('categoria_id')->nullable()->unsigned();
$table->foreign('categoria_id')->references('id')->on('categorias');
$table->string('nome', 100);
$table->string('gtin', 20)->nullable();
$table->string('sku', 80)->nullable();
$table->string('imagem', 100)->nullable();
$table->string('codigo_barra', 60)->nullable();
$table->string('unidade', 20);
$table->string('usa_grade', 1)->default('N');
$table->string('eh_produto', 1)->default('N');
$table->string('eh_insumo', 1)->default('N');
$table->decimal('preco_venda', 10,2);
$table->decimal('preco_custo', 10,2)->nullable()->default(0);
$table->decimal('margem_lucro', 10,2)->nullable()->default(0);
$table->decimal('estoque_minimo', 10,2)->nullable()->default(0);
$table->decimal('estoque_maximo', 10,2)->nullable()->default(0);
$table->decimal('estoque_inicial', 10,2)->nullable()->default(0);
$table->integer('estoque_atual')->nullable()->default(0);
$table->string('ncm', 13);
$table->string('cest', 7)->nullable();
$table->timestamps();
});
Configure os fillables do Model Produto
protected $fillable=[
"id", "status_id", "categoria_id", "codigo_barra",
"nome","gtin","imagem","origem","unidade","preco_venda",
"preco_custo", "margem_lucro","estoque_minimo","estoque_maximo",
"estoque_reservado", "estoque_inicial","estoque_atual","ncm",
"cest","usa_grade","sku","eh_produto","eh_insumo"
];
Crie a seed Produto
para criar a seed Produto use o comando: php artisan make:seed ProdutoSeeder
Popule os dados da tabela produto
Produto::Create(['id'=>8, 'status_id'=> 1 ,'categoria_id' =>1, 'unidade' => 'UNID', 'nome'=> 'Panela 5', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'50.00', 'imagem'=> 'upload/produtos/PANELA_5.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>9, 'status_id'=> 1 ,'categoria_id' =>1, 'unidade' => 'UNID', 'nome'=> 'Panela de Pressão', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'50.00', 'imagem'=> 'upload/produtos/PANELA_DE_PRESAO.png', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>10, 'status_id'=> 1 ,'categoria_id' =>7, 'unidade' => 'UNID', 'nome'=> 'Frigideira Reforçada', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'497.00', 'preco_custo'=>'397.00', 'imagem'=> 'upload/produtos/FRIGIDEIRA_REFORCADA.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>11, 'status_id'=> 1 ,'categoria_id' =>7, 'unidade' => 'UNID', 'nome'=> 'Frigideira Cabo Tubular', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'50.00', 'imagem'=> 'upload/produtos/FRIGIDEIRA_CABO_TUBULAR_2.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>12, 'status_id'=> 1 ,'categoria_id' =>1, 'unidade' => 'UNID', 'nome'=> 'Panela Longa', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'50.00', 'imagem'=> 'upload/produtos/PANELA_LONGA.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>13, 'status_id'=> 1 ,'categoria_id' =>1, 'unidade' => 'UNID', 'nome'=> 'Panela Arredondada', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'50.00', 'imagem'=> 'upload/produtos/PANELA_RREDONDADA2.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>14, 'status_id'=> 1 ,'categoria_id' =>1, 'unidade' => 'UNID', 'nome'=> 'Panela Laranja', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'50.00', 'preco_custo'=>'30.00', 'imagem'=> 'upload/produtos/PANELA_LARANJA.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>15, 'status_id'=> 1 ,'categoria_id' =>1, 'unidade' => 'UNID', 'nome'=> 'Panela Longa 2', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'50.00', 'imagem'=> 'upload/produtos/PANELA_LONGA2.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>16, 'status_id'=> 1 ,'categoria_id' =>1, 'unidade' => 'UNID', 'nome'=> 'Panela Achatada', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'50.00', 'imagem'=> 'upload/produtos/PANELA_ACHATADA.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>17, 'status_id'=> 1 ,'categoria_id' =>1, 'unidade' => 'UNID', 'nome'=> 'Panela Achatada 2', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'50.00', 'imagem'=> 'upload/produtos/PANELA_ACHATADA2.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>18, 'status_id'=> 1 ,'categoria_id' =>1, 'unidade' => 'UNID', 'nome'=> 'Panela Verde', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'100.00', 'imagem'=> 'upload/produtos/PANELA_VERDE.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>19, 'status_id'=> 1 ,'categoria_id' =>1, 'unidade' => 'UNID', 'nome'=> 'Panela Verde 2', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'100.00', 'imagem'=> 'upload/produtos/PANELA_VERDE2.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>20, 'status_id'=> 1 ,'categoria_id' =>7, 'unidade' => 'UNID', 'nome'=> 'Frigideira sem Tampa Laranja', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'100.00', 'imagem'=> 'upload/produtos/FRIGIDEIRA_SEM_TAMPA_LARANJA.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>21, 'status_id'=> 1 ,'categoria_id' =>7, 'unidade' => 'UNID', 'nome'=> 'Frigideira Laranja', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'100.00', 'imagem'=> 'upload/produtos/FRIGIDEIRA_LARANJA.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>22, 'status_id'=> 1 ,'categoria_id' =>2, 'unidade' => 'UNID', 'nome'=> 'Cuscuzeira Laranja', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'100.00', 'imagem'=> 'upload/produtos/CUSCUZEIRA_LARANJA.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>31, 'status_id'=> 1 ,'categoria_id' =>2, 'unidade' => 'UNID', 'nome'=> 'Cuscuzeira 3', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'150.00', 'preco_custo'=>'150.00', 'imagem'=> 'upload/produtos/CUSCUZEIRA3.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>32, 'status_id'=> 1 ,'categoria_id' =>6, 'unidade' => 'UNID', 'nome'=> 'Leiteira Tubular 3', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'50.00', 'preco_custo'=>'50.00', 'imagem'=> 'upload/produtos/LEITEIRAS_TUBULAR3.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>33, 'status_id'=> 1 ,'categoria_id' =>6, 'unidade' => 'UNID', 'nome'=> 'Leiteira com Tampa Laranja', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'30.00', 'preco_custo'=>'30.00', 'imagem'=> 'upload/produtos/LEITEIRA_COM_TAMPA_LARANJA4.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>35, 'status_id'=> 1 ,'categoria_id' =>1, 'unidade' => 'UNID', 'nome'=> 'Panela com tampa 2', 'eh_produto'=> 'S', 'eh_insumo' => 'N', 'preco_venda'=>'100.00', 'preco_custo'=>'100.00', 'imagem'=> 'upload/produtos/PANELA_COM_TAMPA_2.jpg', 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>38, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'ABRASIVO CEBO AMARELO', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'15.70', 'preco_custo'=>'15.70', 'imagem'=> Null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>41, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'ALCA PARA TAMPA', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'15.90', 'preco_custo'=>'15.90', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>52, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'ALÇA DE LEITEIRA', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'0.50', 'preco_custo'=>'0.50', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>57, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'ALÇA PARA PANELA DE PRESSAO', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'0.40', 'preco_custo'=>'0.40', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>60, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'BORRACHAS P/ PANELA PRESSAO', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'0.50', 'preco_custo'=>'0.50', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>61, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'CABO CUSCUZEIRA ', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'0.65', 'preco_custo'=>'0.65', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>62, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'CABO DE CAÇAROLA COD.227', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'0.90', 'preco_custo'=>'0.90', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>63, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'CABO DE FRIGIDEIRA PEQUENA', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'5.90', 'preco_custo'=>'5.90', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>64, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'CABO DE LEITEIRA COD.2046', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'1.30', 'preco_custo'=>'1.30', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>85, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'CABO PARA PANELA DE PRESSAO', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'1.20', 'preco_custo'=>'1.20', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>86, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'CABO REBITADO PEQUENO 3F 90G', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'0.95', 'preco_custo'=>'0.95', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>87, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'HASTE GRANDE 20 X 130', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'15.90', 'preco_custo'=>'15.90', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>91, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'LIXA', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'0.50', 'preco_custo'=>'0.50', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>92, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'ORELHA DE CALDEIRAO', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'31.80', 'preco_custo'=>'31.80', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>93, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'PESO TIPO UNIV.PRETO S/MARCA ', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'1.30', 'preco_custo'=>'1.30', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>94, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'PINO 1/2 DIAM 01 R 3/8 UNF', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'1.30', 'preco_custo'=>'1.30', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>95, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'POMEL COLOR', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'0.60', 'preco_custo'=>'0.60', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>103, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'RALO 110', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'13.70', 'preco_custo'=>'13.70', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>107, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'RIBITE 1/8 X 7 PEQUENO', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'31.80', 'preco_custo'=>'31.80', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>113, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'RODA DE BRIM', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'0.30', 'preco_custo'=>'0.30', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>114, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'SELO DE SEGURANÇA', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'0.00', 'preco_custo'=>'0.00', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>115, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'SUPORTE ALUM. BALDE Nº02', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'31.80', 'preco_custo'=>'31.80', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>117, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'DISC0 210 X 1,10', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'12.70', 'preco_custo'=>'12.70', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>142, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'TAMPA LUXO 14', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'1.00', 'preco_custo'=>'1.00', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>143, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'DISC0 PARA TAMPA', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'1.00', 'preco_custo'=>'1.00', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>144, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'TAMPA PARA PANELA DE PRESSÃO', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'1.00', 'preco_custo'=>'1.00', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Produto::Create(['id'=>145, 'status_id'=> 1 ,'categoria_id' =>11, 'unidade' => 'UNID', 'nome'=> 'VÁLVULA SEGURANÇA PAN. PRESSÃO', 'eh_produto'=> 'N', 'eh_insumo' => 'S', 'preco_venda'=>'1.00', 'preco_custo'=>'1.00', 'imagem'=> null, 'gtin'=> 'SEM GTIN', 'ncm'=> '85167910', 'estoque_minimo'=> 10]);
Crie um controller de recursos chamado Produto, para que o projeto fique mais organizado salve o controller numa pasta chamada Cadastro
No controller ProdutoController implemente o método index, o qual deverá:
- pegar a lista de produtos e colocar um array
- chamar a view Produto/Index com o array criado com a lista de produtos
public function index()
{
$dados["lista"] = Produto::get();
return View("Cadastro.Produto.Index", $dados);
}
Crie a view para a listagem de produto
Dentro da pasta resources/view crie uma pasta chamada de Cadastro e dentro de Cadastro crie uma outra chamada de Produto e dentro da pasta Produto crie um arquivo chamado Index.blade.php
Copie o conteúdo do arquivo lst_produto para o arquivo Cadastro/Produto/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)
@php
$imagem = $l->imagem ? 'storage/' . $l->imagem : 'assets/img/semproduto.png';
@endphp
<tr>
<td align="center">{{ $l->id }}</td>
<td align="center"><img src="{{ asset($imagem) }}" width="40"></td>
<td align="left">{{ $l->nome }}</td>
<td align="left">{{ $l->categoria->categoria ?? '--' }}</td>
<td align="center">{{ $l->preco_venda }}</td>
<td align="center">{{ $l->estoque_atual }}</td>
<td align="center">
<a href="{{ route('produto.edit', $l->id) }}"
class="btn d-inline-flex gap-3 btn-outline-roxo"><i class="fas fa-edit"></i>
Editar</a>
<a href="javascript:;"
onclick="confirm('Tem Certeza?') ? document.getElementById('apagar{{ $l->id }}').submit() : '';"
class="btn d-inline-flex gap-3 btn-outline-vermelho ml-1"><i
class="fas fa-trash-alt"></i> Excluir
<form action="{{ route('produto.destroy', $l->id) }}" method="POST"
id="apagar{{ $l->id }}">
@method('delete')
@csrf
</form>
</a>
</td>
</tr>
@endforeach
Prepare seu sistema para que permita que sejam feitos filtros por descrição e por categoria
No método index faça as seguintes implementações:
- Coloque um Request como parâmetro de recebimento do método
- Crie um objeto chamado filtro com os campos categoria_id e nome
- Na array $dados["lista"] chame o método filtro do model produto e passe como parâmetro o objeto filtro criado
- para o array $dados liste as categorias
public function index(Request $request)
{
$filtro = new stdClass;
$filtro->categoria_id = $request->categoria_id ?? null;
$filtro->nome = $request->nome ?? null;
$dados["lista"] = Produto::filtro($filtro);
$dados["categorias"] = Categoria::get();
$dados["filtro"] = $filtro;
return View("Cadastro.Produto.Index", $dados);
}
No model Produto, crie um método chamado filtro que receba como parâmetro um objeto $filtro e um variável chamada $paginas inicializada com zero e implemente o método de forma que:
- Se houver o campo $filtro->nome, faça o filtro pelo nome
- se houver o campo $filtro->categoria_id, faça o filtro pela categoria_id
- se a variável páginas for maior que zero que o seja do tipo paginate(), senão que seja get()
public static function filtro($filtro, $paginas=0){
$retorno = self::query();
if($filtro->nome){
$retorno->where("nome", "like", '%'.$filtro->nome.'%');
}
if($filtro->categoria_id){
$retorno->where("categoria_id", $filtro->categoria_id);
}
if($paginas>0){
$retorno = $retorno->paginate($paginas);
}else{
$retorno = $retorno->get();
}
return $retorno;
}
Na view index, no formulário do filtro implemente o seguinte:
- Preencha o elemento select do filtro com a lista de categorias e sete a propriedade name para categoria_id
- o input na propriedade name atribua nome e no value faça a verificação se existe o objetivo $filtro->nome se sim mostre.
<form>
<div class="mostraFiltro bg-padrao mt-2 p-2 radius-4 border">
<div class="rows center-middle">
<div class="col-6">
<label class="text-label d-block text-branco">Produto </label>
<input type="text" name="nome" value="{{ $filtro->nome ?? null }}"
class="form-campo" placeholder="Digite aqui..">
</div>
<div class="col-4">
<label class="text-label d-block text-branco">Selecionar categoria </label>
<select name="categoria_id" class="form-campo">
<option value="">Selecione uma categoria</option>
@foreach ($categorias as $cat)
<option value="{{ $cat->id }}"
{{ ($filtro->categoria_id ?? null) == $cat->id ? 'selected' : '' }}>
{{ $cat->categoria }}</option>
@endforeach
</select>
</div>
<div class="col-2 mt-0 pt-4">
<input type="submit" value="Pesquisar" class="width-100 btn btn-roxo text-uppercase">
</div>
</div>
</div>
</form>
Faça o teste com os filtros
Implemente o método create do controller ProdutoController com as seguintes ações:
- no array $dados liste as categorias
- no array $dados liste as unidades
- no array dados sete a variável produtoJs para true
- no array dados sete a variável categoriaJs para true
- chame a view Produto/Create passando o array $dados
public function create()
{
$dados["categorias"] = Categoria::get();
$dados["unidades"] = Unidade::get();
$dados["produtoJs"] = true;
$dados["categoriaJs"] = true;
return View("Cadastro.Produto.Create", $dados);
}
Para fazer o cadastro de produto será necessário criar duas novas views, Dentro da pasta Cadastro/Produto faça o seguinte:
- Crie uma view chamada Create.blade.php
- Crie uma view chamada Edit.blade.php
Copie o conteúdo do arquivo frm_produto para o arquivo Cadastro/Produto/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 produto.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('produto.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-8 px-2">
<div class="rows">
<div class="col-12 mb-3">
<label class="text-label">Nome do produto</label>
<input type="text" name="nome" value="" class="form-campo" required>
</div>
<div class="col-4 mb-3">
<label class="text-label">NCM</label>
<input type="text" name="ncm" value="" data-mask="0000.00.00" maxlength="10"
class="form-campo" required>
</div>
<div class="col-4 mb-3">
<label class="text-label">Código Barra/Gtin/EanTrib</label>
<input type="text" name="gtin" value="" class="form-campo">
</div>
<div class="col-4 mb-3">
<label class="text-label">Cest</label>
<input type="text" name="cest" value="" class="form-campo">
</div>
<div class="col-6 mb-3">
<label class="text-label">Origem</label>
<select class="form-campo" name="origem">
<option value="SACO"> Origem</option>
</select>
</div>
<div class="col-6 mb-3">
<label class="text-label">Categoria</label>
<div class="group-btn d-flex center-midlle">
<select class="form-campo" name="categoria_id">
<option value="SACO"> Unidade</option>
</select>
<a href="javascript:;" onclick="abrirModal('#modalCategoria')"
class="text-verde p-1 border radius-50 ml-1 fas fa-plus"
title="Inserir nova categoria"></a>
</div>
</div>
<div class="col-4 mb-3">
<label class="text-label">Unidade</label>
<select class="form-campo" name="unidade" required>
<option value="SACO"> Unidade</option>
</select>
</div>
<div class="col-4 mb-3">
<label class="text-label">Estoque Inicial</label>
<input type="text" name="estoque_inicial" value=""
class="form-campo mascara-float">
</div>
<div class="col-4 mb-3">
<label class="text-label">Estoque Máximo</label>
<input type="text" name="estoque_maximo" value="" class="form-campo mascara-float">
</div>
<div class="col mb-3">
<label class="text-label">Estoque Minimo</label>
<input type="text" name="estoque_minimo" value="" class="form-campo mascara-float">
</div>
<div class="col mb-3">
<label class="text-label">Preço Custo</label>
<input type="text" name="preco_custo" value="" id="preco_custo"
onkeyup="calcularPreco()" class="form-campo mascara-float">
</div>
<div class="col mb-3">
<label class="text-label">(%) Margem Lucro</label>
<input type="text" name="margem_lucro" value="" onkeyup="calcularPreco()"
id="margem_lucro" class="form-campo mascara-float">
</div>
<div class="col mb-3">
<label class="text-label">Preço Venda</label>
<input type="text" name="preco_venda" value="" id="preco_venda"
class="form-campo mascara-float" required>
</div>
<div class="col-12 mt-4">
<input type="submit" value="Inserir Novo Produto"
class="btn btn-padrao btn-medio d-block m-auto">
</div>
</div>
</div>
Configure os combos: Catetoria, origem e unidade
Faça o loop da lista de categoria e preencha o elemento select
<div class="col-6 mb-3">
<label class="text-label">Categoria</label>
<div class="group-btn d-flex center-midlle">
<select class="form-campo" name="categoria_id" id="cb_categoria_id">
@foreach ($categorias as $cat)
<option value="{{ $cat->id }}">{{ $cat->categoria }} </option>
@endforeach
</select>
<a href="javascript:;" onclick="abrirModal('#modalCategoria')"
class="text-verde p-1 border radius-50 ml-1 fas fa-plus"
title="Inserir nova categoria"></a>
</div>
</div>
Faça o loop da lista de unidades e preencha o elemento select da unidades
<div class="col-4 mb-3">
<label class="text-label">Unidade</label>
<select class="form-campo" name="unidade" required>
@foreach ($unidades as $u)
<option value="{{ $u->unidade }}"> {{ $u->unidade }}</option>
@endforeach
</select>
</div>
Faça o loop da lista de origem e preencha o elemento select de origem e lembre-se que os dados da origem virão do service ConstanteService
<?php
use App\Service\ConstanteService;
?>
<div class="col-6 mb-3">
<label class="text-label">Origem</label>
<select class="form-campo" name="origem">
@foreach (ConstanteService::listaOrigem() as $chave => $valor)
<option value="{{ $chave }}">{{ $valor }} </option>
@endforeach
</select>
</div>
Crie uma função javascript que calcula o preço de venda baseado no preço de custo
Crie um arquivo javascript chamado js_produto.js dentro da public/assets/js em seguida faça os seguintes procedimentos
no arquivo js_produto.js, crie uma função chamada calcularPreco, a qual deverá receber o preço de custo e a margem de lucro e retorne preço de venda calculado, use a formula: preco_venda = preco_custo + (preco_custo*margem_lucro*0.01)
function calcularPreco(){
let preco_custo = converteMoedaFloat( $('#preco_custo').val()) ;
let margem_lucro = converteMoedaFloat($('#margem_lucro').val());
let preco_venda = preco_custo + (preco_custo*margem_lucro*0.01);
$("#preco_venda").val(converteFloatMoeda(preco_venda.toFixed(2)));
}
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
$req['estoque_inicial'] = getFloat($req['estoque_inicial']);
$req['estoque_maximo'] = getFloat($req['estoque_maximo']);
$req['estoque_minimo'] = getFloat($req['estoque_minimo']);
$req['preco_custo'] = getFloat($req['preco_custo']);
$req['margem_lucro'] = getFloat($req['margem_lucro']);
$req['preco_venda'] = getFloat($req['preco_venda']);
Implemente o upload de imagens
Ative o storage link, utilizando o comando: php artisan storage:link
Faça o upload de imagens, seguindo os passo:
- Verifique se a imagem foi passada na request e se seu valor é válido
- receba os dados numa variável $file
- salve os dados na pasta upload/produto e guarde o nome do arquivo em uma variável para que seja salva no banco de dados
if($request->hasFile('imagem') && $request->imagem->isValid()){
$file = $request->file("imagem");
$req["imagem"] = $file->store("upload/produto");
}
Caso não tenha conseguido fazer, segue o código completo
public function store(Request $request)
{
$req = $request->except(["_token"]);
try {
$req['estoque_inicial'] = getFloat($req['estoque_inicial']);
$req['estoque_maximo'] = getFloat($req['estoque_maximo']);
$req['estoque_minimo'] = getFloat($req['estoque_minimo']);
$req['preco_custo'] = getFloat($req['preco_custo']);
$req['margem_lucro'] = getFloat($req['margem_lucro']);
$req['preco_venda'] = getFloat($req['preco_venda']);
$req["status_id"] = config('constantes.status.ATIVO');
if($request->hasFile('imagem') && $request->imagem->isValid()){
$file = $request->file("imagem");
$req["imagem"] = $file->store("upload/produto");
}
Produto::Create($req);
return redirect()->route("produto.index")->with("msg_sucesso", "inserido com sucesso");
} catch (\Throwable $th) {
return redirect()->back()->with("msg_erro", "Erro: " . $th->getMessage());
}
}
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
No arquivo de request configure as validações necessárias e não esqueça de setar o método authorize para true;
public function rules()
{
$id= $this->segment(2);
$rules= [
"nome" => "required",
"origem" => "required",
"preco_venda" => "required",
"ncm" => "required",
"imagem" =>"nullable"
];
if(!is_null($this->imagem)){
$rules['imagem'] = 'file|mimetypes:image/png,image/jpg,image/jpeg|image:jpg,png,jpeg';
}
return $rules;
}
No método store troque o parâmetro Request para ProdutoRequest
public function store(ProdutoRequest $request)
{
$req = $request->except(["_token"]);
try {
$req['estoque_inicial'] = getFloat($req['estoque_inicial']);
$req['estoque_maximo'] = getFloat($req['estoque_maximo']);
$req['estoque_minimo'] = getFloat($req['estoque_minimo']);
$req['preco_custo'] = getFloat($req['preco_custo']);
$req['margem_lucro'] = getFloat($req['margem_lucro']);
$req['preco_venda'] = getFloat($req['preco_venda']);
$req["status_id"] = config('constantes.status.ATIVO');
if($request->hasFile('imagem') && $request->imagem->isValid()){
$file = $request->file("imagem");
$req["imagem"] = $file->store("upload/produto");
}
Produto::Create($req);
return redirect()->route("produto.index")->with("msg_sucesso", "inserido com sucesso");
} catch (\Throwable $th) {
return redirect()->back()->with("msg_erro", "Erro: " . $th->getMessage());
}
}
Teste o sistema fazendo cadastros
Implemente o modal Categoria
Dentro da pasta views/Cadastro/Categoria crie uma view chamada modalCategoria.blade.php e para o seu conteúdo copie os dados do arquivo modal_cateogoria.html o qual foi baixado
Crie um arquivo javascript chamado js_categoria.js dentro de public/assets/js
No arquivo js_caegoria.js crie um método chamado salvarCategoria, o qual deverá salvar a categoria via jquery e como retorno atualizar o combo de categorias do formulário
function salvarCategoria(){
var categoria = $("#txtCategoria").val();
$.ajax({
url:base_url+"categoria/salvarJs",
type:"POST",
dataType:"JSON",
data:{categoria:categoria},
success:function(data){
fecharModal();
if(data.tem_erro==true){
$("#mostrarUmErro").html(MostrarUmaMsgErro("Erro: " + data.erro));
}else{
$("#mostrarSucesso").html(MostrarUmaMsgSucesso("inserido com sucesso"));
var html = "";
for(i=0; i<data.lista.length; i++){
html +="<option value='"+ data.lista[i].id+"'>"+ data.lista[i].categoria+" </option>";
}
$("#cb_categoria_id").html(html);
}
},
error:function(data){
}
});
}
No controller CategoriaController um método chamado salvarJs, este método deverá:
- Receber via post o nome da categoria
- Salvar no banco de dados
- retornar a lista de categoria
public function salvarJs(Request $request){
$retorno = new stdClass;
$req = $request->except(["_token"]);
try {
Categoria::Create($req);
$retorno->tem_erro = false;
$retorno->lista = Categoria::get();
return response()->json($retorno);
} catch (\Throwable $th) {
$retorno->tem_erro = true;
$retorno->erro = $th->getMessage();
$retorno->lista = Categoria::get();
return response()->json($retorno);
}
}
Faça o teste e tente cadastrar uma categoria pelo modal, a esta altura não é pra acontecer nenhum erro
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($id)
{
$dados["produto"] = Produto::find($id);
$dados["categorias"] = Categoria::get();
$dados["unidades"] = Unidade::get();
$dados["categoriaJs"] = true;
$dados["produtoJs"] = true;
return View("Cadastro.Produto.Edit", $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(ProdutoRequest $request, $id)
{
$req = $request->except(["_token","estoque_inicial"]);
try {
$req['estoque_maximo'] = getFloat($req['estoque_maximo']);
$req['estoque_minimo'] = getFloat($req['estoque_minimo']);
$req['preco_custo'] = getFloat($req['preco_custo']);
$req['margem_lucro'] = getFloat($req['margem_lucro']);
$req['preco_venda'] = getFloat($req['preco_venda']);
$req["status_id"] = config('constantes.status.ATIVO');
$produto = Produto::find($id);
if($request->hasFile('imagem') && $request->imagem->isValid()){
$file = $request->file("imagem");
$req["imagem"] = $file->store("upload/produto");
}
$produto->update($req);
return redirect()->route("produto.index")->with("msg_sucesso", "inserido com sucesso");
} catch (\Throwable $th) {
return redirect()->back()->with("msg_erro", "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 o produto 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
public function destroy($id)
{
try {
$produto = Produto::find($id);
if($produto->imagem){
if(Storage::exists($produto->imagem)){
Storage::delete($produto->imagem);
}
}
$produto->delete();
return redirect()->route("produto.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