Banco de Dados

Factories do Laravel - AgrSis

Este documento descreve todas as Factories criadas para facilitar testes e desenvolvimento no projeto AgrSis.

Factories do Laravel - AgrSis

Este documento descreve todas as Factories criadas para facilitar testes e desenvolvimento no projeto AgrSis.

Índice


O que são Factories

Factories são classes do Laravel que facilitam a criação de dados de teste (fake data) para os Models da aplicação. Elas usam a biblioteca Faker para gerar dados realistas em português brasileiro.

Benefícios:

  • Criação rápida de dados para testes
  • Dados consistentes e realistas
  • Facilita o desenvolvimento local
  • Essencial para testes automatizados
  • Agiliza o seeding do banco de dados

Factories Criadas

Total de 19 factories criadas:

1. Core e Autenticação

  • UserFactory - Usuários do sistema
  • AccessTypeFactory - Tipos de acesso

2. Clientes

  • CustomerFactory - Produtores rurais (PF/PJ)

3. Fornecedores

  • SupplierFactory - Fornecedores/Revendedores

4. Cadastros Auxiliares

  • AddressFactory - Endereços
  • ManagerFactory - Responsáveis/Gerentes
  • StateFactory - Estados brasileiros

5. Produtos

  • ProductTypeFactory - Tipos de produtos
  • BrandFactory - Marcas
  • ProductFactory - Produtos/Insumos
  • MeasurementUnitFactory - Unidades de medida
  • PlantationCultureFactory - Culturas/plantações

6. Cotações

  • QuotationStatusFactory - Status de cotações

7. Pedidos

  • OrderStatusFactory - Status de pedidos
  • OrderFactory - Pedidos de compra

8. Contratos

  • ContractTypeFactory - Tipos de contrato

9. Financeiro

  • TransactionFactory - Transações financeiras
  • PaymentMethodFactory - Métodos de pagamento

10. Planos

  • SubscriptionPlanFactory - Planos de assinatura

Como Usar

Uso Básico

// No Tinker, Seeder ou Teste

// Criar um único registro
$user = User::factory()->create();

// Criar múltiplos registros
$users = User::factory()->count(10)->create();

// Criar sem salvar no banco (make)
$user = User::factory()->make();

// Sobrescrever atributos
$user = User::factory()->create([
    'email' => 'email@especifico.com',
]);

No Tinker

# Entrar no Tinker
docker exec -it agrsis_api php artisan tinker

# Ou se não estiver usando Docker
php artisan tinker
// Criar usuário admin
User::factory()->admin()->create();

// Criar 5 clientes PF
Customer::factory()->pf()->count(5)->create();

// Criar fornecedor com site
Supplier::factory()->withSite()->create();

// Criar pedido urgente
Order::factory()->urgent()->create();

Em Seeders

<?php

namespace Database\Seeders;

use App\Models\User;
use App\Models\Customer;
use App\Models\Supplier;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        // Criar usuários
        User::factory()->admin()->create(['email' => 'admin@agrsis.com']);
        User::factory()->count(10)->create();

        // Criar clientes
        Customer::factory()->pf()->count(20)->create();
        Customer::factory()->pj()->count(10)->create();

        // Criar fornecedores
        Supplier::factory()->count(15)->create();
    }
}

Em Testes

<?php

namespace Tests\Feature;

use App\Models\User;
use App\Models\Order;
use Tests\TestCase;

class OrderTest extends TestCase
{
    public function test_can_create_order(): void
    {
        $user = User::factory()->produtor()->create();

        $response = $this->actingAs($user)
            ->post('/api/orders', [
                'descricao' => 'Teste',
            ]);

        $response->assertStatus(201);
    }
}

States Disponíveis

UserFactory

User::factory()->admin()->create();        // Usuário administrador
User::factory()->produtor()->create();     // Usuário produtor
User::factory()->fornecedor()->create();   // Usuário fornecedor
User::factory()->inactive()->create();     // Usuário inativo
User::factory()->unverified()->create();   // Email não verificado

AccessTypeFactory

AccessType::factory()->cliente()->create();       // Tipo Cliente
AccessType::factory()->fornecedor()->create();    // Tipo Fornecedor
AccessType::factory()->administrador()->create(); // Tipo Administrador
AccessType::factory()->inactive()->create();      // Tipo inativo

CustomerFactory

Customer::factory()->pf()->create();       // Pessoa Física
Customer::factory()->pj()->create();       // Pessoa Jurídica
Customer::factory()->inactive()->create(); // Cliente inativo

SupplierFactory

Supplier::factory()->withSite()->create();  // Fornecedor com site
Supplier::factory()->inactive()->create();  // Fornecedor inativo

ManagerFactory

Manager::factory()->solteiro()->create();    // Estado civil: Solteiro
Manager::factory()->casado()->create();      // Estado civil: Casado
Manager::factory()->divorciado()->create();  // Estado civil: Divorciado
Manager::factory()->inactive()->create();    // Manager inativo

OrderFactory

Order::factory()->urgent()->create();      // Pedido com data limite próxima
Order::factory()->rejected()->create();    // Pedido rejeitado
Order::factory()->inactive()->create();    // Pedido inativo

SubscriptionPlanFactory

SubscriptionPlan::factory()->basic()->create();        // Plano Básico
SubscriptionPlan::factory()->professional()->create(); // Plano Profissional
SubscriptionPlan::factory()->premium()->create();      // Plano Premium
SubscriptionPlan::factory()->inactive()->create();     // Plano inativo

TransactionFactory

Transaction::factory()->entrada()->create();   // Transação de entrada
Transaction::factory()->saida()->create();     // Transação de saída
Transaction::factory()->pending()->create();   // Status pendente
Transaction::factory()->approved()->create();  // Status aprovado
Transaction::factory()->rejected()->create();  // Status rejeitado

Outras Factories

Todas as outras factories possuem o state inactive():

ProductType::factory()->inactive()->create();
Brand::factory()->inactive()->create();
Product::factory()->inactive()->create();
MeasurementUnit::factory()->inactive()->create();
PlantationCulture::factory()->inactive()->create();
OrderStatus::factory()->inactive()->create();
QuotationStatus::factory()->inactive()->create();
ContractType::factory()->inactive()->create();
PaymentMethod::factory()->inactive()->create();

Exemplos Práticos

// database/seeders/DatabaseSeeder.php

public function run(): void
{
    // 1. Criar tipos de acesso
    AccessType::factory()->cliente()->create();
    AccessType::factory()->fornecedor()->create();
    AccessType::factory()->administrador()->create();

    // 2. Criar usuários
    User::factory()->admin()->create(['email' => 'admin@agrsis.com']);
    User::factory()->produtor()->count(20)->create();
    User::factory()->fornecedor()->count(10)->create();

    // 3. Criar clientes (produtores)
    Customer::factory()->pf()->count(30)->create();
    Customer::factory()->pj()->count(20)->create();

    // 4. Criar fornecedores
    Supplier::factory()->count(25)->create();
    Supplier::factory()->withSite()->count(10)->create();

    // 5. Criar produtos
    $productTypes = ProductType::factory()->count(8)->create();
    $brands = Brand::factory()->count(10)->create();
    Product::factory()->count(50)->create();

    // 6. Criar culturas
    PlantationCulture::factory()->count(10)->create();

    // 7. Criar unidades de medida
    MeasurementUnit::factory()->count(6)->create();

    // 8. Criar status
    OrderStatus::factory()->count(8)->create();
    QuotationStatus::factory()->count(15)->create();

    // 9. Criar pedidos
    Order::factory()->count(50)->create();
    Order::factory()->urgent()->count(10)->create();

    // 10. Criar planos
    SubscriptionPlan::factory()->basic()->create();
    SubscriptionPlan::factory()->professional()->create();
    SubscriptionPlan::factory()->premium()->create();

    // 11. Criar transações
    Transaction::factory()->entrada()->count(100)->create();
    Transaction::factory()->saida()->count(80)->create();

    // 12. Criar estados brasileiros
    State::factory()->count(27)->create();
}

2. Criar Estrutura Completa de Cliente

// Criar cliente com endereço, manager e pedidos

$customer = Customer::factory()->pj()->create();

// Criar endereço para o cliente
$address = Address::factory()->create();
$customer->addresses()->attach($address->id, ['status' => true]);

// Criar manager para o cliente
$manager = Manager::factory()->casado()->create();
$customer->managers()->attach($manager->id, ['status' => true]);

// Criar pedidos para o cliente
Order::factory()->count(5)->create(['customer_id' => $customer->id]);
Order::factory()->urgent()->count(2)->create(['customer_id' => $customer->id]);

3. Criar Fornecedor Completo

// Criar fornecedor com endereço e estados de atuação

$supplier = Supplier::factory()->withSite()->create();

// Criar endereço
$address = Address::factory()->create();
$supplier->addresses()->attach($address->id, ['status' => true]);

// Criar manager
$manager = Manager::factory()->create();
$supplier->managers()->attach($manager->id, ['status' => true]);

// Adicionar estados de atuação
$states = State::factory()->count(5)->create();
$supplier->states()->attach($states->pluck('id'), ['status' => true]);

4. Testar Fluxo Completo de Pedido

public function test_complete_order_flow(): void
{
    // Criar usuário produtor
    $user = User::factory()->produtor()->create();
    $customer = Customer::factory()->pf()->create();

    // Criar pedido
    $order = Order::factory()->create(['customer_id' => $customer->id]);

    // Criar produtos para o pedido
    $products = Product::factory()->count(3)->create();

    // Criar fornecedores que receberão a cotação
    $suppliers = Supplier::factory()->count(5)->create();
    $order->suppliers()->attach($suppliers->pluck('id'), [
        'enviado' => true,
        'visualizado' => false,
        'data_envio' => now(),
        'status' => true,
    ]);

    // Asserts
    $this->assertEquals(3, $products->count());
    $this->assertEquals(5, $order->suppliers()->count());
}
// Seeder específico para Estados

public function run(): void
{
    $estados = [
        ['sigla' => 'AC', 'nome' => 'Acre'],
        ['sigla' => 'AL', 'nome' => 'Alagoas'],
        ['sigla' => 'AP', 'nome' => 'Amapá'],
        ['sigla' => 'AM', 'nome' => 'Amazonas'],
        ['sigla' => 'BA', 'nome' => 'Bahia'],
        ['sigla' => 'CE', 'nome' => 'Ceará'],
        ['sigla' => 'DF', 'nome' => 'Distrito Federal'],
        ['sigla' => 'ES', 'nome' => 'Espírito Santo'],
        ['sigla' => 'GO', 'nome' => 'Goiás'],
        ['sigla' => 'MA', 'nome' => 'Maranhão'],
        ['sigla' => 'MT', 'nome' => 'Mato Grosso'],
        ['sigla' => 'MS', 'nome' => 'Mato Grosso do Sul'],
        ['sigla' => 'MG', 'nome' => 'Minas Gerais'],
        ['sigla' => 'PA', 'nome' => 'Pará'],
        ['sigla' => 'PB', 'nome' => 'Paraíba'],
        ['sigla' => 'PR', 'nome' => 'Paraná'],
        ['sigla' => 'PE', 'nome' => 'Pernambuco'],
        ['sigla' => 'PI', 'nome' => 'Piauí'],
        ['sigla' => 'RJ', 'nome' => 'Rio de Janeiro'],
        ['sigla' => 'RN', 'nome' => 'Rio Grande do Norte'],
        ['sigla' => 'RS', 'nome' => 'Rio Grande do Sul'],
        ['sigla' => 'RO', 'nome' => 'Rondônia'],
        ['sigla' => 'RR', 'nome' => 'Roraima'],
        ['sigla' => 'SC', 'nome' => 'Santa Catarina'],
        ['sigla' => 'SP', 'nome' => 'São Paulo'],
        ['sigla' => 'SE', 'nome' => 'Sergipe'],
        ['sigla' => 'TO', 'nome' => 'Tocantins'],
    ];

    foreach ($estados as $estado) {
        State::create($estado);
    }
}

Dicas de Uso

1. Combinando States

// Criar usuário produtor inativo
User::factory()->produtor()->inactive()->create();

// Criar cliente PJ inativo
Customer::factory()->pj()->inactive()->create();

// Criar pedido urgente rejeitado
Order::factory()->urgent()->rejected()->create();

2. Relacionamentos Automáticos

Algumas factories já criam relacionamentos automaticamente:

// ProductFactory cria automaticamente um ProductType
$product = Product::factory()->create();
// $product->productType já existe

// OrderFactory cria automaticamente um Customer
$order = Order::factory()->create();
// $order->customer já existe

// TransactionFactory cria automaticamente um Customer
$transaction = Transaction::factory()->create();
// $transaction->customer já existe

3. Dados Específicos para Testes

// Criar usuário com email específico para teste
$user = User::factory()->create([
    'email' => 'teste@agrsis.com',
    'password' => 'senha123',
]);

// Criar cliente com CPF específico
$customer = Customer::factory()->pf()->create([
    'cpf_cnpj' => '12345678901',
]);

// Criar pedido com data específica
$order = Order::factory()->create([
    'data_limite_cotacao' => now()->addDays(7),
]);

4. Resetar Banco de Dados

# Dropar todas as tabelas, rodar migrations e seeders
php artisan migrate:fresh --seed

# Com Docker
docker exec agrsis_api php artisan migrate:fresh --seed

5. Usar em Testes

use Illuminate\Foundation\Testing\RefreshDatabase;

class ExemploTest extends TestCase
{
    use RefreshDatabase; // Reseta banco a cada teste

    public function test_exemplo(): void
    {
        $user = User::factory()->create();

        $this->actingAs($user)
            ->get('/api/orders')
            ->assertStatus(200);
    }
}

6. Criar Dados Temporários (sem salvar)

// Criar objeto sem salvar no banco
$user = User::factory()->make();

// Útil para validações
$this->assertEquals('produtor', $user->perfil);

// Ou para testes de validação
$user->email = 'email-invalido'; // Testa validação

Comandos Úteis

# Tinker
php artisan tinker
docker exec -it agrsis_api php artisan tinker

# Rodar seeders
php artisan db:seed
docker exec agrsis_api php artisan db:seed

# Rodar seeder específico
php artisan db:seed --class=DatabaseSeeder
docker exec agrsis_api php artisan db:seed --class=DatabaseSeeder

# Reset completo
php artisan migrate:fresh --seed
docker exec agrsis_api php artisan migrate:fresh --seed

# Rodar testes
php artisan test
docker exec agrsis_api php artisan test

Dados Brasileiros (Faker pt_BR)

Todas as factories usam o Faker configurado para pt_BR, gerando dados realistas em português:

  • CPF/CNPJ: Válidos e formatados
  • Nomes: Nomes brasileiros comuns
  • Endereços: Logradouros, bairros e cidades brasileiras
  • Telefones: Formato brasileiro
  • Estados: Siglas e nomes corretos

Próximos Passos

Factories Adicionais (se necessário)

  • OrderItemFactory
  • QuotationItemFactory
  • ContractFactory
  • ContractTemplateFactory
  • CustomerSubscriptionFactory
  • OperationFactory
  • PaymentAttemptFactory

Melhorias Futuras

  • Adicionar mais states específicos
  • Criar Seeders específicos por módulo
  • Implementar testes automatizados completos
  • Adicionar validações nos states

Referências


Última atualização: 2025-12-04 Total de Factories: 19 Versão Laravel: 11 Locale Faker: pt_BR

Copyright © 2026