Files
TREK/server/src/nest/vacay/vacay.service.ts
T
Maurice 1a9e49b247 feat(vacay): read and write the leave year over its own window (#737)
Adds GET/PUT /addons/vacay/year-settings and makes the reads window-aware, so
the backend from the previous commit is actually reachable.

Entries and shared calendars now load over the caller's window instead of a
date prefix — a shifted year spans two calendar years and the prefix silently
dropped the second half. Reads are month-aligned (the grid draws month cards),
while entitlement stays day-exact; the two coincide for every window starting
on the 1st, which is all of calendar. deleteYear clears entries per author over
that author's period, and company holidays only over the range every member
shares, so one member deleting a period cannot reach into another's live one.
getStats reports the window it counted, and getOwnPlan seeds the period today
falls into rather than the calendar year.

A start day the month cannot have (Feb 29 from a hire date, a stored Feb 31)
is clamped to one every year has — otherwise the boundary string matches no
date and the whole window slides. Anniversary before a hire date is entered
resolves to the calendar year instead of borrowing a month a previous fiscal
setting left behind.

MCP reads pass their user through; without one the range stays the plain
calendar year, so plan-scoped callers are unchanged.
2026-07-25 11:50:22 +02:00

153 lines
5.1 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import * as svc from '../../services/vacayService';
type UpdatePlanBody = Parameters<typeof svc.updatePlan>[1];
/**
* Thin Nest wrapper around the existing vacay service. All plan logic, the
* holiday-calendar handling, invite flow and the WebSocket broadcasts (driven by
* the forwarded socket id) stay in vacayService, so behaviour is unchanged.
*/
@Injectable()
export class VacayService {
getPlanData(userId: number) {
return svc.getPlanData(userId);
}
getActivePlanId(userId: number): number {
return svc.getActivePlanId(userId);
}
getActivePlan(userId: number) {
return svc.getActivePlan(userId);
}
updatePlan(planId: number, body: UpdatePlanBody, socketId: string | undefined) {
return svc.updatePlan(planId, body, socketId);
}
addHolidayCalendar(planId: number, region: string, label: string | null, color: string | undefined, sortOrder: number | undefined, socketId: string | undefined, type?: 'public_holiday' | 'school_holiday') {
return svc.addHolidayCalendar(planId, region, label, color, sortOrder, socketId, type);
}
updateHolidayCalendar(id: number, planId: number, body: Parameters<typeof svc.updateHolidayCalendar>[2], socketId: string | undefined) {
return svc.updateHolidayCalendar(id, planId, body, socketId);
}
deleteHolidayCalendar(id: number, planId: number, socketId: string | undefined): boolean {
return svc.deleteHolidayCalendar(id, planId, socketId);
}
getPlanUsers(planId: number) {
return svc.getPlanUsers(planId);
}
setUserColor(userId: number, planId: number, color: string | undefined, socketId: string | undefined): void {
svc.setUserColor(userId, planId, color, socketId);
}
sendInvite(planId: number, inviterId: number, inviterUsername: string, inviterEmail: string, targetUserId: number) {
return svc.sendInvite(planId, inviterId, inviterUsername, inviterEmail, targetUserId);
}
acceptInvite(userId: number, planId: number, socketId: string | undefined) {
return svc.acceptInvite(userId, planId, socketId);
}
declineInvite(userId: number, planId: number, socketId: string | undefined): void {
svc.declineInvite(userId, planId, socketId);
}
cancelInvite(planId: number, targetUserId: number): void {
svc.cancelInvite(planId, targetUserId);
}
dissolvePlan(userId: number, socketId: string | undefined): void {
svc.dissolvePlan(userId, socketId);
}
getAvailableUsers(userId: number, planId: number) {
return svc.getAvailableUsers(userId, planId);
}
listYears(planId: number): number[] {
return svc.listYears(planId);
}
addYear(planId: number, year: number, socketId: string | undefined): number[] {
return svc.addYear(planId, year, socketId);
}
deleteYear(planId: number, year: number, socketId: string | undefined): number[] {
return svc.deleteYear(planId, year, socketId);
}
getEntries(planId: number, year: string, viewerId?: number) {
return svc.getEntries(planId, year, viewerId);
}
getYearSettings(userId: number) {
return svc.getYearSettings(userId);
}
updateYearSettings(userId: number, data: Parameters<typeof svc.updateUserYearSettings>[1]) {
return svc.updateUserYearSettings(userId, data);
}
toggleEntry(userId: number, planId: number, date: string, fraction: unknown, kind: unknown, socketId: string | undefined) {
return svc.toggleEntry(userId, planId, date, fraction, kind, socketId);
}
toggleCompanyHoliday(planId: number, date: string, note: string | undefined, socketId: string | undefined) {
return svc.toggleCompanyHoliday(planId, date, note, socketId);
}
getStats(planId: number, year: number) {
return svc.getStats(planId, year);
}
updateStats(userId: number, planId: number, year: number, vacationDays: number, socketId: string | undefined): void {
svc.updateStats(userId, planId, year, vacationDays, socketId);
}
getCountries() {
return svc.getCountries();
}
getSchoolHolidayRegions(country: string, language?: string) {
return svc.getSchoolHolidayRegions(country, language);
}
getHolidays(year: string, country: string) {
return svc.getHolidays(year, country);
}
listShares(userId: number) {
return svc.listShares(userId);
}
shareCalendar(ownerId: number, ownerEmail: string, targetUserId: number, socketId?: string) {
return svc.shareCalendar(ownerId, ownerEmail, targetUserId, socketId);
}
removeShare(shareId: number, userId: number, socketId: string | undefined): boolean {
return svc.removeShare(shareId, userId, socketId);
}
setShareHidden(shareId: number, userId: number, hidden: boolean, socketId: string | undefined): boolean {
return svc.setShareHidden(shareId, userId, hidden, socketId);
}
getShareAvailableUsers(userId: number) {
return svc.getShareAvailableUsers(userId);
}
getSharedCalendars(viewerId: number, year: string) {
return svc.getSharedCalendars(viewerId, year);
}
getSchoolHolidays(year: string, country: string, subdivision?: string | null, language?: string, group?: string | null) {
return svc.getSchoolHolidays(year, country, subdivision, language, group);
}
}