269 lines
9.4 KiB
PHP
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);
|
|
}
|
|
}
|