Consolida recepcoes, stock, equipamentos e identidade SGC
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('warehouses', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('created_by')->constrained('users')->restrictOnDelete();
|
||||
$table->string('code', 30);
|
||||
$table->string('name', 200);
|
||||
$table->timestamps();
|
||||
$table->unique(['tenant_id', 'code']);
|
||||
});
|
||||
Schema::create('stock_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('created_by')->constrained('users')->restrictOnDelete();
|
||||
$table->string('code', 30);
|
||||
$table->string('name', 200);
|
||||
$table->string('unit', 30);
|
||||
$table->timestamps();
|
||||
$table->unique(['tenant_id', 'code']);
|
||||
});
|
||||
Schema::create('goods_receipts', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('purchase_order_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('received_by')->constrained('users')->restrictOnDelete();
|
||||
$table->foreignId('warehouse_id')->nullable()->constrained()->restrictOnDelete();
|
||||
$table->string('number')->nullable()->unique();
|
||||
$table->uuid('idempotency_key');
|
||||
$table->string('payload_hash', 64);
|
||||
$table->string('delivery_note', 100);
|
||||
$table->date('received_on');
|
||||
$table->string('status');
|
||||
$table->json('snapshot');
|
||||
$table->timestamp('confirmed_at');
|
||||
$table->unique(['purchase_order_id', 'idempotency_key']);
|
||||
$table->unique(['purchase_order_id', 'delivery_note']);
|
||||
});
|
||||
Schema::create('goods_receipt_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('goods_receipt_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('purchase_order_item_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('stock_item_id')->nullable()->constrained()->restrictOnDelete();
|
||||
$table->unsignedBigInteger('received_milli');
|
||||
$table->unsignedBigInteger('accepted_milli');
|
||||
$table->unsignedBigInteger('rejected_milli');
|
||||
$table->string('quality_status');
|
||||
$table->text('notes')->nullable();
|
||||
$table->json('snapshot');
|
||||
$table->unique(['goods_receipt_id', 'purchase_order_item_id']);
|
||||
});
|
||||
Schema::create('stock_movements', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('goods_receipt_item_id')->unique()->constrained()->restrictOnDelete();
|
||||
$table->foreignId('stock_item_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('warehouse_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('moved_by')->constrained('users')->restrictOnDelete();
|
||||
$table->string('movement_type')->default('receipt_in');
|
||||
$table->unsignedBigInteger('quantity_milli');
|
||||
$table->json('snapshot');
|
||||
$table->timestamp('moved_at');
|
||||
$table->index(['tenant_id', 'stock_item_id', 'warehouse_id']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('stock_movements');
|
||||
Schema::dropIfExists('goods_receipt_items');
|
||||
Schema::dropIfExists('goods_receipts');
|
||||
Schema::dropIfExists('stock_items');
|
||||
Schema::dropIfExists('warehouses');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('stock_operations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('created_by')->constrained('users')->restrictOnDelete();
|
||||
$table->foreignId('responsible_id')->constrained('users')->restrictOnDelete();
|
||||
$table->foreignId('warehouse_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('destination_warehouse_id')->nullable()->constrained('warehouses')->restrictOnDelete();
|
||||
$table->foreignId('stock_item_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('count_id')->nullable()->unique()->constrained('stock_operations')->restrictOnDelete();
|
||||
$table->string('kind');
|
||||
$table->string('reference', 100);
|
||||
$table->uuid('idempotency_key');
|
||||
$table->string('payload_hash', 64);
|
||||
$table->string('destination', 200)->nullable();
|
||||
$table->text('reason');
|
||||
$table->bigInteger('quantity_milli');
|
||||
$table->bigInteger('theoretical_milli')->nullable();
|
||||
$table->unsignedBigInteger('ledger_version')->nullable();
|
||||
$table->json('snapshot');
|
||||
$table->timestamp('recorded_at');
|
||||
$table->unique(['tenant_id', 'reference']);
|
||||
$table->unique(['tenant_id', 'idempotency_key']);
|
||||
});
|
||||
Schema::table('stock_movements', function (Blueprint $table) {
|
||||
$table->unsignedBigInteger('goods_receipt_item_id')->nullable()->change();
|
||||
$table->bigInteger('quantity_milli')->change();
|
||||
$table->foreignId('stock_operation_id')->nullable()->constrained()->restrictOnDelete();
|
||||
$table->unique(['stock_operation_id', 'warehouse_id']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// Signed ledger entries must never be coerced back to unsigned quantities.
|
||||
throw new LogicException('Migração de histórico irreversível; preservar movimentos e usar migrações aditivas.');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('criticality_levels', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('created_by')->constrained('users')->restrictOnDelete();
|
||||
$table->string('code', 30);
|
||||
$table->string('name', 150);
|
||||
$table->text('criteria');
|
||||
$table->boolean('is_critical');
|
||||
$table->timestamp('created_at');
|
||||
$table->unique(['tenant_id', 'code']);
|
||||
});
|
||||
Schema::create('equipment', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('created_by')->constrained('users')->restrictOnDelete();
|
||||
$table->foreignId('department_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('stock_item_id')->nullable()->constrained()->restrictOnDelete();
|
||||
$table->foreignId('criticality_level_id')->constrained()->restrictOnDelete();
|
||||
$table->string('code', 30);
|
||||
$table->string('description', 255);
|
||||
$table->string('area', 200);
|
||||
$table->string('serial_number', 100)->nullable();
|
||||
$table->string('status', 30);
|
||||
$table->unsignedInteger('version')->default(1);
|
||||
$table->timestamps();
|
||||
$table->unique(['tenant_id', 'code']);
|
||||
});
|
||||
Schema::create('spare_parts', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('created_by')->constrained('users')->restrictOnDelete();
|
||||
$table->foreignId('stock_item_id')->unique()->constrained()->restrictOnDelete();
|
||||
$table->foreignId('criticality_level_id')->constrained()->restrictOnDelete();
|
||||
$table->unsignedBigInteger('minimum_milli');
|
||||
$table->unsignedInteger('version')->default(1);
|
||||
$table->timestamps();
|
||||
});
|
||||
Schema::create('equipment_spare_parts', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('equipment_id')->constrained('equipment')->restrictOnDelete();
|
||||
$table->foreignId('spare_part_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('created_by')->constrained('users')->restrictOnDelete();
|
||||
$table->timestamp('created_at');
|
||||
$table->unique(['equipment_id', 'spare_part_id']);
|
||||
});
|
||||
Schema::create('technical_reviews', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('requisition_id')->constrained()->restrictOnDelete();
|
||||
$table->foreignId('reviewed_by')->constrained('users')->restrictOnDelete();
|
||||
$table->string('basis_hash', 64);
|
||||
$table->string('decision', 30);
|
||||
$table->text('reason');
|
||||
$table->json('snapshot');
|
||||
$table->timestamp('reviewed_at');
|
||||
$table->unique(['requisition_id', 'basis_hash']);
|
||||
});
|
||||
foreach (['stock_operations', 'stock_movements', 'requisition_items', 'purchase_order_items'] as $name) {
|
||||
Schema::table($name, function (Blueprint $table) {
|
||||
$table->foreignId('equipment_id')->nullable()->constrained('equipment')->restrictOnDelete();
|
||||
$table->foreignId('spare_part_id')->nullable()->constrained()->restrictOnDelete();
|
||||
});
|
||||
}
|
||||
Schema::table('requisition_items', function (Blueprint $table) {
|
||||
$table->string('production_area', 200)->nullable();
|
||||
$table->timestamp('downtime_started_at')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
throw new LogicException('Preservar cadastro, associações e decisões técnicas; usar migrações aditivas.');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user