feat:영업파트너 등록/수정에 사업자 정보(상호, 사업자등록번호, 주소) 필드 추가
- 컨트롤러 store/update 유효성 검사에 3개 필드 추가 - 서비스 create/update에서 SalesPartner 레코드 생성/업데이트 - 등록 폼(create.blade.php)에 사업자 정보 섹션 추가 - 수정 모달(edit-modal.blade.php)에 사업자 정보 섹션 추가 - 테스트 데이터 자동입력에 사업자 정보 포함 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,9 @@ public function store(Request $request)
|
||||
'password' => 'required|string|min:4|confirmed',
|
||||
'role_ids' => 'required|array|min:1',
|
||||
'role_ids.*' => 'exists:roles,id',
|
||||
'company_name' => 'nullable|string|max:100',
|
||||
'biz_no' => 'nullable|string|max:20',
|
||||
'address' => 'nullable|string|max:255',
|
||||
'documents' => 'nullable|array',
|
||||
'documents.*.file' => 'nullable|file|max:10240',
|
||||
'documents.*.document_type' => 'nullable|string',
|
||||
@@ -140,7 +143,7 @@ public function modalShow(int $id): View
|
||||
*/
|
||||
public function modalEdit(int $id): View
|
||||
{
|
||||
$partner = User::with(['userRoles.role', 'salesDocuments', 'parent'])->findOrFail($id);
|
||||
$partner = User::with(['userRoles.role', 'salesDocuments', 'parent', 'salesPartner'])->findOrFail($id);
|
||||
$roles = $this->service->getSalesRoles();
|
||||
$currentRoleIds = $partner->userRoles->pluck('role_id')->toArray();
|
||||
$documentTypes = SalesManagerDocument::DOCUMENT_TYPES;
|
||||
@@ -185,6 +188,9 @@ public function update(Request $request, int $id)
|
||||
'password' => 'nullable|string|min:4|confirmed',
|
||||
'role_ids' => 'required|array|min:1',
|
||||
'role_ids.*' => 'exists:roles,id',
|
||||
'company_name' => 'nullable|string|max:100',
|
||||
'biz_no' => 'nullable|string|max:20',
|
||||
'address' => 'nullable|string|max:255',
|
||||
'documents' => 'nullable|array',
|
||||
'documents.*.file' => 'nullable|file|max:10240',
|
||||
'documents.*.document_type' => 'nullable|string',
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
use App\Models\DepartmentUser;
|
||||
use App\Models\Role;
|
||||
use App\Models\Sales\SalesManagerDocument;
|
||||
use App\Models\Sales\SalesPartner;
|
||||
use App\Models\User;
|
||||
use App\Models\UserRole;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
@@ -57,6 +58,21 @@ public function createSalesPartner(array $data, array $documents = []): User
|
||||
// 4. 영업팀 부서 자동 할당
|
||||
$this->assignSalesDepartment($user, $tenantId);
|
||||
|
||||
// 4-1. 사업자 정보 저장 (선택)
|
||||
if (!empty($data['company_name']) || !empty($data['biz_no']) || !empty($data['address'])) {
|
||||
SalesPartner::updateOrCreate(
|
||||
['user_id' => $user->id],
|
||||
[
|
||||
'partner_code' => SalesPartner::generatePartnerCode(),
|
||||
'partner_type' => 'sales',
|
||||
'status' => 'active',
|
||||
'company_name' => $data['company_name'] ?? null,
|
||||
'biz_no' => $data['biz_no'] ?? null,
|
||||
'address' => $data['address'] ?? null,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// 5. 첨부 서류 저장
|
||||
if (!empty($documents)) {
|
||||
$this->uploadDocuments($user, $tenantId, $documents);
|
||||
@@ -93,6 +109,20 @@ public function updateSalesPartner(User $user, array $data, array $documents = [
|
||||
$this->syncRoles($user, $tenantId, $data['role_ids']);
|
||||
}
|
||||
|
||||
// 2-1. 사업자 정보 업데이트
|
||||
if (array_key_exists('company_name', $data) || array_key_exists('biz_no', $data) || array_key_exists('address', $data)) {
|
||||
$sp = SalesPartner::firstOrNew(['user_id' => $user->id]);
|
||||
if (!$sp->exists) {
|
||||
$sp->partner_code = SalesPartner::generatePartnerCode();
|
||||
$sp->partner_type = 'sales';
|
||||
$sp->status = 'active';
|
||||
}
|
||||
$sp->company_name = $data['company_name'] ?? $sp->company_name;
|
||||
$sp->biz_no = $data['biz_no'] ?? $sp->biz_no;
|
||||
$sp->address = $data['address'] ?? $sp->address;
|
||||
$sp->save();
|
||||
}
|
||||
|
||||
// 3. 새 첨부 서류 저장
|
||||
if (!empty($documents)) {
|
||||
$this->uploadDocuments($user, $tenantId, $documents);
|
||||
|
||||
@@ -171,6 +171,33 @@ class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none foc
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 사업자 정보 (전자서명용) -->
|
||||
<div class="bg-white rounded-lg shadow-sm p-6">
|
||||
<h2 class="text-lg font-semibold text-gray-800 mb-1">사업자 정보</h2>
|
||||
<p class="text-sm text-gray-400 mb-4">전자서명 계약 시 자동으로 채워집니다 (선택사항)</p>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">상호</label>
|
||||
<input type="text" name="company_name" value="{{ old('company_name') }}"
|
||||
placeholder="예: (주)홍길동무역"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">사업자등록번호</label>
|
||||
<input type="text" name="biz_no" value="{{ old('biz_no') }}"
|
||||
placeholder="000-00-00000"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</div>
|
||||
<div class="md:col-span-2">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">주소</label>
|
||||
<input type="text" name="address" value="{{ old('address') }}"
|
||||
placeholder="사업장 주소"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 역할 및 조직 -->
|
||||
<div class="bg-white rounded-lg shadow-sm p-6">
|
||||
<h2 class="text-lg font-semibold text-gray-800 mb-4">역할 및 조직</h2>
|
||||
@@ -544,6 +571,14 @@ function fillRandomData() {
|
||||
document.querySelector('input[name="password"]').value = password;
|
||||
document.querySelector('input[name="password_confirmation"]').value = password;
|
||||
|
||||
// 사업자 정보
|
||||
const companyInput = document.querySelector('input[name="company_name"]');
|
||||
const bizNoInput = document.querySelector('input[name="biz_no"]');
|
||||
const addressInput = document.querySelector('input[name="address"]');
|
||||
if (companyInput) companyInput.value = name + ' 개인사업자';
|
||||
if (bizNoInput) bizNoInput.value = randomNum(100, 999) + '-' + randomNum(10, 99) + '-' + randomNum(10000, 99999);
|
||||
if (addressInput) addressInput.value = '서울특별시 강남구 테헤란로 ' + randomNum(1, 500) + '번길 ' + randomNum(1, 30);
|
||||
|
||||
// 역할 체크박스 모두 체크
|
||||
document.querySelectorAll('input[name="role_ids[]"]').forEach(cb => {
|
||||
cb.checked = true;
|
||||
|
||||
@@ -55,6 +55,32 @@ class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none foc
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 사업자 정보 (전자서명용) -->
|
||||
<div class="bg-gray-50 rounded-lg p-4 mb-4">
|
||||
<h3 class="text-sm font-semibold text-gray-800 mb-1">사업자 정보</h3>
|
||||
<p class="text-xs text-gray-400 mb-3">전자서명 계약 시 자동으로 채워집니다 (선택사항)</p>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-xs font-medium text-gray-700 mb-1">상호</label>
|
||||
<input type="text" name="company_name" value="{{ $partner->salesPartner?->company_name }}"
|
||||
placeholder="예: (주)홍길동무역"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-medium text-gray-700 mb-1">사업자등록번호</label>
|
||||
<input type="text" name="biz_no" value="{{ $partner->salesPartner?->biz_no }}"
|
||||
placeholder="000-00-00000"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm">
|
||||
</div>
|
||||
<div class="md:col-span-2">
|
||||
<label class="block text-xs font-medium text-gray-700 mb-1">주소</label>
|
||||
<input type="text" name="address" value="{{ $partner->salesPartner?->address }}"
|
||||
placeholder="사업장 주소"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 역할 -->
|
||||
<div class="bg-gray-50 rounded-lg p-4 mb-4">
|
||||
<h3 class="text-sm font-semibold text-gray-800 mb-3">역할 <span class="text-red-500">*</span></h3>
|
||||
|
||||
Reference in New Issue
Block a user