feat: [finance] 경조사비 관리 API 구현
- Model: CondolenceExpense (BelongsToTenant, Auditable, SoftDeletes) - Service: CRUD + summary 통계 (total_amount 자동 계산) - Controller: 6개 엔드포인트 (목록/등록/상세/수정/삭제/통계) - FormRequest: Store/Update 검증 규칙 분리 - Route: /api/v1/condolence-expenses - Migration: updated_by, deleted_by 컬럼 추가
This commit is contained in:
88
app/Http/Controllers/Api/V1/CondolenceExpenseController.php
Normal file
88
app/Http/Controllers/Api/V1/CondolenceExpenseController.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Helpers\ApiResponse;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\V1\CondolenceExpense\StoreCondolenceExpenseRequest;
|
||||
use App\Http\Requests\V1\CondolenceExpense\UpdateCondolenceExpenseRequest;
|
||||
use App\Services\CondolenceExpenseService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CondolenceExpenseController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly CondolenceExpenseService $service
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 경조사비 목록
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$params = $request->only([
|
||||
'year',
|
||||
'category',
|
||||
'search',
|
||||
'sort_by',
|
||||
'sort_order',
|
||||
'per_page',
|
||||
'page',
|
||||
]);
|
||||
|
||||
$expenses = $this->service->index($params);
|
||||
|
||||
return ApiResponse::success($expenses, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 경조사비 통계
|
||||
*/
|
||||
public function summary(Request $request)
|
||||
{
|
||||
$params = $request->only(['year', 'category']);
|
||||
$summary = $this->service->summary($params);
|
||||
|
||||
return ApiResponse::success($summary, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 경조사비 상세
|
||||
*/
|
||||
public function show(int $id)
|
||||
{
|
||||
$expense = $this->service->show($id);
|
||||
|
||||
return ApiResponse::success($expense, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 경조사비 등록
|
||||
*/
|
||||
public function store(StoreCondolenceExpenseRequest $request)
|
||||
{
|
||||
$expense = $this->service->store($request->validated());
|
||||
|
||||
return ApiResponse::success($expense, __('message.created'), [], 201);
|
||||
}
|
||||
|
||||
/**
|
||||
* 경조사비 수정
|
||||
*/
|
||||
public function update(int $id, UpdateCondolenceExpenseRequest $request)
|
||||
{
|
||||
$expense = $this->service->update($id, $request->validated());
|
||||
|
||||
return ApiResponse::success($expense, __('message.updated'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 경조사비 삭제
|
||||
*/
|
||||
public function destroy(int $id)
|
||||
{
|
||||
$this->service->destroy($id);
|
||||
|
||||
return ApiResponse::success(null, __('message.deleted'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1\CondolenceExpense;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreCondolenceExpenseRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'event_date' => ['nullable', 'date'],
|
||||
'expense_date' => ['nullable', 'date'],
|
||||
'partner_name' => ['required', 'string', 'max:100'],
|
||||
'description' => ['nullable', 'string', 'max:200'],
|
||||
'category' => ['required', 'string', 'in:congratulation,condolence'],
|
||||
'has_cash' => ['nullable', 'boolean'],
|
||||
'cash_method' => ['required_if:has_cash,true', 'nullable', 'string', 'in:cash,transfer,card'],
|
||||
'cash_amount' => ['required_if:has_cash,true', 'nullable', 'integer', 'min:0'],
|
||||
'has_gift' => ['nullable', 'boolean'],
|
||||
'gift_type' => ['nullable', 'string', 'max:50'],
|
||||
'gift_amount' => ['required_if:has_gift,true', 'nullable', 'integer', 'min:0'],
|
||||
'memo' => ['nullable', 'string'],
|
||||
];
|
||||
}
|
||||
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'event_date' => '경조사일자',
|
||||
'expense_date' => '지출일자',
|
||||
'partner_name' => '거래처명',
|
||||
'description' => '내역',
|
||||
'category' => '구분',
|
||||
'has_cash' => '부조금 여부',
|
||||
'cash_method' => '지출방법',
|
||||
'cash_amount' => '부조금액',
|
||||
'has_gift' => '선물 여부',
|
||||
'gift_type' => '선물종류',
|
||||
'gift_amount' => '선물금액',
|
||||
'memo' => '비고',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V1\CondolenceExpense;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateCondolenceExpenseRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'event_date' => ['nullable', 'date'],
|
||||
'expense_date' => ['nullable', 'date'],
|
||||
'partner_name' => ['sometimes', 'required', 'string', 'max:100'],
|
||||
'description' => ['nullable', 'string', 'max:200'],
|
||||
'category' => ['sometimes', 'required', 'string', 'in:congratulation,condolence'],
|
||||
'has_cash' => ['nullable', 'boolean'],
|
||||
'cash_method' => ['required_if:has_cash,true', 'nullable', 'string', 'in:cash,transfer,card'],
|
||||
'cash_amount' => ['required_if:has_cash,true', 'nullable', 'integer', 'min:0'],
|
||||
'has_gift' => ['nullable', 'boolean'],
|
||||
'gift_type' => ['nullable', 'string', 'max:50'],
|
||||
'gift_amount' => ['required_if:has_gift,true', 'nullable', 'integer', 'min:0'],
|
||||
'memo' => ['nullable', 'string'],
|
||||
];
|
||||
}
|
||||
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'event_date' => '경조사일자',
|
||||
'expense_date' => '지출일자',
|
||||
'partner_name' => '거래처명',
|
||||
'description' => '내역',
|
||||
'category' => '구분',
|
||||
'has_cash' => '부조금 여부',
|
||||
'cash_method' => '지출방법',
|
||||
'cash_amount' => '부조금액',
|
||||
'has_gift' => '선물 여부',
|
||||
'gift_type' => '선물종류',
|
||||
'gift_amount' => '선물금액',
|
||||
'memo' => '비고',
|
||||
];
|
||||
}
|
||||
}
|
||||
138
app/Models/Tenants/CondolenceExpense.php
Normal file
138
app/Models/Tenants/CondolenceExpense.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Tenants;
|
||||
|
||||
use App\Traits\Auditable;
|
||||
use App\Traits\BelongsToTenant;
|
||||
use App\Traits\ModelTrait;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class CondolenceExpense extends Model
|
||||
{
|
||||
use Auditable, BelongsToTenant, ModelTrait, SoftDeletes;
|
||||
|
||||
protected $table = 'condolence_expenses';
|
||||
|
||||
// 카테고리 상수
|
||||
public const CATEGORY_CONGRATULATION = 'congratulation';
|
||||
|
||||
public const CATEGORY_CONDOLENCE = 'condolence';
|
||||
|
||||
public const CATEGORY_LABELS = [
|
||||
self::CATEGORY_CONGRATULATION => '축의',
|
||||
self::CATEGORY_CONDOLENCE => '부조',
|
||||
];
|
||||
|
||||
// 지출방법 상수
|
||||
public const CASH_METHOD_CASH = 'cash';
|
||||
|
||||
public const CASH_METHOD_TRANSFER = 'transfer';
|
||||
|
||||
public const CASH_METHOD_CARD = 'card';
|
||||
|
||||
public const CASH_METHOD_LABELS = [
|
||||
self::CASH_METHOD_CASH => '현금',
|
||||
self::CASH_METHOD_TRANSFER => '계좌이체',
|
||||
self::CASH_METHOD_CARD => '카드',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'tenant_id',
|
||||
'event_date',
|
||||
'expense_date',
|
||||
'partner_name',
|
||||
'description',
|
||||
'category',
|
||||
'has_cash',
|
||||
'cash_method',
|
||||
'cash_amount',
|
||||
'has_gift',
|
||||
'gift_type',
|
||||
'gift_amount',
|
||||
'total_amount',
|
||||
'options',
|
||||
'memo',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'deleted_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'event_date' => 'date',
|
||||
'expense_date' => 'date',
|
||||
'has_cash' => 'boolean',
|
||||
'has_gift' => 'boolean',
|
||||
'cash_amount' => 'integer',
|
||||
'gift_amount' => 'integer',
|
||||
'total_amount' => 'integer',
|
||||
'options' => 'array',
|
||||
];
|
||||
|
||||
protected $appends = [
|
||||
'category_label',
|
||||
'cash_method_label',
|
||||
];
|
||||
|
||||
/**
|
||||
* 카테고리 라벨
|
||||
*/
|
||||
public function getCategoryLabelAttribute(): string
|
||||
{
|
||||
return self::CATEGORY_LABELS[$this->category] ?? $this->category;
|
||||
}
|
||||
|
||||
/**
|
||||
* 지출방법 라벨
|
||||
*/
|
||||
public function getCashMethodLabelAttribute(): ?string
|
||||
{
|
||||
if (! $this->cash_method) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return self::CASH_METHOD_LABELS[$this->cash_method] ?? $this->cash_method;
|
||||
}
|
||||
|
||||
/**
|
||||
* 등록자
|
||||
*/
|
||||
public function creator(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(\App\Models\User::class, 'created_by');
|
||||
}
|
||||
|
||||
/**
|
||||
* 카테고리 필터 스코프
|
||||
*/
|
||||
public function scopeByCategory($query, string $category)
|
||||
{
|
||||
return $query->where('category', $category);
|
||||
}
|
||||
|
||||
/**
|
||||
* 연도 필터 스코프
|
||||
*/
|
||||
public function scopeInYear($query, int $year)
|
||||
{
|
||||
return $query->whereYear('event_date', $year);
|
||||
}
|
||||
|
||||
/**
|
||||
* options 헬퍼
|
||||
*/
|
||||
public function getOption(string $key, $default = null)
|
||||
{
|
||||
return data_get($this->options, $key, $default);
|
||||
}
|
||||
|
||||
public function setOption(string $key, $value): self
|
||||
{
|
||||
$options = $this->options ?? [];
|
||||
data_set($options, $key, $value);
|
||||
$this->options = $options;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
189
app/Services/CondolenceExpenseService.php
Normal file
189
app/Services/CondolenceExpenseService.php
Normal file
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Tenants\CondolenceExpense;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CondolenceExpenseService extends Service
|
||||
{
|
||||
/**
|
||||
* 목록 조회 (페이지네이션 + 필터)
|
||||
*/
|
||||
public function index(array $params): LengthAwarePaginator
|
||||
{
|
||||
$query = CondolenceExpense::query();
|
||||
|
||||
// 연도 필터
|
||||
if (! empty($params['year'])) {
|
||||
$query->inYear((int) $params['year']);
|
||||
}
|
||||
|
||||
// 카테고리 필터
|
||||
if (! empty($params['category']) && $params['category'] !== 'all') {
|
||||
$query->byCategory($params['category']);
|
||||
}
|
||||
|
||||
// 통합 검색
|
||||
if (! empty($params['search'])) {
|
||||
$search = $params['search'];
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('partner_name', 'like', "%{$search}%")
|
||||
->orWhere('description', 'like', "%{$search}%")
|
||||
->orWhere('memo', 'like', "%{$search}%");
|
||||
});
|
||||
}
|
||||
|
||||
// 정렬
|
||||
$sortBy = $params['sort_by'] ?? 'event_date';
|
||||
$sortOrder = $params['sort_order'] ?? 'desc';
|
||||
$query->orderBy($sortBy, $sortOrder)->orderByDesc('id');
|
||||
|
||||
$perPage = $params['per_page'] ?? 50;
|
||||
|
||||
return $query->paginate($perPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 상세 조회
|
||||
*/
|
||||
public function show(int $id): CondolenceExpense
|
||||
{
|
||||
return CondolenceExpense::with('creator:id,name')->findOrFail($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 등록
|
||||
*/
|
||||
public function store(array $data): CondolenceExpense
|
||||
{
|
||||
$tenantId = $this->tenantId();
|
||||
$userId = $this->apiUserId();
|
||||
|
||||
return DB::transaction(function () use ($data, $tenantId, $userId) {
|
||||
return CondolenceExpense::create([
|
||||
'tenant_id' => $tenantId,
|
||||
'event_date' => $data['event_date'] ?? null,
|
||||
'expense_date' => $data['expense_date'] ?? null,
|
||||
'partner_name' => $data['partner_name'],
|
||||
'description' => $data['description'] ?? null,
|
||||
'category' => $data['category'],
|
||||
'has_cash' => $data['has_cash'] ?? false,
|
||||
'cash_method' => ($data['has_cash'] ?? false) ? ($data['cash_method'] ?? null) : null,
|
||||
'cash_amount' => ($data['has_cash'] ?? false) ? ($data['cash_amount'] ?? 0) : 0,
|
||||
'has_gift' => $data['has_gift'] ?? false,
|
||||
'gift_type' => ($data['has_gift'] ?? false) ? ($data['gift_type'] ?? null) : null,
|
||||
'gift_amount' => ($data['has_gift'] ?? false) ? ($data['gift_amount'] ?? 0) : 0,
|
||||
'total_amount' => $this->calculateTotal($data),
|
||||
'memo' => $data['memo'] ?? null,
|
||||
'created_by' => $userId,
|
||||
'updated_by' => $userId,
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 수정
|
||||
*/
|
||||
public function update(int $id, array $data): CondolenceExpense
|
||||
{
|
||||
$userId = $this->apiUserId();
|
||||
|
||||
return DB::transaction(function () use ($id, $data, $userId) {
|
||||
$expense = CondolenceExpense::findOrFail($id);
|
||||
|
||||
$expense->fill([
|
||||
'event_date' => $data['event_date'] ?? $expense->event_date,
|
||||
'expense_date' => $data['expense_date'] ?? $expense->expense_date,
|
||||
'partner_name' => $data['partner_name'] ?? $expense->partner_name,
|
||||
'description' => $data['description'] ?? $expense->description,
|
||||
'category' => $data['category'] ?? $expense->category,
|
||||
'has_cash' => $data['has_cash'] ?? $expense->has_cash,
|
||||
'cash_method' => ($data['has_cash'] ?? $expense->has_cash) ? ($data['cash_method'] ?? $expense->cash_method) : null,
|
||||
'cash_amount' => ($data['has_cash'] ?? $expense->has_cash) ? ($data['cash_amount'] ?? $expense->cash_amount) : 0,
|
||||
'has_gift' => $data['has_gift'] ?? $expense->has_gift,
|
||||
'gift_type' => ($data['has_gift'] ?? $expense->has_gift) ? ($data['gift_type'] ?? $expense->gift_type) : null,
|
||||
'gift_amount' => ($data['has_gift'] ?? $expense->has_gift) ? ($data['gift_amount'] ?? $expense->gift_amount) : 0,
|
||||
'total_amount' => $this->calculateTotal(array_merge($expense->toArray(), $data)),
|
||||
'memo' => $data['memo'] ?? $expense->memo,
|
||||
'updated_by' => $userId,
|
||||
]);
|
||||
|
||||
$expense->save();
|
||||
|
||||
return $expense->fresh();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 삭제 (소프트)
|
||||
*/
|
||||
public function destroy(int $id): bool
|
||||
{
|
||||
$userId = $this->apiUserId();
|
||||
|
||||
return DB::transaction(function () use ($id, $userId) {
|
||||
$expense = CondolenceExpense::findOrFail($id);
|
||||
$expense->deleted_by = $userId;
|
||||
$expense->save();
|
||||
$expense->delete();
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 통계 조회
|
||||
*/
|
||||
public function summary(array $params): array
|
||||
{
|
||||
$query = CondolenceExpense::query();
|
||||
|
||||
if (! empty($params['year'])) {
|
||||
$query->inYear((int) $params['year']);
|
||||
}
|
||||
|
||||
if (! empty($params['category']) && $params['category'] !== 'all') {
|
||||
$query->byCategory($params['category']);
|
||||
}
|
||||
|
||||
$stats = $query->selectRaw('
|
||||
COUNT(*) as total_count,
|
||||
COALESCE(SUM(total_amount), 0) as total_amount,
|
||||
COALESCE(SUM(cash_amount), 0) as cash_total,
|
||||
COALESCE(SUM(gift_amount), 0) as gift_total,
|
||||
COALESCE(SUM(CASE WHEN category = ? THEN 1 ELSE 0 END), 0) as congratulation_count,
|
||||
COALESCE(SUM(CASE WHEN category = ? THEN 1 ELSE 0 END), 0) as condolence_count,
|
||||
COALESCE(SUM(CASE WHEN category = ? THEN total_amount ELSE 0 END), 0) as congratulation_amount,
|
||||
COALESCE(SUM(CASE WHEN category = ? THEN total_amount ELSE 0 END), 0) as condolence_amount
|
||||
', [
|
||||
CondolenceExpense::CATEGORY_CONGRATULATION,
|
||||
CondolenceExpense::CATEGORY_CONDOLENCE,
|
||||
CondolenceExpense::CATEGORY_CONGRATULATION,
|
||||
CondolenceExpense::CATEGORY_CONDOLENCE,
|
||||
])->first();
|
||||
|
||||
return [
|
||||
'total_count' => (int) $stats->total_count,
|
||||
'total_amount' => (int) $stats->total_amount,
|
||||
'cash_total' => (int) $stats->cash_total,
|
||||
'gift_total' => (int) $stats->gift_total,
|
||||
'congratulation_count' => (int) $stats->congratulation_count,
|
||||
'condolence_count' => (int) $stats->condolence_count,
|
||||
'congratulation_amount' => (int) $stats->congratulation_amount,
|
||||
'condolence_amount' => (int) $stats->condolence_amount,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 총금액 자동 계산
|
||||
*/
|
||||
private function calculateTotal(array $data): int
|
||||
{
|
||||
$cash = ($data['has_cash'] ?? false) ? (int) ($data['cash_amount'] ?? 0) : 0;
|
||||
$gift = ($data['has_gift'] ?? false) ? (int) ($data['gift_amount'] ?? 0) : 0;
|
||||
|
||||
return $cash + $gift;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// 테이블이 없으면 전체 생성 (이전 마이그레이션이 실행됐지만 테이블이 누락된 경우)
|
||||
if (! Schema::hasTable('condolence_expenses')) {
|
||||
Schema::create('condolence_expenses', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('tenant_id')->index();
|
||||
$table->date('event_date')->nullable()->comment('경조사일자');
|
||||
$table->date('expense_date')->nullable()->comment('지출일자');
|
||||
$table->string('partner_name', 100)->comment('거래처명/대상자');
|
||||
$table->string('description', 200)->nullable()->comment('내역');
|
||||
$table->string('category', 20)->default('congratulation')->comment('구분: congratulation(축의), condolence(부조)');
|
||||
$table->boolean('has_cash')->default(false)->comment('부조금 여부');
|
||||
$table->string('cash_method', 30)->nullable()->comment('지출방법: cash, transfer, card');
|
||||
$table->integer('cash_amount')->default(0)->comment('부조금 금액');
|
||||
$table->boolean('has_gift')->default(false)->comment('선물 여부');
|
||||
$table->string('gift_type', 50)->nullable()->comment('선물 종류');
|
||||
$table->integer('gift_amount')->default(0)->comment('선물 금액');
|
||||
$table->integer('total_amount')->default(0)->comment('총금액');
|
||||
$table->json('options')->nullable();
|
||||
$table->text('memo')->nullable()->comment('비고');
|
||||
$table->unsignedBigInteger('created_by')->nullable();
|
||||
$table->unsignedBigInteger('updated_by')->nullable();
|
||||
$table->unsignedBigInteger('deleted_by')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->index(['tenant_id', 'event_date']);
|
||||
$table->index(['tenant_id', 'category']);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 테이블이 있으면 컬럼만 추가
|
||||
Schema::table('condolence_expenses', function (Blueprint $table) {
|
||||
if (! Schema::hasColumn('condolence_expenses', 'updated_by')) {
|
||||
$table->unsignedBigInteger('updated_by')->nullable()->after('created_by');
|
||||
}
|
||||
if (! Schema::hasColumn('condolence_expenses', 'deleted_by')) {
|
||||
$table->unsignedBigInteger('deleted_by')->nullable()->after('updated_by');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 이 마이그레이션이 테이블 전체를 생성한 경우 삭제하지 않음
|
||||
// (원본 create 마이그레이션의 down에서 처리)
|
||||
if (Schema::hasTable('condolence_expenses')) {
|
||||
Schema::table('condolence_expenses', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('condolence_expenses', 'updated_by')) {
|
||||
$table->dropColumn('updated_by');
|
||||
}
|
||||
if (Schema::hasColumn('condolence_expenses', 'deleted_by')) {
|
||||
$table->dropColumn('deleted_by');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
use App\Http\Controllers\Api\V1\AccountLedgerController;
|
||||
use App\Http\Controllers\Api\V1\AccountSubjectController;
|
||||
use App\Http\Controllers\Api\V1\ClientController;
|
||||
use App\Http\Controllers\Api\V1\BadDebtController;
|
||||
use App\Http\Controllers\Api\V1\BankAccountController;
|
||||
use App\Http\Controllers\Api\V1\BankTransactionController;
|
||||
@@ -27,7 +26,9 @@
|
||||
use App\Http\Controllers\Api\V1\CalendarController;
|
||||
use App\Http\Controllers\Api\V1\CardController;
|
||||
use App\Http\Controllers\Api\V1\CardTransactionController;
|
||||
use App\Http\Controllers\Api\V1\ClientController;
|
||||
use App\Http\Controllers\Api\V1\ComprehensiveAnalysisController;
|
||||
use App\Http\Controllers\Api\V1\CondolenceExpenseController;
|
||||
use App\Http\Controllers\Api\V1\DailyReportController;
|
||||
use App\Http\Controllers\Api\V1\DepositController;
|
||||
use App\Http\Controllers\Api\V1\EntertainmentController;
|
||||
@@ -239,6 +240,16 @@
|
||||
Route::get('/welfare/summary', [WelfareController::class, 'summary'])->name('v1.welfare.summary');
|
||||
Route::get('/welfare/detail', [WelfareController::class, 'detail'])->name('v1.welfare.detail');
|
||||
|
||||
// Condolence Expense API (경조사비 관리)
|
||||
Route::prefix('condolence-expenses')->group(function () {
|
||||
Route::get('', [CondolenceExpenseController::class, 'index'])->name('v1.condolence-expenses.index');
|
||||
Route::post('', [CondolenceExpenseController::class, 'store'])->name('v1.condolence-expenses.store');
|
||||
Route::get('/summary', [CondolenceExpenseController::class, 'summary'])->name('v1.condolence-expenses.summary');
|
||||
Route::get('/{id}', [CondolenceExpenseController::class, 'show'])->whereNumber('id')->name('v1.condolence-expenses.show');
|
||||
Route::put('/{id}', [CondolenceExpenseController::class, 'update'])->whereNumber('id')->name('v1.condolence-expenses.update');
|
||||
Route::delete('/{id}', [CondolenceExpenseController::class, 'destroy'])->whereNumber('id')->name('v1.condolence-expenses.destroy');
|
||||
});
|
||||
|
||||
// Plan API (요금제 관리)
|
||||
Route::prefix('plans')->group(function () {
|
||||
Route::get('', [PlanController::class, 'index'])->name('v1.plans.index');
|
||||
|
||||
Reference in New Issue
Block a user