Files
hqland-app/app/Services/ContractScheduleService.php
2026-04-24 08:58:53 +00:00

70 lines
2.2 KiB
PHP

<?php
namespace App\Services;
use App\Models\Contract;
use App\Models\PaymentSchedule;
use App\Models\PaymentScheduleItem;
use App\Models\PaymentTemplate;
use Carbon\Carbon;
class ContractScheduleService
{
/**
* Tạo lịch thanh toán cho hợp đồng dựa trên mẫu.
* Nếu đã tồn tại lịch cũ, sẽ xóa và tạo lại.
*/
public static function generateFromTemplate(Contract $contract, ?PaymentTemplate $template = null): PaymentSchedule
{
if (! $template) {
// Ưu tiên template của dự án
$template = $contract->product?->project?->paymentTemplate;
}
if (! $template) {
throw new \InvalidArgumentException('Không tìm thấy mẫu thanh toán cho hợp đồng này.');
}
// Xóa lịch cũ nếu có
if ($contract->paymentSchedule) {
$contract->paymentSchedule->items()->delete();
$contract->paymentSchedule->delete();
}
$schedule = PaymentSchedule::create([
'contract_id' => $contract->id,
'template_id' => $template->id,
]);
$items = $template->items()->orderBy('installment_no')->get();
$lastDueDate = Carbon::parse($contract->signing_date);
foreach ($items as $item) {
$dueDate = null;
if ($item->days_after_signing !== null) {
$dueDate = Carbon::parse($contract->signing_date)->addDays($item->days_after_signing);
} elseif ($item->days_after_previous !== null) {
$dueDate = $lastDueDate->copy()->addDays($item->days_after_previous);
} elseif ($item->due_date !== null) {
$dueDate = $item->due_date;
}
PaymentScheduleItem::create([
'schedule_id' => $schedule->id,
'installment_no' => $item->installment_no,
'type' => $item->type,
'percentage' => $item->percentage,
'amount' => $contract->total_value * ($item->percentage / 100),
'due_date' => $dueDate,
]);
if ($dueDate) {
$lastDueDate = $dueDate;
}
}
return $schedule;
}
}