All checks were successful
ERP-Deploy-Demo / deploy-demo (push) Successful in 1m5s
86 lines
3.0 KiB
PHP
86 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Modules\Finance\Services;
|
|
|
|
use App\Modules\Finance\Models\AccountPayable;
|
|
use Illuminate\Support\Facades\DB;
|
|
use App\Modules\Inventory\Contracts\GoodsReceiptServiceInterface;
|
|
|
|
class AccountPayableService
|
|
{
|
|
protected GoodsReceiptServiceInterface $goodsReceiptService;
|
|
|
|
public function __construct(GoodsReceiptServiceInterface $goodsReceiptService)
|
|
{
|
|
$this->goodsReceiptService = $goodsReceiptService;
|
|
}
|
|
|
|
/**
|
|
* 根據進貨單建立應付帳款
|
|
*
|
|
* @param int $goodsReceiptId
|
|
* @param int $userId 執行操作的使用者 ID
|
|
* @return AccountPayable
|
|
* @throws \Exception
|
|
*/
|
|
public function createFromGoodsReceipt(int $goodsReceiptId, int $userId): AccountPayable
|
|
{
|
|
// 透過 Contract 取得 Inventory 模組的資料,避免直接依賴 Model
|
|
$receiptData = $this->goodsReceiptService->getGoodsReceiptData($goodsReceiptId);
|
|
|
|
if (!$receiptData) {
|
|
throw new \Exception("找不到對應的進貨單資料 (ID: {$goodsReceiptId})");
|
|
}
|
|
|
|
// 檢查是否已經建立過(密等性)
|
|
$existingAp = AccountPayable::where('source_document_type', 'goods_receipt')
|
|
->where('source_document_id', $goodsReceiptId)
|
|
->first();
|
|
|
|
if ($existingAp) {
|
|
return $existingAp;
|
|
}
|
|
|
|
return DB::transaction(function () use ($receiptData, $userId) {
|
|
$ap = AccountPayable::create([
|
|
'vendor_id' => $receiptData['vendor_id'],
|
|
'source_document_type' => 'goods_receipt',
|
|
'source_document_id' => $receiptData['id'],
|
|
'document_number' => $this->generateApNumber(),
|
|
'total_amount' => collect($receiptData['items'] ?? [])->sum('total_amount'),
|
|
'tax_amount' => 0, // 假設後續會實作稅額計算,目前預設為 0
|
|
'status' => AccountPayable::STATUS_PENDING,
|
|
// 設定應付日期,預設為進貨後天數 (由系統設定決定,預設 30 天)
|
|
'due_date' => now()->addDays(\App\Modules\Core\Models\SystemSetting::getVal('finance.ap_payment_days', 30))->toDateString(),
|
|
'created_by' => $userId,
|
|
'remarks' => "由進貨單 {$receiptData['code']} 自動生成",
|
|
]);
|
|
|
|
return $ap;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 產生應付帳款單號
|
|
*/
|
|
protected function generateApNumber(): string
|
|
{
|
|
$prefix = 'AP-' . date('Ymd') . '-';
|
|
$lastPrefix = "{$prefix}%";
|
|
|
|
$latest = AccountPayable::where('document_number', 'like', $lastPrefix)
|
|
->orderBy('document_number', 'desc')
|
|
->first();
|
|
|
|
if (!$latest) {
|
|
return $prefix . '01';
|
|
}
|
|
|
|
$parts = explode('-', $latest->document_number);
|
|
$lastNumber = intval(end($parts));
|
|
$newNumber = str_pad((string)($lastNumber + 1), 2, '0', STR_PAD_LEFT);
|
|
|
|
return $prefix . $newNumber;
|
|
}
|
|
}
|