diff --git a/models/hr/src/index.ts b/models/hr/src/index.ts index 2e0ad18824..43ca82faf0 100644 --- a/models/hr/src/index.ts +++ b/models/hr/src/index.ts @@ -83,6 +83,9 @@ export class TDepartment extends TSpace implements Department { @Prop(ArrOf(TypeRef(contact.class.Contact)), hr.string.Subscribers) subscribers?: Arr> + + @Prop(ArrOf(TypeRef(contact.class.Employee)), hr.string.Managers) + managers!: Arr> } @Model(hr.class.DepartmentMember, contact.class.EmployeeAccount) diff --git a/models/hr/src/migration.ts b/models/hr/src/migration.ts index 4cb07e07a2..e0345d2957 100644 --- a/models/hr/src/migration.ts +++ b/models/hr/src/migration.ts @@ -15,9 +15,9 @@ import { Employee } from '@hcengineering/contact' import { DOMAIN_TX, TxCollectionCUD, TxCreateDoc, TxOperations, TxUpdateDoc } from '@hcengineering/core' -import { Request, TzDate } from '@hcengineering/hr' +import { Department, Request, TzDate } from '@hcengineering/hr' import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@hcengineering/model' -import core from '@hcengineering/model-core' +import core, { DOMAIN_SPACE } from '@hcengineering/model-core' import hr, { DOMAIN_HR } from './index' async function createSpace (tx: TxOperations): Promise { @@ -34,7 +34,8 @@ async function createSpace (tx: TxOperations): Promise { private: false, archived: false, members: [], - teamLead: null + teamLead: null, + managers: [] }, hr.ids.Head ) @@ -147,9 +148,35 @@ async function migrateTime (client: MigrationClient): Promise { } } +async function fillManagers (client: MigrationClient): Promise { + await client.update( + DOMAIN_SPACE, + { + _class: hr.class.Department, + managers: { $exists: false } + }, + { + managers: [] + } + ) + + await client.update>( + DOMAIN_TX, + { + _class: core.class.TxCreateDoc, + objectClass: hr.class.Department, + 'attributes.managers': { $exists: false } + }, + { + 'attributes.managers': [] + } + ) +} + export const hrOperation: MigrateOperation = { async migrate (client: MigrationClient): Promise { await migrateTime(client) + await fillManagers(client) }, async upgrade (client: MigrationUpgradeClient): Promise { const tx = new TxOperations(client, core.account.System) diff --git a/plugins/hr-assets/lang/en.json b/plugins/hr-assets/lang/en.json index 9df3eb9670..36801afbe1 100644 --- a/plugins/hr-assets/lang/en.json +++ b/plugins/hr-assets/lang/en.json @@ -46,6 +46,7 @@ "Title": "Title", "Description": "Description", "MarkAsPublicHoliday": "Mark as public holiday", - "EditPublicHoliday": "Edit public holiday" + "EditPublicHoliday": "Edit public holiday", + "Managers": "Managers" } } diff --git a/plugins/hr-assets/lang/ru.json b/plugins/hr-assets/lang/ru.json index 5bc1e442fc..8e20704141 100644 --- a/plugins/hr-assets/lang/ru.json +++ b/plugins/hr-assets/lang/ru.json @@ -46,6 +46,7 @@ "Description": "Описание", "PublicHoliday": "Праздничный день", "MarkAsPublicHoliday": "Отметить как праздничный день", - "EditPublicHoliday": "Редактировать праздничный день" + "EditPublicHoliday": "Редактировать праздничный день", + "Managers": "Менеджера" } } diff --git a/plugins/hr-resources/src/components/CreateDepartment.svelte b/plugins/hr-resources/src/components/CreateDepartment.svelte index a0059b1e0b..019d034c7d 100644 --- a/plugins/hr-resources/src/components/CreateDepartment.svelte +++ b/plugins/hr-resources/src/components/CreateDepartment.svelte @@ -40,7 +40,8 @@ private: false, archived: false, members: [], - teamLead: lead + teamLead: lead, + managers: [] }) dispatch('close', id) diff --git a/plugins/hr-resources/src/components/ScheduleView.svelte b/plugins/hr-resources/src/components/ScheduleView.svelte index 288f3e9a5d..85372dc07e 100644 --- a/plugins/hr-resources/src/components/ScheduleView.svelte +++ b/plugins/hr-resources/src/components/ScheduleView.svelte @@ -121,33 +121,70 @@ $: updateRequest(reqests, startDate, endDate) - function updateEditableList () { - editableList = [] - departmentById.forEach((department) => { - if (department.teamLead === currentEmployee) { - const departmentIds = [department._id] - departmentIds.concat(getDescendants(department._id, descendants)).forEach((id) => { - editableList.push( - ...Array.from( - departmentStaff.filter((p) => p.department === id), - (s) => s._id - ) - ) - }) - } - }) - if (departmentStaff.filter((p) => p._id === currentEmployee).length > 0) { - editableList.push(currentEmployee) + function pushChilds ( + department: Ref, + departmentStaff: Staff[], + descendants: Map, Department[]> + ): void { + const staff = departmentStaff.filter((p) => p.department === department) + editableList.push(...staff.map((p) => p._id)) + const desc = descendants.get(department) ?? [] + for (const des of desc) { + pushChilds(des._id, departmentStaff, descendants) } - editableList = [...new Set(editableList)] } - function updateStaff (staff: Staff[], departments: Ref[], employeeRequests: Map, Request[]>) { + function isEditable (department: Department): boolean { + return department.teamLead === currentEmployee || department.managers.includes(currentEmployee) + } + + function checkDepartmentEditable ( + departmentById: Map, Department>, + department: Ref, + departmentStaff: Staff[], + descendants: Map, Department[]> + ) { + const dep = departmentById.get(department) + if (dep !== undefined && isEditable(dep)) { + pushChilds(dep._id, departmentStaff, descendants) + } else { + const descendantDepartments = descendants.get(department) + if (descendantDepartments !== undefined) { + for (const department of descendantDepartments) { + if (isEditable(department)) { + pushChilds(department._id, departmentStaff, descendants) + } else { + checkDepartmentEditable(departmentById, department._id, departmentStaff, descendants) + } + } + } + } + } + + function updateEditableList ( + departmentById: Map, Department>, + department: Ref, + departmentStaff: Staff[], + descendants: Map, Department[]> + ) { + editableList = [currentEmployee] + checkDepartmentEditable(departmentById, department, departmentStaff, descendants) + editableList = editableList + } + + function updateStaff ( + staff: Staff[], + departments: Ref[], + employeeRequests: Map, Request[]>, + department: Ref, + descendants: Map, Department[]>, + departmentById: Map, Department> + ) { departmentStaff = staff.filter((p) => departments.includes(p.department) || employeeRequests.has(p._id)) - updateEditableList() + updateEditableList(departmentById, department, departmentStaff, descendants) } - $: updateStaff(staff, departments, employeeRequests) + $: updateStaff(staff, departments, employeeRequests, department, descendants, departmentById) const reportQuery = createQuery() diff --git a/plugins/hr-resources/src/plugin.ts b/plugins/hr-resources/src/plugin.ts index 6f27d53928..7708340bad 100644 --- a/plugins/hr-resources/src/plugin.ts +++ b/plugins/hr-resources/src/plugin.ts @@ -50,6 +50,7 @@ export default mergeIds(hrId, hr, { Title: '' as IntlString, Description: '' as IntlString, MarkAsPublicHoliday: '' as IntlString, - EditPublicHoliday: '' as IntlString + EditPublicHoliday: '' as IntlString, + Managers: '' as IntlString } }) diff --git a/plugins/hr/src/index.ts b/plugins/hr/src/index.ts index f470a43997..af93eac118 100644 --- a/plugins/hr/src/index.ts +++ b/plugins/hr/src/index.ts @@ -32,6 +32,7 @@ export interface Department extends Space { channels?: number members: Arr> subscribers?: Arr> + managers: Arr> } /**