5) {
sleep(1);
header("Location:" . $WebSite . "login/login_form.php");
exit;
}
// 에러 표시 설정
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// HTML 헤더 로드
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
$title_message = '월별 수입/지출 예상내역서';
// 데이터베이스 연결 설정 파일 로드
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
// DB명 하드코딩 (mydb.php에서 db_name은 chandj)
if(empty($DB)) {
$DB = 'chandj';
}
/**
* 데이터베이스 쿼리를 실행하고 결과를 반환합니다.
*
* @param PDO $pdo PDO 객체
* @param string $sql 실행할 SQL 쿼리
* @param array $params 쿼리에 바인딩할 파라미터 배열 (선택 사항)
* @return array|false 쿼리 결과 (연관 배열) 또는 실패 시 false
* @throws PDOException 쿼리 실행 중 오류가 발생한 경우
*/
function executeQuery(PDO $pdo, string $sql, array $params = [])
{
try {
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
error_log("Query execution failed: " . $e->getMessage());
return false;
}
}
?>
= $title_message ?>
0) ? $balance : 0;
$receivables[$secondordnum] = $receivableAmount;
// 거래처 이름 가져오기
$vendorNameSql = "SELECT vendor_name FROM phonebook WHERE secondordnum = :secondordnum AND (is_deleted IS NULL OR is_deleted = 0)";
$vendorNameParams = [':secondordnum' => $secondordnum];
$vendorNameResult = executeQuery($pdo, $vendorNameSql, $vendorNameParams);
$vendorNames[$secondordnum] = $vendorNameResult[0]['vendor_name'] ?? '';
}
// 수입 내역 (계산서 발행 등은 기존 monthly_sales 테이블 사용, 필요시 output 기반으로 확장)
$incomeData = [];
foreach ($receivables as $secondordnum => $receivableAmount) {
if ($receivableAmount > 0) {
$incomeData[] = [
'customer_name' => $vendorNames[$secondordnum],
'receivableAmount' => $receivableAmount,
'totalAmount' => $receivableAmount,
'secondordnum' => $secondordnum
];
}
}
// 현재 잔액 계산서
$currentDate = date("Y-m-d"); // 현재 날짜
// fromdate 또는 todate가 빈 문자열이거나 null인 경우
if (empty($formattedStartDate) || empty($formattedEndDate)) {
// 현재 월의 1일을 fromdate로 설정
$formattedStartDate = date("Y-m-01");
// 전달의 29일 구하기
// $formattedStartDate = date("Y-m-29", strtotime("-1 month", strtotime($formattedStartDate)));
$formattedEndDate = $currentDate;
$Transtodate = $formattedEndDate;
} else {
$Transtodate = $formattedEndDate;
}
/**
* 문자열이 null이 아니고 빈 문자열이 아닌지 확인합니다.
*
* @param string|null $str 확인할 문자열
* @return bool 문자열이 null이 아니고 비어 있지 않으면 true, 그렇지 않으면 false
*/
function checkNull(?string $str): bool
{
return $str !== null && trim($str) !== '';
}
// account 테이블 쿼리 조건 및 파라미터 설정
$accountQueryConditions = [];
$accountQueryParams = [];
if (checkNull($searchKeyword)) {
$accountQueryConditions[] = "searchtag LIKE :searchKeyword";
$accountQueryParams[':searchKeyword'] = "%$searchKeyword%";
}
$accountQueryConditions[] = "registDate BETWEEN :formattedStartDate AND :formattedEndDate";
$accountQueryParams[':formattedStartDate'] = $formattedStartDate;
$accountQueryParams[':formattedEndDate'] = $formattedEndDate;
$accountQueryConditions[] = "(is_deleted = 0 OR is_deleted IS NULL)";
// 수입/지출 구분
$inoutType = isset($_REQUEST['inoutsep_select']) ? $_REQUEST['inoutsep_select'] : '';
if (checkNull($inoutType)) {
$accountQueryConditions[] = "inoutsep = :inoutType";
$accountQueryParams[':inoutType'] = $inoutType;
}
// 내용
$contentType = isset($_REQUEST['content_select']) ? $_REQUEST['content_select'] : '';
if (checkNull($contentType)) {
$accountQueryConditions[] = "content = :contentType";
$accountQueryParams[':contentType'] = $contentType;
}
// account 테이블에서 데이터 조회
$accountTable = $DB . '.account';
$accountOrder = " ORDER BY registDate ASC, num ASC ";
$accountSql = "SELECT * FROM {$accountTable} WHERE " . implode(' AND ', $accountQueryConditions) . $accountOrder;
// PDO prepared statement 사용
$stmt = $pdo->prepare($accountSql);
$stmt->execute($accountQueryParams);
$accountData = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 수입, 지출을 기반으로 초기 잔액 계산
$initialBalanceSql = "
SELECT
SUM(CASE WHEN inoutsep = '수입' THEN REPLACE(amount, ',', '') ELSE 0 END) +
SUM(CASE WHEN inoutsep = '최초전월이월' THEN REPLACE(amount, ',', '') ELSE 0 END) -
SUM(CASE WHEN inoutsep = '지출' THEN REPLACE(amount, ',', '') ELSE 0 END) AS balance
FROM {$accountTable}
WHERE is_deleted = '0' AND registDate < :formattedStartDate
";
$initialBalanceParams = [':formattedStartDate' => $formattedStartDate];
$initialBalanceResult = executeQuery($pdo, $initialBalanceSql, $initialBalanceParams);
$initialBalance = $initialBalanceResult[0]['balance'];
// 총 수입 계산
$totalIncomeSql = "
SELECT SUM(REPLACE(amount, ',', '')) AS totalIncome
FROM {$accountTable}
WHERE is_deleted = '0' AND (inoutsep = '수입' OR inoutsep = '최초전월이월')
AND registDate BETWEEN :formattedStartDate AND :formattedEndDate
";
$totalIncomeParams = [
':formattedStartDate' => $formattedStartDate,
':formattedEndDate' => $formattedEndDate
];
$totalIncomeResult = executeQuery($pdo, $totalIncomeSql, $totalIncomeParams);
$totalIncome = $totalIncomeResult[0]['totalIncome'];
// 총 지출 계산
$totalExpenseSql = "
SELECT SUM(REPLACE(amount, ',', '')) AS totalExpense
FROM {$accountTable}
WHERE is_deleted = '0' AND inoutsep = '지출'
AND registDate BETWEEN :formattedStartDate AND :formattedEndDate
";
$totalExpenseParams = [
':formattedStartDate' => $formattedStartDate,
':formattedEndDate' => $formattedEndDate
];
$totalExpenseResult = executeQuery($pdo, $totalExpenseSql, $totalExpenseParams);
$totalExpense = $totalExpenseResult[0]['totalExpense'];
// 최종 잔액 계산
$finalBalance = $initialBalance + $totalIncome - $totalExpense;
// Bankbook options
$bankbookOptions = [];
$jsonFile = $_SERVER['DOCUMENT_ROOT'] . "/account/accoutlist.json";
$accounts = [];
$selectedAccount = null;
$accountBalances = [];
if (file_exists($jsonFile)) {
$jsonContent = file_get_contents($jsonFile);
$accounts = json_decode($jsonContent, true);
if (is_array($accounts) && !empty($accounts)) {
// 선택된 계좌 또는 기본 계좌(첫 번째) 설정
$selectedAccountIndex = isset($_REQUEST['selected_account']) ? intval($_REQUEST['selected_account']) : 0;
$selectedAccount = $accounts[$selectedAccountIndex] ?? $accounts[0];
// 각 계좌별 잔액 계산
foreach ($accounts as $index => $account) {
$accountDisplay = $account['company'] . ' ' . $account['number'];
if (!empty($account['memo'])) {
$accountDisplay .= ' (' . $account['memo'] . ')';
}
// 해당 계좌의 잔액 계산
$accountBalanceSql = "SELECT
SUM(CASE WHEN inoutsep = '수입' AND bankbook = ? THEN REPLACE(amount, ',', '') ELSE 0 END) +
SUM(CASE WHEN inoutsep = '최초전월이월' AND bankbook = ? THEN REPLACE(amount, ',', '') ELSE 0 END) -
SUM(CASE WHEN inoutsep = '지출' AND bankbook = ? THEN REPLACE(amount, ',', '') ELSE 0 END) AS balance
FROM $tablename
WHERE is_deleted = '0'";
$accountBalanceStmh = $pdo->prepare($accountBalanceSql);
$accountBalanceStmh->bindValue(1, $accountDisplay, PDO::PARAM_STR);
$accountBalanceStmh->bindValue(2, $accountDisplay, PDO::PARAM_STR);
$accountBalanceStmh->bindValue(3, $accountDisplay, PDO::PARAM_STR);
$accountBalanceStmh->execute();
$accountBalances[$index] = $accountBalanceStmh->fetch(PDO::FETCH_ASSOC)['balance'] ?? 0;
}
}
}
// 각 계좌별 요약 정보를 담을 배열 초기화
$accountSummaries = [];
if (is_array($accounts)) {
foreach ($accounts as $index => $account) {
$accountDisplay = $account['company'] . ' ' . $account['number'];
if (!empty($account['memo'])) {
$accountDisplay .= ' (' . $account['memo'] . ')';
}
// 1. 계좌별 기초 잔액 (기간 이전)
$initialSql = "SELECT
(SUM(CASE WHEN inoutsep = '수입' OR inoutsep = '최초전월이월' THEN REPLACE(amount, ',', '') ELSE 0 END) -
SUM(CASE WHEN inoutsep = '지출' THEN REPLACE(amount, ',', '') ELSE 0 END)) AS balance
FROM $tablename
WHERE is_deleted = '0' AND registDate < :fromdate AND bankbook = :bankbook";
$initialStmh = $pdo->prepare($initialSql);
$initialStmh->bindParam(':fromdate', $fromdate);
$initialStmh->bindParam(':bankbook', $accountDisplay);
$initialStmh->execute();
$initialBalanceAccount = $initialStmh->fetch(PDO::FETCH_ASSOC)['balance'] ?? 0;
// 2. 기간 내 수입
$incomeSql = "SELECT SUM(REPLACE(amount, ',', '')) AS totalIncome
FROM $tablename
WHERE is_deleted = '0' AND (inoutsep = '수입' OR inoutsep = '최초전월이월')
AND registDate BETWEEN :fromdate AND :todate AND bankbook = :bankbook";
$incomeStmh = $pdo->prepare($incomeSql);
$incomeStmh->bindParam(':fromdate', $fromdate);
$incomeStmh->bindParam(':todate', $todate);
$incomeStmh->bindParam(':bankbook', $accountDisplay);
$incomeStmh->execute();
$totalIncomeAccount = $incomeStmh->fetch(PDO::FETCH_ASSOC)['totalIncome'] ?? 0;
// 3. 기간 내 지출
$expenseSql = "SELECT SUM(REPLACE(amount, ',', '')) AS totalExpense
FROM $tablename
WHERE is_deleted = '0' AND inoutsep = '지출'
AND registDate BETWEEN :fromdate AND :todate AND bankbook = :bankbook";
$expenseStmh = $pdo->prepare($expenseSql);
$expenseStmh->bindParam(':fromdate', $fromdate);
$expenseStmh->bindParam(':todate', $todate);
$expenseStmh->bindParam(':bankbook', $accountDisplay);
$expenseStmh->execute();
$totalExpenseAccount = $expenseStmh->fetch(PDO::FETCH_ASSOC)['totalExpense'] ?? 0;
// 4. 최종 잔액
$finalBalanceAccount = $initialBalanceAccount + $totalIncomeAccount - $totalExpenseAccount;
// 계산된 정보를 배열에 저장
$accountSummaries[$index] = [
'name' => $accountDisplay,
'income' => $totalIncomeAccount,
'expense' => $totalExpenseAccount,
'balance' => $finalBalanceAccount
];
}
}
// 각 계좌별 최종 잔액 정보를 담을 배열 초기화
$accountFinalBalances = [];
if (is_array($accounts)) {
foreach ($accounts as $index => $account) {
$accountDisplay = $account['company'] . ' ' . $account['number'];
if (!empty($account['memo'])) {
$accountDisplay .= ' (' . $account['memo'] . ')';
}
// 계좌별 전체 기간의 최종 잔액 계산
$balanceSql = "SELECT
(SUM(CASE WHEN inoutsep = '수입' OR inoutsep = '최초전월이월' THEN REPLACE(amount, ',', '') ELSE 0 END) -
SUM(CASE WHEN inoutsep = '지출' THEN REPLACE(amount, ',', '') ELSE 0 END)) AS balance
FROM {$DB}.account
WHERE is_deleted = '0' AND bankbook = :bankbook";
$balanceStmh = $pdo->prepare($balanceSql);
$balanceStmh->bindParam(':bankbook', $accountDisplay);
$balanceStmh->execute();
$balanceResult = $balanceStmh->fetch(PDO::FETCH_ASSOC);
// 계산된 정보를 배열에 저장
$accountFinalBalances[$index] = [
'name' => $accountDisplay,
'balance' => $balanceResult['balance'] ?? 0
];
}
}
// 수입/지출 내역 조회를 위한 연도 설정
$year = isset($_REQUEST['year']) ? $_REQUEST['year'] : date('Y');
// 조회할 월 설정 (기본값: 현재 월)
$selectedMonth = isset($_REQUEST['startMonth']) ? $_REQUEST['startMonth'] : date('m');
// 계산서 발행 조회할 전달(이전 월) 계산
$prevMonth = $selectedMonth - 1;
if ($prevMonth == 0) {
$prevMonth = 12;
$year = $year - 1; // 연도가 바뀌는 경우 처리
}
// 이전달의 시작일과 종료일 설정
$prevStartDate = "$year-$prevMonth-01";
// $prevStartDate = date("Y-m-29", strtotime("-1 month", strtotime($prevStartDate)));
$prevEndDate = date("Y-m-t", strtotime($prevStartDate));
// 수입 내역 조회
$monthlySalesTable = $DB . '.monthly_sales';
$incomeSql = "
SELECT customer_name, invoice_issued, sales as amount, secondordnum, SUM(sales) as totalAmount
FROM {$monthlySalesTable}
WHERE invoice_issued = '발행'
AND closure_date BETWEEN :prevStartDate AND :prevEndDate
AND (is_deleted = '0' or is_deleted IS NULL)
GROUP BY customer_name
";
$incomeParams = [
':prevStartDate' => $prevStartDate,
':prevEndDate' => $prevEndDate
];
$incomeData = executeQuery($pdo, $incomeSql, $incomeParams);
// 미수금을 수입 내역에 추가
foreach ($receivables as $secondordnum => $receivableAmount) {
if ($receivableAmount > 0) {
$incomeData[] = [
'customer_name' => $vendorNames[$secondordnum],
'receivableAmount' => $receivableAmount,
'totalAmount' => $receivableAmount,
'secondordnum' => $secondordnum
];
}
}
// 미수금 누계 처리
$accumulatedIncomeData = [];
foreach ($incomeData as $item) {
$secondordnum = $item['secondordnum'];
// 누적 데이터에 secondordnum이 이미 존재하는지 확인
if (isset($accumulatedIncomeData[$secondordnum])) {
// 존재하면 금액을 누계
$accumulatedIncomeData[$secondordnum]['amount'] += isset($item['amount']) ? $item['amount'] : 0;
$accumulatedIncomeData[$secondordnum]['receivableAmount'] += isset($item['receivableAmount']) ? $item['receivableAmount'] : 0;
$accumulatedIncomeData[$secondordnum]['totalAmount'] += isset($item['totalAmount']) ? $item['totalAmount'] : 0;
} else {
// 존재하지 않으면 새로운 항목을 추가, 없는 필드 초기화
$accumulatedIncomeData[$secondordnum] = [
'customer_name' => $item['customer_name'],
'amount' => isset($item['amount']) ? $item['amount'] : 0,
'receivableAmount' => isset($item['receivableAmount']) ? $item['receivableAmount'] : 0,
'totalAmount' => isset($item['totalAmount']) ? $item['totalAmount'] : 0,
'secondordnum' => $secondordnum
];
}
}
// 배열을 다시 숫자 인덱스로 변환
$incomeData = array_values($accumulatedIncomeData);
// 현재 기준월의 1일부터 현재 날짜까지 수금된 데이터 조회
$fromdate = date("Y-m-01");
// 전전달의 29일 구하기
// $fromdate = date("Y-m-29", strtotime("-1 month", strtotime($fromdate)));
// $todate = date("Y-m-d");
// $lastmonthEnddate = date("Y-m-t", strtotime("first day of last month")); //전달의 **말일(마지막 날)**을
$lastmonthEnddate = date("Y-m-t");
// account 테이블에서 해당 거래처의 수금된 항목 조회
$paymentSql = "
SELECT secondordnum, SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) AS total_payment
FROM {$accountTable}
WHERE inoutsep = '수입'
AND registDate BETWEEN :fromdate AND :lastmonthEnddate
AND (is_deleted IS NULL OR is_deleted = 0)
GROUP BY secondordnum
";
$paymentParams = [
':fromdate' => $fromdate,
':lastmonthEnddate' => $lastmonthEnddate
];
$paymentData = executeQuery($pdo, $paymentSql, $paymentParams);
// 이미 수금된 secondordnum을 배열로 저장
$receivedPayments = [];
foreach ($paymentData as $row) {
$secondordnum = $row['secondordnum'];
$totalPayment = (float)$row['total_payment'];
// $totalPayment = 0 ; // 이미 수금된것 제외 코드
// 수금 내역을 기록 (이미 수금된 금액이 있으면 배열에 추가) 수금이 계산서 금액과 일치하면 제외되는 알고리즘 추가한다.
if (intval($totalPayment) > 0) {
$receivedPayments[$secondordnum] = $totalPayment;
}
}
// echo '';
// print_r($paymentData);
// echo ' ';
// 수금된 금액을 차감한 나머지 미수금 계산
$filteredIncomeData = [];
foreach ($incomeData as $incomeRow) {
$secondordnum = $incomeRow['secondordnum'] ?? '';
// 수금된 금액이 있는지 확인
if (isset($receivedPayments[$secondordnum])) {
// echo ' , ' . $incomeRow['receivableAmount'] . ' 미수금 : ' . $receivedPayments[$secondordnum] ;
if( $incomeRow['receivableAmount'] == $receivedPayments[$secondordnum]) {
// 수금된 금액을 차감한 나머지 미수금을 계산
$remainingAmount = $incomeRow['receivableAmount'] - $receivedPayments[$secondordnum]; // 현재월의 수금내역 차감공식 수정 250415 찾음
}
else
{
$remainingAmount = $incomeRow['receivableAmount'] ;
}
// 나머지 미수금이 0보다 크거나 같으면 배열에 추가
if ($remainingAmount >= 0) {
$incomeRow['receivableAmount'] = $remainingAmount;
// totalAmount는 원래의 매출 금액으로 유지되므로 별도 할당 불필요
$filteredIncomeData[] = $incomeRow;
}
} else {
// 수금된 금액이 없으면 그대로 추가
$filteredIncomeData[] = $incomeRow;
}
}
// vendorNames 기준으로 $filteredIncomeData 정렬
usort($filteredIncomeData, function ($a, $b) use ($vendorNames) {
return strcmp($vendorNames[$a['secondordnum']], $vendorNames[$b['secondordnum']]);
});
// 제외된 항목 파일 경로
$excludedItemsFile = $_SERVER['DOCUMENT_ROOT'] . "/account_plan/excluded_items.json";
// 제외된 항목 로드
$excludedItems = [];
if (file_exists($excludedItemsFile)) {
$excludedItems = json_decode(file_get_contents($excludedItemsFile), true);
}
// 디버깅을 위한 코드 추가
// echo '--- 제외된 항목 ($excludedItems) ---';
// print_r($excludedItems);
// echo ' ';
// $filteredIncomeData에서 제외된 항목 필터링
$filteredIncomeDataForDebugging = $filteredIncomeData; // 디버깅을 위해 원본 배열 복사
if (!empty($excludedItems)) {
$filteredIncomeData = array_filter($filteredIncomeData, function ($item) use ($excludedItems, $selectedYearMonth) {
// 디버깅을 위한 코드 추가
// echo '--- 현재 비교 중인 항목 ($item) ---';
// print_r($item);
// echo ' ';
$isExcluded = false; // 제외 여부 플래그
foreach ($excludedItems as $excludedItem) {
// 디버깅을 위한 코드 추가
// echo '--- 제외된 항목과 비교 ($excludedItem) ---';
// print_r($excludedItem);
// echo '--- 비교 결과 ---';
// echo '$excludedItem[\'yearMonth\'] === $selectedYearMonth : ' . ($excludedItem['yearMonth'] === $selectedYearMonth ? 'true' : 'false') . ' ';
// echo '$excludedItem[\'customerName\'] === $item[\'customer_name\'] : ' . ($excludedItem['customerName'] === $item['customer_name'] ? 'true' : 'false') . ' ';
// echo 'intval($excludedItem[\'amount\']) === intval($item[\'totalAmount\']) : ' . (intval($excludedItem['amount']) === intval($item['totalAmount']) ? 'true' : 'false') . ' ';
// echo ' ';
if (
$excludedItem['yearMonth'] === $selectedYearMonth &&
$excludedItem['customerName'] === $item['customer_name'] &&
intval($excludedItem['amount']) === intval($item['totalAmount'])
) {
$isExcluded = true; // 제외 플래그 설정
break;
}
}
// 디버깅을 위한 코드 추가
// echo '--- 최종 제외 여부: ' . ($isExcluded ? '제외됨' : '유지됨') . ' --- ';
return !$isExcluded; // 제외 여부에 따라 반환
});
}
// 디버깅을 위한 코드 추가: 필터링 전후 비교
// echo '--- 필터링 전 ($filteredIncomeDataForDebugging) ---';
// print_r($filteredIncomeDataForDebugging);
// echo ' ';
// echo '--- 필터링 후 ($filteredIncomeData) ---';
// print_r($filteredIncomeData);
// echo ' ';
// ... (나머지 코드는 동일) ...
// 이번 달로 설정, 계산서는 지난달
$startMonth = isset($_REQUEST['startMonth']) ? $_REQUEST['startMonth'] : date('m');
$endMonth = isset($_REQUEST['endMonth']) ? $_REQUEST['endMonth'] : date('m');
$startDate = "$year-$startMonth-01";
$endDate = date("Y-m-t", strtotime("$year-$endMonth-01"));
// 지출 내역 조회 (월별 누적)
$accountPlanTable = 'account_plan';
$expenseSql = "
SELECT content, SUM(amount) as totalAmount
FROM $DB.$accountPlanTable
WHERE inoutsep = '지출'
AND (is_deleted = '0' or is_deleted IS NULL)
GROUP BY content
";
$expenseData = executeQuery($pdo, $expenseSql);
// 지출 상세 내역 조회
$expenseDetailSql = "
SELECT num, content, amount, registDate, memo, ForeDate, approvalRequest, eworksNum, workDone
FROM $DB.$accountPlanTable
WHERE inoutsep = '지출'
AND (is_deleted = '0' or is_deleted IS NULL)
";
$expenseDetailData = executeQuery($pdo, $expenseDetailSql);
// 수입/지출 합계 및 순이익 계산 (필터링된 데이터 사용)
$filteredTotalIncome = array_sum(array_column($filteredIncomeData, 'totalAmount'));
$filteredTotalExpense = array_sum(array_column($expenseData, 'totalAmount'));
$filteredNetIncome = $filteredTotalIncome - $filteredTotalExpense + $finalBalance;
// receivableAmount 또는 totalAmount 값이 0보다 큰 항목만 필터링
$filteredIncomeData = array_filter($filteredIncomeData, function ($item) {
return (isset($item['receivableAmount']) && intval($item['receivableAmount']) > 0) ||
(isset($item['totalAmount']) && intval($item['totalAmount']) > 0);
});
// vendorNames 기준으로 $filteredIncomeData 정렬
usort($filteredIncomeData, function ($a, $b) {
return strcmp($a['customer_name'], $b['customer_name']);
});
// 수금을 바로 하는 업체를 처리하기 위한 코드
// 현재 날짜로부터 2개월 전의 1일을 시작일로 설정
$specialStartDate = (new DateTime('first day of -2 months'))->format('Y-m-d');
$specialEndDate = date("Y-m-d");
// account 테이블에서 해당 거래처의 수금된 항목 조회
$specialPaymentSql = "
SELECT secondordnum, SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) AS total_payment
FROM {$accountTable}
WHERE inoutsep = '수입'
AND registDate BETWEEN :specialStartDate AND :specialEndDate
AND (is_deleted IS NULL OR is_deleted = 0)
GROUP BY secondordnum
";
$specialPaymentParams = [
':specialStartDate' => $specialStartDate,
':specialEndDate' => $specialEndDate
];
$specialPaymentData = executeQuery($pdo, $specialPaymentSql, $specialPaymentParams);
// paymentDataSpecial 배열을 secondordnum을 키로 하는 형태로 재구성
$specialPaymentMap = [];
foreach ($specialPaymentData as $payment) {
$specialPaymentMap[$payment['secondordnum']] = intval($payment['total_payment']);
}
// filteredIncomeData에서 secondordnum과 total_payment가 일치하는 항목 제거
$filteredIncomeData = array_filter($filteredIncomeData, function ($item) use ($specialPaymentMap) {
// receivableAmount 또는 totalAmount 값이 있으면 intval로 변환
$item['receivableAmount'] = isset($item['receivableAmount']) ? intval($item['receivableAmount']) : 0;
$item['totalAmount'] = isset($item['totalAmount']) ? intval($item['totalAmount']) : 0;
// paymentDataSpecial에 secondordnum이 있고, totalAmount와 total_payment가 일치하면 해당 항목을 제거
if (isset($specialPaymentMap[$item['secondordnum']]) && $specialPaymentMap[$item['secondordnum']] === $item['totalAmount']) {
return false; // 제거
}
// 제거되지 않은 항목만 반환
return true;
});
// vendorNames 기준으로 $filteredIncomeData 정렬
usort($filteredIncomeData, function ($a, $b) {
return strcmp($a['customer_name'], $b['customer_name']);
});
// 예상지급일 오름차순 정렬 코드
// 1) $expenseDetailData 배열이 준비된 직후, 테이블 출력 전에 추가
usort($expenseDetailData, function($a, $b) {
// '0000-00-00' 혹은 빈 문자열은 매우 미래 날짜로 처리
$dateA = (!empty($a['ForeDate']) && $a['ForeDate'] !== '0000-00-00')
? strtotime($a['ForeDate'])
: PHP_INT_MAX;
$dateB = (!empty($b['ForeDate']) && $b['ForeDate'] !== '0000-00-00')
? strtotime($b['ForeDate'])
: PHP_INT_MAX;
return $dateA <=> $dateB;
});
?>