diff --git a/public_html/doc/report_region.php b/public_html/doc/report_region.php
new file mode 100644
index 0000000..b96a9f0
--- /dev/null
+++ b/public_html/doc/report_region.php
@@ -0,0 +1,2096 @@
+checkLevelModal(9);
+
+
+// =========================================================================
+// 2. 날짜 파라미터 처리 및 보안 정제 (처음 진입 시 '해당 월 말일' 기본 지정)
+// =========================================================================
+$start_date = isset($_REQUEST['start_date']) && trim($_REQUEST['start_date']) !== ''
+ ? trim($_REQUEST['start_date'])
+ : date('Y-m-01');
+
+$end_date = isset($_REQUEST['end_date']) && trim($_REQUEST['end_date']) !== ''
+ ? trim($_REQUEST['end_date'])
+ : date('Y-m-t');
+
+$start_date_esc = preg_replace("/[^0-9-]/", "", $start_date);
+$end_date_esc = preg_replace("/[^0-9-]/", "", $end_date);
+
+$today_date = date('Y-m-d');
+
+
+// =========================================================================
+// 3-1. [쿼리 1] 지역별 통계 데이터 조회
+// =========================================================================
+$summary_sql = "
+ SELECT
+ A.c_regionuid AS region_uid,
+ CONCAT(
+ MAX(A.c_region),
+ '(',
+ MAX(COALESCE(
+ NULLIF(M.m_initial, ''),
+ CONCAT(UPPER(LEFT(M.m_firstname,1)), '.', UPPER(LEFT(M.m_lastname,1)))
+ )),
+ ')'
+ ) AS region_name,
+ COUNT(DISTINCT CASE WHEN A.c_contractdate IS NOT NULL
+ AND A.c_contractdate != ''
+ AND A.c_contractdate != '0000-00-00'
+ AND DATE_FORMAT(A.c_contractdate, '%Y-%m-%d') BETWEEN '$start_date_esc' AND '$end_date_esc'
+ THEN A.c_uid ELSE NULL END) AS plus_count,
+ COUNT(DISTINCT CASE WHEN A.c_inactivedate IS NOT NULL
+ AND A.c_inactivedate != ''
+ AND A.c_inactivedate != '0000-00-00'
+ AND DATE_FORMAT(A.c_inactivedate, '%Y-%m-%d') BETWEEN '$start_date_esc' AND '$end_date_esc'
+ THEN A.c_uid ELSE NULL END) AS minus_count,
+ COUNT(DISTINCT CASE
+ WHEN (A.c_contractdate IS NOT NULL AND A.c_contractdate != '' AND A.c_contractdate != '0000-00-00' AND DATE_FORMAT(A.c_contractdate, '%Y-%m-%d') <= '$end_date_esc')
+ AND (A.c_inactivedate IS NULL OR A.c_inactivedate = '' OR A.c_inactivedate = '0000-00-00' OR DATE_FORMAT(A.c_inactivedate, '%Y-%m-%d') > '$end_date_esc')
+ THEN A.c_uid ELSE NULL END) AS current_total,
+ SUM(CASE WHEN B.cc_install_date IS NOT NULL
+ AND B.cc_install_date != ''
+ AND B.cc_install_date != '0000-00-00'
+ AND DATE_FORMAT(B.cc_install_date, '%Y-%m-%d') BETWEEN '$start_date_esc' AND '$end_date_esc'
+ THEN 1 ELSE 0 END) AS container_plus_count,
+ SUM(CASE WHEN B.cc_pickup_date IS NOT NULL
+ AND B.cc_pickup_date != ''
+ AND B.cc_pickup_date != '0000-00-00'
+ AND DATE_FORMAT(B.cc_pickup_date, '%Y-%m-%d') BETWEEN '$start_date_esc' AND '$end_date_esc'
+ THEN 1 ELSE 0 END) AS container_minus_count,
+ SUM(CASE WHEN B.cc_customer_uid IS NOT NULL
+ AND (B.cc_install_date IS NOT NULL AND B.cc_install_date != '' AND B.cc_install_date != '0000-00-00' AND DATE_FORMAT(B.cc_install_date, '%Y-%m-%d') <= '$end_date_esc')
+ AND (B.cc_pickup_date IS NULL OR B.cc_pickup_date = '' OR B.cc_pickup_date = '0000-00-00' OR DATE_FORMAT(B.cc_pickup_date, '%Y-%m-%d') > '$end_date_esc')
+ THEN 1 ELSE 0 END) AS current_container_total
+
+ FROM tbl_customer A
+ LEFT JOIN tbl_customer_container B ON A.c_uid = B.cc_customer_uid
+ LEFT JOIN tbl_member M ON A.c_regionuid = M.m_regionuid
+ GROUP BY A.c_regionuid
+ ORDER BY
+ CASE WHEN A.c_regionuid IS NULL OR A.c_regionuid = '' OR A.c_regionuid = '0' THEN 1 ELSE 0 END ASC,
+ CAST(A.c_regionuid AS UNSIGNED) ASC
+";
+$summary_result = $jdb->nQuery($summary_sql, "summary query error");
+
+
+// =========================================================================
+// 3-1-2. [쿼리 1-2] 지역별 기름 통계 데이터 조회 (TBL_DAILY 연동)
+// =========================================================================
+$rd_start = str_replace('-', '', $start_date_esc);
+$rd_end = str_replace('-', '', $end_date_esc);
+
+$oil_sql = "
+ SELECT
+ M.m_regionuid AS region_uid,
+ SUM(RD.rd_quantity) AS total_pickup_qty,
+ SUM(RD.rd_visit) AS total_visit_cnt
+ FROM tbl_report_daily RD
+ INNER JOIN tbl_member M ON RD.rd_driveruid = M.m_uid
+ WHERE RD.rd_orderdate BETWEEN '{$rd_start}' AND '{$rd_end}'
+ GROUP BY M.m_regionuid
+";
+$oil_result = $jdb->nQuery($oil_sql, "oil daily query error");
+
+$oil_data_map = [];
+if ($oil_result) {
+ while ($row = mysqli_fetch_array($oil_result, MYSQLI_ASSOC)) {
+ $r_uid = !$row['region_uid'] || $row['region_uid'] == '0' ? '0' : $row['region_uid'];
+ $oil_data_map[$r_uid] = [
+ 'pickup_qty' => (float)$row['total_pickup_qty'],
+ 'visit_cnt' => (int)$row['total_visit_cnt']
+ ];
+ }
+}
+
+// =========================================================================
+// 3-1-3. [쿼리 1-3] 신규 고객 기반 오일 픽업량 & 방문수
+// =========================================================================
+$new_customer_oil_sql = "
+ SELECT
+ d.d_regionuid AS region_uid,
+ MAX(d.d_region) AS region_name,
+ COUNT(DISTINCT d.d_customeruid) AS new_customer_cnt,
+ SUM(d.d_quantity) AS oil_pickup_qty,
+ SUM(CASE WHEN d.d_quantity IS NOT NULL THEN 1 ELSE 0 END) AS visit_cnt
+ FROM tbl_daily d
+ WHERE d.d_customeruid IN (
+ SELECT c_uid
+ FROM tbl_customer
+ WHERE c_contractdate IS NOT NULL
+ AND c_contractdate != ''
+ AND c_contractdate != '0000-00-00'
+ AND DATE_FORMAT(c_contractdate, '%Y-%m-%d') BETWEEN '$start_date_esc' AND '$end_date_esc'
+ )
+ AND d.d_orderdate BETWEEN '{$rd_start}' AND '{$rd_end}'
+ GROUP BY d.d_regionuid
+ ORDER BY CAST(d.d_regionuid AS UNSIGNED)
+";
+$new_customer_oil_result = $jdb->nQuery($new_customer_oil_sql, "new customer oil query error");
+
+$new_oil_data_map = [];
+$total_new_customer_oil = 0;
+$total_new_customer_visit = 0;
+if ($new_customer_oil_result) {
+ while ($row = mysqli_fetch_array($new_customer_oil_result, MYSQLI_ASSOC)) {
+ $r_uid = !$row['region_uid'] || $row['region_uid'] == '0' ? '0' : $row['region_uid'];
+ $new_oil_data_map[$r_uid] = [
+ 'oil_pickup_qty' => (float)$row['oil_pickup_qty'],
+ 'visit_cnt' => (int)$row['visit_cnt'],
+ ];
+ $total_new_customer_oil += (float)$row['oil_pickup_qty'];
+ $total_new_customer_visit += (int)$row['visit_cnt'];
+ }
+}
+
+
+// =========================================================================
+// 3-2. 결제수단별 통계 데이터 조회
+// =========================================================================
+$pay_sql = "
+ SELECT
+ c_regionuid AS region_uid,
+ MAX(c_region) AS region_name,
+ c_paymenttype AS payment_code,
+ SUM(CASE WHEN c_contractdate IS NOT NULL
+ AND c_contractdate != ''
+ AND c_contractdate != '0000-00-00'
+ AND DATE_FORMAT(c_contractdate, '%Y-%m-%d') BETWEEN '$start_date_esc' AND '$end_date_esc'
+ THEN 1 ELSE 0 END) AS plus_count,
+ SUM(CASE WHEN c_inactivedate IS NOT NULL
+ AND c_inactivedate != ''
+ AND c_inactivedate != '0000-00-00'
+ AND DATE_FORMAT(c_inactivedate, '%Y-%m-%d') BETWEEN '$start_date_esc' AND '$end_date_esc'
+ THEN 1 ELSE 0 END) AS minus_count,
+ SUM(CASE WHEN (c_contractdate IS NOT NULL AND c_contractdate != '' AND c_contractdate != '0000-00-00' AND DATE_FORMAT(c_contractdate, '%Y-%m-%d') <= '$end_date_esc')
+ AND (c_inactivedate IS NULL OR c_inactivedate = '' OR c_inactivedate = '0000-00-00' OR DATE_FORMAT(c_inactivedate, '%Y-%m-%d') > '$end_date_esc')
+ THEN 1 ELSE 0 END) AS current_total
+
+ FROM tbl_customer
+ GROUP BY c_regionuid, c_paymenttype
+ ORDER BY
+ CASE WHEN c_regionuid IS NULL OR c_regionuid = '' OR c_regionuid = '0' THEN 1 ELSE 0 END ASC,
+ CAST(c_regionuid AS UNSIGNED) ASC
+";
+$pay_result = $jdb->nQuery($pay_sql, "payment query error");
+
+
+// =========================================================================
+// 3-3. 컨테이너 종류별 전체 통계 (B, D, ETC 3대 그룹)
+// =========================================================================
+$type_cap_sql = "
+ SELECT
+ CASE
+ WHEN cc_type LIKE '%BUCKET%' THEN 'ETC'
+ WHEN cc_type LIKE '%B%' THEN 'B'
+ WHEN cc_type LIKE '%D%' THEN 'D'
+ ELSE 'ETC'
+ END AS container_group,
+ SUM(CASE WHEN cc_install_date IS NOT NULL AND cc_install_date != '' AND cc_install_date != '0000-00-00' AND DATE_FORMAT(cc_install_date, '%Y-%m-%d') BETWEEN '$start_date_esc' AND '$end_date_esc' THEN 1 ELSE 0 END) AS plus_count,
+ SUM(CASE WHEN cc_pickup_date IS NOT NULL AND cc_pickup_date != '' AND cc_pickup_date != '0000-00-00' AND DATE_FORMAT(cc_pickup_date, '%Y-%m-%d') BETWEEN '$start_date_esc' AND '$end_date_esc' THEN 1 ELSE 0 END) AS minus_count,
+ SUM(CASE WHEN cc_customer_uid IS NOT NULL AND (cc_install_date IS NOT NULL AND cc_install_date != '' AND cc_install_date != '0000-00-00' AND DATE_FORMAT(cc_install_date, '%Y-%m-%d') <= '$end_date_esc') AND (cc_pickup_date IS NULL OR cc_pickup_date = '' OR cc_pickup_date = '0000-00-00' OR DATE_FORMAT(cc_pickup_date, '%Y-%m-%d') > '$end_date_esc') THEN 1 ELSE 0 END) AS current_total
+ FROM tbl_customer_container
+ WHERE cc_type IS NOT NULL AND cc_type != ''
+ AND (cc_pickup_date IS NULL OR cc_pickup_date = '' OR cc_pickup_date = '0000-00-00' OR DATE_FORMAT(cc_pickup_date, '%Y-%m-%d') >= '$start_date_esc')
+ GROUP BY
+ CASE
+ WHEN cc_type LIKE '%BUCKET%' THEN 'ETC'
+ WHEN cc_type LIKE '%B%' THEN 'B'
+ WHEN cc_type LIKE '%D%' THEN 'D'
+ ELSE 'ETC'
+ END
+ ORDER BY
+ CASE
+ WHEN container_group = 'B' THEN 1
+ WHEN container_group = 'D' THEN 2
+ ELSE 3
+ END ASC
+";
+$type_cap_result = $jdb->nQuery($type_cap_sql, "container type query error");
+
+
+// =========================================================================
+// 3-4. 지역별 X 컨테이너 대분류 교차 통계
+// =========================================================================
+$region_type_sql = "
+ SELECT
+ A.c_regionuid AS region_uid,
+ MAX(A.c_region) AS region_name,
+ CASE
+ WHEN B.cc_type LIKE '%BUCKET%' THEN 'ETC'
+ WHEN B.cc_type LIKE '%B%' THEN 'B'
+ WHEN B.cc_type LIKE '%D%' THEN 'D'
+ ELSE 'ETC'
+ END AS container_group,
+ SUM(CASE WHEN B.cc_install_date IS NOT NULL AND B.cc_install_date != '' AND B.cc_install_date != '0000-00-00' AND DATE_FORMAT(B.cc_install_date, '%Y-%m-%d') BETWEEN '$start_date_esc' AND '$end_date_esc' THEN 1 ELSE 0 END) AS plus_count,
+ SUM(CASE WHEN B.cc_pickup_date IS NOT NULL AND B.cc_pickup_date != '' AND B.cc_pickup_date != '0000-00-00' AND DATE_FORMAT(B.cc_pickup_date, '%Y-%m-%d') BETWEEN '$start_date_esc' AND '$end_date_esc' THEN 1 ELSE 0 END) AS minus_count,
+ SUM(CASE WHEN B.cc_customer_uid IS NOT NULL AND (B.cc_install_date IS NOT NULL AND B.cc_install_date != '' AND B.cc_install_date != '0000-00-00' AND DATE_FORMAT(B.cc_install_date, '%Y-%m-%d') <= '$end_date_esc') AND (B.cc_pickup_date IS NULL OR B.cc_pickup_date = '' OR B.cc_pickup_date = '0000-00-00' OR DATE_FORMAT(B.cc_pickup_date, '%Y-%m-%d') > '$end_date_esc') THEN 1 ELSE 0 END) AS current_total
+ FROM tbl_customer A
+ LEFT JOIN tbl_customer_container B ON A.c_uid = B.cc_customer_uid
+ AND (B.cc_pickup_date IS NULL OR B.cc_pickup_date = '' OR B.cc_pickup_date = '0000-00-00' OR DATE_FORMAT(B.cc_pickup_date, '%Y-%m-%d') >= '$start_date_esc')
+ GROUP BY A.c_regionuid,
+ CASE
+ WHEN B.cc_type LIKE '%BUCKET%' THEN 'ETC'
+ WHEN B.cc_type LIKE '%B%' THEN 'B'
+ WHEN B.cc_type LIKE '%D%' THEN 'D'
+ ELSE 'ETC'
+ END
+ ORDER BY
+ CASE WHEN A.c_regionuid IS NULL OR A.c_regionuid = '' OR A.c_regionuid = '0' THEN 1 ELSE 0 END ASC,
+ CAST(A.c_regionuid AS UNSIGNED) ASC,
+ CASE
+ WHEN container_group = 'B' THEN 1
+ WHEN container_group = 'D' THEN 2
+ ELSE 3
+ END ASC
+";
+$region_type_result = $jdb->nQuery($region_type_sql, "region type query error");
+
+
+// =========================================================================
+// 4-1. 지역별 통계 기본 구조 빌드
+// =========================================================================
+$region_data_list = [];
+
+$total_plus = 0; $total_minus = 0; $total_net = 0; $total_current = 0;
+$total_con_plus = 0; $total_con_minus = 0; $total_con_net = 0; $total_container = 0;
+$total_oil_pickup = 0; $total_oil_visit = 0;
+
+$chart_region_labels = [];
+$chart_region_data = [];
+$chart_container_data = [];
+
+if ($summary_result) {
+ while ($row = mysqli_fetch_array($summary_result, MYSQLI_ASSOC)) {
+ if (!$row['region_uid'] || $row['region_uid'] == '0' || $row['region_name'] == 'EXT') {
+ continue;
+ }
+ $pureRegionName = $row['region_name'] ? $row['region_name'] : "NO NAME";
+ $regionDisplay = htmlspecialchars($pureRegionName);
+ $r_uid = $row['region_uid'];
+
+ $p_cnt = (int)$row['plus_count'];
+ $m_cnt = (int)$row['minus_count'];
+ $c_cnt = (int)$row['current_total'];
+ $con_p_cnt = (int)$row['container_plus_count'];
+ $con_m_cnt = (int)$row['container_minus_count'];
+ $con_cnt = (int)$row['current_container_total'];
+ $net_count = $p_cnt - $m_cnt;
+ $con_net_count = $con_p_cnt - $con_m_cnt;
+
+ $oil_pickup = isset($oil_data_map[$r_uid]) ? (float)$oil_data_map[$r_uid]['pickup_qty'] : 0;
+ $oil_visit = isset($oil_data_map[$r_uid]) ? (int)$oil_data_map[$r_uid]['visit_cnt'] : 0;
+
+ $region_data_list[] = [
+ 'r_uid' => $r_uid,
+ 'display_name' => $regionDisplay,
+ 'p_cnt' => $p_cnt,
+ 'm_cnt' => $m_cnt,
+ 'net_count' => $net_count,
+ 'c_cnt' => $c_cnt,
+ 'con_p_cnt' => $con_p_cnt,
+ 'con_m_cnt' => $con_m_cnt,
+ 'con_net_count' => $con_net_count,
+ 'con_cnt' => $con_cnt,
+ 'oil_pickup' => $oil_pickup,
+ 'oil_visit' => $oil_visit
+ ];
+
+ $total_plus += $p_cnt;
+ $total_minus += $m_cnt;
+ $total_net += $net_count;
+ $total_current += $c_cnt;
+ $total_con_plus += $con_p_cnt;
+ $total_con_minus += $con_m_cnt;
+ $total_con_net += $con_net_count;
+ $total_container += $con_cnt;
+ $total_oil_pickup += $oil_pickup;
+ $total_oil_visit += $oil_visit;
+
+ $chart_region_labels[] = $pureRegionName;
+ $chart_region_data[] = $c_cnt;
+ $chart_container_data[] = $con_cnt;
+ }
+}
+
+// 결제수단 매트릭스
+$chart_pay_labels = [];
+$chart_pay_data = [];
+$pay_matrix_methods = [];
+$pay_matrix_data = [];
+$pay_method_totals = [];
+
+if ($pay_result) {
+ mysqli_data_seek($pay_result, 0);
+ while ($row = mysqli_fetch_array($pay_result, MYSQLI_ASSOC)) {
+ if (!$row['region_uid'] || $row['region_uid'] == '0' || $row['region_name'] == 'EXT' || $row['payment_code'] == 'EXT') {
+ continue;
+ }
+ $r_uid = $row['region_uid'];
+ $pay_name = htmlspecialchars($row['payment_code']);
+
+ if (!in_array($pay_name, $pay_matrix_methods)) {
+ $pay_matrix_methods[] = $pay_name;
+ }
+
+ $p_cnt = (int)$row['plus_count'];
+ $m_cnt = (int)$row['minus_count'];
+ $c_cnt = (int)$row['current_total'];
+ $net_cnt = $p_cnt - $m_cnt;
+
+ if (!isset($pay_matrix_data[$pay_name][$r_uid])) {
+ $pay_matrix_data[$pay_name][$r_uid] = ['p' => 0, 'm' => 0, 'net' => 0, 'c' => 0];
+ }
+ $pay_matrix_data[$pay_name][$r_uid]['p'] += $p_cnt;
+ $pay_matrix_data[$pay_name][$r_uid]['m'] += $m_cnt;
+ $pay_matrix_data[$pay_name][$r_uid]['net'] += $net_cnt;
+ $pay_matrix_data[$pay_name][$r_uid]['c'] += $c_cnt;
+
+ if (!isset($pay_method_totals[$pay_name])) $pay_method_totals[$pay_name] = 0;
+ $pay_method_totals[$pay_name] += $c_cnt;
+ }
+
+ usort($pay_matrix_methods, function($a, $b) use ($pay_method_totals) {
+ $ta = $pay_method_totals[$a] ?? 0;
+ $tb = $pay_method_totals[$b] ?? 0;
+ if ($ta === $tb) return 0;
+ return ($ta > $tb) ? -1 : 1;
+ });
+}
+
+// =========================================================================
+// 4-3. B, D, ETC 3대 분류 데이터 수집
+// =========================================================================
+$tc_data_list = [];
+$tc_total_plus = 0; $tc_total_minus = 0; $tc_total_net = 0; $tc_total_current = 0;
+
+$temp_groups = [
+ 'B' => ['p' => 0, 'm' => 0, 'c' => 0],
+ 'D' => ['p' => 0, 'm' => 0, 'c' => 0],
+ 'ETC' => ['p' => 0, 'm' => 0, 'c' => 0]
+];
+
+if ($type_cap_result) {
+ mysqli_data_seek($type_cap_result, 0);
+ while ($row = mysqli_fetch_array($type_cap_result, MYSQLI_ASSOC)) {
+ $group_type = $row['container_group'] ? $row['container_group'] : "ETC";
+ if (isset($temp_groups[$group_type])) {
+ $temp_groups[$group_type]['p'] += (int)$row['plus_count'];
+ $temp_groups[$group_type]['m'] += (int)$row['minus_count'];
+ $temp_groups[$group_type]['c'] += (int)$row['current_total'];
+ }
+ }
+}
+
+foreach (['B', 'D', 'ETC'] as $g_name) {
+ $p_cnt = $temp_groups[$g_name]['p'];
+ $m_cnt = $temp_groups[$g_name]['m'];
+ $c_cnt = $temp_groups[$g_name]['c'];
+ $net_count = $p_cnt - $m_cnt;
+
+ $tc_data_list[] = [
+ 'display_name' => "
" . $g_name . "",
+ 'p_cnt' => $p_cnt,
+ 'm_cnt' => $m_cnt,
+ 'net_count' => $net_count,
+ 'c_cnt' => $c_cnt
+ ];
+
+ $tc_total_plus += $p_cnt;
+ $tc_total_minus += $m_cnt;
+ $tc_total_net += $net_count;
+ $tc_total_current += $c_cnt;
+}
+
+$chart_tc_labels = ['B', 'D', 'ETC'];
+$chart_tc_data = [
+ (int)$temp_groups['B']['c'],
+ (int)$temp_groups['D']['c'],
+ (int)$temp_groups['ETC']['c']
+];
+
+// =========================================================================
+// 4-4. 가로(지역) X 세로(B, D, ETC) 교차 매트릭스 빌드
+// =========================================================================
+$matrix_regions = [];
+$matrix_types = ['B', 'D', 'ETC'];
+$matrix_data = [];
+
+if (!empty($region_data_list)) {
+ if ($summary_result) {
+ mysqli_data_seek($summary_result, 0);
+ while ($s_row = mysqli_fetch_array($summary_result, MYSQLI_ASSOC)) {
+ if (!$s_row['region_uid'] || $s_row['region_uid'] == '0' || $s_row['region_name'] == 'EXT') {
+ continue;
+ }
+ $r_uid = $s_row['region_uid'];
+ $r_name = $s_row['region_name'] ? $s_row['region_name'] : "NO NAME";
+ $matrix_regions[$r_uid] = htmlspecialchars($r_name);
+ }
+ }
+}
+
+foreach ($matrix_types as $g_name) {
+ foreach ($matrix_regions as $r_uid => $r_name) {
+ $matrix_data[$g_name][$r_uid] = ['p' => 0, 'm' => 0, 'net' => 0, 'c' => 0];
+ }
+}
+
+if ($region_type_result) {
+ mysqli_data_seek($region_type_result, 0);
+ while ($row = mysqli_fetch_array($region_type_result, MYSQLI_ASSOC)) {
+ if (!$row['region_uid'] || $row['region_uid'] == '0' || $row['region_name'] == 'EXT') {
+ continue;
+ }
+ $r_uid = $row['region_uid'];
+ $group_type = $row['container_group'] ? $row['container_group'] : 'ETC';
+
+ if (isset($matrix_data[$group_type][$r_uid])) {
+ $p_cnt = (int)$row['plus_count'];
+ $m_cnt = (int)$row['minus_count'];
+ $c_cnt = (int)$row['current_total'];
+
+ $matrix_data[$group_type][$r_uid]['p'] += $p_cnt;
+ $matrix_data[$group_type][$r_uid]['m'] += $m_cnt;
+ $matrix_data[$group_type][$r_uid]['net'] += ($p_cnt - $m_cnt);
+ $matrix_data[$group_type][$r_uid]['c'] += $c_cnt;
+ }
+ }
+}
+
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
CUSTOMER & CONTAINER STATS REPORT
+
+ - HOME
+ - REPORT
+ - CUSTOMER REPORT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Region-wise Customer, Container & Oil Stats
+
+
+
+
+
+
+
+ | Classification |
+
+
+ =$r_data['display_name']?> |
+
+ TOTAL |
+
+ No Data |
+
+
+
+
+
+
+
+
+ | +=number_format($r_data['p_cnt'])?> |
+
+ +=number_format($total_plus)?> |
+
+
+
+
+ | -=number_format($r_data['m_cnt'])?> |
+
+ -=number_format($total_minus)?> |
+
+
+
+ 0 ? "txt-plus" : ($r_data['net_count'] < 0 ? "txt-minus" : "");
+ $net_sign = $r_data['net_count'] > 0 ? "+" : "";
+ ?>
+ | =$net_sign.number_format($r_data['net_count'])?> |
+
+ 0 ? "txt-plus" : ($total_net < 0 ? "txt-minus" : "");
+ $t_net_sign = $total_net > 0 ? "+" : "";
+ ?>
+ =$t_net_sign.number_format($total_net)?> |
+
+
+
+
+ | =number_format($r_data['c_cnt'])?> |
+
+ =number_format($total_current)?> |
+
+
+
+ |
+
+
+
+
+
+ | +=number_format($r_data['con_p_cnt'])?> |
+
+ +=number_format($total_con_plus)?> |
+
+
+
+
+ | -=number_format($r_data['con_m_cnt'])?> |
+
+ -=number_format($total_con_minus)?> |
+
+
+
+ 0 ? "txt-plus" : ($r_data['con_net_count'] < 0 ? "txt-minus" : "");
+ $con_net_sign = $r_data['con_net_count'] > 0 ? "+" : "";
+ ?>
+ | =$con_net_sign.number_format($r_data['con_net_count'])?> |
+
+ 0 ? "txt-plus" : ($total_con_net < 0 ? "txt-minus" : "");
+ $t_con_net_sign = $total_con_net > 0 ? "+" : "";
+ ?>
+ =$t_con_net_sign.number_format($total_con_net)?> |
+
+
+
+
+ | =number_format($r_data['con_cnt'])?> |
+
+ =number_format($total_container)?> |
+
+
+
+ |
+
+
+
+ | Oil Pickup Quantity (L) |
+
+ =number_format(floatval($r_data['oil_pickup']))?> |
+
+ =number_format(floatval($total_oil_pickup))?> |
+
+
+ | Total Visit Count |
+
+ =number_format($r_data['oil_visit'])?> |
+
+ =number_format($total_oil_visit)?> |
+
+
+ | Avg. Qty per Visit |
+ 0 ? round($r_data['oil_pickup'] / $r_data['oil_visit'], 1) : 0;
+ ?>
+ =number_format($avg, 1)?> |
+
+ 0 ? round($total_oil_pickup / $total_oil_visit, 1) : 0; ?>
+ =number_format($total_avg, 1)?> |
+
+
+
+ | No records found for the selected period. |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Region-wise Customer Trend Breakdowns
+
+
+
+
+
+
Customer Trend Analysis
+
Customer Growth and Trend Analysis by Region (GH excluded)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
New Customer — Oil Pickup & Visit Stats
+
+
+
+
+
+
+
+
+
+ | Classification |
+
+ =$r_data['display_name']?> |
+
+ TOTAL |
+
+
+
+
+ | New Customer (#) |
+
+ +=number_format($r_data['p_cnt'])?> |
+
+ +=number_format($total_plus)?> |
+
+
+ | Oil Pickup Qty (L) |
+
+ =number_format($oil_qty, 1)?> |
+
+ =number_format($total_new_customer_oil, 1)?> |
+
+
+ | Visit Count |
+
+ =number_format($v_cnt)?> |
+
+ =number_format($total_new_customer_visit)?> |
+
+
+ | Avg Oil / New Customer (L) |
+ 0 ? round($o / $n, 1) : 0;
+ ?>
+ =number_format($avg, 1)?> |
+
+ 0 ? round($total_new_customer_oil / $total_plus, 1) : 0; ?>
+ =number_format($t_avg, 1)?> |
+
+
+
+
+
+
+ $nc_max_new) $nc_max_new = (int)$r_data['p_cnt'];
+ $oil_v = isset($new_oil_data_map[$r_data['r_uid']]) ? (float)$new_oil_data_map[$r_data['r_uid']]['oil_pickup_qty'] : 0;
+ if ($oil_v > $nc_max_oil) $nc_max_oil = $oil_v;
+ }
+ ?>
+
+
+
+ New customers
+ |
+ Oil qty (L)
+
+
+ Total new: =number_format($nc_total_new)?>
+ Total oil: =number_format($nc_total_oil, 0)?> L
+
+
+
+
+ 0;
+ $nPct = $nc_max_new > 0 ? round($n / $nc_max_new * 100) : 0;
+ $oPct = $nc_max_oil > 0 ? round($oil / $nc_max_oil * 100) : 0;
+ $oilText = $hasOil ? number_format($oil, 0) . ' L' : '—';
+ ?>
+
+
=$r_data['display_name']?>
+
+
+
+ Oil
+ =$oilText?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Region × Container Specification Cross Analysis
+
+
+
+
+
+
+ | Container Specification |
+ Classification |
+
+ $r_name): ?>
+ =$r_name?> |
+
+ TOTAL |
+
+ No Data |
+
+
+
+
+
+
+
+
+
+ | =$type_key?> |
+ Installed (+) |
+ $r_name): ?>
+
+ =($val > 0 ? "+".number_format($val) : "0")?> |
+
+ +=number_format($row_total_p)?> |
+
+
+ | Picked up (-) |
+ $r_name): ?>
+
+ =($val > 0 ? "-".number_format($val) : "0")?> |
+
+ -=number_format($row_total_m)?> |
+
+
+ | Net Change |
+ $r_name): ?>
+ 0 ? "txt-plus" : ($val < 0 ? "txt-minus" : "");
+ $nc_sign = $val > 0 ? "+" : "";
+ ?>
+ =$nc_sign.number_format($val)?> |
+
+ 0 ? "txt-plus" : ($row_total_net < 0 ? "txt-minus" : "");
+ $rt_nc_sign = $row_total_net > 0 ? "+" : "";
+ ?>
+ =$rt_nc_sign.number_format($row_total_net)?> |
+
+
+ | Active Total |
+ $r_name): ?>
+
+ =number_format($val)?> |
+
+ =number_format($row_total_c)?> |
+
+
+
+
+
+ | TOTAL MATRIX MAP |
+ Total Installed (+) |
+ $r_name): ?>
+ +=number_format($grand_col_p[$r_uid] ?? 0)?> |
+
+ +=number_format($total_of_all_p)?> |
+
+
+ | Total Picked up (-) |
+ $r_name): ?>
+ -=number_format($grand_col_m[$r_uid] ?? 0)?> |
+
+ -=number_format($total_of_all_m)?> |
+
+
+ | Total Net Change |
+ $r_name):
+ $g_net = $grand_col_net[$r_uid] ?? 0;
+ $gn_class = $g_net > 0 ? "txt-plus" : ($g_net < 0 ? "txt-minus" : "");
+ $gn_sign = $g_net > 0 ? "+" : "";
+ ?>
+ =$gn_sign.number_format($g_net)?> |
+
+ 0 ? "txt-plus" : ($total_of_all_net < 0 ? "txt-minus" : "");
+ $tot_gn_sign = $total_of_all_net > 0 ? "+" : "";
+ ?>
+ =$tot_gn_sign.number_format($total_of_all_net)?> |
+
+
+ | Total Active Volume |
+ $r_name): ?>
+ =number_format($grand_col_c[$r_uid] ?? 0)?> |
+
+ =number_format($total_of_all_c)?> |
+
+
+ | Insufficient data to generate the cross-analysis matrix. |
+
+
+
+
+
+
+
+
+ $r_name) {
+ $chart2_regions[$r_uid] = $r_name;
+ }
+ }
+ $chart2_types = ['B', 'D', 'ETC'];
+ $chart2_combined_data = [];
+ if (!empty($matrix_data)) {
+ foreach ($chart2_types as $g_name) {
+ if (!isset($matrix_data[$g_name])) continue;
+ foreach ($matrix_data[$g_name] as $r_uid => $val) {
+ $chart2_combined_data[$g_name][$r_uid] = [
+ 'c' => isset($val['c']) ? (int)$val['c'] : 0,
+ 'p' => isset($val['p']) ? (int)$val['p'] : 0,
+ 'm' => isset($val['m']) ? (int)$val['m'] : 0
+ ];
+ }
+ }
+ }
+ ?>
+
+
+
+
+
+
+
+
Region × Container Specification Independent Analysis
+
+
+
+
+
+
+
Active Container
+
Current Count by Container Specification
+
+
+
+
Install / Pickup Trend
+
Installation and Collection Status During the Period
+
+
+
+
+
+
+
+
+
+
+
+
+
Region × Payment Method Cross Analysis
+
+
+
+
+
+
+
+ | Payment Method |
+ Classification |
+
+ $r_name): ?>
+ =$r_name?> |
+
+ TOTAL |
+
+ No Region Registered |
+
+
+
+
+
+
+
+
+ 3) ? 'hidden-method-row' : '';
+ $row_hidden_style = ($method_counter > 3) ? 'display: none;' : '';
+ ?>
+
+ | =$method_name?> |
+ New (+) |
+ $r_name): ?>
+
+ =($val > 0 ? "+".number_format($val) : "0")?> |
+
+ +=number_format($row_pay_p)?> |
+
+
+ | Inact (-) |
+ $r_name): ?>
+
+ =($val > 0 ? "-".number_format($val) : "0")?> |
+
+ -=number_format($row_pay_m)?> |
+
+
+ | Net Change |
+ $r_name): ?>
+ 0 ? "txt-plus" : ($val < 0 ? "txt-minus" : "");
+ $nc_sign = $val > 0 ? "+" : "";
+ ?>
+ =$nc_sign.number_format($val)?> |
+
+ 0 ? "txt-plus" : ($row_pay_net < 0 ? "txt-minus" : "");
+ $r_nc_sign = $row_pay_net > 0 ? "+" : "";
+ ?>
+ =$r_nc_sign.number_format($row_pay_net)?> |
+
+
+ | Active Total |
+ $r_name): ?>
+
+ =number_format($val)?> |
+
+ =number_format($row_pay_c)?> |
+
+
+
+
+
+ | TOTAL PAYMENT MAP |
+ Total New (+) |
+ $r_name): $v = $grand_pay_col_p[$r_uid] ?? 0; ?>
+ +=number_format($v)?> |
+
+ +=number_format($total_of_pay_all_p)?> |
+
+
+ | Total Inact (-) |
+ $r_name): $v = $grand_pay_col_m[$r_uid] ?? 0; ?>
+ -=number_format($v)?> |
+
+ -=number_format($total_of_pay_all_m)?> |
+
+
+ | Total Net Change |
+ $r_name):
+ $v = $grand_pay_col_net[$r_uid] ?? 0;
+ $g_nc_class = $v > 0 ? "txt-plus" : ($v < 0 ? "txt-minus" : "");
+ $g_nc_sign = $v > 0 ? "+" : "";
+ ?>
+ =$g_nc_sign.number_format($v)?> |
+
+ 0 ? "txt-plus" : ($total_of_pay_all_net < 0 ? "txt-minus" : "");
+ $m_tot_nc_sign = $total_of_pay_all_net > 0 ? "+" : "";
+ ?>
+ =$m_tot_nc_sign.number_format($total_of_pay_all_net)?> |
+
+
+ | Total Active Volume |
+ $r_name): $v = $grand_pay_col_c[$r_uid] ?? 0; ?>
+ =number_format($v)?> |
+
+ =number_format($total_of_pay_all_c)?> |
+
+
+ | The payment method data could not be parsed. |
+
+
+
+
+
+ 3): ?>
+
+
+ See More (+=count($pay_matrix_methods) - 3?>) ▼
+
+
+
+
+
+
+ $r_name) {
+ $sum_c += $pay_matrix_data[$mname][$r_uid]['c'] ?? 0;
+ $sum_p += $pay_matrix_data[$mname][$r_uid]['p'] ?? 0;
+ $sum_m += $pay_matrix_data[$mname][$r_uid]['m'] ?? 0;
+ }
+ $pay_chart_methods[] = ['method' => $mname, 'c' => $sum_c, 'p' => $sum_p, 'm' => $sum_m];
+ }
+ $pay_chart_regions_json = json_encode(array_values($matrix_regions));
+ $pay_chart_methods_json = json_encode($pay_matrix_methods);
+ $pay_chart_matrix_json = json_encode($pay_matrix_data);
+ $pay_chart_regions_keys = json_encode(array_keys($matrix_regions));
+ ?>
+
+
+
+
+
+
+
Region × Payment Method
+
+
+
+
+
+
+
Active Total Share
+
+
+
+
+
+
+
Active Total by Region
+
Current Number of Accounts Managed by Payment Method
+
+
+
+
New (+) & Inact (−) by Method
+
Change by Payment Method During the Period
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public_html/include/top.php b/public_html/include/top.php
index a8b9654..6cc3fc6 100644
--- a/public_html/include/top.php
+++ b/public_html/include/top.php
@@ -91,6 +91,7 @@ $canExport = in_array($level, [1, 5, 6, 7]);
MONTHLY-AREA
MONTHLY-DRIVER
DAILY
+
REGION
------------------
MONTHLY-AREA(~2023)
DAILY(~2023)