Files
wace_rps/backend-node/src/controllers/reportCellValueController.ts
T
kjs 51c4fddde0 feat: Add report cell value management functionality
- Introduced a new controller for managing custom input values in report cells, allowing users to retrieve and upsert values associated with specific reports and targets.
- Implemented API routes for fetching and saving report cell values, ensuring proper authentication and data handling.
- Enhanced the frontend components to support the new report cell input functionality, including the ability to edit and save input values in a modal.
- Updated inventory and equipment management pages to include new features for handling missing items and managing warehouse locations effectively.
2026-04-20 17:59:28 +09:00

94 lines
3.2 KiB
TypeScript

/**
* 리포트 셀 커스텀 입력값 컨트롤러
*
* 리포트 디자이너에서 cellType="input"으로 지정한 셀에 대해
* 각 대상 레코드(quote 등)별로 사용자가 입력한 값을 관리
*/
import type { Response } from "express";
import { getPool } from "../database/db";
import type { AuthenticatedRequest } from "../types/auth";
import { logger } from "../utils/logger";
// 목록 조회: 특정 리포트 + 타겟에 대한 모든 셀 값
export async function getList(req: AuthenticatedRequest, res: Response) {
try {
const companyCode = req.user!.companyCode;
const { report_id, target_type, target_id } = req.query;
if (!report_id || !target_type || !target_id) {
return res.status(400).json({
success: false,
message: "report_id, target_type, target_id는 필수입니다.",
});
}
const pool = getPool();
const result = await pool.query(
`SELECT id, report_id, target_type, target_id, component_id, cell_id, value
FROM report_cell_values
WHERE company_code = $1 AND report_id = $2 AND target_type = $3 AND target_id = $4`,
[companyCode, report_id, target_type, target_id],
);
return res.json({ success: true, data: result.rows });
} catch (error: any) {
logger.error("리포트 셀 값 조회 실패", { error: error.message });
return res.status(500).json({ success: false, message: error.message });
}
}
// UPSERT 단건: 같은 (report_id, target_type, target_id, component_id, cell_id)면 UPDATE, 아니면 INSERT
export async function upsert(req: AuthenticatedRequest, res: Response) {
try {
const companyCode = req.user!.companyCode;
const userId = req.user!.userId;
const { report_id, target_type, target_id, component_id, cell_id, value } =
req.body;
if (!report_id || !target_type || !target_id || !component_id || !cell_id) {
return res.status(400).json({
success: false,
message: "필수 필드 누락",
});
}
const pool = getPool();
// value가 빈 문자열이면 DELETE (오버라이드 해제)
if (value === "" || value === null || value === undefined) {
await pool.query(
`DELETE FROM report_cell_values
WHERE company_code = $1 AND report_id = $2 AND target_type = $3
AND target_id = $4 AND component_id = $5 AND cell_id = $6`,
[companyCode, report_id, target_type, target_id, component_id, cell_id],
);
return res.json({ success: true, data: null });
}
const result = await pool.query(
`INSERT INTO report_cell_values
(id, company_code, report_id, target_type, target_id, component_id, cell_id, value, created_by, updated_by)
VALUES (gen_random_uuid()::text, $1, $2, $3, $4, $5, $6, $7, $8, $8)
ON CONFLICT (company_code, report_id, target_type, target_id, component_id, cell_id)
DO UPDATE SET value = EXCLUDED.value, updated_at = CURRENT_TIMESTAMP, updated_by = EXCLUDED.updated_by
RETURNING *`,
[
companyCode,
report_id,
target_type,
target_id,
component_id,
cell_id,
value,
userId,
],
);
return res.json({ success: true, data: result.rows[0] });
} catch (error: any) {
logger.error("리포트 셀 값 저장 실패", { error: error.message });
return res.status(500).json({ success: false, message: error.message });
}
}