feat: 實作出貨單模組並暫時導向通用製作中頁面,同步優化盤點與調撥功能的活動日誌顯示
This commit is contained in:
118
app/Modules/Procurement/Services/ShippingService.php
Normal file
118
app/Modules/Procurement/Services/ShippingService.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modules\Procurement\Services;
|
||||
|
||||
use App\Modules\Procurement\Models\ShippingOrder;
|
||||
use App\Modules\Procurement\Models\ShippingOrderItem;
|
||||
use App\Modules\Inventory\Contracts\InventoryServiceInterface;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ShippingService
|
||||
{
|
||||
protected $inventoryService;
|
||||
|
||||
public function __construct(InventoryServiceInterface $inventoryService)
|
||||
{
|
||||
$this->inventoryService = $inventoryService;
|
||||
}
|
||||
|
||||
public function createShippingOrder(array $data)
|
||||
{
|
||||
return DB::transaction(function () use ($data) {
|
||||
$order = ShippingOrder::create([
|
||||
'warehouse_id' => $data['warehouse_id'],
|
||||
'customer_name' => $data['customer_name'] ?? null,
|
||||
'shipping_date' => $data['shipping_date'],
|
||||
'status' => 'draft',
|
||||
'remarks' => $data['remarks'] ?? null,
|
||||
'created_by' => auth()->id(),
|
||||
'total_amount' => $data['total_amount'] ?? 0,
|
||||
'tax_amount' => $data['tax_amount'] ?? 0,
|
||||
'grand_total' => $data['grand_total'] ?? 0,
|
||||
]);
|
||||
|
||||
foreach ($data['items'] as $item) {
|
||||
$order->items()->create([
|
||||
'product_id' => $item['product_id'],
|
||||
'batch_number' => $item['batch_number'] ?? null,
|
||||
'quantity' => $item['quantity'],
|
||||
'unit_price' => $item['unit_price'] ?? 0,
|
||||
'subtotal' => $item['subtotal'] ?? ($item['quantity'] * ($item['unit_price'] ?? 0)),
|
||||
'remark' => $item['remark'] ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
return $order;
|
||||
});
|
||||
}
|
||||
|
||||
public function updateShippingOrder(ShippingOrder $order, array $data)
|
||||
{
|
||||
return DB::transaction(function () use ($order, $data) {
|
||||
$order->update([
|
||||
'warehouse_id' => $data['warehouse_id'],
|
||||
'customer_name' => $data['customer_name'] ?? null,
|
||||
'shipping_date' => $data['shipping_date'],
|
||||
'remarks' => $data['remarks'] ?? null,
|
||||
'total_amount' => $data['total_amount'] ?? 0,
|
||||
'tax_amount' => $data['tax_amount'] ?? 0,
|
||||
'grand_total' => $data['grand_total'] ?? 0,
|
||||
]);
|
||||
|
||||
// 簡單處理:刪除舊項目並新增
|
||||
$order->items()->delete();
|
||||
foreach ($data['items'] as $item) {
|
||||
$order->items()->create([
|
||||
'product_id' => $item['product_id'],
|
||||
'batch_number' => $item['batch_number'] ?? null,
|
||||
'quantity' => $item['quantity'],
|
||||
'unit_price' => $item['unit_price'] ?? 0,
|
||||
'subtotal' => $item['subtotal'] ?? ($item['quantity'] * ($item['unit_price'] ?? 0)),
|
||||
'remark' => $item['remark'] ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
return $order;
|
||||
});
|
||||
}
|
||||
|
||||
public function post(ShippingOrder $order)
|
||||
{
|
||||
if ($order->status !== 'draft') {
|
||||
throw new \Exception('該單據已過帳或已取消。');
|
||||
}
|
||||
|
||||
return DB::transaction(function () use ($order) {
|
||||
foreach ($order->items as $item) {
|
||||
// 尋找對應的庫存紀錄
|
||||
$inventory = $this->inventoryService->findInventoryByBatch(
|
||||
$order->warehouse_id,
|
||||
$item->product_id,
|
||||
$item->batch_number
|
||||
);
|
||||
|
||||
if (!$inventory || $inventory->quantity < $item->quantity) {
|
||||
$productName = $this->inventoryService->getProduct($item->product_id)?->name ?? 'Unknown';
|
||||
throw new \Exception("商品 [{$productName}] (批號: {$item->batch_number}) 庫存不足。");
|
||||
}
|
||||
|
||||
// 扣除庫存
|
||||
$this->inventoryService->decreaseInventoryQuantity(
|
||||
$inventory->id,
|
||||
$item->quantity,
|
||||
"出貨扣款: 單號 [{$order->doc_no}]",
|
||||
'ShippingOrder',
|
||||
$order->id
|
||||
);
|
||||
}
|
||||
|
||||
$order->update([
|
||||
'status' => 'completed',
|
||||
'posted_by' => auth()->id(),
|
||||
'posted_at' => now(),
|
||||
]);
|
||||
|
||||
return $order;
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user