feat: 修正庫存與撥補單邏輯並整合文件
1. 修復倉庫統計數據加總與樣式。 2. 修正可用庫存計算邏輯(排除不可銷售倉庫)。 3. 撥補單商品列表加入批號與效期顯示。 4. 修正撥補單儲存邏輯以支援精確批號轉移。 5. 整合 FEATURES.md 至 README.md。
This commit is contained in:
@@ -11,6 +11,13 @@ use Illuminate\Support\Str;
|
||||
*/
|
||||
class UserFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = \App\Modules\Core\Models\User::class;
|
||||
|
||||
/**
|
||||
* The current password being used by the factory.
|
||||
*/
|
||||
@@ -25,6 +32,7 @@ class UserFactory extends Factory
|
||||
{
|
||||
return [
|
||||
'name' => fake()->name(),
|
||||
'username' => fake()->unique()->userName(),
|
||||
'email' => fake()->unique()->safeEmail(),
|
||||
'email_verified_at' => now(),
|
||||
'password' => static::$password ??= Hash::make('password'),
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?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
|
||||
{
|
||||
Schema::create('recipes', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('product_id')->constrained('products')->onDelete('cascade')->comment('連結的成品商品 ID');
|
||||
$table->string('code')->unique()->comment('配方代號');
|
||||
$table->string('name')->comment('配方名稱');
|
||||
$table->text('description')->nullable()->comment('配方描述');
|
||||
$table->decimal('yield_quantity', 10, 2)->default(1.00)->comment('標準產出數量');
|
||||
$table->boolean('is_active')->default(true)->comment('是否啟用');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
|
||||
Schema::create('recipe_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('recipe_id')->constrained('recipes')->onDelete('cascade');
|
||||
$table->foreignId('product_id')->constrained('products')->comment('原物料商品 ID');
|
||||
$table->decimal('quantity', 10, 4)->comment('標準用量');
|
||||
$table->foreignId('unit_id')->nullable()->constrained('units')->comment('單位 ID');
|
||||
$table->string('remark')->nullable()->comment('備註');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('recipe_items');
|
||||
Schema::dropIfExists('recipes');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* 新增配方管理權限
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
$guard = 'web';
|
||||
|
||||
// 建立配方管理權限
|
||||
$permissions = [
|
||||
'recipes.view' => '檢視配方',
|
||||
'recipes.create' => '建立配方',
|
||||
'recipes.edit' => '編輯配方',
|
||||
'recipes.delete' => '刪除配方',
|
||||
];
|
||||
|
||||
foreach ($permissions as $name => $description) {
|
||||
Permission::firstOrCreate(
|
||||
['name' => $name, 'guard_name' => $guard],
|
||||
['name' => $name, 'guard_name' => $guard]
|
||||
);
|
||||
}
|
||||
|
||||
// 授予 super-admin 所有新權限
|
||||
$superAdmin = Role::where('name', 'super-admin')->first();
|
||||
if ($superAdmin) {
|
||||
$superAdmin->givePermissionTo(array_keys($permissions));
|
||||
}
|
||||
|
||||
// 授予 admin 所有新權限
|
||||
$admin = Role::where('name', 'admin')->first();
|
||||
if ($admin) {
|
||||
$admin->givePermissionTo(array_keys($permissions));
|
||||
}
|
||||
|
||||
// 授予 warehouse-manager 檢視權限 (配方通常與庫存相關)
|
||||
$whManager = Role::where('name', 'warehouse-manager')->first();
|
||||
if ($whManager) {
|
||||
$whManager->givePermissionTo(['recipes.view']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
$permissions = [
|
||||
'recipes.view',
|
||||
'recipes.create',
|
||||
'recipes.edit',
|
||||
'recipes.delete',
|
||||
];
|
||||
|
||||
foreach ($permissions as $name) {
|
||||
Permission::where('name', $name)->delete();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?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
|
||||
{
|
||||
Schema::table('warehouses', function (Blueprint $table) {
|
||||
$table->boolean('is_sellable')->default(true)->after('description')->comment('是否可銷售');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('warehouses', function (Blueprint $table) {
|
||||
$table->dropColumn('is_sellable');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -13,21 +13,21 @@ class UnitSeeder extends Seeder
|
||||
public function run(): void
|
||||
{
|
||||
$units = [
|
||||
['name' => '個', 'code' => 'pc'],
|
||||
['name' => '箱', 'code' => 'box'],
|
||||
['name' => '瓶', 'code' => 'btl'],
|
||||
['name' => '包', 'code' => 'pkg'],
|
||||
['name' => '公斤', 'code' => 'kg'],
|
||||
['name' => '公克', 'code' => 'g'],
|
||||
['name' => '公升', 'code' => 'l'],
|
||||
['name' => '毫升', 'code' => 'ml'],
|
||||
['name' => '籃', 'code' => 'bsk'],
|
||||
['name' => '桶', 'code' => 'bucket'],
|
||||
['name' => '罐', 'code' => 'can'],
|
||||
['name' => '個', 'code' => 'PCE'], // Piece
|
||||
['name' => '箱', 'code' => 'BX'], // Box
|
||||
['name' => '瓶', 'code' => 'BO'], // Bottle
|
||||
['name' => '包', 'code' => 'PK'], // Package
|
||||
['name' => '公斤', 'code' => 'KGM'], // Kilogram
|
||||
['name' => '公克', 'code' => 'GRM'], // Gram
|
||||
['name' => '公升', 'code' => 'LTR'], // Litre
|
||||
['name' => '毫升', 'code' => 'MLT'], // Millilitre
|
||||
['name' => '籃', 'code' => 'BK'], // Basket
|
||||
['name' => '桶', 'code' => 'BJ'], // Bucket
|
||||
['name' => '罐', 'code' => 'CA'], // Can
|
||||
];
|
||||
|
||||
foreach ($units as $unit) {
|
||||
Unit::firstOrCreate(
|
||||
Unit::updateOrCreate(
|
||||
['name' => $unit['name']],
|
||||
['code' => $unit['code']]
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user