fix: [barobill] 회원사 수정 시 바로빌 아이디 변경 가능하도록 개선
- 수정 모달에서 바로빌 아이디 필드 표시 (기존: hidden) - 컨트롤러 update 메서드에 barobill_id 유효성 검증 추가 - 아이디/비밀번호 모두 '변경 시에만 입력' 힌트 표시
This commit is contained in:
@@ -9,7 +9,6 @@
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\Rule;
|
||||
@@ -19,6 +18,7 @@ class BarobillMemberController extends Controller
|
||||
public function __construct(
|
||||
protected BarobillService $barobillService
|
||||
) {}
|
||||
|
||||
// 바로빌 파트너사 (본사) 테넌트 ID
|
||||
private const HEADQUARTERS_TENANT_ID = 1;
|
||||
|
||||
@@ -33,7 +33,7 @@ private function validateMemberForUrlApi(int $id): BarobillMember|JsonResponse
|
||||
{
|
||||
$member = BarobillMember::find($id);
|
||||
|
||||
if (!$member) {
|
||||
if (! $member) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '회원사를 찾을 수 없습니다.',
|
||||
@@ -59,6 +59,7 @@ private function validateMemberForUrlApi(int $id): BarobillMember|JsonResponse
|
||||
*
|
||||
* - 테넌트 1(본사)이면 자동으로 모든 회원사 표시
|
||||
* - 다른 테넌트면 해당 테넌트의 회원사만 표시
|
||||
*
|
||||
* @param all_tenants bool 전체 테넌트 조회 모드 (수동 선택용)
|
||||
*/
|
||||
public function index(Request $request): JsonResponse|Response
|
||||
@@ -76,30 +77,30 @@ public function index(Request $request): JsonResponse|Response
|
||||
|
||||
foreach ($missingTenants as $tenant) {
|
||||
BarobillMember::create([
|
||||
'tenant_id' => $tenant->id,
|
||||
'biz_no' => $tenant->business_num ?? '',
|
||||
'corp_name' => $tenant->company_name,
|
||||
'ceo_name' => $tenant->ceo_name ?? '',
|
||||
'barobill_id' => '',
|
||||
'tenant_id' => $tenant->id,
|
||||
'biz_no' => $tenant->business_num ?? '',
|
||||
'corp_name' => $tenant->company_name,
|
||||
'ceo_name' => $tenant->ceo_name ?? '',
|
||||
'barobill_id' => '',
|
||||
'barobill_pwd' => '',
|
||||
'status' => 'pending',
|
||||
'server_mode' => 'test',
|
||||
'status' => 'pending',
|
||||
'server_mode' => 'test',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$query = BarobillMember::query()
|
||||
// 본사(테넌트 1)이거나 전체 테넌트 모드일 때는 필터 없음
|
||||
->when(!$isHeadquarters && !$allTenants && $tenantId, fn($q) => $q->where('tenant_id', $tenantId))
|
||||
->when(! $isHeadquarters && ! $allTenants && $tenantId, fn ($q) => $q->where('tenant_id', $tenantId))
|
||||
->when($request->search, function ($q, $search) {
|
||||
$q->where(function ($q) use ($search) {
|
||||
$q->where('corp_name', 'like', "%{$search}%")
|
||||
->orWhere('biz_no', 'like', "%{$search}%")
|
||||
->orWhere('barobill_id', 'like', "%{$search}%")
|
||||
->orWhere('manager_name', 'like', "%{$search}%");
|
||||
->orWhere('biz_no', 'like', "%{$search}%")
|
||||
->orWhere('barobill_id', 'like', "%{$search}%")
|
||||
->orWhere('manager_name', 'like', "%{$search}%");
|
||||
});
|
||||
})
|
||||
->when($request->status, fn($q, $status) => $q->where('status', $status))
|
||||
->when($request->status, fn ($q, $status) => $q->where('status', $status))
|
||||
->with('tenant:id,company_name')
|
||||
->orderBy('created_at', 'desc');
|
||||
|
||||
@@ -147,7 +148,7 @@ public function store(Request $request): JsonResponse
|
||||
? $request->integer('tenant_id')
|
||||
: session('selected_tenant_id');
|
||||
|
||||
if (!$tenantId) {
|
||||
if (! $tenantId) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '테넌트를 선택해주세요.',
|
||||
@@ -192,7 +193,7 @@ public function store(Request $request): JsonResponse
|
||||
unset($validated['skip_api']);
|
||||
|
||||
// 바로빌 API 호출 (skip_api가 false일 때만)
|
||||
if (!$skipApi) {
|
||||
if (! $skipApi) {
|
||||
$apiResult = $this->barobillService->registCorp([
|
||||
'biz_no' => $validated['biz_no'],
|
||||
'corp_name' => $validated['corp_name'],
|
||||
@@ -209,7 +210,7 @@ public function store(Request $request): JsonResponse
|
||||
'tel' => $validated['tel'] ?? '',
|
||||
]);
|
||||
|
||||
if (!$apiResult['success']) {
|
||||
if (! $apiResult['success']) {
|
||||
Log::error('바로빌 회원사 등록 API 실패', [
|
||||
'biz_no' => $validated['biz_no'],
|
||||
'error' => $apiResult['error'] ?? 'Unknown error',
|
||||
@@ -253,7 +254,7 @@ public function show(Request $request, int $id): JsonResponse
|
||||
{
|
||||
$member = BarobillMember::with('tenant:id,company_name')->find($id);
|
||||
|
||||
if (!$member) {
|
||||
if (! $member) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '회원사를 찾을 수 없습니다.',
|
||||
@@ -269,7 +270,7 @@ public function show(Request $request, int $id): JsonResponse
|
||||
|
||||
// 비밀번호 설정 여부 추가
|
||||
$memberData = $member->toArray();
|
||||
$memberData['has_password'] = !empty($member->barobill_pwd);
|
||||
$memberData['has_password'] = ! empty($member->barobill_pwd);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
@@ -286,7 +287,7 @@ public function update(Request $request, int $id): JsonResponse
|
||||
{
|
||||
$member = BarobillMember::find($id);
|
||||
|
||||
if (!$member) {
|
||||
if (! $member) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '회원사를 찾을 수 없습니다.',
|
||||
@@ -303,10 +304,14 @@ public function update(Request $request, int $id): JsonResponse
|
||||
'manager_email' => 'nullable|email|max:100',
|
||||
'manager_hp' => 'nullable|string|max:20',
|
||||
'status' => 'nullable|in:active,inactive,pending',
|
||||
'barobill_pwd' => 'nullable|string|max:255', // 비밀번호 선택적 업데이트
|
||||
'barobill_id' => 'nullable|string|max:50',
|
||||
'barobill_pwd' => 'nullable|string|max:255',
|
||||
]);
|
||||
|
||||
// 비밀번호가 비어있으면 제외 (기존 값 유지)
|
||||
// 비어있으면 제외 (기존 값 유지)
|
||||
if (empty($validated['barobill_id'])) {
|
||||
unset($validated['barobill_id']);
|
||||
}
|
||||
if (empty($validated['barobill_pwd'])) {
|
||||
unset($validated['barobill_pwd']);
|
||||
}
|
||||
@@ -327,7 +332,7 @@ public function destroy(int $id): JsonResponse
|
||||
{
|
||||
$member = BarobillMember::find($id);
|
||||
|
||||
if (!$member) {
|
||||
if (! $member) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '회원사를 찾을 수 없습니다.',
|
||||
@@ -357,7 +362,7 @@ public function stats(Request $request): JsonResponse|Response
|
||||
$isHeadquarters = $tenantId == self::HEADQUARTERS_TENANT_ID;
|
||||
|
||||
$query = BarobillMember::query()
|
||||
->when(!$isHeadquarters && !$allTenants && $tenantId, fn($q) => $q->where('tenant_id', $tenantId));
|
||||
->when(! $isHeadquarters && ! $allTenants && $tenantId, fn ($q) => $q->where('tenant_id', $tenantId));
|
||||
|
||||
$stats = [
|
||||
'total' => (clone $query)->count(),
|
||||
@@ -403,7 +408,7 @@ public function getBankAccountUrl(Request $request, int $id): JsonResponse
|
||||
$member->barobill_pwd
|
||||
);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '계좌 등록 URL을 가져오는데 실패했습니다.',
|
||||
@@ -438,7 +443,7 @@ public function getBankAccountManageUrl(Request $request, int $id): JsonResponse
|
||||
$member->barobill_pwd
|
||||
);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '계좌 관리 URL을 가져오는데 실패했습니다.',
|
||||
@@ -473,7 +478,7 @@ public function getCertificateUrl(Request $request, int $id): JsonResponse
|
||||
$member->barobill_pwd
|
||||
);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '인증서 등록 URL을 가져오는데 실패했습니다.',
|
||||
@@ -508,7 +513,7 @@ public function getCashChargeUrl(Request $request, int $id): JsonResponse
|
||||
$member->barobill_pwd
|
||||
);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '충전 URL을 가져오는데 실패했습니다.',
|
||||
@@ -534,7 +539,7 @@ public function getCertificateStatus(int $id): JsonResponse
|
||||
{
|
||||
$member = BarobillMember::find($id);
|
||||
|
||||
if (!$member) {
|
||||
if (! $member) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '회원사를 찾을 수 없습니다.',
|
||||
@@ -569,7 +574,7 @@ public function getBalance(int $id): JsonResponse
|
||||
{
|
||||
$member = BarobillMember::find($id);
|
||||
|
||||
if (!$member) {
|
||||
if (! $member) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '회원사를 찾을 수 없습니다.',
|
||||
@@ -578,7 +583,7 @@ public function getBalance(int $id): JsonResponse
|
||||
|
||||
$result = $this->barobillService->getBalanceCostAmount($member->biz_no);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '잔액 조회에 실패했습니다.',
|
||||
@@ -603,7 +608,7 @@ public function getBankAccounts(int $id): JsonResponse
|
||||
{
|
||||
$member = BarobillMember::find($id);
|
||||
|
||||
if (!$member) {
|
||||
if (! $member) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '회원사를 찾을 수 없습니다.',
|
||||
@@ -612,7 +617,7 @@ public function getBankAccounts(int $id): JsonResponse
|
||||
|
||||
$result = $this->barobillService->getBankAccounts($member->biz_no);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '계좌 목록 조회에 실패했습니다.',
|
||||
@@ -642,7 +647,7 @@ public function getBankAccountLogUrl(Request $request, int $id): JsonResponse
|
||||
$member->barobill_pwd
|
||||
);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '입출금내역 URL을 가져오는데 실패했습니다.',
|
||||
@@ -681,7 +686,7 @@ public function getCardUrl(Request $request, int $id): JsonResponse
|
||||
$member->barobill_pwd
|
||||
);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '카드 등록 URL을 가져오는데 실패했습니다.',
|
||||
@@ -716,7 +721,7 @@ public function getCardManageUrl(Request $request, int $id): JsonResponse
|
||||
$member->barobill_pwd
|
||||
);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '카드 관리 URL을 가져오는데 실패했습니다.',
|
||||
@@ -749,7 +754,7 @@ public function getCardLogUrl(Request $request, int $id): JsonResponse
|
||||
$member->barobill_pwd
|
||||
);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '카드 사용내역 URL을 가져오는데 실패했습니다.',
|
||||
@@ -775,7 +780,7 @@ public function getCards(int $id): JsonResponse
|
||||
{
|
||||
$member = BarobillMember::find($id);
|
||||
|
||||
if (!$member) {
|
||||
if (! $member) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '회원사를 찾을 수 없습니다.',
|
||||
@@ -784,7 +789,7 @@ public function getCards(int $id): JsonResponse
|
||||
|
||||
$result = $this->barobillService->getCards($member->biz_no);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '카드 목록 조회에 실패했습니다.',
|
||||
@@ -818,7 +823,7 @@ public function getTaxInvoiceUrl(Request $request, int $id): JsonResponse
|
||||
$member->barobill_pwd
|
||||
);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '세금계산서 발행 URL을 가져오는데 실패했습니다.',
|
||||
@@ -851,7 +856,7 @@ public function getTaxInvoiceListUrl(Request $request, int $id): JsonResponse
|
||||
$member->barobill_pwd
|
||||
);
|
||||
|
||||
if (!$result['success']) {
|
||||
if (! $result['success']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '세금계산서 목록 URL을 가져오는데 실패했습니다.',
|
||||
@@ -892,7 +897,7 @@ public function updateServerMode(Request $request, int $id): JsonResponse
|
||||
{
|
||||
$member = BarobillMember::find($id);
|
||||
|
||||
if (!$member) {
|
||||
if (! $member) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '회원사를 찾을 수 없습니다.',
|
||||
@@ -909,7 +914,7 @@ public function updateServerMode(Request $request, int $id): JsonResponse
|
||||
]);
|
||||
|
||||
// 확인 체크
|
||||
if (!$validated['confirmed']) {
|
||||
if (! $validated['confirmed']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '서버 변경 경고를 확인해주세요.',
|
||||
@@ -923,7 +928,7 @@ public function updateServerMode(Request $request, int $id): JsonResponse
|
||||
if ($oldMode === $newMode) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => '서버 모드가 이미 ' . ($newMode === 'test' ? '테스트' : '운영') . ' 서버입니다.',
|
||||
'message' => '서버 모드가 이미 '.($newMode === 'test' ? '테스트' : '운영').' 서버입니다.',
|
||||
'data' => $member,
|
||||
]);
|
||||
}
|
||||
@@ -941,7 +946,7 @@ public function updateServerMode(Request $request, int $id): JsonResponse
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => ($newMode === 'test' ? '테스트' : '운영') . ' 서버로 변경되었습니다.',
|
||||
'message' => ($newMode === 'test' ? '테스트' : '운영').' 서버로 변경되었습니다.',
|
||||
'data' => $member->fresh(),
|
||||
]);
|
||||
}
|
||||
@@ -953,7 +958,7 @@ public function getServerMode(int $id): JsonResponse
|
||||
{
|
||||
$member = BarobillMember::find($id);
|
||||
|
||||
if (!$member) {
|
||||
if (! $member) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '회원사를 찾을 수 없습니다.',
|
||||
|
||||
@@ -226,8 +226,10 @@ class="flex-1 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 tran
|
||||
// 비밀번호 필드 표시 (필수 입력)
|
||||
document.getElementById('passwordFields').classList.remove('hidden');
|
||||
document.getElementById('barobillIdField').classList.remove('hidden'); // 아이디 표시
|
||||
document.getElementById('pwdRequired').classList.remove('hidden'); // 필수 표시
|
||||
document.getElementById('pwdHint').classList.add('hidden'); // 힌트 숨김
|
||||
document.getElementById('idRequired').classList.remove('hidden'); // 아이디 필수 표시
|
||||
document.getElementById('idHint').classList.add('hidden'); // 아이디 힌트 숨김
|
||||
document.getElementById('pwdRequired').classList.remove('hidden'); // 비밀번호 필수 표시
|
||||
document.getElementById('pwdHint').classList.add('hidden'); // 비밀번호 힌트 숨김
|
||||
document.getElementById('pwdStatusBadge').classList.add('hidden'); // 상태 뱃지 숨김
|
||||
// API 검증 건너뛰기 체크박스 표시 (신규 등록 시에만)
|
||||
document.getElementById('skipApiField').classList.remove('hidden');
|
||||
@@ -252,8 +254,10 @@ class="flex-1 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 tran
|
||||
document.getElementById('submitBtn').textContent = '수정하기';
|
||||
// 비밀번호 필드 표시 (선택적 입력)
|
||||
document.getElementById('passwordFields').classList.remove('hidden');
|
||||
document.getElementById('barobillIdField').classList.add('hidden'); // 아이디는 숨김
|
||||
document.getElementById('pwdRequired').classList.add('hidden'); // 필수 표시 숨김
|
||||
document.getElementById('barobillIdField').classList.remove('hidden'); // 아이디 표시 (수정 가능)
|
||||
document.getElementById('idRequired').classList.add('hidden'); // 아이디 필수 표시 숨김
|
||||
document.getElementById('idHint').classList.remove('hidden'); // 아이디 변경 힌트 표시
|
||||
document.getElementById('pwdRequired').classList.add('hidden'); // 비밀번호 필수 표시 숨김
|
||||
document.getElementById('pwdHint').classList.remove('hidden'); // 힌트 표시
|
||||
// API 검증 건너뛰기 체크박스 숨김 (수정 시에는 불필요)
|
||||
document.getElementById('skipApiField').classList.add('hidden');
|
||||
@@ -279,7 +283,7 @@ class="flex-1 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 tran
|
||||
this.form.biz_type.value = m.biz_type || '';
|
||||
this.form.biz_class.value = m.biz_class || '';
|
||||
this.form.barobill_id.value = m.barobill_id || '';
|
||||
this.form.barobill_id.disabled = true;
|
||||
this.form.barobill_id.disabled = false;
|
||||
this.form.manager_name.value = m.manager_name || '';
|
||||
this.form.manager_email.value = m.manager_email || '';
|
||||
this.form.manager_hp.value = m.manager_hp || '';
|
||||
@@ -330,12 +334,14 @@ class="flex-1 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 tran
|
||||
// skip_api 체크박스 값을 boolean으로 변환
|
||||
data.skip_api = this.form.querySelector('input[name="skip_api"]')?.checked || false;
|
||||
|
||||
// 수정 시 disabled 필드 제외
|
||||
// 수정 시 불필요 필드 제외
|
||||
if (this.isEditing) {
|
||||
delete data.biz_no;
|
||||
delete data.barobill_id;
|
||||
delete data.skip_api; // 수정 시에는 skip_api 불필요
|
||||
// 비밀번호가 비어있으면 제외 (서버에서도 빈 값은 무시)
|
||||
delete data.skip_api;
|
||||
// 아이디/비밀번호가 비어있으면 제외 (서버에서 기존 값 유지)
|
||||
if (!data.barobill_id) {
|
||||
delete data.barobill_id;
|
||||
}
|
||||
if (!data.barobill_pwd) {
|
||||
delete data.barobill_pwd;
|
||||
}
|
||||
|
||||
@@ -91,8 +91,11 @@ class="w-10 h-10 flex items-center justify-center rounded-full text-gray-600 hov
|
||||
<!-- 바로빌 계정 -->
|
||||
<div id="passwordFields" class="col-span-2 grid grid-cols-2 gap-4">
|
||||
<div id="barobillIdField">
|
||||
<label class="block text-xs font-bold text-gray-400 uppercase mb-1">바로빌 아이디 <span class="text-red-500">*</span></label>
|
||||
<input type="text" name="barobill_id" class="w-full px-3 py-2 bg-gray-50 border border-gray-200 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500 disabled:opacity-50" placeholder="barobill_id">
|
||||
<label class="block text-xs font-bold text-gray-400 uppercase mb-1">
|
||||
바로빌 아이디 <span id="idRequired" class="text-red-500">*</span>
|
||||
</label>
|
||||
<input type="text" name="barobill_id" class="w-full px-3 py-2 bg-gray-50 border border-gray-200 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="barobill_id">
|
||||
<p id="idHint" class="hidden text-xs text-gray-500 mt-1">변경 시에만 입력</p>
|
||||
</div>
|
||||
<div>
|
||||
<label id="pwdLabel" class="block text-xs font-bold text-gray-400 uppercase mb-1">
|
||||
|
||||
Reference in New Issue
Block a user