From 806f27d04539b86e587a891c912b9000013e5a6b Mon Sep 17 00:00:00 2001 From: kimbokon Date: Sat, 20 Dec 2025 21:46:23 +0900 Subject: [PATCH] Finalize commission display: Remove educator 3% and replace with menu collaborator --- salesmanagement/index.php | 170 +++++++++++++++++++------------------- 1 file changed, 83 insertions(+), 87 deletions(-) diff --git a/salesmanagement/index.php b/salesmanagement/index.php index b5d6c16..8777eac 100644 --- a/salesmanagement/index.php +++ b/salesmanagement/index.php @@ -188,9 +188,9 @@ const educatorContracts = generateContracts(Math.floor(Math.random() * 5) + 1); // 2차 하위 // 역할 구분 추가 - directContracts.forEach(c => c.role = 'direct'); // 직접 판매 20% - managerContracts.forEach(c => c.role = 'manager'); // 관리자 5% - educatorContracts.forEach(c => c.role = 'educator'); // 교육자 3% + directContracts.forEach(c => c.role = 'direct'); // 판매자 + managerContracts.forEach(c => c.role = 'manager'); // 관리자 + educatorContracts.forEach(c => c.role = 'educator'); // 메뉴제작 협업자 const allContracts = [...directContracts, ...managerContracts, ...educatorContracts]; @@ -203,7 +203,7 @@ // 역할별 수당 const directCommission = directSales * 0.20; const managerCommission = managerSales * 0.05; - const educatorCommission = educatorSales * 0.03; + const educatorCommission = 0; // 메뉴제작 협업수당: 운영팀 별도 산정 const totalCommission = directCommission + managerCommission + educatorCommission; // 당월 필터링 @@ -219,7 +219,7 @@ const monthlyManagerSales = currentMonthContracts.filter(c => c.role === 'manager').reduce((sum, c) => sum + c.amount, 0); const monthlyEducatorSales = currentMonthContracts.filter(c => c.role === 'educator').reduce((sum, c) => sum + c.amount, 0); const monthlySales = monthlyDirectSales + monthlyManagerSales + monthlyEducatorSales; - const monthlyCommission = (monthlyDirectSales * 0.20) + (monthlyManagerSales * 0.05) + (monthlyEducatorSales * 0.03); + const monthlyCommission = (monthlyDirectSales * 0.20) + (monthlyManagerSales * 0.05); // 메뉴제작 협업수당 제외 // 지난달 필터링 const lastMonth = currentMonth === 0 ? 11 : currentMonth - 1; @@ -233,7 +233,7 @@ const lastMonthManagerSales = lastMonthContracts.filter(c => c.role === 'manager').reduce((sum, c) => sum + c.amount, 0); const lastMonthEducatorSales = lastMonthContracts.filter(c => c.role === 'educator').reduce((sum, c) => sum + c.amount, 0); const lastMonthSales = lastMonthDirectSales + lastMonthManagerSales + lastMonthEducatorSales; - const lastMonthCommission = (lastMonthDirectSales * 0.20) + (lastMonthManagerSales * 0.05) + (lastMonthEducatorSales * 0.03); + const lastMonthCommission = (lastMonthDirectSales * 0.20) + (lastMonthManagerSales * 0.05); // 메뉴제작 협업수당 제외 return { id: idx + 1, @@ -393,11 +393,11 @@
- 직접 판매 + 판매자 20%
{formatCurrency(selectedManager.directCommission)}
-
{formatCurrency(selectedManager.directSales)} × 20%
+
@@ -405,15 +405,15 @@ 5%
{formatCurrency(selectedManager.managerCommission)}
-
{formatCurrency(selectedManager.managerSales)} × 5%
+
- 교육자 수당 - 3% + 메뉴제작 협업수당 + 별도
-
{formatCurrency(selectedManager.educatorCommission)}
-
{formatCurrency(selectedManager.educatorSales)} × 3%
+
운영팀 산정
+
@@ -434,9 +434,9 @@ {selectedManager.contracts && selectedManager.contracts.map((contract, idx) => { const getRoleName = (role) => { - if (role === 'direct') return '직접 판매'; + if (role === 'direct') return '판매자'; if (role === 'manager') return '관리자'; - if (role === 'educator') return '교육자'; + if (role === 'educator') return '메뉴제작 협업자'; return '-'; }; @@ -450,7 +450,7 @@ const getCommissionRate = (role) => { if (role === 'direct') return 0.20; if (role === 'manager') return 0.05; - if (role === 'educator') return 0.03; + if (role === 'educator') return 0; return 0; }; @@ -467,7 +467,9 @@ {formatCurrency(contract.amount)} - {formatCurrency(commission)} + + {contract.role === 'educator' ? '운영팀 산정' : formatCurrency(commission)} + ); })} @@ -513,8 +515,8 @@ 총 가입비 {formatCurrency(manager.totalSales)} -
- └ 직접 판매 (20%) +
+ └ 판매자 (20%) {formatCurrency(manager.directCommission)}
@@ -522,7 +524,7 @@ {formatCurrency(manager.managerCommission)}
- └ 교육자 (3%) + └ 메뉴제작 협업자 (별도) {formatCurrency(manager.educatorCommission)}
@@ -969,8 +971,8 @@ const totalSales = contractsData.reduce((sum, c) => sum + c.amount, 0); const contractCount = contractsData.length; - // 내 조직(Depth 0) 입장에서 Depth 2는 교육자 수당 3% - const commission = totalSales * 0.03; + // 내 조직(Depth 0) 입장에서 Depth 2는 메뉴제작 협업수당 (별도 산정) + const commission = 0; return { id: `l2-${Date.now()}-${i}`, @@ -1027,7 +1029,7 @@ id: 'root-direct', name: '내 직접 판매', depth: 0, - role: '직접 판매', + role: '판매자', isDirect: true, totalSales: ownSales, contractCount: ownContracts, @@ -1041,15 +1043,15 @@ // 1차 하위의 직접 판매 (관리자 수당 5%) const level1DirectSales = level1Children.reduce((sum, c) => sum + c.totalSales, 0); - // 2차 하위의 판매 (교육자 수당 3%) + // 2차 하위의 판매 (메뉴제작 협업수당 별도) const level2Sales = level1Children.reduce((sum, c) => c.children.reduce((s, gc) => s + gc.totalSales, 0), 0); const totalSales = ownSales + level1DirectSales; const contractCount = ownContracts + level1Children.reduce((sum, c) => sum + c.contractCount, 0); - // 내 조직의 총 수당: 직접 판매 20% + 1차 하위 5% + 2차 하위 3% - const commission = (ownSales * 0.20) + (level1DirectSales * 0.05) + (level2Sales * 0.03); + // 내 조직의 총 수당: 직접 판매 20% + 1차 하위 5% (메뉴제작 협업수당 별도) + const commission = (ownSales * 0.20) + (level1DirectSales * 0.05); const orgData = { id: 'root', @@ -1096,19 +1098,19 @@ educatorCommission: 0 }; - // 직접 판매 (20%) + // 판매자 (20%) const myDirectSales = orgData.children.find(c => c.isDirect); const sellerCommission = myDirectSales ? myDirectSales.totalSales * 0.20 : 0; - // 1차 하위 (5%) + // 관리자 (5%) const level1Children = orgData.children.filter(c => !c.isDirect && c.depth === 1); const level1Sales = level1Children.reduce((sum, c) => sum + c.totalSales, 0); const managerCommission = level1Sales * 0.05; - // 2차 하위 (3%) + // 메뉴제작 협업자 (별도) const level2Sales = level1Children.reduce((sum, c) => c.children.reduce((s, gc) => s + gc.totalSales, 0), 0); - const educatorCommission = level2Sales * 0.03; + const educatorCommission = 0; // 메뉴제작 협업수당 별도 return { totalRevenue: orgData.totalSales, @@ -1234,7 +1236,7 @@ const level2Sales = level1Children.reduce((sum, c) => c.children.reduce((s, gc) => s + gc.totalSales, 0), 0); - const educatorCommission = level2Sales * 0.03; + const educatorCommission = 0; // 메뉴제작 협업수당: 운영팀 별도 산정 const totalCommission = sellerCommission + managerCommission + educatorCommission; @@ -1291,21 +1293,21 @@ // 직접 판매 if (node.depth === 0) commission = ownSales * 0.20; else if (node.depth === 1) commission = ownSales * 0.05; - else if (node.depth === 2) commission = ownSales * 0.03; + else if (node.depth === 2) commission = 0; // 메뉴제작 협업수당: 운영팀 별도 산정 } else { // 영업관리 if (node.depth === 0) { - // 내 조직: 직접 20% + 1차 하위 5% + 2차 하위 3% + // 내 조직: 직접 20% + 1차 하위 5% (메뉴제작 협업수당 별도) const myDirect = filteredChildren.find(c => c.isDirect); const level1 = filteredChildren.filter(c => !c.isDirect && c.depth === 1); const level1Sales = level1.reduce((sum, c) => sum + c.totalSales, 0); const level2Sales = level1.reduce((sum, c) => c.children.reduce((s, gc) => s + gc.totalSales, 0), 0); - commission = (myDirect ? myDirect.totalSales * 0.20 : 0) + (level1Sales * 0.05) + (level2Sales * 0.03); + commission = (myDirect ? myDirect.totalSales * 0.20 : 0) + (level1Sales * 0.05); // 메뉴제작 협업수당 제외 } else if (node.depth === 1) { commission = totalSales * 0.05; } else if (node.depth === 2) { - commission = totalSales * 0.03; + commission = 0; // 메뉴제작 협업수당: 운영팀 별도 산정 } } @@ -1490,12 +1492,12 @@
- 판매자 수당 + 판매자
20%
{formatCurrency(periodStats.sellerCommission)}
-
직접 판매 수당
+
@@ -1504,43 +1506,37 @@
- 관리자 수당 + 관리자
5%
{formatCurrency(periodStats.managerCommission)}
-
1차 하위 관리 수당
+
- +
- 교육자 수당 + 메뉴제작 협업수당
- 3% + 별도
-
{formatCurrency(periodStats.educatorCommission)}
-
2차 하위 교육 수당
+
운영팀 산정
+
-
-
- - - 판매자는 직접 판매, 관리자는 하위 1단계, 교육자는 하위 2단계 실적에서 수당 지급 - -
+
{formatCurrency(periodStats.totalCommission)}
-
총 가입비의 {periodStats.commissionRate}%
-
-
-
+
총 가입비 대비 수당
+
+ + {/* 기간별 조직 트리 */} @@ -1639,7 +1635,7 @@ {node.depth === 0 && !isDirect ? ( 내 총 수당: {formatCurrency(node.commission)} ) : ( - + 내 수당: {formatCurrency(node.commission)} )} @@ -1710,13 +1706,13 @@
- 직접 판매: 내 수당 20% + 판매자 (20%)
- 직속 하위: 내 수당 5% + 관리자 (5%)
- 2차 하위: 내 수당 3% + 메뉴제작 협업자 (별도)
@@ -1902,7 +1898,7 @@

1. 수당 체계 개요

영업 수당은 가입비에 대해서만 지급됩니다.

-

수당은 판매자와 그 상위 관리자, 교육자에게 차등 지급됩니다.

+

수당은 판매자와 그 상위 관리자, 메뉴제작 협업자에게 지급됩니다.

@@ -1911,7 +1907,7 @@
  • 판매자 (Seller): 직접 영업을 성사시킨 담당자 - 가입비의 20%
  • 관리자 (Manager): 판매자를 데려온 상위 담당자 - 가입비의 5%
  • -
  • 교육자 (Educator): 관리자를 데려온 상위 담당자 - 가입비의 3%
  • +
  • 메뉴제작 협업자 (Collaborator): 관리자를 데려온 상위 담당자 - 운영팀 별도 산정
@@ -1935,8 +1931,8 @@ 5% - 교육자 - 3% + 메뉴제작 협업자 + 별도 산정 @@ -1953,7 +1949,7 @@ @@ -1971,7 +1967,7 @@

6. 회사 마진

-

가입비에서 총 수당(최대 28%)을 제외한 금액이 회사 마진으로 귀속됩니다.

+

가입비에서 영업 수당(총 25%)을 제외한 금액이 회사 마진으로 귀속됩니다. (메뉴제작 협업수당은 별도)

@@ -2056,11 +2052,11 @@ const price = getItemPrice('model', modelId, model.join_fee, model.subscription_fee); totalJoinFee += price.join_fee || 0; - // 가입비에 대한 수당만 계산: 판매자 20%, 관리자 5%, 교육자 3% - const rates = model.commission_rates || { seller: { join: 0.20 }, manager: { join: 0.05 }, educator: { join: 0.03 } }; + // 가입비에 대한 수당만 계산: 판매자 20%, 관리자 5%, 메뉴제작 협업수당 별도 + const rates = model.commission_rates || { seller: { join: 0.20 }, manager: { join: 0.05 }, educator: { join: 0 } }; totalSellerCommission += (price.join_fee * (rates.seller.join || 0.20)); totalManagerCommission += (price.join_fee * (rates.manager.join || 0.05)); - totalEducatorCommission += (price.join_fee * (rates.educator?.join || 0.03)); + totalEducatorCommission += 0; // 운영팀 별도 산정 } }); } @@ -2070,10 +2066,10 @@ const price = getItemPrice('package', 'construction_management', constructionPackage.join_fee, constructionPackage.subscription_fee); totalJoinFee += price.join_fee || 0; - const rates = constructionPackage.commission_rates || { seller: { join: 0.20 }, manager: { join: 0.05 }, educator: { join: 0.03 } }; + const rates = constructionPackage.commission_rates || { seller: { join: 0.20 }, manager: { join: 0.05 }, educator: { join: 0 } }; totalSellerCommission += (price.join_fee * (rates.seller.join || 0.20)); totalManagerCommission += (price.join_fee * (rates.manager.join || 0.05)); - totalEducatorCommission += (price.join_fee * (rates.educator?.join || 0.03)); + totalEducatorCommission += 0; } // 공정/정부지원사업 패키지 @@ -2081,10 +2077,10 @@ const price = getItemPrice('package', 'process_government', processGovPackage.join_fee, processGovPackage.subscription_fee); totalJoinFee += price.join_fee || 0; - const rates = processGovPackage.commission_rates || { seller: { join: 0.20 }, manager: { join: 0.05 }, educator: { join: 0.03 } }; + const rates = processGovPackage.commission_rates || { seller: { join: 0.20 }, manager: { join: 0.05 }, educator: { join: 0 } }; totalSellerCommission += (price.join_fee * (rates.seller.join || 0.20)); totalManagerCommission += (price.join_fee * (rates.manager.join || 0.05)); - totalEducatorCommission += (price.join_fee * (rates.educator?.join || 0.03)); + totalEducatorCommission += 0; } const totalCommission = totalSellerCommission + totalManagerCommission + totalEducatorCommission; @@ -2350,8 +2346,8 @@ {formatCurrency(totalManagerCommission)}
- 교육자 수당 (3%) - {formatCurrency(totalEducatorCommission)} + 메뉴제작 협업수당 + 운영팀 별도 산정
@@ -2522,8 +2518,8 @@
-
교육자 수당 (3%)
-

가입비 × 3%

+
메뉴제작 협업수당
+

운영팀 별도 산정

@@ -2533,8 +2529,8 @@ @@ -2550,7 +2546,7 @@ @@ -2647,7 +2643,7 @@ if (!record) return null; const program = programs.find(p => p.id === record.program_id); - const rates = program?.commission_rates || { seller: { join: 0.20 }, manager: { join: 0.05 }, educator: { join: 0.03 } }; + const rates = program?.commission_rates || { seller: { join: 0.20 }, manager: { join: 0.05 }, educator: { join: 0 } }; // Calculations (구독료 제거, 가입비에 대한 수당만 계산) const joinFee = record.join_fee; @@ -2662,12 +2658,12 @@ const managerJoin = calc(joinFee, rates.manager.join || 0.05); const managerTotal = managerJoin; - // 교육자: 가입비의 3% - const educatorJoin = calc(joinFee, rates.educator?.join || 0.03); + // 메뉴제작 협업자: 운영팀 별도 산정 + const educatorJoin = 0; const educatorTotal = educatorJoin; const totalCommission = sellerTotal + managerTotal + educatorTotal; - const companyMargin = joinFee - totalCommission; // 회사 마진 = 가입비 - 총 수당 + const companyMargin = joinFee - totalCommission; // 회사 마진 = 가입비 - 영업 수당 const formatCurrency = (val) => new Intl.NumberFormat('ko-KR', { style: 'currency', currency: 'KRW' }).format(val); @@ -2742,17 +2738,17 @@ {formatCurrency(managerTotal)} - 교육자 + 메뉴제작 협업자 - 3% + 별도 - {formatCurrency(educatorTotal)} + 운영팀 산정 회사 마진 - 가입비 - 총 수당 + 가입비 - 영업 수당 {formatCurrency(companyMargin)}