mirror of
https://github.com/hcengineering/platform.git
synced 2025-03-21 15:02:24 +00:00

* EZQMS-1145: Fixes doc import tool Signed-off-by: Alexey Zinoviev <alexey.zinoviev@xored.com>
315 lines
9.0 KiB
TypeScript
315 lines
9.0 KiB
TypeScript
//
|
|
// Copyright @ 2022-2023 Hardcore Engineering Inc.
|
|
//
|
|
|
|
import { type Data, type Ref, TxOperations, generateId, DOMAIN_TX, getCollaborativeDoc } from '@hcengineering/core'
|
|
import {
|
|
createDefaultSpace,
|
|
createOrUpdate,
|
|
tryMigrate,
|
|
tryUpgrade,
|
|
type MigrateOperation,
|
|
type MigrationClient,
|
|
type MigrationUpgradeClient
|
|
} from '@hcengineering/model'
|
|
import core from '@hcengineering/model-core'
|
|
import tags from '@hcengineering/tags'
|
|
import {
|
|
type ChangeControl,
|
|
type DocumentCategory,
|
|
DocumentState,
|
|
documentsId,
|
|
createDocumentTemplate,
|
|
type ControlledDocument,
|
|
createChangeControl
|
|
} from '@hcengineering/controlled-documents'
|
|
|
|
import documents from './index'
|
|
|
|
async function createTemplatesSpace (tx: TxOperations): Promise<void> {
|
|
const existingSpace = await tx.findOne(documents.class.DocumentSpace, {
|
|
_id: documents.space.UnsortedTemplates
|
|
})
|
|
|
|
if (existingSpace === undefined) {
|
|
await tx.createDoc(
|
|
documents.class.DocumentSpace,
|
|
core.space.Space,
|
|
{
|
|
name: 'Unsorted templates',
|
|
description: 'Unsorted templates',
|
|
private: false,
|
|
archived: false,
|
|
autoJoin: true,
|
|
members: [],
|
|
type: documents.spaceType.DocumentSpaceType
|
|
},
|
|
documents.space.UnsortedTemplates
|
|
)
|
|
}
|
|
}
|
|
|
|
async function createQualityDocumentsSpace (tx: TxOperations): Promise<void> {
|
|
const existingSpace = await tx.findOne(documents.class.OrgSpace, {
|
|
_id: documents.space.QualityDocuments
|
|
})
|
|
|
|
if (existingSpace === undefined) {
|
|
await tx.createDoc(
|
|
documents.class.OrgSpace,
|
|
core.space.Space,
|
|
{
|
|
name: 'Quality documents',
|
|
description: "Space for organization's quality documents",
|
|
private: true,
|
|
archived: false,
|
|
members: [],
|
|
autoJoin: true,
|
|
owners: [],
|
|
type: documents.spaceType.DocumentSpaceType
|
|
},
|
|
documents.space.QualityDocuments
|
|
)
|
|
}
|
|
}
|
|
|
|
async function fixChangeControlsForDocs (tx: TxOperations): Promise<void> {
|
|
const defaultCCSpec: Data<ChangeControl> = {
|
|
description: '',
|
|
reason: '',
|
|
impact: '',
|
|
impactedDocuments: []
|
|
}
|
|
const controlledDocuments = await tx.findAll(
|
|
documents.class.ControlledDocument,
|
|
{},
|
|
{ lookup: { changeControl: documents.class.ChangeControl } }
|
|
)
|
|
|
|
for (const cdoc of controlledDocuments) {
|
|
const existingCC = await tx.findOne(documents.class.ChangeControl, { _id: cdoc.changeControl })
|
|
|
|
if (existingCC !== undefined) {
|
|
continue
|
|
}
|
|
|
|
const newCc = await tx.createDoc(
|
|
documents.class.ChangeControl,
|
|
cdoc.space,
|
|
defaultCCSpec,
|
|
cdoc.changeControl?.length > 0 ? cdoc.changeControl : undefined
|
|
)
|
|
|
|
if (cdoc.changeControl === undefined) {
|
|
await tx.update(cdoc, { changeControl: newCc })
|
|
}
|
|
}
|
|
}
|
|
|
|
async function createProductChangeControlTemplate (tx: TxOperations): Promise<void> {
|
|
const ccCategory = 'documents:category:DOC - CC' as Ref<DocumentCategory>
|
|
const productChangeControlTemplate = await tx.findOne(documents.mixin.DocumentTemplate, {
|
|
category: ccCategory
|
|
})
|
|
|
|
if (productChangeControlTemplate === undefined) {
|
|
const ccRecordId = generateId<ChangeControl>()
|
|
const ccRecord: Data<ChangeControl> = {
|
|
description: '',
|
|
reason: 'New template creation',
|
|
impact: '',
|
|
impactedDocuments: []
|
|
}
|
|
|
|
const seq = await tx.findOne(documents.class.Sequence, {
|
|
_id: documents.sequence.Templates
|
|
})
|
|
|
|
if (seq === undefined) {
|
|
return
|
|
}
|
|
|
|
const { success } = await createDocumentTemplate(
|
|
tx,
|
|
documents.class.ControlledDocument,
|
|
documents.space.QualityDocuments,
|
|
documents.mixin.DocumentTemplate,
|
|
documents.ids.NoProject,
|
|
undefined,
|
|
documents.template.ProductChangeControl as unknown as Ref<ControlledDocument>,
|
|
'CC',
|
|
{
|
|
title: 'Change Control Template for new Product Version',
|
|
abstract:
|
|
'This Template is to be used to create a Change Control document each time you want to create a new product version.',
|
|
changeControl: ccRecordId,
|
|
requests: 0,
|
|
reviewers: [],
|
|
approvers: [],
|
|
coAuthors: [],
|
|
code: `TMPL-${seq.sequence + 1}`,
|
|
seqNumber: 0,
|
|
major: 0,
|
|
minor: 1,
|
|
state: DocumentState.Effective,
|
|
sections: 0,
|
|
commentSequence: 0,
|
|
content: getCollaborativeDoc(generateId())
|
|
},
|
|
ccCategory,
|
|
undefined,
|
|
{
|
|
title: 'Section 1'
|
|
}
|
|
)
|
|
|
|
if (!success) {
|
|
return
|
|
}
|
|
|
|
await createChangeControl(tx, ccRecordId, ccRecord, documents.space.QualityDocuments)
|
|
}
|
|
}
|
|
|
|
async function createTemplateSequence (tx: TxOperations): Promise<void> {
|
|
const templateSeq = await tx.findOne(documents.class.Sequence, {
|
|
_id: documents.sequence.Templates
|
|
})
|
|
|
|
if (templateSeq === undefined) {
|
|
await tx.createDoc(
|
|
documents.class.Sequence,
|
|
documents.space.Documents,
|
|
{
|
|
attachedTo: documents.mixin.DocumentTemplate,
|
|
sequence: 0
|
|
},
|
|
documents.sequence.Templates
|
|
)
|
|
}
|
|
}
|
|
|
|
async function createDocumentCategories (tx: TxOperations): Promise<void> {
|
|
const categories: Pick<Data<DocumentCategory>, 'code' | 'title'>[] = [
|
|
{ code: 'CA', title: 'CAPA (Corrective and Preventive Action)' },
|
|
{ code: 'CC', title: 'Change Control' },
|
|
{ code: 'CE', title: 'Clinical Evaluation, Post-Market Clinical Follow-Up' },
|
|
{ code: 'CH', title: 'Complaint Handling & Support' },
|
|
{ code: 'CS', title: 'Clincial Studies' },
|
|
{ code: 'DC', title: 'Document-Control' },
|
|
{ code: 'DI', title: 'Design-Input' },
|
|
{ code: 'DT', title: 'Design Transfer' },
|
|
{ code: 'HF', title: 'Human Factors' },
|
|
{ code: 'HR', title: 'Human Resources' },
|
|
{ code: 'HW', title: 'Hardware Development' },
|
|
{ code: 'IA', title: 'Internal Audit' },
|
|
{ code: 'IM', title: 'Installation & Maintenance' },
|
|
{ code: 'IS', title: 'Infrastructure' },
|
|
{ code: 'LA', title: 'Labeling' },
|
|
{ code: 'MA', title: 'Marketing' },
|
|
{ code: 'MR', title: 'Management Review' },
|
|
{ code: 'PD', title: 'Product Development' },
|
|
{ code: 'PM', title: 'Post-Market Surveillance' },
|
|
{ code: 'PR', title: 'Production' },
|
|
{ code: 'PS', title: 'Purchase and Supplier Management' },
|
|
{ code: 'PSA', title: 'Product Safety' },
|
|
{ code: 'QM', title: 'Quality Manual' },
|
|
{ code: 'RM', title: 'Risk Management' },
|
|
{ code: 'RU', title: 'Regulatory Update' },
|
|
{ code: 'SA', title: 'Sales and Marketing' },
|
|
{ code: 'SU', title: 'Support' },
|
|
{ code: 'SW', title: 'Software Development' },
|
|
{ code: 'TF', title: 'Technical File, Product Release' },
|
|
{ code: 'VI', title: 'Vigilance' },
|
|
{ code: 'VV', title: 'Verification & Validation' },
|
|
{ code: 'CM', title: 'Client Management' }
|
|
]
|
|
|
|
await Promise.all(
|
|
categories.map((c) =>
|
|
createOrUpdate(
|
|
tx,
|
|
documents.class.DocumentCategory,
|
|
documents.space.QualityDocuments,
|
|
{ ...c, attachments: 0 },
|
|
((documents.category.DOC as string) + ' - ' + c.code) as Ref<DocumentCategory>
|
|
)
|
|
)
|
|
)
|
|
}
|
|
|
|
async function createTagCategories (tx: TxOperations): Promise<void> {
|
|
await createOrUpdate(
|
|
tx,
|
|
tags.class.TagCategory,
|
|
core.space.Workspace,
|
|
{
|
|
icon: tags.icon.Tags,
|
|
label: 'Labels',
|
|
targetClass: documents.class.Document,
|
|
tags: [],
|
|
default: true
|
|
},
|
|
documents.category.Other
|
|
)
|
|
|
|
await createOrUpdate(
|
|
tx,
|
|
tags.class.TagCategory,
|
|
core.space.Workspace,
|
|
{
|
|
icon: tags.icon.Tags,
|
|
label: 'Labels',
|
|
targetClass: documents.mixin.DocumentTemplate,
|
|
tags: [],
|
|
default: true
|
|
},
|
|
documents.category.OtherTemplate
|
|
)
|
|
}
|
|
|
|
async function migrateSpaceTypes (client: MigrationClient): Promise<void> {
|
|
await client.update(
|
|
DOMAIN_TX,
|
|
{
|
|
_class: core.class.TxCreateDoc,
|
|
objectClass: core.class.SpaceType,
|
|
'attributes.descriptor': documents.descriptor.DocumentSpaceType
|
|
},
|
|
{
|
|
$set: {
|
|
objectClass: documents.class.DocumentSpaceType
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
export const documentsOperation: MigrateOperation = {
|
|
async migrate (client: MigrationClient): Promise<void> {
|
|
await tryMigrate(client, documentsId, [
|
|
{
|
|
state: 'migrateSpaceTypes',
|
|
func: migrateSpaceTypes
|
|
}
|
|
])
|
|
},
|
|
async upgrade (state: Map<string, Set<string>>, client: () => Promise<MigrationUpgradeClient>): Promise<void> {
|
|
await tryUpgrade(state, client, documentsId, [
|
|
{
|
|
state: 'init-documents',
|
|
func: async (client) => {
|
|
const tx = new TxOperations(client, core.account.System)
|
|
await createDefaultSpace(client, documents.space.Documents, { name: 'Documents', description: 'Documents' })
|
|
await createQualityDocumentsSpace(tx)
|
|
await createTemplatesSpace(tx)
|
|
await createTemplateSequence(tx)
|
|
await createTagCategories(tx)
|
|
await createDocumentCategories(tx)
|
|
await fixChangeControlsForDocs(tx)
|
|
await createProductChangeControlTemplate(tx)
|
|
}
|
|
}
|
|
])
|
|
}
|
|
}
|