51c4fddde0
- 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.
94 lines
3.2 KiB
TypeScript
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 });
|
|
}
|
|
}
|