mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
TSK-1236: trigger to remove members when deleting department. Fix for already broken departments (#3120)
Signed-off-by: Vyacheslav Tumanov <me@slavatumanov.me>
This commit is contained in:
parent
239d4da6ce
commit
8d20a510d4
@ -13,8 +13,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Employee } from '@hcengineering/contact'
|
||||
import { DOMAIN_TX, TxCollectionCUD, TxCreateDoc, TxOperations, TxUpdateDoc } from '@hcengineering/core'
|
||||
import contact, { Employee } from '@hcengineering/contact'
|
||||
import { DOMAIN_TX, Ref, toIdMap, TxCollectionCUD, TxCreateDoc, TxOperations, TxUpdateDoc } from '@hcengineering/core'
|
||||
import { Department, Request, TzDate } from '@hcengineering/hr'
|
||||
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@hcengineering/model'
|
||||
import core, { DOMAIN_SPACE } from '@hcengineering/model-core'
|
||||
@ -42,6 +42,57 @@ async function createSpace (tx: TxOperations): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
async function fixDuplicatesInDepartments (tx: TxOperations): Promise<void> {
|
||||
const departments = await tx.findAll(hr.class.Department, {})
|
||||
const departmentUpdate = departments.map((department) => {
|
||||
const uniqueMembers = [...new Set(department.members)]
|
||||
return tx.update(department, { members: uniqueMembers })
|
||||
})
|
||||
await Promise.all(departmentUpdate)
|
||||
}
|
||||
|
||||
async function fixDepartmentsFromStaff (tx: TxOperations): Promise<void> {
|
||||
const departments = await tx.findAll(hr.class.Department, {})
|
||||
const parentsWithDepartmentMap: Map<Ref<Department>, Department[]> = new Map()
|
||||
const departmentsMap = toIdMap(departments)
|
||||
const ancestors: Map<Ref<Department>, Ref<Department>> = new Map()
|
||||
for (const department of departments) {
|
||||
if (department._id === hr.ids.Head) continue
|
||||
ancestors.set(department._id, department.space)
|
||||
}
|
||||
for (const departmentTest of departments) {
|
||||
const parents: Department[] = parentsWithDepartmentMap.get(departmentTest._id) ?? []
|
||||
let _id = departmentTest._id
|
||||
while (true) {
|
||||
const department = departmentsMap.get(_id)
|
||||
if (department === undefined) break
|
||||
if (!parents.includes(department)) parents.push(department)
|
||||
const next = ancestors.get(department._id)
|
||||
if (next === undefined) break
|
||||
_id = next
|
||||
}
|
||||
parentsWithDepartmentMap.set(departmentTest._id, parents)
|
||||
}
|
||||
const staff = await tx.findAll(hr.mixin.Staff, {})
|
||||
const promises = []
|
||||
const employeeAccountByEmployeeMap = new Map(
|
||||
(await tx.findAll(contact.class.EmployeeAccount, {})).map((ea) => [ea.employee, ea])
|
||||
)
|
||||
for (const st of staff) {
|
||||
if (st.department == null) continue
|
||||
const correctDepartments: Department[] = parentsWithDepartmentMap.get(st.department) ?? []
|
||||
promises.push(
|
||||
...departments
|
||||
.filter((department) => !correctDepartments.includes(department))
|
||||
.map((dep) => {
|
||||
const employeeAccount = employeeAccountByEmployeeMap.get(st._id)
|
||||
if (employeeAccount == null) return []
|
||||
return tx.update(dep, { $pull: { members: employeeAccount._id } })
|
||||
})
|
||||
)
|
||||
}
|
||||
await Promise.all(promises)
|
||||
}
|
||||
function toTzDate (date: number): TzDate {
|
||||
const res = new Date(date)
|
||||
return {
|
||||
@ -181,5 +232,7 @@ export const hrOperation: MigrateOperation = {
|
||||
async upgrade (client: MigrationUpgradeClient): Promise<void> {
|
||||
const tx = new TxOperations(client, core.account.System)
|
||||
await createSpace(tx)
|
||||
await fixDuplicatesInDepartments(tx)
|
||||
await fixDepartmentsFromStaff(tx)
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,15 @@ export function createModel (builder: Builder): void {
|
||||
}
|
||||
})
|
||||
|
||||
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||
trigger: serverHr.trigger.OnDepartmentRemove,
|
||||
txMatch: {
|
||||
_class: core.class.TxCollectionCUD,
|
||||
'tx.objectClass': hr.class.Department,
|
||||
'tx._class': core.class.TxRemoveDoc
|
||||
}
|
||||
})
|
||||
|
||||
builder.createDoc(serverCore.class.Trigger, core.space.Model, {
|
||||
trigger: serverHr.trigger.OnRequestCreate,
|
||||
txMatch: {
|
||||
|
@ -24,6 +24,7 @@ import core, {
|
||||
TxFactory,
|
||||
TxMixin,
|
||||
TxProcessor,
|
||||
TxRemoveDoc,
|
||||
TxUpdateDoc
|
||||
} from '@hcengineering/core'
|
||||
import hr, {
|
||||
@ -155,6 +156,40 @@ export async function OnDepartmentStaff (tx: Tx, control: TriggerControl): Promi
|
||||
return []
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export async function OnDepartmentRemove (tx: Tx, control: TriggerControl): Promise<Tx[]> {
|
||||
const ctx = TxProcessor.extractTx(tx) as TxRemoveDoc<Department>
|
||||
|
||||
const department = (await control.findAll(hr.class.Department, { _id: ctx.objectSpace as Ref<Department> }))[0]
|
||||
|
||||
const targetAccounts = await control.modelDb.findAll(contact.class.EmployeeAccount, {
|
||||
_id: { $in: department.members }
|
||||
})
|
||||
const employeeIds = targetAccounts.map((acc) => acc.employee as Ref<Staff>)
|
||||
|
||||
const employee = await control.findAll(contact.class.Employee, {
|
||||
_id: { $in: employeeIds }
|
||||
})
|
||||
const removed = await buildHierarchy(department._id, control)
|
||||
const res: Tx[] = []
|
||||
employee.forEach((em) => {
|
||||
res.push(control.txFactory.createTxMixin(em._id, em._class, em.space, hr.mixin.Staff, { department: undefined }))
|
||||
})
|
||||
targetAccounts.forEach((acc) => {
|
||||
res.push(
|
||||
...getTxes(
|
||||
control.txFactory,
|
||||
acc._id,
|
||||
[],
|
||||
removed.map((p) => p._id)
|
||||
)
|
||||
)
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@ -399,6 +434,7 @@ export default async () => ({
|
||||
OnRequestUpdate,
|
||||
OnRequestRemove,
|
||||
OnDepartmentStaff,
|
||||
OnDepartmentRemove,
|
||||
OnEmployeeDeactivate,
|
||||
OnPublicHolidayCreate
|
||||
},
|
||||
|
@ -29,6 +29,7 @@ export const serverHrId = 'server-hr' as Plugin
|
||||
export default plugin(serverHrId, {
|
||||
trigger: {
|
||||
OnDepartmentStaff: '' as Resource<TriggerFunc>,
|
||||
OnDepartmentRemove: '' as Resource<TriggerFunc>,
|
||||
OnRequestCreate: '' as Resource<TriggerFunc>,
|
||||
OnRequestUpdate: '' as Resource<TriggerFunc>,
|
||||
OnRequestRemove: '' as Resource<TriggerFunc>,
|
||||
|
Loading…
Reference in New Issue
Block a user