227 lines
8.5 KiB
PHP
227 lines
8.5 KiB
PHP
<?php
|
|
header("Content-Type: application/json; charset=utf-8");
|
|
require_once(__DIR__ . "/../../lib/mydb.php");
|
|
|
|
session_start();
|
|
|
|
if (!isset($_SESSION['sales_user'])) {
|
|
try {
|
|
$pdo_init = db_connect();
|
|
$stmt = $pdo_init->prepare("SELECT * FROM sales_member WHERE member_id = 'sales' LIMIT 1");
|
|
$stmt->execute();
|
|
$testUser = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
if ($testUser) {
|
|
$currentUser = $testUser;
|
|
$userId = $currentUser['id'];
|
|
$userRole = $currentUser['role'];
|
|
} else {
|
|
echo json_encode(['success' => false, 'error' => '로그인이 필요합니다.']);
|
|
exit;
|
|
}
|
|
} catch (Exception $e) {
|
|
echo json_encode(['success' => false, 'error' => '로그인이 필요합니다.']);
|
|
exit;
|
|
}
|
|
} else {
|
|
$currentUser = $_SESSION['sales_user'];
|
|
$userId = $currentUser['id'];
|
|
$userRole = $currentUser['role'];
|
|
}
|
|
|
|
// 기간 필터링 (기본값: 당월)
|
|
$startDate = $_GET['startDate'] ?? date('Y-m-01');
|
|
$endDate = $_GET['endDate'] ?? date('Y-m-t');
|
|
|
|
try {
|
|
$pdo = db_connect();
|
|
|
|
// 1. 조직도 트리 생성 함수 (재귀)
|
|
function buildOrgTree($pdo, $parentId, $depth, $startDate, $endDate, $targetUserId) {
|
|
// 이 멤버의 정보 가져오기
|
|
$stmt = $pdo->prepare("SELECT id, name, role FROM sales_member WHERE id = ? AND is_active = 1");
|
|
$stmt->execute([$parentId]);
|
|
$member = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (!$member) return null;
|
|
|
|
// 이 멤버의 직접 실적 가져오기
|
|
$stmt = $pdo->prepare("SELECT id, customer_name as customer, contract_date as contractDate, amount FROM sales_record WHERE member_id = ? AND status = 'completed' AND contract_date BETWEEN ? AND ?");
|
|
$stmt->execute([$parentId, $startDate, $endDate]);
|
|
$directContracts = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
$directSales = 0;
|
|
$rate = 0;
|
|
if ($parentId == $targetUserId) $rate = 0.20;
|
|
else if ($depth == 1) $rate = 0.05;
|
|
else if ($depth == 2) $rate = 0.03;
|
|
|
|
foreach ($directContracts as &$c) {
|
|
$c['commission'] = $c['amount'] * $rate;
|
|
$directSales += $c['amount'];
|
|
}
|
|
unset($c);
|
|
|
|
// 하위 멤버들 가져오기
|
|
$stmt = $pdo->prepare("SELECT id FROM sales_member WHERE parent_id = ? AND is_active = 1");
|
|
$stmt->execute([$parentId]);
|
|
$childrenIds = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
|
|
|
$children = [];
|
|
$totalSales = $directSales;
|
|
$totalContractCount = count($directContracts);
|
|
|
|
$commission = $directSales * $rate;
|
|
$subtreeCommission = $commission;
|
|
|
|
foreach ($childrenIds as $childId) {
|
|
$childNode = buildOrgTree($pdo, $childId, $depth + 1, $startDate, $endDate, $targetUserId);
|
|
if ($childNode) {
|
|
$children[] = $childNode;
|
|
$totalSales += $childNode['totalSales'];
|
|
$totalContractCount += $childNode['contractCount'];
|
|
$subtreeCommission += $childNode['commission']; // Aggregate commissions
|
|
}
|
|
}
|
|
|
|
// 수당 계산 (targetUserId 기준)
|
|
// targetUserId == parentId 이면 본인의 직접 판매 (20%)
|
|
// targetUserId 가 parentId의 부모이면 (depth=1) 관리자 수당 (5%)
|
|
// targetUserId 가 parentId의 조부모이면 (depth=2) 교육자 수당 (3%)
|
|
|
|
$commission = 0;
|
|
if ($parentId == $targetUserId) {
|
|
$commission = $directSales * 0.20;
|
|
} else if ($depth == 1) {
|
|
$commission = $directSales * 0.05;
|
|
} else if ($depth == 2) {
|
|
$commission = $directSales * 0.03;
|
|
}
|
|
|
|
return [
|
|
'id' => 'node_' . $member['id'],
|
|
'real_id' => $member['id'],
|
|
'name' => $member['name'],
|
|
'role' => $member['role'],
|
|
'depth' => $depth,
|
|
'isDirect' => ($parentId == $targetUserId),
|
|
'directSales' => $directSales,
|
|
'totalSales' => $totalSales,
|
|
'contractCount' => $totalContractCount,
|
|
'directCommission' => $commission,
|
|
'commission' => $subtreeCommission,
|
|
'contracts' => $directContracts,
|
|
'children' => $children
|
|
];
|
|
}
|
|
|
|
// 대상 사용자 결정
|
|
$rootUserId = $userId;
|
|
if ($userRole === 'operator' && isset($_GET['target_id'])) {
|
|
$rootUserId = $_GET['target_id'];
|
|
}
|
|
|
|
// 트리 구축 (본인 노드)
|
|
$rootNode = buildOrgTree($pdo, $rootUserId, 0, $startDate, $endDate, $rootUserId);
|
|
|
|
// 프론트엔드 형식에 맞게 내 직접 판매 노드를 children의 첫번째로 삽입
|
|
if ($rootNode) {
|
|
$directNode = [
|
|
'id' => 'root-direct',
|
|
'name' => '내 직접 판매',
|
|
'depth' => 0,
|
|
'role' => '판매자',
|
|
'isDirect' => true,
|
|
'totalSales' => $rootNode['directSales'],
|
|
'contractCount' => count($rootNode['contracts']),
|
|
'commission' => $rootNode['directSales'] * 0.20,
|
|
'contracts' => $rootNode['contracts'],
|
|
'children' => []
|
|
];
|
|
|
|
// Root node's children should include this direct node + actual children
|
|
$actualChildren = $rootNode['children'];
|
|
$rootNode['children'] = array_merge([$directNode], $actualChildren);
|
|
|
|
// Root node should keep its aggregated commission as its primary commission value
|
|
$rootNode['isDirect'] = false;
|
|
}
|
|
|
|
// 전체 누적 실적 계산 (전체 기간)
|
|
function calculateTotalStats($pdo, $parentId, $targetUserId, $depth) {
|
|
$stmt = $pdo->prepare("SELECT amount FROM sales_record WHERE member_id = ? AND status = 'completed'");
|
|
$stmt->execute([$parentId]);
|
|
$amounts = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
|
|
|
$directSales = array_sum($amounts);
|
|
$count = count($amounts);
|
|
|
|
$commission = 0;
|
|
if ($parentId == $targetUserId) $commission = $directSales * 0.20;
|
|
else if ($depth == 1) $commission = $directSales * 0.05;
|
|
else if ($depth == 2) $commission = $directSales * 0.03;
|
|
|
|
$stats = [
|
|
'totalSales' => $directSales,
|
|
'totalCommission' => $commission,
|
|
'totalCount' => $count
|
|
];
|
|
|
|
$stmt = $pdo->prepare("SELECT id FROM sales_member WHERE parent_id = ? AND is_active = 1");
|
|
$stmt->execute([$parentId]);
|
|
$children = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
|
|
|
foreach ($children as $childId) {
|
|
if ($depth < 2) { // 수당은 2단계 하위까지만
|
|
$childStats = calculateTotalStats($pdo, $childId, $targetUserId, $depth + 1);
|
|
$stats['totalSales'] += $childStats['totalSales'];
|
|
$stats['totalCommission'] += $childStats['totalCommission'];
|
|
$stats['totalCount'] += $childStats['totalCount'];
|
|
} else {
|
|
// 실적만 합산
|
|
$childStats = calculateTotalStats($pdo, $childId, $targetUserId, $depth + 1);
|
|
$stats['totalSales'] += $childStats['totalSales'];
|
|
$stats['totalCount'] += $childStats['totalCount'];
|
|
}
|
|
}
|
|
|
|
return $stats;
|
|
}
|
|
|
|
$totalStats = calculateTotalStats($pdo, $rootUserId, $rootUserId, 0);
|
|
|
|
// 역할별 수당 합계 계산 (현재 기간 트리 기반)
|
|
function summarizeCommissions($node, &$summary) {
|
|
if ($node['isDirect']) {
|
|
$summary['direct'] += $node['commission'];
|
|
} else if ($node['depth'] == 1) {
|
|
$summary['manager'] += $node['commission'];
|
|
} else if ($node['depth'] == 2) {
|
|
$summary['educator'] += $node['commission'];
|
|
}
|
|
|
|
foreach ($node['children'] as $child) {
|
|
summarizeCommissions($child, $summary);
|
|
}
|
|
}
|
|
|
|
$commissionSummary = ['direct' => 0, 'manager' => 0, 'educator' => 0];
|
|
if ($rootNode) {
|
|
summarizeCommissions($rootNode, $commissionSummary);
|
|
}
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'total_stats' => $totalStats,
|
|
'period_stats' => [
|
|
'startDate' => $startDate,
|
|
'endDate' => $endDate,
|
|
'commission_summary' => $commissionSummary,
|
|
'total_period_commission' => array_sum($commissionSummary)
|
|
],
|
|
'org_tree' => $rootNode
|
|
], JSON_UNESCAPED_UNICODE);
|
|
|
|
} catch (Exception $e) {
|
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
|
}
|