170 lines
4.7 KiB
PHP
170 lines
4.7 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Observers\ExpenseSync;
|
||
|
|
|
||
|
|
use App\Models\Tenants\Bill;
|
||
|
|
use App\Models\Tenants\ExpectedExpense;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 발행어음 데이터를 예상 지출(expected_expenses)로 자동 동기화
|
||
|
|
* (bill_type = 'issued' 인 경우만)
|
||
|
|
*/
|
||
|
|
class BillExpenseSyncObserver
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* 어음 생성 시 → 발행어음인 경우 예상 지출 생성
|
||
|
|
*/
|
||
|
|
public function created(Bill $bill): void
|
||
|
|
{
|
||
|
|
if ($this->isIssuedBill($bill)) {
|
||
|
|
$this->syncToExpectedExpense($bill);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 어음 수정 시 → 발행어음 상태 변경 처리
|
||
|
|
*/
|
||
|
|
public function updated(Bill $bill): void
|
||
|
|
{
|
||
|
|
$wasIssued = $bill->getOriginal('bill_type') === 'issued';
|
||
|
|
$isIssued = $this->isIssuedBill($bill);
|
||
|
|
|
||
|
|
if ($isIssued) {
|
||
|
|
// 발행어음 → 동기화
|
||
|
|
$this->syncToExpectedExpense($bill);
|
||
|
|
} elseif ($wasIssued && ! $isIssued) {
|
||
|
|
// 발행어음에서 수취어음으로 변경 → 예상 지출 삭제
|
||
|
|
$this->deleteExpectedExpense($bill);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 어음 삭제 시 → 예상 지출 삭제
|
||
|
|
*/
|
||
|
|
public function deleted(Bill $bill): void
|
||
|
|
{
|
||
|
|
if ($this->isIssuedBill($bill)) {
|
||
|
|
$this->deleteExpectedExpense($bill);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 어음 복원 시 → 발행어음인 경우 예상 지출 복원
|
||
|
|
*/
|
||
|
|
public function restored(Bill $bill): void
|
||
|
|
{
|
||
|
|
if (! $this->isIssuedBill($bill)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
$expense = ExpectedExpense::withTrashed()
|
||
|
|
->withoutGlobalScopes()
|
||
|
|
->bySource('bills', $bill->id)
|
||
|
|
->first();
|
||
|
|
|
||
|
|
if ($expense) {
|
||
|
|
$expense->restore();
|
||
|
|
$this->updateExpectedExpense($expense, $bill);
|
||
|
|
} else {
|
||
|
|
$this->createExpectedExpense($bill);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 어음 강제 삭제 시 → 예상 지출 강제 삭제
|
||
|
|
*/
|
||
|
|
public function forceDeleted(Bill $bill): void
|
||
|
|
{
|
||
|
|
ExpectedExpense::withTrashed()
|
||
|
|
->withoutGlobalScopes()
|
||
|
|
->bySource('bills', $bill->id)
|
||
|
|
->forceDelete();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 발행어음 여부 확인
|
||
|
|
*/
|
||
|
|
protected function isIssuedBill(Bill $bill): bool
|
||
|
|
{
|
||
|
|
return $bill->bill_type === 'issued';
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 예상 지출에 동기화
|
||
|
|
*/
|
||
|
|
protected function syncToExpectedExpense(Bill $bill): void
|
||
|
|
{
|
||
|
|
$expense = ExpectedExpense::withoutGlobalScopes()
|
||
|
|
->bySource('bills', $bill->id)
|
||
|
|
->first();
|
||
|
|
|
||
|
|
if ($expense) {
|
||
|
|
$this->updateExpectedExpense($expense, $bill);
|
||
|
|
} else {
|
||
|
|
$this->createExpectedExpense($bill);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 예상 지출 삭제
|
||
|
|
*/
|
||
|
|
protected function deleteExpectedExpense(Bill $bill): void
|
||
|
|
{
|
||
|
|
ExpectedExpense::withoutGlobalScopes()
|
||
|
|
->bySource('bills', $bill->id)
|
||
|
|
->delete();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 어음 상태 → 지급상태 매핑
|
||
|
|
*/
|
||
|
|
protected function mapPaymentStatus(string $billStatus): string
|
||
|
|
{
|
||
|
|
return match ($billStatus) {
|
||
|
|
'paymentComplete', 'collectionComplete' => 'paid',
|
||
|
|
'dishonored' => 'overdue',
|
||
|
|
default => 'pending',
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 예상 지출 생성
|
||
|
|
*/
|
||
|
|
protected function createExpectedExpense(Bill $bill): void
|
||
|
|
{
|
||
|
|
ExpectedExpense::create([
|
||
|
|
'tenant_id' => $bill->tenant_id,
|
||
|
|
'expected_payment_date' => $bill->maturity_date, // 만기일을 예상 지급일로
|
||
|
|
'transaction_type' => 'bill',
|
||
|
|
'amount' => $bill->amount,
|
||
|
|
'client_id' => $bill->client_id,
|
||
|
|
'client_name' => $bill->client_name,
|
||
|
|
'bank_account_id' => $bill->bank_account_id,
|
||
|
|
'description' => $bill->note ?? "어음번호: {$bill->bill_number}",
|
||
|
|
'payment_status' => $this->mapPaymentStatus($bill->status),
|
||
|
|
'approval_status' => 'none',
|
||
|
|
'source_type' => 'bills',
|
||
|
|
'source_id' => $bill->id,
|
||
|
|
'created_by' => $bill->created_by,
|
||
|
|
'updated_by' => $bill->updated_by,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 예상 지출 업데이트
|
||
|
|
*/
|
||
|
|
protected function updateExpectedExpense(ExpectedExpense $expense, Bill $bill): void
|
||
|
|
{
|
||
|
|
$expense->update([
|
||
|
|
'expected_payment_date' => $bill->maturity_date,
|
||
|
|
'amount' => $bill->amount,
|
||
|
|
'client_id' => $bill->client_id,
|
||
|
|
'client_name' => $bill->client_name,
|
||
|
|
'bank_account_id' => $bill->bank_account_id,
|
||
|
|
'description' => $bill->note ?? "어음번호: {$bill->bill_number}",
|
||
|
|
'payment_status' => $this->mapPaymentStatus($bill->status),
|
||
|
|
'updated_by' => $bill->updated_by,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
}
|