From 29775429d560bb1f0d118e11057311dcee3fc3f5 Mon Sep 17 00:00:00 2001 From: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com> Date: Sat, 30 Jul 2022 19:57:51 +0600 Subject: [PATCH] HR minor fixes (#2245) --- .../components/schedule/MonthTableView.svelte | 182 +++++++++--------- .../src/components/schedule/MonthView.svelte | 2 +- .../src/components/schedule/YearView.svelte | 2 +- plugins/hr-resources/src/utils.ts | 30 ++- 4 files changed, 116 insertions(+), 100 deletions(-) diff --git a/plugins/hr-resources/src/components/schedule/MonthTableView.svelte b/plugins/hr-resources/src/components/schedule/MonthTableView.svelte index 6c20f6cebf..d609f2cc81 100644 --- a/plugins/hr-resources/src/components/schedule/MonthTableView.svelte +++ b/plugins/hr-resources/src/components/schedule/MonthTableView.svelte @@ -21,7 +21,7 @@ import view, { BuildModelKey, Viewlet, ViewletPreference } from '@anticrm/view' import { Table, ViewletSettingButton } from '@anticrm/view-resources' import hr from '../../plugin' - import { fromTzDate, getMonth, getTotal, tableToCSV, weekDays } from '../../utils' + import { fromTzDate, getMonth, getRequestDays, getTotal, tableToCSV, weekDays } from '../../utils' import NumberPresenter from './StatPresenter.svelte' export let currentDate: Date = new Date() @@ -35,21 +35,14 @@ $: wDays = weekDays(month.getUTCFullYear(), month.getUTCMonth()) function getDateRange (request: Request): string { - const st = new Date(fromTzDate(request.tzDate)).getDate() - const days = - Math.floor(Math.abs((1 + fromTzDate(request.tzDueDate) - fromTzDate(request.tzDate)) / 1000 / 60 / 60 / 24)) + 1 - const stDate = new Date(fromTzDate(request.tzDate)) - let ds = Array.from(Array(days).keys()).map((it) => st + it) - const type = types.get(request.type) - if ((type?.value ?? -1) < 0) { - ds = ds.filter((it) => ![0, 6].includes(new Date(stDate.setDate(it)).getDay())) - } + const ds = getRequestDays(request, types, month.getMonth()) return ds.join(' ') } function getEndDate (date: Date): number { return new Date(date).setMonth(date.getMonth() + 1) } + function getRequests (employee: Ref, date: Date): Request[] { const requests = employeeRequests.get(employee) if (requests === undefined) return [] @@ -64,80 +57,89 @@ return res } - $: typevals = new Map( - Array.from(types.values()).map((it) => [ - it.label as string, - { - key: '', - label: it.label, - presenter: NumberPresenter, - props: { - month: month ?? getMonth(currentDate, currentDate.getMonth()), - display: (req: Request[]) => - req - .filter((r) => r.type === it._id) - .map((it) => getDateRange(it)) - .join(' '), - getRequests + function getTypeVals (month: Date): Map { + return new Map( + Array.from(types.values()).map((it) => [ + it.label as string, + { + key: '', + label: it.label, + presenter: NumberPresenter, + props: { + month: month ?? getMonth(currentDate, currentDate.getMonth()), + display: (req: Request[]) => + req + .filter((r) => r.type === it._id) + .map((it) => getDateRange(it)) + .join(' '), + getRequests + } } - } - ]) - ) + ]) + ) + } - $: overrideConfig = new Map([ - [ - '@wdCount', - { - key: '', - label: getEmbeddedLabel('Working days'), - presenter: NumberPresenter, - props: { - month: month ?? getMonth(currentDate, currentDate.getMonth()), - display: (req: Request[]) => wDays + getTotal(req, types), - getRequests - }, - sortingKey: '@wdCount', - sortingFunction: (a: Doc, b: Doc) => - getTotal(getRequests(b._id as Ref, month), types) - - getTotal(getRequests(a._id as Ref, month), types) - } - ], - [ - '@ptoCount', - { - key: '', - label: getEmbeddedLabel('PTOs'), - presenter: NumberPresenter, - props: { - month: month ?? getMonth(currentDate, currentDate.getMonth()), - display: (req: Request[]) => getTotal(req, types, (a) => (a < 0 ? Math.abs(a) : 0)), - getRequests - }, - sortingKey: '@ptoCount', - sortingFunction: (a: Doc, b: Doc) => - getTotal(getRequests(b._id as Ref, month), types, (a) => (a < 0 ? Math.abs(a) : 0)) - - getTotal(getRequests(a._id as Ref, month), types, (a) => (a < 0 ? Math.abs(a) : 0)) - } - ], - [ - '@extraCount', - { - key: '', - label: getEmbeddedLabel('EXTRa'), - presenter: NumberPresenter, - props: { - month: month ?? getMonth(currentDate, currentDate.getMonth()), - display: (req: Request[]) => getTotal(req, types, (a) => (a > 0 ? Math.abs(a) : 0)), - getRequests - }, - sortingKey: '@extraCount', - sortingFunction: (a: Doc, b: Doc) => - getTotal(getRequests(b._id as Ref, month), types, (a) => (a > 0 ? Math.abs(a) : 0)) - - getTotal(getRequests(a._id as Ref, month), types, (a) => (a > 0 ? Math.abs(a) : 0)) - } - ], - ...typevals - ]) + function getOverrideConfig (month: Date): Map { + const typevals = getTypeVals(month) + return new Map([ + [ + '@wdCount', + { + key: '', + label: getEmbeddedLabel('Working days'), + presenter: NumberPresenter, + props: { + month: month ?? getMonth(currentDate, currentDate.getMonth()), + display: (req: Request[]) => wDays + getTotal(req, month.getMonth(), types), + getRequests + }, + sortingKey: '@wdCount', + sortingFunction: (a: Doc, b: Doc) => + getTotal(getRequests(b._id as Ref, month), month.getMonth(), types) - + getTotal(getRequests(a._id as Ref, month), month.getMonth(), types) + } + ], + [ + '@ptoCount', + { + key: '', + label: getEmbeddedLabel('PTOs'), + presenter: NumberPresenter, + props: { + month: month ?? getMonth(currentDate, currentDate.getMonth()), + display: (req: Request[]) => getTotal(req, month.getMonth(), types, (a) => (a < 0 ? Math.abs(a) : 0)), + getRequests + }, + sortingKey: '@ptoCount', + sortingFunction: (a: Doc, b: Doc) => + getTotal(getRequests(b._id as Ref, month), month.getMonth(), types, (a) => + a < 0 ? Math.abs(a) : 0 + ) - + getTotal(getRequests(a._id as Ref, month), month.getMonth(), types, (a) => (a < 0 ? Math.abs(a) : 0)) + } + ], + [ + '@extraCount', + { + key: '', + label: getEmbeddedLabel('EXTRa'), + presenter: NumberPresenter, + props: { + month: month ?? getMonth(currentDate, currentDate.getMonth()), + display: (req: Request[]) => getTotal(req, month.getMonth(), types, (a) => (a > 0 ? Math.abs(a) : 0)), + getRequests + }, + sortingKey: '@extraCount', + sortingFunction: (a: Doc, b: Doc) => + getTotal(getRequests(b._id as Ref, month), month.getMonth(), types, (a) => + a > 0 ? Math.abs(a) : 0 + ) - + getTotal(getRequests(a._id as Ref, month), month.getMonth(), types, (a) => (a > 0 ? Math.abs(a) : 0)) + } + ], + ...typevals + ]) + } const preferenceQuery = createQuery() let preference: ViewletPreference | undefined @@ -173,14 +175,16 @@ }) } - function createConfig (descr: Viewlet, preference: ViewletPreference | undefined): (string | BuildModelKey)[] { + function createConfig ( + descr: Viewlet, + preference: ViewletPreference | undefined, + month: Date + ): (string | BuildModelKey)[] { const base = preference?.config ?? descr.config const result: (string | BuildModelKey)[] = [] + const overrideConfig = getOverrideConfig(month) - for (const c of overrideConfig.values()) { - base.push(c) - } - for (const key of base) { + for (const key of [...base, ...overrideConfig.values()]) { if (typeof key === 'string') { result.push(overrideConfig.get(key) ?? key) } else { @@ -213,7 +217,7 @@ link.setAttribute('target', '_blank') link.setAttribute( 'href', - 'data:text/csv;charset=utf-8,' + encodeURIComponent(tableToCSV('exportableData')) + 'data:text/csv;charset=utf-8,%EF%BB%BF' + encodeURIComponent(tableToCSV('exportableData')) ) link.setAttribute('download', filename) document.body.appendChild(link) @@ -226,7 +230,7 @@ tableId={'exportableData'} _class={hr.mixin.Staff} query={{ _id: { $in: departmentStaff.map((it) => it._id) } }} - config={createConfig(descr, preference)} + config={createConfig(descr, preference, month)} options={descr.options} /> {/if} diff --git a/plugins/hr-resources/src/components/schedule/MonthView.svelte b/plugins/hr-resources/src/components/schedule/MonthView.svelte index 55c6acd26d..22809217f3 100644 --- a/plugins/hr-resources/src/components/schedule/MonthView.svelte +++ b/plugins/hr-resources/src/components/schedule/MonthView.svelte @@ -136,7 +136,7 @@ - {getTotal(requests, types)} + {getTotal(requests, startDate.getMonth(), types)} {#each values as value, i} {@const date = getDay(startDate, value)} diff --git a/plugins/hr-resources/src/components/schedule/YearView.svelte b/plugins/hr-resources/src/components/schedule/YearView.svelte index 7ea6b2214a..5845e61827 100644 --- a/plugins/hr-resources/src/components/schedule/YearView.svelte +++ b/plugins/hr-resources/src/components/schedule/YearView.svelte @@ -127,7 +127,7 @@ use:tooltip={tooltipValue} >
- {getTotal(requests, types)} + {getTotal(requests, value, types)}
{/key} diff --git a/plugins/hr-resources/src/utils.ts b/plugins/hr-resources/src/utils.ts index 2ad1bb17d7..8501ea7629 100644 --- a/plugins/hr-resources/src/utils.ts +++ b/plugins/hr-resources/src/utils.ts @@ -2,7 +2,7 @@ import { Employee, formatName } from '@anticrm/contact' import { Ref, TxOperations } from '@anticrm/core' import { Department, Request, RequestType, TzDate } from '@anticrm/hr' import { MessageBox } from '@anticrm/presentation' -import { showPopup } from '@anticrm/ui' +import { isWeekend, showPopup } from '@anticrm/ui' import hr from './plugin' export async function addMember (client: TxOperations, employee?: Employee, value?: Department): Promise { @@ -98,22 +98,34 @@ export function getMonth (date: Date, m: number): Date { return date } +export function getRequestDays (request: Request, types: Map, RequestType>, month: number): number[] { + const type = types.get(request.type) + const startDate = + request.tzDate.month === month ? fromTzDate(request.tzDate) : fromTzDate({ ...request.tzDate, month, day: 1 }) + const endDate = + request.tzDueDate.month === month + ? fromTzDate(request.tzDueDate) + : fromTzDate({ ...request.tzDueDate, month: month + 1, day: -1 }) + const days = Math.floor(Math.abs((1 + endDate - startDate) / 1000 / 60 / 60 / 24)) + 1 + const stDate = new Date(startDate) + const stDateDate = stDate.getDate() + let ds = Array.from(Array(days).keys()).map((it) => stDateDate + it) + if ((type?.value ?? -1) < 0) { + ds = ds.filter((it) => !isWeekend(new Date(stDate.setDate(it)))) + } + return ds +} + export function getTotal ( requests: Request[], + month: number, types: Map, RequestType>, f: (v: number) => number = (f) => f ): number { let total = 0 for (const request of requests) { + const ds = getRequestDays(request, types, month) const type = types.get(request.type) - const days = - Math.floor(Math.abs((1 + fromTzDate(request.tzDueDate) - fromTzDate(request.tzDate)) / 1000 / 60 / 60 / 24)) + 1 - const stDate = new Date(fromTzDate(request.tzDate)) - const stDateDate = stDate.getDate() - let ds = Array.from(Array(days).keys()).map((it) => stDateDate + it) - if ((type?.value ?? -1) < 0) { - ds = ds.filter((it) => ![0, 6].includes(new Date(stDate.setDate(it)).getDay())) - } const val = Math.ceil(ds.length) * (type?.value ?? 0) total += f(val) }