UI優化: 全系統狀態標籤 (StatusBadge) 統一化重構完成 (Phase 3 & 4)
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Has been skipped
Koori-ERP-Deploy-System / deploy-production (push) Successful in 1m8s

This commit is contained in:
2026-02-13 13:16:05 +08:00
56 changed files with 3343 additions and 429 deletions

View File

@@ -0,0 +1,40 @@
<?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('store_requisitions', function (Blueprint $table) {
$table->id();
$table->string('doc_no')->unique()->comment('單號 SR-YYYYMMDD-XX');
$table->unsignedBigInteger('store_warehouse_id')->comment('申請倉庫(任意類型)');
$table->unsignedBigInteger('supply_warehouse_id')->nullable()->comment('供貨倉庫(審核時填入)');
$table->enum('status', ['draft', 'pending', 'approved', 'rejected', 'completed', 'cancelled'])
->default('draft');
$table->text('remark')->nullable()->comment('申請備註');
$table->text('reject_reason')->nullable()->comment('駁回原因');
$table->unsignedBigInteger('created_by')->comment('申請人');
$table->unsignedBigInteger('approved_by')->nullable()->comment('審核人');
$table->timestamp('submitted_at')->nullable()->comment('提交時間');
$table->timestamp('approved_at')->nullable()->comment('審核時間');
$table->unsignedBigInteger('transfer_order_id')->nullable()->comment('關聯調撥單');
$table->timestamps();
$table->index('status');
$table->index('store_warehouse_id');
$table->index('created_by');
});
}
public function down(): void
{
Schema::dropIfExists('store_requisitions');
}
};

View File

@@ -0,0 +1,31 @@
<?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('store_requisition_items', function (Blueprint $table) {
$table->id();
$table->foreignId('store_requisition_id')->constrained()->cascadeOnDelete();
$table->unsignedBigInteger('product_id');
$table->decimal('requested_qty', 12, 2)->comment('需求數量');
$table->decimal('approved_qty', 12, 2)->nullable()->comment('核准數量(審核時填入)');
$table->text('remark')->nullable();
$table->timestamps();
$table->index('product_id');
});
}
public function down(): void
{
Schema::dropIfExists('store_requisition_items');
}
};

View File

@@ -0,0 +1,50 @@
<?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::table('inventory_transfer_orders', function (Blueprint $table) {
// 在途倉庫(可選)
$table->foreignId('transit_warehouse_id')
->nullable()
->after('to_warehouse_id')
->constrained('warehouses')
->nullOnDelete();
// 出貨資訊
$table->timestamp('dispatched_at')->nullable()->after('posted_at');
$table->foreignId('dispatched_by')->nullable()->after('dispatched_at')->constrained('users')->nullOnDelete();
// 收貨確認資訊
$table->timestamp('received_at')->nullable()->after('dispatched_by');
$table->foreignId('received_by')->nullable()->after('received_at')->constrained('users')->nullOnDelete();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('inventory_transfer_orders', function (Blueprint $table) {
$table->dropForeign(['transit_warehouse_id']);
$table->dropForeign(['dispatched_by']);
$table->dropForeign(['received_by']);
$table->dropColumn([
'transit_warehouse_id',
'dispatched_at',
'dispatched_by',
'received_at',
'received_by',
]);
});
}
};

View File

@@ -0,0 +1,33 @@
<?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::table('warehouses', function (Blueprint $table) {
$table->foreignId('default_transit_warehouse_id')
->nullable()
->after('driver_name')
->constrained('warehouses')
->nullOnDelete();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('warehouses', function (Blueprint $table) {
$table->dropForeign(['default_transit_warehouse_id']);
$table->dropColumn('default_transit_warehouse_id');
});
}
};

View File

@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
if (!Schema::hasColumn('warehouses', 'default_transit_warehouse_id')) {
Schema::table('warehouses', function (Blueprint $table) {
$table->foreignId('default_transit_warehouse_id')
->nullable()
->after('driver_name')
->comment('預設使用的在途倉(物流車)')
->constrained('warehouses')
->nullOnDelete();
});
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('warehouses', function (Blueprint $table) {
$table->dropForeign(['default_transit_warehouse_id']);
$table->dropColumn('default_transit_warehouse_id');
});
}
};

View File

@@ -55,6 +55,8 @@ class PermissionSeeder extends Seeder
'inventory_transfer.create' => '建立',
'inventory_transfer.edit' => '編輯',
'inventory_transfer.delete' => '刪除',
'inventory_transfer.dispatch' => '確認出貨',
'inventory_transfer.receive' => '確認收貨',
// 庫存報表
'inventory_report.view' => '檢視',
@@ -129,6 +131,14 @@ class PermissionSeeder extends Seeder
'sales_imports.create' => '建立',
'sales_imports.confirm' => '確認',
'sales_imports.delete' => '刪除',
// 門市叫貨申請
'store_requisitions.view' => '檢視',
'store_requisitions.create' => '建立',
'store_requisitions.edit' => '編輯',
'store_requisitions.delete' => '刪除',
'store_requisitions.approve' => '核準',
'store_requisitions.cancel' => '取消',
];
foreach ($permissions as $name => $displayName) {
@@ -158,7 +168,7 @@ class PermissionSeeder extends Seeder
'inventory.view', 'inventory.view_cost', 'inventory.delete',
'inventory_count.view', 'inventory_count.create', 'inventory_count.edit', 'inventory_count.delete',
'inventory_adjust.view', 'inventory_adjust.create', 'inventory_adjust.edit', 'inventory_adjust.delete',
'inventory_transfer.view', 'inventory_transfer.create', 'inventory_transfer.edit', 'inventory_transfer.delete',
'inventory_transfer.view', 'inventory_transfer.create', 'inventory_transfer.edit', 'inventory_transfer.delete', 'inventory_transfer.dispatch', 'inventory_transfer.receive',
'inventory_report.view', 'inventory_report.export',
'goods_receipts.view', 'goods_receipts.create', 'goods_receipts.edit', 'goods_receipts.delete',
'delivery_notes.view', 'delivery_notes.create', 'delivery_notes.edit', 'delivery_notes.delete',
@@ -172,6 +182,8 @@ class PermissionSeeder extends Seeder
'utility_fees.view', 'utility_fees.create', 'utility_fees.edit', 'utility_fees.delete',
'accounting.view', 'accounting.export',
'sales_imports.view', 'sales_imports.create', 'sales_imports.confirm', 'sales_imports.delete',
'store_requisitions.view', 'store_requisitions.create', 'store_requisitions.edit',
'store_requisitions.delete', 'store_requisitions.approve', 'store_requisitions.cancel',
]);
// warehouse-manager 管理庫存與倉庫
@@ -180,12 +192,14 @@ class PermissionSeeder extends Seeder
'inventory.view', 'inventory.delete',
'inventory_count.view', 'inventory_count.create', 'inventory_count.edit', 'inventory_count.delete',
'inventory_adjust.view', 'inventory_adjust.create', 'inventory_adjust.edit', 'inventory_adjust.delete',
'inventory_transfer.view', 'inventory_transfer.create', 'inventory_transfer.edit', 'inventory_transfer.delete',
'inventory_transfer.view', 'inventory_transfer.create', 'inventory_transfer.edit', 'inventory_transfer.delete', 'inventory_transfer.dispatch', 'inventory_transfer.receive',
'inventory_report.view', 'inventory_report.export',
'goods_receipts.view', 'goods_receipts.create', 'goods_receipts.edit', 'goods_receipts.delete',
'goods_receipts.view', 'goods_receipts.create', 'goods_receipts.edit', 'goods_receipts.delete',
'production_orders.view', 'production_orders.create', 'production_orders.edit',
'warehouses.view', 'warehouses.create', 'warehouses.edit',
'store_requisitions.view', 'store_requisitions.create', 'store_requisitions.edit',
'store_requisitions.delete', 'store_requisitions.approve', 'store_requisitions.cancel',
]);
// purchaser 管理採購與供應商