Files
sam-manage/app/Http/Controllers/Api/Admin/Barobill/BarobillUsageController.php
2026-02-25 11:45:01 +09:00

269 lines
9.4 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Admin\Barobill;
use App\Http\Controllers\Controller;
use App\Models\Barobill\BarobillMember;
use App\Services\Barobill\BarobillUsageService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
/**
* 바로빌 사용량조회 API 컨트롤러
*/
class BarobillUsageController extends Controller
{
// 바로빌 파트너사 (본사) 테넌트 ID
private const HEADQUARTERS_TENANT_ID = 1;
public function __construct(
protected BarobillUsageService $usageService
) {}
/**
* 사용량 목록 조회
*
* @param start_date string 시작일 (YYYY-MM-DD)
* @param end_date string 종료일 (YYYY-MM-DD)
* @param all_tenants bool 전체 테넌트 조회 (본사용)
*/
public function index(Request $request): JsonResponse|Response
{
$tenantId = session('selected_tenant_id');
$allTenants = $request->boolean('all_tenants', false);
$isHeadquarters = $tenantId == self::HEADQUARTERS_TENANT_ID;
// 날짜 파라미터 (기본: 이번 달)
$startDate = $request->input('start_date', now()->startOfMonth()->format('Y-m-d'));
$endDate = $request->input('end_date', now()->format('Y-m-d'));
// 바로빌 API 형식으로 변환 (YYYYMMDD)
$apiStartDate = str_replace('-', '', $startDate);
$apiEndDate = str_replace('-', '', $endDate);
// 테넌트 필터링
$filterTenantId = (! $isHeadquarters && ! $allTenants && $tenantId) ? $tenantId : null;
// 사용량 목록 조회
$usageList = $this->usageService->getUsageList($apiStartDate, $apiEndDate, $filterTenantId);
// 통계 집계
$stats = $this->usageService->aggregateStats($usageList);
// 합계 행 추가
$totalRow = [
'member_id' => null,
'tenant_id' => null,
'tenant_name' => '합계',
'biz_no' => '',
'formatted_biz_no' => '',
'corp_name' => '',
'barobill_id' => '',
'tax_invoice_count' => $stats['total_tax_invoice'],
'bank_account_count' => $stats['total_bank_account'],
'card_count' => $stats['total_card'],
'hometax_count' => $stats['total_hometax'],
'total_amount' => $stats['total_amount'],
'is_total_row' => true,
];
// 본사이거나 전체 테넌트 모드면 테넌트 컬럼 표시
$showAllTenants = $isHeadquarters || $allTenants;
// HTMX 요청 시 HTML 반환
if ($request->header('HX-Request')) {
return response(
view('barobill.usage.partials.table', [
'usageList' => $usageList,
'totalRow' => $totalRow,
'allTenants' => $showAllTenants,
'startDate' => $startDate,
'endDate' => $endDate,
])->render(),
200,
['Content-Type' => 'text/html']
);
}
return response()->json([
'success' => true,
'data' => $usageList,
'total' => $totalRow,
'meta' => [
'start_date' => $startDate,
'end_date' => $endDate,
'all_tenants' => $showAllTenants,
],
]);
}
/**
* 통계 카드 데이터 조회
*/
public function stats(Request $request): JsonResponse|Response
{
$tenantId = session('selected_tenant_id');
$allTenants = $request->boolean('all_tenants', false);
$isHeadquarters = $tenantId == self::HEADQUARTERS_TENANT_ID;
// 날짜 파라미터
$startDate = $request->input('start_date', now()->startOfMonth()->format('Y-m-d'));
$endDate = $request->input('end_date', now()->format('Y-m-d'));
// 바로빌 API 형식으로 변환
$apiStartDate = str_replace('-', '', $startDate);
$apiEndDate = str_replace('-', '', $endDate);
// 테넌트 필터링
$filterTenantId = (! $isHeadquarters && ! $allTenants && $tenantId) ? $tenantId : null;
// 사용량 목록 조회 및 통계 집계
$usageList = $this->usageService->getUsageList($apiStartDate, $apiEndDate, $filterTenantId);
$stats = $this->usageService->aggregateStats($usageList);
// HTMX 요청 시 HTML 반환
if ($request->header('HX-Request')) {
return response(
view('barobill.usage.partials.stats', compact('stats'))->render(),
200,
['Content-Type' => 'text/html']
);
}
return response()->json([
'success' => true,
'data' => $stats,
]);
}
/**
* 단일 회원사 상세 사용량 조회
*/
public function show(Request $request, int $memberId): JsonResponse|Response
{
$member = BarobillMember::with('tenant:id,company_name')->find($memberId);
if (! $member) {
return response()->json([
'success' => false,
'message' => '회원사를 찾을 수 없습니다.',
], 404);
}
// 날짜 파라미터
$startDate = $request->input('start_date', now()->startOfMonth()->format('Y-m-d'));
$endDate = $request->input('end_date', now()->format('Y-m-d'));
// 바로빌 API 형식으로 변환
$apiStartDate = str_replace('-', '', $startDate);
$apiEndDate = str_replace('-', '', $endDate);
// 사용량 조회
$usage = $this->usageService->getMemberUsage($member, $apiStartDate, $apiEndDate);
// 서비스별 단가 정보
$priceInfo = BarobillUsageService::getPriceInfo();
// HTMX 요청 시 모달 HTML 반환
if ($request->header('HX-Request')) {
return response(
view('barobill.usage.partials.detail-modal', [
'member' => $member,
'usage' => $usage,
'priceInfo' => $priceInfo,
'startDate' => $startDate,
'endDate' => $endDate,
])->render(),
200,
['Content-Type' => 'text/html']
);
}
return response()->json([
'success' => true,
'data' => [
'member' => $member,
'usage' => $usage,
'price_info' => $priceInfo,
],
]);
}
/**
* 엑셀 다운로드
*/
public function export(Request $request)
{
$tenantId = session('selected_tenant_id');
$allTenants = $request->boolean('all_tenants', false);
$isHeadquarters = $tenantId == self::HEADQUARTERS_TENANT_ID;
// 날짜 파라미터
$startDate = $request->input('start_date', now()->startOfMonth()->format('Y-m-d'));
$endDate = $request->input('end_date', now()->format('Y-m-d'));
// 바로빌 API 형식으로 변환
$apiStartDate = str_replace('-', '', $startDate);
$apiEndDate = str_replace('-', '', $endDate);
// 테넌트 필터링
$filterTenantId = (! $isHeadquarters && ! $allTenants && $tenantId) ? $tenantId : null;
// 사용량 목록 조회
$usageList = $this->usageService->getUsageList($apiStartDate, $apiEndDate, $filterTenantId);
$stats = $this->usageService->aggregateStats($usageList);
// CSV 생성
$filename = "barobill_usage_{$startDate}_{$endDate}.csv";
$headers = [
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Disposition' => "attachment; filename=\"{$filename}\"",
];
$callback = function () use ($usageList, $stats, $isHeadquarters, $allTenants) {
$file = fopen('php://output', 'w');
// BOM for Excel UTF-8
fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));
// 헤더
$headerRow = ['사업자번호', '상호', '바로빌ID', '세금계산서(건)', '계좌조회(건)', '카드내역(건)', '홈텍스(건)', '과금액(원)'];
if ($isHeadquarters || $allTenants) {
array_unshift($headerRow, 'T-ID', '테넌트');
}
fputcsv($file, $headerRow);
// 데이터
foreach ($usageList as $usage) {
$row = [
$usage['formatted_biz_no'],
$usage['corp_name'],
$usage['barobill_id'],
$usage['tax_invoice_count'],
$usage['bank_account_count'],
$usage['card_count'],
$usage['hometax_count'],
$usage['total_amount'],
];
if ($isHeadquarters || $allTenants) {
array_unshift($row, $usage['tenant_id'], $usage['tenant_name']);
}
fputcsv($file, $row);
}
// 합계
$totalRow = ['', '', '합계', $stats['total_tax_invoice'], $stats['total_bank_account'], $stats['total_card'], $stats['total_hometax'], $stats['total_amount']];
if ($isHeadquarters || $allTenants) {
array_unshift($totalRow, '', '');
}
fputcsv($file, $totalRow);
fclose($file);
};
return response()->stream($callback, 200, $headers);
}
}