112 lines
2.7 KiB
TypeScript
112 lines
2.7 KiB
TypeScript
|
|
import { getPool } from "../database/db";
|
||
|
|
|
||
|
|
export class MaterialService {
|
||
|
|
// 임시 자재 마스터 목록 조회
|
||
|
|
async getTempMaterials(params: {
|
||
|
|
search?: string;
|
||
|
|
category?: string;
|
||
|
|
page?: number;
|
||
|
|
limit?: number;
|
||
|
|
}) {
|
||
|
|
const { search, category, page = 1, limit = 20 } = params;
|
||
|
|
const offset = (page - 1) * limit;
|
||
|
|
|
||
|
|
let whereConditions: string[] = ["is_active = true"];
|
||
|
|
const queryParams: any[] = [];
|
||
|
|
let paramIndex = 1;
|
||
|
|
|
||
|
|
if (search) {
|
||
|
|
whereConditions.push(
|
||
|
|
`(material_code ILIKE $${paramIndex} OR material_name ILIKE $${paramIndex})`
|
||
|
|
);
|
||
|
|
queryParams.push(`%${search}%`);
|
||
|
|
paramIndex++;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (category) {
|
||
|
|
whereConditions.push(`category = $${paramIndex}`);
|
||
|
|
queryParams.push(category);
|
||
|
|
paramIndex++;
|
||
|
|
}
|
||
|
|
|
||
|
|
const whereClause =
|
||
|
|
whereConditions.length > 0
|
||
|
|
? `WHERE ${whereConditions.join(" AND ")}`
|
||
|
|
: "";
|
||
|
|
|
||
|
|
const pool = getPool();
|
||
|
|
|
||
|
|
// 전체 개수 조회
|
||
|
|
const countQuery = `SELECT COUNT(*) as total FROM temp_material_master ${whereClause}`;
|
||
|
|
const countResult = await pool.query(countQuery, queryParams);
|
||
|
|
const total = parseInt(countResult.rows[0].total);
|
||
|
|
|
||
|
|
// 데이터 조회
|
||
|
|
const dataQuery = `
|
||
|
|
SELECT
|
||
|
|
id,
|
||
|
|
material_code,
|
||
|
|
material_name,
|
||
|
|
category,
|
||
|
|
unit,
|
||
|
|
default_color,
|
||
|
|
description,
|
||
|
|
created_at
|
||
|
|
FROM temp_material_master
|
||
|
|
${whereClause}
|
||
|
|
ORDER BY material_code ASC
|
||
|
|
LIMIT $${paramIndex} OFFSET $${paramIndex + 1}
|
||
|
|
`;
|
||
|
|
|
||
|
|
queryParams.push(limit, offset);
|
||
|
|
const dataResult = await pool.query(dataQuery, queryParams);
|
||
|
|
|
||
|
|
return {
|
||
|
|
data: dataResult.rows,
|
||
|
|
pagination: {
|
||
|
|
page,
|
||
|
|
limit,
|
||
|
|
total,
|
||
|
|
totalPages: Math.ceil(total / limit),
|
||
|
|
},
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// 특정 자재 상세 조회
|
||
|
|
async getTempMaterialByCode(materialCode: string) {
|
||
|
|
const query = `
|
||
|
|
SELECT
|
||
|
|
id,
|
||
|
|
material_code,
|
||
|
|
material_name,
|
||
|
|
category,
|
||
|
|
unit,
|
||
|
|
default_color,
|
||
|
|
description,
|
||
|
|
created_at
|
||
|
|
FROM temp_material_master
|
||
|
|
WHERE material_code = $1 AND is_active = true
|
||
|
|
`;
|
||
|
|
|
||
|
|
const pool = getPool();
|
||
|
|
const result = await pool.query(query, [materialCode]);
|
||
|
|
return result.rows[0] || null;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 카테고리 목록 조회
|
||
|
|
async getCategories() {
|
||
|
|
const query = `
|
||
|
|
SELECT DISTINCT category
|
||
|
|
FROM temp_material_master
|
||
|
|
WHERE is_active = true AND category IS NOT NULL
|
||
|
|
ORDER BY category ASC
|
||
|
|
`;
|
||
|
|
|
||
|
|
const pool = getPool();
|
||
|
|
const result = await pool.query(query);
|
||
|
|
return result.rows.map((row) => row.category);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export default new MaterialService();
|