feat: 입고/자재현황/분석리포트 컨트롤러 및 프론트엔드 개선
- receivingController: 헤더-디테일 JOIN 구조로 변경, 검색/조회 로직 개선 - materialStatusController: work_instruction 테이블 기반으로 쿼리 수정 - analyticsReportController: 구매 리포트 company_code 필터링 로직 개선 - material-status 페이지: COMPANY_29/COMPANY_7 프론트엔드 업데이트 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 자재현황 컨트롤러
|
||||
* - 생산계획(작업지시) 조회
|
||||
* - 작업지시(work_instruction + work_instruction_detail) 조회
|
||||
* - 선택된 작업지시의 BOM 기반 자재소요량 + 재고 현황 조회
|
||||
* - 창고 목록 조회
|
||||
*/
|
||||
@@ -10,7 +10,7 @@ import { AuthenticatedRequest } from "../types/auth";
|
||||
import { pool } from "../database/db";
|
||||
import { logger } from "../utils/logger";
|
||||
|
||||
// ─── 생산계획(작업지시) 조회 ───
|
||||
// ─── 작업지시 조회 (work_instruction + work_instruction_detail) ───
|
||||
|
||||
export async function getWorkOrders(
|
||||
req: AuthenticatedRequest,
|
||||
@@ -27,31 +27,31 @@ export async function getWorkOrders(
|
||||
if (companyCode === "*") {
|
||||
logger.info("최고 관리자 전체 작업지시 조회");
|
||||
} else {
|
||||
conditions.push(`p.company_code = $${paramIndex}`);
|
||||
conditions.push(`wi.company_code = $${paramIndex}`);
|
||||
params.push(companyCode);
|
||||
paramIndex++;
|
||||
}
|
||||
|
||||
if (dateFrom) {
|
||||
conditions.push(`p.plan_date >= $${paramIndex}::date`);
|
||||
conditions.push(`wi.start_date::date >= $${paramIndex}::date`);
|
||||
params.push(dateFrom);
|
||||
paramIndex++;
|
||||
}
|
||||
|
||||
if (dateTo) {
|
||||
conditions.push(`p.plan_date <= $${paramIndex}::date`);
|
||||
conditions.push(`wi.start_date::date <= $${paramIndex}::date`);
|
||||
params.push(dateTo);
|
||||
paramIndex++;
|
||||
}
|
||||
|
||||
if (itemCode) {
|
||||
conditions.push(`p.item_code ILIKE $${paramIndex}`);
|
||||
conditions.push(`d.item_number ILIKE $${paramIndex}`);
|
||||
params.push(`%${itemCode}%`);
|
||||
paramIndex++;
|
||||
}
|
||||
|
||||
if (itemName) {
|
||||
conditions.push(`p.item_name ILIKE $${paramIndex}`);
|
||||
conditions.push(`COALESCE(itm.item_name, '') ILIKE $${paramIndex}`);
|
||||
params.push(`%${itemName}%`);
|
||||
paramIndex++;
|
||||
}
|
||||
@@ -60,22 +60,28 @@ export async function getWorkOrders(
|
||||
conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
||||
|
||||
const query = `
|
||||
SELECT
|
||||
p.id,
|
||||
p.plan_no,
|
||||
p.item_code,
|
||||
p.item_name,
|
||||
p.plan_qty,
|
||||
p.completed_qty,
|
||||
p.plan_date,
|
||||
p.start_date,
|
||||
p.end_date,
|
||||
p.status,
|
||||
p.work_order_no,
|
||||
p.company_code
|
||||
FROM production_plan_mng p
|
||||
SELECT
|
||||
d.id,
|
||||
wi.work_instruction_no AS plan_no,
|
||||
d.item_number AS item_code,
|
||||
COALESCE(itm.item_name, '') AS item_name,
|
||||
d.qty AS plan_qty,
|
||||
wi.completed_qty,
|
||||
wi.start_date AS plan_date,
|
||||
wi.start_date,
|
||||
wi.end_date,
|
||||
wi.status,
|
||||
wi.work_instruction_no AS work_order_no,
|
||||
wi.company_code
|
||||
FROM work_instruction wi
|
||||
INNER JOIN work_instruction_detail d
|
||||
ON d.work_instruction_no = wi.work_instruction_no AND d.company_code = wi.company_code
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT item_name FROM item_info
|
||||
WHERE item_number = d.item_number AND company_code = wi.company_code LIMIT 1
|
||||
) itm ON true
|
||||
${whereClause}
|
||||
ORDER BY p.plan_date DESC, p.created_date DESC
|
||||
ORDER BY wi.start_date DESC, wi.created_date DESC
|
||||
`;
|
||||
|
||||
const result = await pool.query(query, params);
|
||||
@@ -108,14 +114,14 @@ export async function getMaterialStatus(
|
||||
.json({ success: false, message: "작업지시를 선택해주세요." });
|
||||
}
|
||||
|
||||
// 1) 선택된 작업지시의 품목코드 + 수량 조회
|
||||
// 1) 선택된 작업지시 상세의 품목코드 + 수량 조회
|
||||
const planPlaceholders = planIds
|
||||
.map((_, i) => `$${i + 1}`)
|
||||
.join(",");
|
||||
let paramIndex = planIds.length + 1;
|
||||
|
||||
const companyCondition =
|
||||
companyCode === "*" ? "" : `AND p.company_code = $${paramIndex}`;
|
||||
companyCode === "*" ? "" : `AND d.company_code = $${paramIndex}`;
|
||||
const planParams: any[] = [...planIds];
|
||||
if (companyCode !== "*") {
|
||||
planParams.push(companyCode);
|
||||
@@ -123,9 +129,13 @@ export async function getMaterialStatus(
|
||||
}
|
||||
|
||||
const planQuery = `
|
||||
SELECT p.item_code, p.item_name, p.plan_qty
|
||||
FROM production_plan_mng p
|
||||
WHERE p.id IN (${planPlaceholders})
|
||||
SELECT d.item_number AS item_code, COALESCE(itm.item_name, '') AS item_name, d.qty AS plan_qty
|
||||
FROM work_instruction_detail d
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT item_name FROM item_info
|
||||
WHERE item_number = d.item_number AND company_code = d.company_code LIMIT 1
|
||||
) itm ON true
|
||||
WHERE d.id IN (${planPlaceholders})
|
||||
${companyCondition}
|
||||
`;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user