Files
sam-api/app/Services/BarobillBankTransactionService.php

250 lines
8.4 KiB
PHP
Raw Normal View History

<?php
namespace App\Services;
use App\Models\Barobill\BarobillBankTransaction;
use App\Models\Barobill\BarobillBankTransactionOverride;
use App\Models\Barobill\BarobillBankTransactionSplit;
use Illuminate\Support\Facades\DB;
/**
* 바로빌 은행 거래 서비스 (React 연동용)
*
* MNG에서 동기화된 barobill_bank_transactions 데이터를
* React 프론트엔드에서 조회/분개/수정 처리
*/
class BarobillBankTransactionService extends Service
{
/**
* 은행 거래 목록 조회 (기간별, 계좌번호별)
*/
public function index(array $params): array
{
$tenantId = $this->tenantId();
$startDate = $params['start_date'] ?? now()->startOfMonth()->format('Y-m-d');
$endDate = $params['end_date'] ?? now()->format('Y-m-d');
$accountNum = $params['bank_account_num'] ?? null;
$search = $params['search'] ?? null;
$perPage = $params['per_page'] ?? 50;
$query = BarobillBankTransaction::where('tenant_id', $tenantId)
->whereBetween('trans_date', [$startDate, $endDate]);
if ($accountNum) {
$query->where('bank_account_num', $accountNum);
}
if ($search) {
$query->where(function ($q) use ($search) {
$q->where('summary', 'like', "%{$search}%")
->orWhere('memo', 'like', "%{$search}%")
->orWhere('client_name', 'like', "%{$search}%");
});
}
$query->orderByDesc('trans_date')->orderByDesc('trans_dt');
$transactions = $query->paginate($perPage);
// 분할/오버라이드 정보 로드
$uniqueKeys = $transactions->getCollection()->map->unique_key->toArray();
$splits = BarobillBankTransactionSplit::where('tenant_id', $tenantId)
->whereIn('original_unique_key', $uniqueKeys)
->orderBy('sort_order')
->get()
->groupBy('original_unique_key');
$overrides = BarobillBankTransactionOverride::getByUniqueKeys($tenantId, $uniqueKeys);
$transactions->getCollection()->transform(function ($tx) use ($splits, $overrides) {
$tx->splits = $splits->get($tx->unique_key, collect());
$tx->has_splits = $tx->splits->isNotEmpty();
$tx->override = $overrides->get($tx->unique_key);
return $tx;
});
return [
'data' => $transactions,
];
}
/**
* 계좌 목록 (필터용)
*/
public function accounts(): array
{
$tenantId = $this->tenantId();
$accounts = BarobillBankTransaction::where('tenant_id', $tenantId)
->select('bank_account_num', 'bank_name')
->distinct()
->orderBy('bank_account_num')
->get();
return ['items' => $accounts];
}
/**
* 거래 분할 조회
*/
public function getSplits(string $uniqueKey): array
{
$tenantId = $this->tenantId();
$splits = BarobillBankTransactionSplit::getByUniqueKey($tenantId, $uniqueKey);
return ['items' => $splits];
}
/**
* 거래 분할 저장
*/
public function saveSplits(string $uniqueKey, array $items): array
{
$tenantId = $this->tenantId();
return DB::transaction(function () use ($tenantId, $uniqueKey, $items) {
BarobillBankTransactionSplit::where('tenant_id', $tenantId)
->where('original_unique_key', $uniqueKey)
->delete();
$created = [];
foreach ($items as $index => $item) {
$created[] = BarobillBankTransactionSplit::create([
'tenant_id' => $tenantId,
'original_unique_key' => $uniqueKey,
'split_amount' => $item['split_amount'],
'account_code' => $item['account_code'] ?? null,
'account_name' => $item['account_name'] ?? null,
'deduction_type' => $item['deduction_type'] ?? null,
'evidence_name' => $item['evidence_name'] ?? null,
'description' => $item['description'] ?? null,
'memo' => $item['memo'] ?? null,
'sort_order' => $index + 1,
'bank_account_num' => $item['bank_account_num'] ?? null,
'trans_dt' => $item['trans_dt'] ?? null,
'trans_date' => $item['trans_date'] ?? null,
'original_deposit' => $item['original_deposit'] ?? 0,
'original_withdraw' => $item['original_withdraw'] ?? 0,
'summary' => $item['summary'] ?? null,
]);
}
return ['items' => $created, 'count' => count($created)];
});
}
/**
* 거래 분할 삭제
*/
public function deleteSplits(string $uniqueKey): array
{
$tenantId = $this->tenantId();
$deleted = BarobillBankTransactionSplit::where('tenant_id', $tenantId)
->where('original_unique_key', $uniqueKey)
->delete();
return ['deleted_count' => $deleted];
}
/**
* 적요/분류 오버라이드 저장
*/
public function saveOverride(string $uniqueKey, ?string $modifiedSummary, ?string $modifiedCast): BarobillBankTransactionOverride
{
$tenantId = $this->tenantId();
return BarobillBankTransactionOverride::saveOverride($tenantId, $uniqueKey, $modifiedSummary, $modifiedCast);
}
/**
* 수동 은행 거래 등록
*/
public function storeManual(array $data): BarobillBankTransaction
{
$tenantId = $this->tenantId();
return BarobillBankTransaction::create([
'tenant_id' => $tenantId,
'bank_account_num' => $data['bank_account_num'],
'bank_code' => $data['bank_code'] ?? null,
'bank_name' => $data['bank_name'] ?? null,
'trans_date' => $data['trans_date'],
'trans_time' => $data['trans_time'] ?? null,
'trans_dt' => $data['trans_dt'] ?? $data['trans_date'].($data['trans_time'] ?? '000000'),
'deposit' => $data['deposit'] ?? 0,
'withdraw' => $data['withdraw'] ?? 0,
'balance' => $data['balance'] ?? 0,
'summary' => $data['summary'] ?? null,
'cast' => $data['cast'] ?? null,
'memo' => $data['memo'] ?? null,
'trans_office' => $data['trans_office'] ?? null,
'account_code' => $data['account_code'] ?? null,
'account_name' => $data['account_name'] ?? null,
'client_code' => $data['client_code'] ?? null,
'client_name' => $data['client_name'] ?? null,
'is_manual' => true,
]);
}
/**
* 수동 은행 거래 수정
*/
public function updateManual(int $id, array $data): BarobillBankTransaction
{
$tx = BarobillBankTransaction::where('tenant_id', $this->tenantId())
->where('is_manual', true)
->findOrFail($id);
$tx->update($data);
return $tx->fresh();
}
/**
* 수동 은행 거래 삭제
*/
public function destroyManual(int $id): bool
{
$tx = BarobillBankTransaction::where('tenant_id', $this->tenantId())
->where('is_manual', true)
->findOrFail($id);
return $tx->delete();
}
/**
* 잔액 요약
*/
public function balanceSummary(array $params): array
{
$tenantId = $this->tenantId();
$date = $params['date'] ?? now()->format('Y-m-d');
$accounts = BarobillBankTransaction::where('tenant_id', $tenantId)
->select('bank_account_num', 'bank_name')
->distinct()
->get();
$summary = [];
foreach ($accounts as $account) {
$lastTx = BarobillBankTransaction::where('tenant_id', $tenantId)
->where('bank_account_num', $account->bank_account_num)
->where('trans_date', '<=', $date)
->orderByDesc('trans_date')
->orderByDesc('trans_dt')
->first();
$summary[] = [
'bank_account_num' => $account->bank_account_num,
'bank_name' => $account->bank_name,
'balance' => $lastTx ? $lastTx->balance : 0,
'last_trans_date' => $lastTx?->trans_date,
];
}
return ['items' => $summary];
}
}