feat: [barobill] 구독/과금/사용량 관리 API 이관
- BarobillBillingService 생성 (구독 CRUD, 월별 과금 배치, 사용량 과금, 집계) - BarobillUsageService 생성 (회원별 사용량 조회, 통계, 정책 기반 과금 계산) - BarobillBillingController 생성 (9개 엔드포인트) - 구독 관리, 월별 현황, 과금 배치, 연간 추이, 정책 관리 - BarobillUsageController 생성 (4개 엔드포인트) - 사용량 목록/통계, 회원별 상세, 과금 정책 정보 - finance.php 라우트 등록 (barobill/billing/*, barobill/usage/*)
This commit is contained in:
172
app/Http/Controllers/Api/V1/BarobillBillingController.php
Normal file
172
app/Http/Controllers/Api/V1/BarobillBillingController.php
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Helpers\ApiResponse;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\Barobill\BarobillBillingService;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BarobillBillingController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private BarobillBillingService $billingService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 구독 목록
|
||||
*/
|
||||
public function subscriptions(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'member_id' => 'nullable|integer',
|
||||
]);
|
||||
|
||||
return ApiResponse::handle(function () use ($data) {
|
||||
return [
|
||||
'subscriptions' => $this->billingService->getSubscriptions($data['member_id'] ?? null),
|
||||
];
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 구독 등록/수정
|
||||
*/
|
||||
public function saveSubscription(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'member_id' => 'required|integer|exists:barobill_members,id',
|
||||
'service_type' => 'required|in:bank_account,card,hometax',
|
||||
'monthly_fee' => 'nullable|integer|min:0',
|
||||
'started_at' => 'nullable|date',
|
||||
'ended_at' => 'nullable|date|after_or_equal:started_at',
|
||||
'is_active' => 'nullable|boolean',
|
||||
'memo' => 'nullable|string|max:500',
|
||||
]);
|
||||
|
||||
return ApiResponse::handle(function () use ($data) {
|
||||
return $this->billingService->saveSubscription(
|
||||
$data['member_id'],
|
||||
$data['service_type'],
|
||||
$data
|
||||
);
|
||||
}, __('message.created'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 구독 해지
|
||||
*/
|
||||
public function cancelSubscription(int $id)
|
||||
{
|
||||
return ApiResponse::handle(function () use ($id) {
|
||||
$this->billingService->cancelSubscription($id);
|
||||
|
||||
return ['cancelled' => true];
|
||||
}, __('message.deleted'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 월별 과금 현황 목록
|
||||
*/
|
||||
public function billingList(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'billing_month' => 'nullable|string|date_format:Y-m',
|
||||
'tenant_id' => 'nullable|integer',
|
||||
]);
|
||||
|
||||
return ApiResponse::handle(function () use ($data) {
|
||||
$billingMonth = $data['billing_month'] ?? Carbon::now()->format('Y-m');
|
||||
$tenantId = $data['tenant_id'] ?? null;
|
||||
|
||||
return [
|
||||
'list' => $this->billingService->getMonthlyBillingList($billingMonth, $tenantId),
|
||||
'total' => $this->billingService->getMonthlyTotal($billingMonth, $tenantId),
|
||||
'billing_month' => $billingMonth,
|
||||
];
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 월별 과금 통계
|
||||
*/
|
||||
public function billingStats(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'billing_month' => 'nullable|string|date_format:Y-m',
|
||||
'tenant_id' => 'nullable|integer',
|
||||
]);
|
||||
|
||||
return ApiResponse::handle(function () use ($data) {
|
||||
$billingMonth = $data['billing_month'] ?? Carbon::now()->format('Y-m');
|
||||
|
||||
return $this->billingService->getMonthlyTotal($billingMonth, $data['tenant_id'] ?? null);
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 월별 과금 배치 처리
|
||||
*/
|
||||
public function processBilling(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'billing_month' => 'nullable|string|date_format:Y-m',
|
||||
]);
|
||||
|
||||
return ApiResponse::handle(function () use ($data) {
|
||||
return $this->billingService->processMonthlyBilling($data['billing_month'] ?? null);
|
||||
}, __('message.created'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 연간 과금 추이
|
||||
*/
|
||||
public function yearlyTrend(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'year' => 'nullable|integer|min:2020|max:2030',
|
||||
'tenant_id' => 'nullable|integer',
|
||||
]);
|
||||
|
||||
return ApiResponse::handle(function () use ($data) {
|
||||
$year = $data['year'] ?? Carbon::now()->year;
|
||||
|
||||
return [
|
||||
'trend' => $this->billingService->getYearlyTrend($year, $data['tenant_id'] ?? null),
|
||||
'year' => $year,
|
||||
];
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 과금 정책 목록
|
||||
*/
|
||||
public function pricingPolicies()
|
||||
{
|
||||
return ApiResponse::handle(function () {
|
||||
return ['policies' => $this->billingService->getPricingPolicies()];
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 과금 정책 수정
|
||||
*/
|
||||
public function updatePricingPolicy(Request $request, int $id)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'name' => 'nullable|string|max:100',
|
||||
'description' => 'nullable|string|max:500',
|
||||
'free_quota' => 'nullable|integer|min:0',
|
||||
'free_quota_unit' => 'nullable|string|max:10',
|
||||
'additional_unit' => 'nullable|integer|min:1',
|
||||
'additional_unit_label' => 'nullable|string|max:10',
|
||||
'additional_price' => 'nullable|integer|min:0',
|
||||
'is_active' => 'nullable|boolean',
|
||||
]);
|
||||
|
||||
return ApiResponse::handle(function () use ($id, $data) {
|
||||
return $this->billingService->updatePricingPolicy($id, $data);
|
||||
}, __('message.updated'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user