diff --git a/database/migrations/2026_01_26_010000_create_sales_managers_table.php b/database/migrations/2026_01_26_010000_create_sales_managers_table.php new file mode 100644 index 0000000..ea1d55b --- /dev/null +++ b/database/migrations/2026_01_26_010000_create_sales_managers_table.php @@ -0,0 +1,41 @@ +id(); + $table->string('member_id', 50)->unique()->comment('로그인 ID'); + $table->string('password', 255)->comment('비밀번호'); + $table->string('name', 100)->comment('성명'); + $table->string('phone', 20)->nullable()->comment('전화번호'); + $table->string('email', 100)->nullable()->comment('이메일'); + $table->foreignId('parent_id')->nullable()->comment('상위 관리자 ID'); + $table->enum('role', ['operator', 'sales_admin', 'manager'])->default('manager')->comment('역할'); + $table->text('remarks')->nullable()->comment('비고'); + $table->boolean('is_active')->default(true)->comment('활성화 여부'); + $table->timestamps(); + $table->softDeletes(); + + $table->index('parent_id'); + $table->index('role'); + $table->index('is_active'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('sales_managers'); + } +}; diff --git a/database/migrations/2026_01_26_010100_create_sales_prospects_table.php b/database/migrations/2026_01_26_010100_create_sales_prospects_table.php new file mode 100644 index 0000000..b5afc86 --- /dev/null +++ b/database/migrations/2026_01_26_010100_create_sales_prospects_table.php @@ -0,0 +1,42 @@ +id(); + $table->foreignId('manager_id')->constrained('sales_managers')->cascadeOnDelete()->comment('영업한 영업파트너 ID'); + $table->foreignId('sales_manager_id')->nullable()->constrained('sales_managers')->nullOnDelete()->comment('매칭된 매니저 ID'); + $table->string('company_name', 200)->comment('업체명'); + $table->string('representative', 100)->nullable()->comment('대표자명'); + $table->string('business_no', 20)->nullable()->comment('사업자번호'); + $table->string('contact_phone', 20)->nullable()->comment('연락처'); + $table->string('email', 100)->nullable()->comment('이메일'); + $table->string('address', 500)->nullable()->comment('주소'); + $table->enum('status', ['lead', 'prospect', 'negotiation', 'contracted', 'lost'])->default('lead')->comment('상태'); + $table->timestamps(); + $table->softDeletes(); + + $table->index('manager_id'); + $table->index('sales_manager_id'); + $table->index('status'); + $table->index('business_no'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('sales_prospects'); + } +}; diff --git a/database/migrations/2026_01_26_010200_create_sales_prospect_products_table.php b/database/migrations/2026_01_26_010200_create_sales_prospect_products_table.php new file mode 100644 index 0000000..3a67f33 --- /dev/null +++ b/database/migrations/2026_01_26_010200_create_sales_prospect_products_table.php @@ -0,0 +1,43 @@ +id(); + $table->foreignId('prospect_id')->constrained('sales_prospects')->cascadeOnDelete(); + $table->string('product_name', 200)->comment('상품명'); + $table->decimal('contract_amount', 15, 2)->default(0)->comment('계약금액'); + $table->decimal('subscription_fee', 15, 2)->default(0)->comment('구독료'); + $table->decimal('commission_rate', 5, 2)->default(20)->comment('수수료율'); + $table->decimal('commission_amount', 15, 2)->default(0)->comment('수수료'); + $table->date('contract_date')->nullable()->comment('계약일'); + $table->boolean('join_approved')->default(false)->comment('가입 승인 여부'); + $table->boolean('payment_approved')->default(false)->comment('결제 승인 여부'); + $table->decimal('payout_rate', 5, 2)->default(0)->comment('지급율'); + $table->decimal('payout_amount', 15, 2)->default(0)->comment('지급금액'); + $table->json('sub_models')->nullable()->comment('선택모델 목록'); + $table->timestamps(); + $table->softDeletes(); + + $table->index('prospect_id'); + $table->index('contract_date'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('sales_prospect_products'); + } +}; diff --git a/database/migrations/2026_01_26_010300_create_sales_prospect_scenarios_table.php b/database/migrations/2026_01_26_010300_create_sales_prospect_scenarios_table.php new file mode 100644 index 0000000..ee8fdab --- /dev/null +++ b/database/migrations/2026_01_26_010300_create_sales_prospect_scenarios_table.php @@ -0,0 +1,35 @@ +id(); + $table->foreignId('prospect_id')->constrained('sales_prospects')->cascadeOnDelete(); + $table->enum('scenario_type', ['sales', 'manager'])->default('manager')->comment('시나리오 유형'); + $table->unsignedInteger('step_id')->comment('단계 ID'); + $table->unsignedInteger('checkpoint_index')->comment('체크포인트 인덱스'); + $table->boolean('is_checked')->default(false)->comment('체크 여부'); + $table->timestamps(); + + $table->unique(['prospect_id', 'scenario_type', 'step_id', 'checkpoint_index'], 'unique_prospect_scenario_step'); + $table->index('prospect_id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('sales_prospect_scenarios'); + } +}; diff --git a/database/migrations/2026_01_26_010400_create_sales_prospect_consultations_table.php b/database/migrations/2026_01_26_010400_create_sales_prospect_consultations_table.php new file mode 100644 index 0000000..8f7763b --- /dev/null +++ b/database/migrations/2026_01_26_010400_create_sales_prospect_consultations_table.php @@ -0,0 +1,40 @@ +id(); + $table->foreignId('prospect_id')->constrained('sales_prospects')->cascadeOnDelete(); + $table->foreignId('manager_id')->constrained('sales_managers')->cascadeOnDelete(); + $table->enum('scenario_type', ['sales', 'manager'])->default('manager')->comment('시나리오 유형'); + $table->unsignedInteger('step_id')->nullable()->comment('단계 ID'); + $table->text('log_text')->comment('상담 내용'); + $table->string('audio_file_path', 500)->nullable()->comment('음성 파일 경로'); + $table->json('attachment_paths')->nullable()->comment('첨부파일 경로 목록'); + $table->enum('consultation_type', ['text', 'audio', 'file'])->default('text')->comment('상담 유형'); + $table->timestamps(); + $table->softDeletes(); + + $table->index('prospect_id'); + $table->index('manager_id'); + $table->index('scenario_type'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('sales_prospect_consultations'); + } +}; diff --git a/database/migrations/2026_01_26_010500_create_sales_records_table.php b/database/migrations/2026_01_26_010500_create_sales_records_table.php new file mode 100644 index 0000000..f30d133 --- /dev/null +++ b/database/migrations/2026_01_26_010500_create_sales_records_table.php @@ -0,0 +1,41 @@ +id(); + $table->foreignId('manager_id')->constrained('sales_managers')->cascadeOnDelete()->comment('담당자 ID'); + $table->foreignId('prospect_id')->nullable()->constrained('sales_prospects')->nullOnDelete()->comment('가망고객 ID'); + $table->date('record_date')->comment('실적 일자'); + $table->string('record_type', 50)->comment('실적 유형'); + $table->decimal('amount', 15, 2)->default(0)->comment('실적 금액'); + $table->decimal('commission', 15, 2)->default(0)->comment('수수료'); + $table->text('description')->nullable()->comment('설명'); + $table->enum('status', ['pending', 'approved', 'rejected', 'paid'])->default('pending')->comment('상태'); + $table->timestamps(); + $table->softDeletes(); + + $table->index('manager_id'); + $table->index('prospect_id'); + $table->index('record_date'); + $table->index('status'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('sales_records'); + } +};