- 바로빌 카드 거래 API (16 엔드포인트): 조회, 분할, 수동입력, 숨김/복원, 금액수정, 분개 - 바로빌 은행 거래 API (13 엔드포인트): 조회, 분할, 오버라이드, 수동입력, 잔액요약, 분개 - 홈택스 세금계산서 API (13 엔드포인트): 매출/매입 조회, 수동입력, 자체분개, 통합분개 - JournalEntry 소스 타입 상수 추가 (barobill_card, barobill_bank, hometax_invoice)
250 lines
8.4 KiB
PHP
250 lines
8.4 KiB
PHP
<?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];
|
|
}
|
|
}
|