- 사업자등록번호 유효성 검사 API (바로빌 연동) - 회사 추가 신청/승인/반려 워크플로우 - 신청 승인 시 테넌트 자동 생성 및 사용자 연결 - 관리자용 신청 목록/상세 조회 - 사용자용 내 신청 목록 조회 - Swagger 문서 및 i18n 메시지 추가
238 lines
6.0 KiB
PHP
238 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Models\Members\User;
|
|
use App\Models\Tenants\Tenant;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
/**
|
|
* 회사 추가 신청 모델
|
|
*
|
|
* @property int $id
|
|
* @property int $user_id 신청자 ID
|
|
* @property string $business_number 사업자등록번호
|
|
* @property string $company_name 회사명
|
|
* @property string|null $ceo_name 대표자명
|
|
* @property string|null $address 주소
|
|
* @property string|null $phone 전화번호
|
|
* @property string|null $email 이메일
|
|
* @property string $status 상태 (pending, approved, rejected)
|
|
* @property string|null $message 신청 메시지
|
|
* @property string|null $reject_reason 반려 사유
|
|
* @property array|null $barobill_response 바로빌 검증 응답
|
|
* @property int|null $approved_by 승인/반려 처리자
|
|
* @property int|null $created_tenant_id 생성된 테넌트 ID
|
|
* @property \Carbon\Carbon|null $processed_at 처리일시
|
|
* @property \Carbon\Carbon $created_at
|
|
* @property \Carbon\Carbon $updated_at
|
|
*/
|
|
class CompanyRequest extends Model
|
|
{
|
|
// =========================================================================
|
|
// 상수 정의
|
|
// =========================================================================
|
|
|
|
/** 상태 */
|
|
public const STATUS_PENDING = 'pending';
|
|
|
|
public const STATUS_APPROVED = 'approved';
|
|
|
|
public const STATUS_REJECTED = 'rejected';
|
|
|
|
public const STATUSES = [
|
|
self::STATUS_PENDING,
|
|
self::STATUS_APPROVED,
|
|
self::STATUS_REJECTED,
|
|
];
|
|
|
|
/** 상태 라벨 */
|
|
public const STATUS_LABELS = [
|
|
self::STATUS_PENDING => '대기중',
|
|
self::STATUS_APPROVED => '승인',
|
|
self::STATUS_REJECTED => '반려',
|
|
];
|
|
|
|
// =========================================================================
|
|
// 모델 설정
|
|
// =========================================================================
|
|
|
|
protected $fillable = [
|
|
'user_id',
|
|
'business_number',
|
|
'company_name',
|
|
'ceo_name',
|
|
'address',
|
|
'phone',
|
|
'email',
|
|
'status',
|
|
'message',
|
|
'reject_reason',
|
|
'barobill_response',
|
|
'approved_by',
|
|
'created_tenant_id',
|
|
'processed_at',
|
|
];
|
|
|
|
protected $casts = [
|
|
'barobill_response' => 'array',
|
|
'processed_at' => 'datetime',
|
|
];
|
|
|
|
protected $attributes = [
|
|
'status' => self::STATUS_PENDING,
|
|
];
|
|
|
|
// =========================================================================
|
|
// 관계
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 신청자
|
|
*/
|
|
public function user(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class);
|
|
}
|
|
|
|
/**
|
|
* 처리자 (승인/반려)
|
|
*/
|
|
public function approver(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'approved_by');
|
|
}
|
|
|
|
/**
|
|
* 생성된 테넌트
|
|
*/
|
|
public function createdTenant(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Tenant::class, 'created_tenant_id');
|
|
}
|
|
|
|
// =========================================================================
|
|
// 스코프
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 대기중인 신청만
|
|
*/
|
|
public function scopePending($query)
|
|
{
|
|
return $query->where('status', self::STATUS_PENDING);
|
|
}
|
|
|
|
/**
|
|
* 승인된 신청만
|
|
*/
|
|
public function scopeApproved($query)
|
|
{
|
|
return $query->where('status', self::STATUS_APPROVED);
|
|
}
|
|
|
|
/**
|
|
* 반려된 신청만
|
|
*/
|
|
public function scopeRejected($query)
|
|
{
|
|
return $query->where('status', self::STATUS_REJECTED);
|
|
}
|
|
|
|
/**
|
|
* 상태 필터
|
|
*/
|
|
public function scopeOfStatus($query, string $status)
|
|
{
|
|
return $query->where('status', $status);
|
|
}
|
|
|
|
// =========================================================================
|
|
// 접근자
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 상태 라벨
|
|
*/
|
|
public function getStatusLabelAttribute(): string
|
|
{
|
|
return self::STATUS_LABELS[$this->status] ?? $this->status;
|
|
}
|
|
|
|
/**
|
|
* 대기중 여부
|
|
*/
|
|
public function getIsPendingAttribute(): bool
|
|
{
|
|
return $this->status === self::STATUS_PENDING;
|
|
}
|
|
|
|
/**
|
|
* 승인됨 여부
|
|
*/
|
|
public function getIsApprovedAttribute(): bool
|
|
{
|
|
return $this->status === self::STATUS_APPROVED;
|
|
}
|
|
|
|
/**
|
|
* 반려됨 여부
|
|
*/
|
|
public function getIsRejectedAttribute(): bool
|
|
{
|
|
return $this->status === self::STATUS_REJECTED;
|
|
}
|
|
|
|
/**
|
|
* 사업자등록번호 포맷 (하이픈 포함)
|
|
*/
|
|
public function getFormattedBusinessNumberAttribute(): string
|
|
{
|
|
$num = preg_replace('/[^0-9]/', '', $this->business_number);
|
|
if (strlen($num) === 10) {
|
|
return substr($num, 0, 3).'-'.substr($num, 3, 2).'-'.substr($num, 5, 5);
|
|
}
|
|
|
|
return $this->business_number;
|
|
}
|
|
|
|
// =========================================================================
|
|
// 헬퍼 메서드
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 승인 처리
|
|
*/
|
|
public function approve(int $approverId, int $tenantId): bool
|
|
{
|
|
if (! $this->is_pending) {
|
|
return false;
|
|
}
|
|
|
|
$this->status = self::STATUS_APPROVED;
|
|
$this->approved_by = $approverId;
|
|
$this->created_tenant_id = $tenantId;
|
|
$this->processed_at = now();
|
|
|
|
return $this->save();
|
|
}
|
|
|
|
/**
|
|
* 반려 처리
|
|
*/
|
|
public function reject(int $approverId, ?string $reason = null): bool
|
|
{
|
|
if (! $this->is_pending) {
|
|
return false;
|
|
}
|
|
|
|
$this->status = self::STATUS_REJECTED;
|
|
$this->approved_by = $approverId;
|
|
$this->reject_reason = $reason;
|
|
$this->processed_at = now();
|
|
|
|
return $this->save();
|
|
}
|
|
}
|