summaryrefslogtreecommitdiff
path: root/lib/vendor-document-list/plant
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vendor-document-list/plant')
-rw-r--r--lib/vendor-document-list/plant/document-stage-dialogs.tsx520
-rw-r--r--lib/vendor-document-list/plant/document-stage-toolbar.tsx2
-rw-r--r--lib/vendor-document-list/plant/document-stages-columns.tsx4
-rw-r--r--lib/vendor-document-list/plant/document-stages-service.ts3
-rw-r--r--lib/vendor-document-list/plant/shi-buyer-system-api.ts8
5 files changed, 310 insertions, 227 deletions
diff --git a/lib/vendor-document-list/plant/document-stage-dialogs.tsx b/lib/vendor-document-list/plant/document-stage-dialogs.tsx
index f49d7d47..4c1861b9 100644
--- a/lib/vendor-document-list/plant/document-stage-dialogs.tsx
+++ b/lib/vendor-document-list/plant/document-stage-dialogs.tsx
@@ -64,6 +64,7 @@ import { cn, formatDate } from "@/lib/utils"
import ExcelJS from 'exceljs'
import { Progress } from "@/components/ui/progress"
import { Alert, AlertDescription } from "@/components/ui/alert"
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
const getStatusVariant = (status: string) => {
switch (status) {
@@ -97,69 +98,116 @@ interface AddDocumentDialogProps {
projectType: "ship" | "plant"
}
+
export function AddDocumentDialog({
open,
onOpenChange,
contractId,
projectType
}: AddDocumentDialogProps) {
- const [isLoading, setIsLoading] = React.useState(false)
+ const [isLoadingInitialData, setIsLoadingInitialData] = React.useState(false)
+ const [isSubmitting, setIsSubmitting] = React.useState(false)
const [documentNumberTypes, setDocumentNumberTypes] = React.useState<any[]>([])
const [documentClasses, setDocumentClasses] = React.useState<any[]>([])
const [selectedTypeConfigs, setSelectedTypeConfigs] = React.useState<any[]>([])
const [comboBoxOptions, setComboBoxOptions] = React.useState<Record<number, any[]>>({})
const [documentClassOptions, setDocumentClassOptions] = React.useState<any[]>([])
- const [isLoadingInitialData, setIsLoadingInitialData] = React.useState(false)
- const [isSubmitting, setIsSubmitting] = React.useState(false)
+
+ // SHI와 CPY 타입 체크
+ const [shiType, setShiType] = React.useState<any>(null)
+ const [cpyType, setCpyType] = React.useState<any>(null)
+ const [activeTab, setActiveTab] = React.useState<"SHI" | "CPY">("SHI")
+ const [dataLoaded, setDataLoaded] = React.useState(false)
+ console.log(dataLoaded,"dataLoaded")
const [formData, setFormData] = React.useState({
documentNumberTypeId: "",
documentClassId: "",
title: "",
- vendorDocNumber: "",
fieldValues: {} as Record<string, string>,
- planDates: {} as Record<number, string> // optionId -> planDate
+ planDates: {} as Record<number, string>
})
// Load initial data
- React.useEffect(() => {
- if (open) {
- resetForm() // 폼 리셋 추가
- loadInitialData()
- }
- }, [open])
+// Dialog가 닫힐 때 상태 초기화를 확실히 하기
+React.useEffect(() => {
+ if (!open) {
+ // Dialog가 닫힐 때만 초기화
+ resetForm()
+ } else if (!dataLoaded) {
+ // Dialog가 열리고 데이터가 로드되지 않았을 때만
+ loadInitialData()
+ }
+}, [open])
+
const loadInitialData = async () => {
- setIsLoadingInitialData(true) // isLoading 대신
+ setIsLoadingInitialData(true)
+ let foundShiType = null;
+ let foundCpyType = null;
+
try {
const [typesResult, classesResult] = await Promise.all([
getDocumentNumberTypes(contractId),
getDocumentClasses(contractId)
])
- if (typesResult.success) {
+ console.log(typesResult,"typesResult")
+
+ if (typesResult.success && typesResult.data) {
setDocumentNumberTypes(typesResult.data)
+
+ // 로컬 변수에 먼저 저장
+ foundShiType = typesResult.data.find((type: any) =>
+ type.name?.toUpperCase().trim() === "SHI"
+ )
+ foundCpyType = typesResult.data.find((type: any) =>
+ type.name?.toUpperCase().trim() === "CPY"
+ )
+
+ setShiType(foundShiType || null)
+ setCpyType(foundCpyType || null)
+
+ // 로컬 변수 사용
+ if (foundShiType) {
+ await handleTabChange("SHI", String(foundShiType.id))
+ } else if (foundCpyType) {
+ setActiveTab("CPY")
+ await handleTabChange("CPY", String(foundCpyType.id))
+ }
}
+
if (classesResult.success) {
setDocumentClasses(classesResult.data)
}
+
+ setDataLoaded(true)
} catch (error) {
+ console.error("Error loading data:", error)
toast.error("Error loading data.")
} finally {
+ // 로컬 변수를 체크
+ if (!foundShiType && !foundCpyType) {
+ console.error("No types found after loading")
+ }
setIsLoadingInitialData(false)
}
}
- // Handle document type change
- const handleDocumentTypeChange = async (documentNumberTypeId: string) => {
- setFormData({
- ...formData,
- documentNumberTypeId,
- fieldValues: {}
- })
-
+ // 탭 변경 처리
+ const handleTabChange = async (tab: "SHI" | "CPY", typeId?: string) => {
+ setActiveTab(tab)
+
+ const documentNumberTypeId = typeId || (tab === "SHI" ? shiType?.id : cpyType?.id)
+
if (documentNumberTypeId) {
+ setFormData(prev => ({
+ ...prev,
+ documentNumberTypeId: String(documentNumberTypeId),
+ fieldValues: {}
+ }))
+
const configsResult = await getDocumentNumberTypeConfigs(Number(documentNumberTypeId))
if (configsResult.success) {
setSelectedTypeConfigs(configsResult.data)
@@ -238,22 +286,21 @@ export function AddDocumentDialog({
selectedTypeConfigs.forEach((config, index) => {
const fieldKey = `field_${config.sdq}`
const value = formData.fieldValues[fieldKey] || "[value]"
- preview += value
- if (index < selectedTypeConfigs.length - 1) {
- preview += "-"
+
+ if (index > 0 && config.delimiter) {
+ preview += config.delimiter
}
+ preview += value
})
return preview
}
// Check if form is valid for submission
const isFormValid = () => {
- // Check basic required fields
if (!formData.documentNumberTypeId || !formData.documentClassId || !formData.title.trim()) {
return false
}
- // Check if all required document number components are filled
const requiredConfigs = selectedTypeConfigs.filter(config => config.required)
for (const config of requiredConfigs) {
const fieldKey = `field_${config.sdq}`
@@ -263,7 +310,6 @@ export function AddDocumentDialog({
}
}
- // Check if document number can be generated
const docNumber = generatePreviewDocNumber()
if (!docNumber || docNumber === "" || docNumber.includes("[value]")) {
return false
@@ -278,24 +324,27 @@ export function AddDocumentDialog({
return
}
- const docNumber = generatePreviewDocNumber()
- if (!docNumber) {
+ const generatedDocNumber = generatePreviewDocNumber()
+ if (!generatedDocNumber) {
toast.error("Cannot generate document number.")
return
}
- setIsSubmitting(true) // isLoading 대신
+ setIsSubmitting(true)
try {
- const result = await createDocument({
+ // CPY 탭에서는 생성된 문서번호를 vendorDocNumber로 저장
+ const submitData = {
contractId,
documentNumberTypeId: Number(formData.documentNumberTypeId),
documentClassId: Number(formData.documentClassId),
title: formData.title,
- docNumber: docNumber, // 미리 생성된 문서번호 전송
+ docNumber: activeTab === "SHI" ? generatedDocNumber : "", // SHI는 docNumber로
+ vendorDocNumber: activeTab === "CPY" ? generatedDocNumber : "", // CPY는 vendorDocNumber로
fieldValues: formData.fieldValues,
planDates: formData.planDates,
- vendorDocNumber: formData.vendorDocNumber,
- })
+ }
+
+ const result = await createDocument(submitData)
if (result.success) {
toast.success("Document added successfully.")
@@ -307,7 +356,7 @@ export function AddDocumentDialog({
} catch (error) {
toast.error("Error adding document.")
} finally {
- setIsSubmitting(false) // isLoading 대신
+ setIsSubmitting(false)
}
}
@@ -316,16 +365,165 @@ export function AddDocumentDialog({
documentNumberTypeId: "",
documentClassId: "",
title: "",
- vendorDocNumber: "",
fieldValues: {},
planDates: {}
})
setSelectedTypeConfigs([])
setComboBoxOptions({})
setDocumentClassOptions([])
+ setActiveTab("SHI")
+ setDataLoaded(false)
}
- const isPlantProject = projectType === "plant"
+ // 공통 폼 컴포넌트
+ const DocumentForm = () => (
+ <div className="grid gap-4">
+ {/* Dynamic Fields */}
+ {selectedTypeConfigs.length > 0 && (
+ <div className="border rounded-lg p-4 bg-blue-50/30 dark:bg-blue-950/30">
+ <Label className="text-sm font-medium text-blue-800 dark:text-blue-200 mb-3 block">
+ Document Number Components
+ </Label>
+ <div className="grid gap-3">
+ {selectedTypeConfigs.map((config) => (
+ <div key={config.id} className="grid gap-2">
+ <Label className="text-sm">
+ {config.codeGroup?.description || config.description}
+ {config.required && <span className="text-red-500 ml-1">*</span>}
+ {config.remark && (
+ <span className="text-xs text-gray-500 dark:text-gray-400 ml-2">({config.remark})</span>
+ )}
+ </Label>
+
+ {config.codeGroup?.controlType === 'combobox' ? (
+ <Select
+ value={formData.fieldValues[`field_${config.sdq}`] || ""}
+ onValueChange={(value) => handleFieldValueChange(`field_${config.sdq}`, value)}
+ >
+ <SelectTrigger>
+ <SelectValue placeholder="Select option" />
+ </SelectTrigger>
+ <SelectContent>
+ {(comboBoxOptions[config.codeGroupId!] || []).map((option) => (
+ <SelectItem key={option.id} value={option.code}>
+ {option.code} - {option.description}
+ </SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
+ ) : config.documentClass ? (
+ <div className="p-2 bg-gray-100 dark:bg-gray-800 rounded text-sm">
+ {config.documentClass.code} - {config.documentClass.description}
+ </div>
+ ) : (
+ <Input
+ value={formData.fieldValues[`field_${config.sdq}`] || ""}
+ onChange={(e) => handleFieldValueChange(`field_${config.sdq}`, e.target.value)}
+ placeholder="Enter value"
+ />
+ )}
+ </div>
+ ))}
+ </div>
+
+ {/* Document Number Preview */}
+ <div className="mt-3 p-2 bg-white dark:bg-gray-900 border rounded">
+ <Label className="text-xs text-gray-600 dark:text-gray-400">
+ {activeTab === "SHI" ? "Document Number" : "Vendor Document Number"} Preview:
+ </Label>
+ <div className="font-mono text-sm font-medium text-blue-600 dark:text-blue-400">
+ {generatePreviewDocNumber()}
+ </div>
+ </div>
+ </div>
+ )}
+
+ {/* Document Class Selection */}
+ <div className="grid gap-2">
+ <Label htmlFor="documentClassId">
+ Document Class <span className="text-red-500">*</span>
+ </Label>
+ <Select
+ value={formData.documentClassId}
+ onValueChange={handleDocumentClassChange}
+ >
+ <SelectTrigger>
+ <SelectValue placeholder="Select document class" />
+ </SelectTrigger>
+ <SelectContent>
+ {documentClasses.map((cls) => (
+ <SelectItem key={cls.id} value={String(cls.id)}>
+ {cls.value}
+ </SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
+ {formData.documentClassId && (
+ <p className="text-xs text-gray-600 dark:text-gray-400">
+ Options from the selected class will be automatically created as stages.
+ </p>
+ )}
+ </div>
+
+ {/* Document Class Options with Plan Dates */}
+ {documentClassOptions.length > 0 && (
+ <div className="border rounded-lg p-4 bg-green-50/30 dark:bg-green-950/30">
+ <Label className="text-sm font-medium text-green-800 dark:text-green-200 mb-3 block">
+ Document Class Stages with Plan Dates
+ </Label>
+ <div className="grid gap-3">
+ {documentClassOptions.map((option) => (
+ <div key={option.id} className="grid grid-cols-2 gap-3 items-center">
+ <div>
+ <Label className="text-sm font-medium">
+ {option.optionValue}
+ </Label>
+ {option.optionCode && (
+ <p className="text-xs text-gray-500 dark:text-gray-400">Code: {option.optionCode}</p>
+ )}
+ </div>
+ <div className="grid gap-1">
+ <Label className="text-xs text-gray-600 dark:text-gray-400">Plan Date</Label>
+ <Input
+ type="date"
+ value={formData.planDates[option.id] || ""}
+ onChange={(e) => handlePlanDateChange(option.id, e.target.value)}
+ className="text-sm"
+ />
+ </div>
+ </div>
+ ))}
+ </div>
+ </div>
+ )}
+
+ {/* Document Title */}
+ <div className="grid gap-2">
+ <Label htmlFor="title">
+ Document Title <span className="text-red-500">*</span>
+ </Label>
+ <Input
+ id="title"
+ value={formData.title}
+ onChange={(e) => setFormData({ ...formData, title: e.target.value })}
+ placeholder="Enter document title"
+ />
+ </div>
+ </div>
+ )
+
+ // 로딩 중이거나 데이터 체크 중일 때 표시
+ if (isLoadingInitialData) {
+ return (
+ <Dialog open={open} onOpenChange={onOpenChange}>
+ <DialogContent className="sm:max-w-[700px] h-[80vh] flex flex-col">
+ <div className="flex items-center justify-center py-8 flex-1">
+ <Loader2 className="h-8 w-8 animate-spin" />
+ </div>
+ </DialogContent>
+ </Dialog>
+ )
+ }
return (
<Dialog open={open} onOpenChange={onOpenChange}>
@@ -337,195 +535,77 @@ export function AddDocumentDialog({
</DialogDescription>
</DialogHeader>
- {isLoading ? (
- <div className="flex items-center justify-center py-8 flex-1">
- <Loader2 className="h-8 w-8 animate-spin" />
+ {!shiType && !cpyType ? (
+ <div className="flex-1 flex items-center justify-center">
+ <Alert className="max-w-md">
+ <AlertTriangle className="h-4 w-4" />
+ <AlertDescription>
+ 필수 Document Number Type (SHI, CPY)이 설정되지 않았습니다.
+ 먼저 Number Types 관리에서 설정해주세요.
+ </AlertDescription>
+ </Alert>
</div>
) : (
- <div className="flex-1 overflow-y-auto pr-2">
- <div className="grid gap-4 py-4">
- {/* Document Number Type Selection */}
- <div className="grid gap-2">
- <Label htmlFor="documentNumberTypeId">
- Document Number Type <span className="text-red-500">*</span>
- </Label>
- <Select
- value={formData.documentNumberTypeId}
- onValueChange={handleDocumentTypeChange}
- >
- <SelectTrigger>
- <SelectValue placeholder="Select document number type" />
- </SelectTrigger>
- <SelectContent>
- {documentNumberTypes.map((type) => (
- <SelectItem key={type.id} value={String(type.id)}>
- {type.name}
- </SelectItem>
- ))}
- </SelectContent>
- </Select>
- </div>
-
- {/* Dynamic Fields */}
- {selectedTypeConfigs.length > 0 && (
- <div className="border rounded-lg p-4 bg-blue-50/30 dark:bg-blue-950/30">
- <Label className="text-sm font-medium text-blue-800 dark:text-blue-200 mb-3 block">
- Document Number Components
- </Label>
- <div className="grid gap-3">
- {selectedTypeConfigs.map((config) => (
- <div key={config.id} className="grid gap-2">
- <Label className="text-sm">
- {config.codeGroup?.description || config.description}
- {config.required && <span className="text-red-500 ml-1">*</span>}
- {config.remark && (
- <span className="text-xs text-gray-500 dark:text-gray-400 ml-2">({config.remark})</span>
- )}
- </Label>
-
- {config.codeGroup?.controlType === 'combobox' ? (
- <Select
- value={formData.fieldValues[`field_${config.sdq}`] || ""}
- onValueChange={(value) => handleFieldValueChange(`field_${config.sdq}`, value)}
- >
- <SelectTrigger>
- <SelectValue placeholder="Select option" />
- </SelectTrigger>
- <SelectContent>
- {(comboBoxOptions[config.codeGroupId!] || []).map((option) => (
- <SelectItem key={option.id} value={option.code}>
- {option.code} - {option.description}
- </SelectItem>
- ))}
- </SelectContent>
- </Select>
- ) : config.documentClass ? (
- <div className="p-2 bg-gray-100 dark:bg-gray-800 rounded text-sm">
- {config.documentClass.code} - {config.documentClass.description}
- </div>
- ) : (
- <Input
- value={formData.fieldValues[`field_${config.sdq}`] || ""}
- onChange={(e) => handleFieldValueChange(`field_${config.sdq}`, e.target.value)}
- placeholder="Enter value"
- />
- )}
- </div>
- ))}
- </div>
-
- {/* Document Number Preview */}
- <div className="mt-3 p-2 bg-white dark:bg-gray-900 border rounded">
- <Label className="text-xs text-gray-600 dark:text-gray-400">Document Number Preview:</Label>
- <div className="font-mono text-sm font-medium text-blue-600 dark:text-blue-400">
- {generatePreviewDocNumber()}
- </div>
- </div>
- </div>
- )}
-
- {/* Document Class Selection */}
- <div className="grid gap-2">
- <Label htmlFor="documentClassId">
- Document Class <span className="text-red-500">*</span>
- </Label>
- <Select
- value={formData.documentClassId}
- onValueChange={handleDocumentClassChange}
- >
- <SelectTrigger>
- <SelectValue placeholder="Select document class" />
- </SelectTrigger>
- <SelectContent>
- {documentClasses.map((cls) => (
- <SelectItem key={cls.id} value={String(cls.id)}>
- {cls.value}
- </SelectItem>
- ))}
- </SelectContent>
- </Select>
- {formData.documentClassId && (
- <p className="text-xs text-gray-600 dark:text-gray-400">
- Options from the selected class will be automatically created as stages.
- </p>
- )}
- </div>
-
- {/* Document Class Options with Plan Dates */}
- {documentClassOptions.length > 0 && (
- <div className="border rounded-lg p-4 bg-green-50/30 dark:bg-green-950/30">
- <Label className="text-sm font-medium text-green-800 dark:text-green-200 mb-3 block">
- Document Class Stages with Plan Dates
- </Label>
- <div className="grid gap-3">
- {documentClassOptions.map((option) => (
- <div key={option.id} className="grid grid-cols-2 gap-3 items-center">
- <div>
- <Label className="text-sm font-medium">
- {option.optionValue}
- </Label>
- {option.optionCode && (
- <p className="text-xs text-gray-500 dark:text-gray-400">Code: {option.optionCode}</p>
- )}
- </div>
- <div className="grid gap-1">
- <Label className="text-xs text-gray-600 dark:text-gray-400">Plan Date</Label>
- <Input
- type="date"
- value={formData.planDates[option.id] || ""}
- onChange={(e) => handlePlanDateChange(option.id, e.target.value)}
- className="text-sm"
- />
- </div>
- </div>
- ))}
- </div>
- </div>
- )}
-
- {/* Document Title */}
- <div className="grid gap-2">
- <Label htmlFor="title">
- Document Title <span className="text-red-500">*</span>
- </Label>
- <Input
- id="title"
- value={formData.title}
- onChange={(e) => setFormData({ ...formData, title: e.target.value })}
- placeholder="Enter document title"
- />
+ <>
+ <Tabs value={activeTab} onValueChange={(v) => handleTabChange(v as "SHI" | "CPY")} className="flex-1 flex flex-col">
+ <TabsList className="grid w-full grid-cols-2">
+ <TabsTrigger value="SHI" disabled={!shiType}>
+ SHI (삼성중공업 도서번호)
+ {!shiType && <AlertTriangle className="ml-2 h-3 w-3" />}
+ </TabsTrigger>
+ <TabsTrigger value="CPY" disabled={!cpyType}>
+ CPY (프로젝트 문서번호)
+ {!cpyType && <AlertTriangle className="ml-2 h-3 w-3" />}
+ </TabsTrigger>
+ </TabsList>
+
+ <div className="flex-1 overflow-y-auto pr-2 mt-4">
+ <TabsContent value="SHI" className="mt-0">
+ {shiType ? (
+ <DocumentForm />
+ ) : (
+ <Alert>
+ <AlertTriangle className="h-4 w-4" />
+ <AlertDescription>
+ SHI Document Number Type이 설정되지 않았습니다.
+ </AlertDescription>
+ </Alert>
+ )}
+ </TabsContent>
+
+ <TabsContent value="CPY" className="mt-0">
+ {cpyType ? (
+ <DocumentForm />
+ ) : (
+ <Alert>
+ <AlertTriangle className="h-4 w-4" />
+ <AlertDescription>
+ CPY Document Number Type이 설정되지 않았습니다.
+ </AlertDescription>
+ </Alert>
+ )}
+ </TabsContent>
</div>
+ </Tabs>
- {/* Additional Information */}
- {isPlantProject && (
- <div className="grid gap-2">
- <Label htmlFor="vendorDocNumber">Vendor Document Number</Label>
- <Input
- id="vendorDocNumber"
- value={formData.vendorDocNumber}
- onChange={(e) => setFormData({ ...formData, vendorDocNumber: e.target.value })}
- placeholder="Vendor provided document number"
- />
- </div>
- )}
- </div>
- </div>
+ <DialogFooter className="flex-shrink-0">
+ <Button variant="outline" onClick={() => onOpenChange(false)} disabled={isSubmitting}>
+ Cancel
+ </Button>
+ <Button
+ onClick={handleSubmit}
+ disabled={isSubmitting || !isFormValid() || (!shiType && !cpyType)}
+ >
+ {isSubmitting ? <Loader2 className="h-4 w-4 animate-spin mr-2" /> : null}
+ Add Document
+ </Button>
+ </DialogFooter>
+ </>
)}
-
- <DialogFooter className="flex-shrink-0">
- <Button variant="outline" onClick={() => onOpenChange(false)} disabled={isSubmitting}>
- Cancel
- </Button>
- <Button onClick={handleSubmit} disabled={isSubmitting || !isFormValid()}>
- {isSubmitting ? <Loader2 className="h-4 w-4 animate-spin mr-2" /> : null}
- Add Document
- </Button>
- </DialogFooter>
</DialogContent>
</Dialog>
)
}
-
// =============================================================================
// Edit Document Dialog (with improved stage plan date editing)
// =============================================================================
@@ -1236,7 +1316,7 @@ export function ExcelImportDialog({
<li>Document Name* (문서명)</li>
<li>Document Class* (문서클래스 - 드롭다운 선택)</li>
{projectType === "plant" && (
- <li>Vendor Doc No. (벤더문서번호)</li>
+ <li>Project Doc No. (벤더문서번호)</li>
)}
</ul>
<p className="mt-2"><strong>Stage Plan Dates 시트 (선택사항):</strong></p>
@@ -1513,7 +1593,7 @@ async function createImportTemplate(projectType: "ship" | "plant", contractId: n
"Document Number*",
"Document Name*",
"Document Class*",
- ...(projectType === "plant" ? ["Vendor Doc No."] : []),
+ ...(projectType === "plant" ? ["Project Doc No."] : []),
"Notes",
];
const documentHeaderRow = documentsSheet.addRow(documentHeaders);
@@ -1596,7 +1676,7 @@ async function createImportTemplate(projectType: "ship" | "plant", contractId: n
[" - Document Number*: 고유한 문서 번호를 입력하세요"],
[" - Document Name*: 문서명을 입력하세요"],
[" - Document Class*: 드롭다운에서 문서 클래스를 선택하세요"],
- [" - Vendor Doc No.: 벤더 문서 번호"],
+ [" - Project Doc No.: 벤더 문서 번호"],
[" - Notes: 참고사항"],
[""],
["2. Stage Plan Dates 시트 (선택사항)"],
diff --git a/lib/vendor-document-list/plant/document-stage-toolbar.tsx b/lib/vendor-document-list/plant/document-stage-toolbar.tsx
index 601a9152..ccb9e15c 100644
--- a/lib/vendor-document-list/plant/document-stage-toolbar.tsx
+++ b/lib/vendor-document-list/plant/document-stage-toolbar.tsx
@@ -18,7 +18,7 @@ import { sendDocumentsToSHI } from "./document-stages-service"
import { useDocumentPolling } from "@/hooks/use-document-polling"
import { cn } from "@/lib/utils"
import { MultiUploadDialog } from "./upload/components/multi-upload-dialog"
-// import { useRouter } from "next/navigation"
+import { useRouter } from "next/navigation"
// 서버 액션 import (필요한 경우)
// import { importDocumentsExcel } from "./document-stages-service"
diff --git a/lib/vendor-document-list/plant/document-stages-columns.tsx b/lib/vendor-document-list/plant/document-stages-columns.tsx
index 2f8fd482..0b85c3f8 100644
--- a/lib/vendor-document-list/plant/document-stages-columns.tsx
+++ b/lib/vendor-document-list/plant/document-stages-columns.tsx
@@ -298,7 +298,7 @@ export function getDocumentStagesColumns({
{
accessorKey: "vendorDocNumber",
header: ({ column }) => (
- <DataTableColumnHeaderSimple column={column} title="Vendor Doc No." />
+ <DataTableColumnHeaderSimple column={column} title="Project Doc No." />
),
cell: ({ row }) => {
const doc = row.original
@@ -311,7 +311,7 @@ export function getDocumentStagesColumns({
size: 120,
enableResizing: true,
meta: {
- excelHeader: "Vendor Doc No."
+ excelHeader: "Project Doc No."
},
},
)
diff --git a/lib/vendor-document-list/plant/document-stages-service.ts b/lib/vendor-document-list/plant/document-stages-service.ts
index 30a235c3..2c65b4e6 100644
--- a/lib/vendor-document-list/plant/document-stages-service.ts
+++ b/lib/vendor-document-list/plant/document-stages-service.ts
@@ -689,6 +689,8 @@ export async function getDocumentNumberTypes(contractId: number) {
}
}
+ console.log(project,"project")
+
const types = await db
.select()
.from(documentNumberTypes)
@@ -711,6 +713,7 @@ export async function getDocumentNumberTypeConfigs(documentNumberTypeId: number)
id: documentNumberTypeConfigs.id,
sdq: documentNumberTypeConfigs.sdq,
description: documentNumberTypeConfigs.description,
+ delimiter: documentNumberTypeConfigs.delimiter,
remark: documentNumberTypeConfigs.remark,
codeGroupId: documentNumberTypeConfigs.codeGroupId,
// documentClassId: documentNumberTypeConfigs.documentClassId,
diff --git a/lib/vendor-document-list/plant/shi-buyer-system-api.ts b/lib/vendor-document-list/plant/shi-buyer-system-api.ts
index 1f15efa6..582490af 100644
--- a/lib/vendor-document-list/plant/shi-buyer-system-api.ts
+++ b/lib/vendor-document-list/plant/shi-buyer-system-api.ts
@@ -162,10 +162,9 @@ export class ShiBuyerSystemAPI {
vendorName: sql<string>`(SELECT vendor_name FROM vendors WHERE id = ${stageDocuments.vendorId})`,
stages: sql<any[]>`
COALESCE(
- (SELECT json_agg(row_to_json(s.*))
+ (SELECT json_agg(row_to_json(s.*) ORDER BY s.stage_order)
FROM stage_issue_stages s
- WHERE s.document_id = ${stageDocuments.id}
- ORDER BY s.stage_order),
+ WHERE s.document_id = ${stageDocuments.id}),
'[]'::json
)
`
@@ -178,7 +177,8 @@ export class ShiBuyerSystemAPI {
ne(stageDocuments.buyerSystemStatus, "승인(DC)")
)
)
-
+
+
return result
}