diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/basic-contract/vendor-table/basic-contract-sign-dialog.tsx | 10 | ||||
| -rw-r--r-- | lib/pq/pq-criteria/pq-table-column.tsx | 40 | ||||
| -rw-r--r-- | lib/pq/pq-review-table-new/vendors-table-columns.tsx | 10 | ||||
| -rw-r--r-- | lib/pq/service.ts | 81 | ||||
| -rw-r--r-- | lib/vendors/table/request-pq-dialog.tsx | 18 |
5 files changed, 114 insertions, 45 deletions
diff --git a/lib/basic-contract/vendor-table/basic-contract-sign-dialog.tsx b/lib/basic-contract/vendor-table/basic-contract-sign-dialog.tsx index 534a2705..635993fb 100644 --- a/lib/basic-contract/vendor-table/basic-contract-sign-dialog.tsx +++ b/lib/basic-contract/vendor-table/basic-contract-sign-dialog.tsx @@ -35,7 +35,7 @@ import { getVendorAttachments, processBuyerSignatureAction } from "../service"; // 계약서 상태 타입 정의 interface ContractStatus { id: number; - status: 'pending' | 'completed' | 'error'; + status: 'pending' | 'completed' | 'error' | 'vendor_signed'; errorMessage?: string; } @@ -151,7 +151,9 @@ const canCompleteCurrentContract = React.useMemo(() => { }, [contracts, contractStatuses.length]); // 완료된 계약서 수 계산 - const completedCount = contractStatuses.filter(status => status.status === 'completed').length; + const completedCount = contractStatuses.filter(status => + status.status === 'completed' || status.status === 'vendor_signed' + ).length; const totalCount = contracts.length; const allCompleted = completedCount === totalCount && totalCount > 0; @@ -162,7 +164,9 @@ const canCompleteCurrentContract = React.useMemo(() => { // 다음 미완료 계약서 찾기 const getNextPendingContract = () => { - const pendingStatuses = contractStatuses.filter(status => status.status === 'pending'); + const pendingStatuses = contractStatuses.filter(status => + status.status === 'pending' || status.status === 'error' + ); if (pendingStatuses.length === 0) return null; const nextPendingId = pendingStatuses[0].id; diff --git a/lib/pq/pq-criteria/pq-table-column.tsx b/lib/pq/pq-criteria/pq-table-column.tsx index 924d80c4..de7396bf 100644 --- a/lib/pq/pq-criteria/pq-table-column.tsx +++ b/lib/pq/pq-criteria/pq-table-column.tsx @@ -125,26 +125,26 @@ export function getColumns({ minSize: 180, size: 180, }, - // { - // accessorKey: "remarks", - // header: ({ column }) => ( - // <DataTableColumnHeaderSimple column={column} title="SHI Comment" /> - // ), - // cell: ({ row }) => { - // const text = row.getValue("remarks") as string - // return ( - // <div style={{ whiteSpace: "pre-wrap" }}> - // {text || "-"} - // </div> - // ) - // }, - // meta: { - // excelHeader: "Remarks" - // }, - // enableResizing: true, - // minSize: 180, - // size: 180, - // }, + { + accessorKey: "remarks", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="비고" /> + ), + cell: ({ row }) => { + const text = row.getValue("remarks") as string + return ( + <div style={{ whiteSpace: "pre-wrap" }}> + {text || "-"} + </div> + ) + }, + meta: { + excelHeader: "Remarks" + }, + enableResizing: true, + minSize: 180, + size: 180, + }, { accessorKey: "inputFormat", header: ({ column }) => ( diff --git a/lib/pq/pq-review-table-new/vendors-table-columns.tsx b/lib/pq/pq-review-table-new/vendors-table-columns.tsx index 449b69be..e3687f52 100644 --- a/lib/pq/pq-review-table-new/vendors-table-columns.tsx +++ b/lib/pq/pq-review-table-new/vendors-table-columns.tsx @@ -175,6 +175,8 @@ export function getColumns({ setRowAction, router }: GetColumnsProps): ColumnDef <span className="text-xs text-muted-foreground">{row.original.vendorCode ? row.original.vendorCode : "-"}/{row.original.taxId}</span>
</div>
),
+ enableSorting: true,
+ enableHiding: true,
}
// PQ 유형 컬럼
@@ -200,6 +202,8 @@ export function getColumns({ setRowAction, router }: GetColumnsProps): ColumnDef filterFn: (row, id, value) => {
return value.includes(row.getValue(id));
},
+ enableSorting: true,
+ enableHiding: true,
}
// 프로젝트 컬럼
@@ -225,6 +229,8 @@ export function getColumns({ setRowAction, router }: GetColumnsProps): ColumnDef </div>
)
},
+ enableSorting: true,
+ enableHiding: true,
}
// 상태 컬럼
@@ -241,6 +247,8 @@ export function getColumns({ setRowAction, router }: GetColumnsProps): ColumnDef const combinedStatus = getCombinedStatus(row.original);
return value.includes(combinedStatus.status);
},
+ enableSorting: true,
+ enableHiding: true,
};
// PQ 상태와 실사 상태를 결합하는 헬퍼 함수
@@ -362,6 +370,8 @@ export function getColumns({ setRowAction, router }: GetColumnsProps): ColumnDef if (!investigation || !investigation.evaluationResult) return value.includes("null");
return value.includes(investigation.evaluationResult);
},
+ enableSorting: true,
+ enableHiding: true,
};
// 답변 수 컬럼
diff --git a/lib/pq/service.ts b/lib/pq/service.ts index 5870a77f..172542a3 100644 --- a/lib/pq/service.ts +++ b/lib/pq/service.ts @@ -18,7 +18,7 @@ import { vendorRegularRegistrations } from "@/db/schema/vendorRegistrations"; import { saveFile, saveDRMFile } from "@/lib/file-stroage";
import { GetVendorsSchema } from "../vendors/validations";
import { selectVendors } from "../vendors/repository";
-import { projects, users } from "@/db/schema";
+import { projects, users, roles, userRoles } from "@/db/schema";
import { headers } from 'next/headers';
import { getServerSession } from "next-auth/next"
import { authOptions } from "@/app/api/auth/[...nextauth]/route"
@@ -1763,8 +1763,20 @@ export async function getPQSubmissions(input: GetPQSubmissionsSchema) { // 7) 정렬 및 페이징 처리된 데이터 조회
const orderByColumns = input.sort.map((sort) => {
- const column = sort.id as keyof typeof vendorPQSubmissions.$inferSelect;
- return sort.desc ? desc(vendorPQSubmissions[column]) : asc(vendorPQSubmissions[column]);
+ const column = sort.id;
+
+ // JOIN된 테이블의 컬럼인 경우 적절한 테이블 참조
+ if (column === 'vendorName') {
+ return sort.desc ? desc(vendors.vendorName) : asc(vendors.vendorName);
+ } else if (column === 'projectName') {
+ return sort.desc ? desc(projects.name) : asc(projects.name);
+ } else if (column === 'requesterName') {
+ return sort.desc ? desc(users.name) : asc(users.name);
+ } else {
+ // vendorPQSubmissions 테이블의 컬럼인 경우
+ const dbColumn = column as keyof typeof vendorPQSubmissions.$inferSelect;
+ return sort.desc ? desc(vendorPQSubmissions[dbColumn]) : asc(vendorPQSubmissions[dbColumn]);
+ }
});
if (orderByColumns.length === 0) {
@@ -2818,40 +2830,75 @@ function getInvestigationMethodLabel(method: string): string { }
}
+// export async function getQMManagers() {
+// try {
+// // QM 부서 사용자만 필터링 (department 필드가 있다고 가정)
+// // 또는 QM 역할을 가진 사용자만 필터링 (role 필드가 있다고 가정)
+// const qmUsers = await db
+// .select({
+// id: users.id,
+// name: users.name,
+// email: users.email,
+// })
+// .from(users)
+// // .where(
+// // // 필요에 따라 조건 조정 (예: QM 부서 또는 특정 역할만)
+// // // eq(users.department, "QM") 또는
+// // // eq(users.role, "QM_MANAGER")
+// // // 테스트를 위해 모든 사용자 반환도 가능
+// // eq(users.active, true)
+// // )
+// .orderBy(users.name)
+
+// return {
+// data: qmUsers,
+// success: true
+// }
+// } catch (error) {
+// console.error("QM 담당자 목록 조회 오류:", error)
+// return {
+// data: [],
+// success: false,
+// error: error instanceof Error ? error.message : "QM 담당자 목록을 가져오는 중 오류가 발생했습니다."
+// }
+// }
+// }
export async function getQMManagers() {
try {
- // QM 부서 사용자만 필터링 (department 필드가 있다고 가정)
- // 또는 QM 역할을 가진 사용자만 필터링 (role 필드가 있다고 가정)
+ // QM 역할이 할당된 사용자들을 조회
const qmUsers = await db
.select({
id: users.id,
name: users.name,
email: users.email,
+ employeeNumber: users.employeeNumber,
+ deptName: users.deptName,
+ isActive: users.isActive,
})
.from(users)
- // .where(
- // // 필요에 따라 조건 조정 (예: QM 부서 또는 특정 역할만)
- // // eq(users.department, "QM") 또는
- // // eq(users.role, "QM_MANAGER")
- // // 테스트를 위해 모든 사용자 반환도 가능
- // eq(users.active, true)
- // )
+ .innerJoin(userRoles, eq(users.id, userRoles.userId))
+ .innerJoin(roles, eq(userRoles.roleId, roles.id))
+ .where(
+ and(
+ ilike(roles.name, "%QM%"), // "QM"이 포함된 역할명
+ eq(users.isActive, true) // 활성 사용자만
+ )
+ )
.orderBy(users.name)
- return {
+ return {
data: qmUsers,
- success: true
+ success: true
}
} catch (error) {
console.error("QM 담당자 목록 조회 오류:", error)
- return {
+ return {
data: [],
success: false,
- error: error instanceof Error ? error.message : "QM 담당자 목록을 가져오는 중 오류가 발생했습니다."
+ error: error instanceof Error ? error.message : "QM 담당자 목록을 가져오는 중 오류가 발생했습니다."
}
}
}
-
export async function getFactoryLocationAnswer(vendorId: number, projectId: number | null = null) {
try {
// 1. "Location of Factory" 체크포인트를 가진 criteria 찾기
diff --git a/lib/vendors/table/request-pq-dialog.tsx b/lib/vendors/table/request-pq-dialog.tsx index aeb0c717..206846df 100644 --- a/lib/vendors/table/request-pq-dialog.tsx +++ b/lib/vendors/table/request-pq-dialog.tsx @@ -154,10 +154,14 @@ export function RequestPQDialog({ vendors, showTrigger = true, onSuccess, ...pro if (isAllForeign) {
// 외자: 준법서약 (영문), GTC 선택 (GTC는 1개만 선택하도록)
- const foreignTemplates = templates.filter(template =>
- template.templateName?.includes('준법서약') && template.templateName?.includes('영문') ||
- template.templateName?.includes('gtc')
- )
+ // 비밀유지 계약서, 기술자료 요구서 제외
+ const foreignTemplates = templates.filter(template => {
+ const name = template.templateName?.toLowerCase() || ''
+ return (
+ (template.templateName?.includes('준법서약') && template.templateName?.includes('영문')) ||
+ template.templateName?.includes('gtc')
+ ) && !name.includes('비밀유지') && !name.includes('기술자료')
+ })
// GTC 템플릿 중 최신 리비전의 것만 선택
const gtcTemplates = foreignTemplates.filter(t => t.templateName?.includes('gtc'))
const nonGtcTemplates = foreignTemplates.filter(t => !t.templateName?.includes('gtc'))
@@ -173,9 +177,13 @@ export function RequestPQDialog({ vendors, showTrigger = true, onSuccess, ...pro }
} else if (isAllDomestic) {
// 내자: 준법서약 (영문), GTC 제외한 모든 템플릿 선택
+ // 비밀유지 계약서, 기술자료 요구서 제외
const domesticTemplates = templates.filter(template => {
const name = template.templateName?.toLowerCase() || ''
- return !(name.includes('준법서약') && name.includes('영문')) && !name.includes('gtc')
+ return !(name.includes('준법서약') && name.includes('영문')) &&
+ !name.includes('gtc') &&
+ !name.includes('비밀유지') &&
+ !name.includes('기술자료')
})
setSelectedTemplateIds(domesticTemplates.map(t => t.id))
}
|
