refactor(modular): 完成第三與第四階段深層掃描與 Model 清理
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Successful in 1m5s
Koori-ERP-Deploy-System / deploy-production (push) Has been skipped

This commit is contained in:
2026-01-27 09:09:55 +08:00
parent 0e51992cb4
commit 9b0e3b4f6f
4 changed files with 36 additions and 70 deletions

View File

@@ -12,10 +12,20 @@ use App\Modules\Inventory\Models\Product;
use App\Modules\Inventory\Models\Inventory; use App\Modules\Inventory\Models\Inventory;
use App\Modules\Inventory\Models\WarehouseProductSafetyStock; use App\Modules\Inventory\Models\WarehouseProductSafetyStock;
use App\Modules\Core\Contracts\CoreServiceInterface;
class InventoryController extends Controller class InventoryController extends Controller
{ {
protected $coreService;
public function __construct(CoreServiceInterface $coreService)
{
$this->coreService = $coreService;
}
public function index(Request $request, Warehouse $warehouse) public function index(Request $request, Warehouse $warehouse)
{ {
// ... (existing code for index) ...
$warehouse->load([ $warehouse->load([
'inventories.product.category', 'inventories.product.category',
'inventories.product.baseUnit', 'inventories.product.baseUnit',
@@ -118,7 +128,7 @@ class InventoryController extends Controller
public function create(Warehouse $warehouse) public function create(Warehouse $warehouse)
{ {
// 取得所有商品供前端選單使用 // ... (unchanged) ...
$products = Product::with(['baseUnit', 'largeUnit']) $products = Product::with(['baseUnit', 'largeUnit'])
->select('id', 'name', 'code', 'base_unit_id', 'large_unit_id', 'conversion_rate') ->select('id', 'name', 'code', 'base_unit_id', 'large_unit_id', 'conversion_rate')
->get() ->get()
@@ -141,6 +151,7 @@ class InventoryController extends Controller
public function store(Request $request, Warehouse $warehouse) public function store(Request $request, Warehouse $warehouse)
{ {
// ... (unchanged) ...
$validated = $request->validate([ $validated = $request->validate([
'inboundDate' => 'required|date', 'inboundDate' => 'required|date',
'reason' => 'required|string', 'reason' => 'required|string',
@@ -232,9 +243,7 @@ class InventoryController extends Controller
}); });
} }
/** // ... (getBatches unchanged) ...
* API: 取得商品在特定倉庫的所有批號,並回傳當前日期/產地下的一個流水號
*/
public function getBatches(Warehouse $warehouse, $productId, Request $request) public function getBatches(Warehouse $warehouse, $productId, Request $request)
{ {
$originCountry = $request->query('originCountry', 'TW'); $originCountry = $request->query('originCountry', 'TW');
@@ -272,17 +281,21 @@ class InventoryController extends Controller
]); ]);
} }
public function edit(Request $request, Warehouse $warehouse, $inventoryId) public function edit(Request $request, Warehouse $warehouse, $inventoryId)
{ {
// 取得庫存紀錄,包含商品資訊與異動紀錄 (含經手人)
// 這裡如果是 Mock 的 ID (mock-inv-1),需要特殊處理
if (str_starts_with($inventoryId, 'mock-inv-')) { if (str_starts_with($inventoryId, 'mock-inv-')) {
return redirect()->back()->with('error', '無法編輯範例資料'); return redirect()->back()->with('error', '無法編輯範例資料');
} }
// 移除 'transactions.user' 預載入
$inventory = Inventory::with(['product', 'transactions' => function($query) { $inventory = Inventory::with(['product', 'transactions' => function($query) {
$query->orderBy('actual_time', 'desc')->orderBy('id', 'desc'); $query->orderBy('actual_time', 'desc')->orderBy('id', 'desc');
}, 'transactions.user'])->findOrFail($inventoryId); }])->findOrFail($inventoryId);
// 手動 Hydrate 使用者資料
$userIds = $inventory->transactions->pluck('user_id')->filter()->unique()->toArray();
$users = $this->coreService->getUsersByIds($userIds)->keyBy('id');
// 轉換為前端需要的格式 // 轉換為前端需要的格式
$inventoryData = [ $inventoryData = [
@@ -300,7 +313,8 @@ class InventoryController extends Controller
]; ];
// 整理異動紀錄 // 整理異動紀錄
$transactions = $inventory->transactions->map(function ($tx) { $transactions = $inventory->transactions->map(function ($tx) use ($users) {
$user = $tx->user_id ? ($users[$tx->user_id] ?? null) : null;
return [ return [
'id' => (string) $tx->id, 'id' => (string) $tx->id,
'type' => $tx->type, 'type' => $tx->type,
@@ -308,7 +322,7 @@ class InventoryController extends Controller
'unit_cost' => (float) $tx->unit_cost, 'unit_cost' => (float) $tx->unit_cost,
'balanceAfter' => (float) $tx->balance_after, 'balanceAfter' => (float) $tx->balance_after,
'reason' => $tx->reason, 'reason' => $tx->reason,
'userName' => $tx->user ? $tx->user->name : '系統', 'userName' => $user ? $user->name : '系統', // 手動對應
'actualTime' => $tx->actual_time ? $tx->actual_time->format('Y-m-d H:i') : $tx->created_at->format('Y-m-d H:i'), 'actualTime' => $tx->actual_time ? $tx->actual_time->format('Y-m-d H:i') : $tx->created_at->format('Y-m-d H:i'),
]; ];
}); });
@@ -322,9 +336,7 @@ class InventoryController extends Controller
public function update(Request $request, Warehouse $warehouse, $inventoryId) public function update(Request $request, Warehouse $warehouse, $inventoryId)
{ {
// ... (略,後續由服務或在此處更新成本邏輯) ... // ... (unchanged) ...
// 為求簡單,先僅加上驗證與欄位更新
$inventory = Inventory::find($inventoryId); $inventory = Inventory::find($inventoryId);
// 如果找不到 (可能是舊路由傳 product ID) // 如果找不到 (可能是舊路由傳 product ID)
@@ -435,7 +447,8 @@ class InventoryController extends Controller
public function destroy(Warehouse $warehouse, $inventoryId) public function destroy(Warehouse $warehouse, $inventoryId)
{ {
$inventory = Inventory::findOrFail($inventoryId); // ... (unchanged) ...
$inventory = Inventory::findOrFail($inventoryId);
// 庫存 > 0 不允許刪除 (哪怕是軟刪除) // 庫存 > 0 不允許刪除 (哪怕是軟刪除)
if ($inventory->quantity > 0) { if ($inventory->quantity > 0) {
@@ -474,11 +487,17 @@ class InventoryController extends Controller
if ($inventoryId) { if ($inventoryId) {
// 單一批號查詢 // 單一批號查詢
// 移除 'transactions.user'
$inventory = Inventory::with(['product', 'transactions' => function($query) { $inventory = Inventory::with(['product', 'transactions' => function($query) {
$query->orderBy('actual_time', 'desc')->orderBy('id', 'desc'); $query->orderBy('actual_time', 'desc')->orderBy('id', 'desc');
}, 'transactions.user'])->findOrFail($inventoryId); }])->findOrFail($inventoryId);
$transactions = $inventory->transactions->map(function ($tx) { // 手動 Hydrate 使用者資料
$userIds = $inventory->transactions->pluck('user_id')->filter()->unique()->toArray();
$users = $this->coreService->getUsersByIds($userIds)->keyBy('id');
$transactions = $inventory->transactions->map(function ($tx) use ($users) {
$user = $tx->user_id ? ($users[$tx->user_id] ?? null) : null;
return [ return [
'id' => (string) $tx->id, 'id' => (string) $tx->id,
'type' => $tx->type, 'type' => $tx->type,
@@ -486,7 +505,7 @@ class InventoryController extends Controller
'unit_cost' => (float) $tx->unit_cost, 'unit_cost' => (float) $tx->unit_cost,
'balanceAfter' => (float) $tx->balance_after, 'balanceAfter' => (float) $tx->balance_after,
'reason' => $tx->reason, 'reason' => $tx->reason,
'userName' => $tx->user ? $tx->user->name : '系統', 'userName' => $user ? $user->name : '系統', // 手動對應
'actualTime' => $tx->actual_time ? $tx->actual_time->format('Y-m-d H:i') : $tx->created_at->format('Y-m-d H:i'), 'actualTime' => $tx->actual_time ? $tx->actual_time->format('Y-m-d H:i') : $tx->created_at->format('Y-m-d H:i'),
]; ];
}); });

View File

@@ -4,7 +4,7 @@ namespace App\Modules\Inventory\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use App\Modules\Core\Models\User; // 跨模組核心依賴
class InventoryTransaction extends Model class InventoryTransaction extends Model
{ {
@@ -35,11 +35,6 @@ class InventoryTransaction extends Model
return $this->belongsTo(Inventory::class); return $this->belongsTo(Inventory::class);
} }
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(User::class);
}
public function reference(): \Illuminate\Database\Eloquent\Relations\MorphTo public function reference(): \Illuminate\Database\Eloquent\Relations\MorphTo
{ {
return $this->morphTo(); return $this->morphTo();

View File

@@ -70,30 +70,6 @@ class ProductionOrder extends Model
return $prefix . $sequence; return $prefix . $sequence;
} }
/**
* @deprecated 使用 InventoryServiceInterface 獲取產品資訊
*/
public function product()
{
return null;
}
/**
* @deprecated 使用 InventoryServiceInterface 獲取倉庫資訊
*/
public function warehouse()
{
return null;
}
/**
* @deprecated 使用 CoreServiceInterface 獲取使用者資訊
*/
public function user()
{
return null;
}
public function items(): \Illuminate\Database\Eloquent\Relations\HasMany public function items(): \Illuminate\Database\Eloquent\Relations\HasMany
{ {
return $this->hasMany(ProductionOrderItem::class); return $this->hasMany(ProductionOrderItem::class);

View File

@@ -22,32 +22,8 @@ class ProductionOrderItem extends Model
'quantity_used' => 'decimal:4', 'quantity_used' => 'decimal:4',
]; ];
/**
* @deprecated 使用 InventoryServiceInterface 獲取庫存資訊
*/
public function inventory()
{
return null;
}
/**
* @deprecated
*/
public function unit()
{
return null;
}
public function productionOrder(): \Illuminate\Database\Eloquent\Relations\BelongsTo public function productionOrder(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{ {
return $this->belongsTo(ProductionOrder::class); return $this->belongsTo(ProductionOrder::class);
} }
/**
* @deprecated 使用 InventoryServiceInterface 獲取產品資訊
*/
public function product()
{
return null;
}
} }