- BarobillBillingService 생성 (구독 CRUD, 월별 과금 배치, 사용량 과금, 집계) - BarobillUsageService 생성 (회원별 사용량 조회, 통계, 정책 기반 과금 계산) - BarobillBillingController 생성 (9개 엔드포인트) - 구독 관리, 월별 현황, 과금 배치, 연간 추이, 정책 관리 - BarobillUsageController 생성 (4개 엔드포인트) - 사용량 목록/통계, 회원별 상세, 과금 정책 정보 - finance.php 라우트 등록 (barobill/billing/*, barobill/usage/*)
164 lines
5.3 KiB
PHP
164 lines
5.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Barobill;
|
|
|
|
use App\Models\Barobill\BarobillBankTransaction;
|
|
use App\Models\Barobill\BarobillCardTransaction;
|
|
use App\Models\Barobill\BarobillMember;
|
|
use App\Models\Barobill\BarobillPricingPolicy;
|
|
use App\Models\Barobill\HometaxInvoice;
|
|
use App\Services\Service;
|
|
|
|
class BarobillUsageService extends Service
|
|
{
|
|
/**
|
|
* 전체 회원사 사용량 목록
|
|
*/
|
|
public function getUsageList(string $startDate, string $endDate, ?int $tenantId = null): array
|
|
{
|
|
$query = BarobillMember::withoutGlobalScopes()
|
|
->where('status', 'active');
|
|
|
|
if ($tenantId) {
|
|
$query->where('tenant_id', $tenantId);
|
|
}
|
|
|
|
$members = $query->get();
|
|
$usageList = [];
|
|
|
|
foreach ($members as $member) {
|
|
$usageList[] = $this->getMemberUsage($member, $startDate, $endDate);
|
|
}
|
|
|
|
return $usageList;
|
|
}
|
|
|
|
/**
|
|
* 단일 회원사 사용량 상세
|
|
*/
|
|
public function getMemberUsage(BarobillMember $member, string $startDate, string $endDate): array
|
|
{
|
|
$taxInvoiceCount = $this->getTaxInvoiceCount($member, $startDate, $endDate);
|
|
$bankAccountCount = $this->getBankAccountCount($member);
|
|
$cardCount = $this->getCardCount($member);
|
|
$hometaxCount = $this->getHometaxCount($member, $startDate, $endDate);
|
|
|
|
$taxInvoiceBilling = $this->calculateBillingByPolicy('tax_invoice', $taxInvoiceCount);
|
|
|
|
return [
|
|
'member_id' => $member->id,
|
|
'tenant_id' => $member->tenant_id,
|
|
'biz_no' => $member->biz_no,
|
|
'corp_name' => $member->corp_name,
|
|
'barobill_id' => $member->barobill_id,
|
|
'server_mode' => $member->server_mode ?? 'test',
|
|
'tax_invoice_count' => $taxInvoiceCount,
|
|
'bank_account_count' => $bankAccountCount,
|
|
'card_count' => $cardCount,
|
|
'hometax_count' => $hometaxCount,
|
|
'tax_invoice_billing' => $taxInvoiceBilling,
|
|
'total_amount' => $taxInvoiceBilling['billable_amount'] ?? 0,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 사용량 통계 집계
|
|
*/
|
|
public function aggregateStats(array $usageList): array
|
|
{
|
|
$stats = [
|
|
'total_members' => count($usageList),
|
|
'total_tax_invoice_count' => 0,
|
|
'total_bank_account_count' => 0,
|
|
'total_card_count' => 0,
|
|
'total_hometax_count' => 0,
|
|
'total_amount' => 0,
|
|
];
|
|
|
|
foreach ($usageList as $usage) {
|
|
$stats['total_tax_invoice_count'] += $usage['tax_invoice_count'];
|
|
$stats['total_bank_account_count'] += $usage['bank_account_count'];
|
|
$stats['total_card_count'] += $usage['card_count'];
|
|
$stats['total_hometax_count'] += $usage['hometax_count'];
|
|
$stats['total_amount'] += $usage['total_amount'];
|
|
}
|
|
|
|
return $stats;
|
|
}
|
|
|
|
/**
|
|
* 과금 정책 정보
|
|
*/
|
|
public static function getPriceInfo(): array
|
|
{
|
|
$policies = BarobillPricingPolicy::withoutGlobalScopes()
|
|
->where('is_active', true)
|
|
->orderBy('sort_order')
|
|
->get();
|
|
|
|
$info = [];
|
|
foreach ($policies as $policy) {
|
|
$info[$policy->service_type] = [
|
|
'name' => $policy->name,
|
|
'free_quota' => $policy->free_quota,
|
|
'free_quota_unit' => $policy->free_quota_unit,
|
|
'additional_unit' => $policy->additional_unit,
|
|
'additional_unit_label' => $policy->additional_unit_label,
|
|
'additional_price' => $policy->additional_price,
|
|
];
|
|
}
|
|
|
|
return $info;
|
|
}
|
|
|
|
/**
|
|
* 정책 기반 과금액 계산
|
|
*/
|
|
public static function calculateBillingByPolicy(string $serviceType, int $usageCount): array
|
|
{
|
|
$policy = BarobillPricingPolicy::withoutGlobalScopes()
|
|
->where('service_type', $serviceType)
|
|
->where('is_active', true)
|
|
->first();
|
|
|
|
if (! $policy) {
|
|
return ['free_count' => $usageCount, 'billable_count' => 0, 'billable_amount' => 0];
|
|
}
|
|
|
|
return $policy->calculateBilling($usageCount);
|
|
}
|
|
|
|
protected function getTaxInvoiceCount(BarobillMember $member, string $startDate, string $endDate): int
|
|
{
|
|
return HometaxInvoice::withoutGlobalScopes()
|
|
->where('tenant_id', $member->tenant_id)
|
|
->where('invoice_type', 'sales')
|
|
->whereBetween('write_date', [$startDate, $endDate])
|
|
->count();
|
|
}
|
|
|
|
protected function getBankAccountCount(BarobillMember $member): int
|
|
{
|
|
return BarobillBankTransaction::withoutGlobalScopes()
|
|
->where('tenant_id', $member->tenant_id)
|
|
->distinct('bank_account_num')
|
|
->count('bank_account_num');
|
|
}
|
|
|
|
protected function getCardCount(BarobillMember $member): int
|
|
{
|
|
return BarobillCardTransaction::withoutGlobalScopes()
|
|
->where('tenant_id', $member->tenant_id)
|
|
->distinct('card_num')
|
|
->count('card_num');
|
|
}
|
|
|
|
protected function getHometaxCount(BarobillMember $member, string $startDate, string $endDate): int
|
|
{
|
|
return HometaxInvoice::withoutGlobalScopes()
|
|
->where('tenant_id', $member->tenant_id)
|
|
->whereBetween('write_date', [$startDate, $endDate])
|
|
->count();
|
|
}
|
|
}
|