70 lines
2.2 KiB
PHP
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;
|
|
}
|
|
}
|