diff --git a/apps/server/src/rooms/room-inspections.service.ts b/apps/server/src/rooms/room-inspections.service.ts index 5226b55..5283499 100644 --- a/apps/server/src/rooms/room-inspections.service.ts +++ b/apps/server/src/rooms/room-inspections.service.ts @@ -1,13 +1,14 @@ import { BadRequestException, Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common'; import { Cron } from '@nestjs/schedule'; import { InjectRepository } from '@nestjs/typeorm'; -import { DataSource, EntityManager, IsNull, LessThanOrEqual, MoreThanOrEqual, Repository } from 'typeorm'; +import { DataSource, EntityManager, Repository } from 'typeorm'; import { Bed } from '../entities/bed.entity'; import { Occupancy } from '../entities/occupancy.entity'; import { Room } from '../entities/room.entity'; import { RoomInspection } from '../entities/room-inspection.entity'; import { RoomInspectionDetail } from '../entities/room-inspection-detail.entity'; import { OperationLogsService } from '../operation-logs/operation-logs.service'; +import { occupancyWhereOnDate } from './room-occupancy-date'; interface InspectorIdentity { id?: number; @@ -211,10 +212,7 @@ export class RoomInspectionsService implements OnApplicationBootstrap { private findOccupanciesForDate(manager: EntityManager, roomId: number, date: string) { return manager.getRepository(Occupancy).find({ - where: [ - { roomId, checkInDate: LessThanOrEqual(date), checkOutDate: IsNull() }, - { roomId, checkInDate: LessThanOrEqual(date), checkOutDate: MoreThanOrEqual(date) }, - ], + where: occupancyWhereOnDate(date, roomId), relations: ['student', 'bed'], order: { id: 'ASC' }, }); @@ -222,10 +220,7 @@ export class RoomInspectionsService implements OnApplicationBootstrap { private findAllOccupanciesForDate(manager: EntityManager, date: string) { return manager.getRepository(Occupancy).find({ - where: [ - { checkInDate: LessThanOrEqual(date), checkOutDate: IsNull() }, - { checkInDate: LessThanOrEqual(date), checkOutDate: MoreThanOrEqual(date) }, - ], + where: occupancyWhereOnDate(date), relations: ['student', 'bed'], order: { roomId: 'ASC', id: 'ASC' }, }); diff --git a/apps/server/src/rooms/room-occupancy-date.spec.ts b/apps/server/src/rooms/room-occupancy-date.spec.ts new file mode 100644 index 0000000..cf6fb25 --- /dev/null +++ b/apps/server/src/rooms/room-occupancy-date.spec.ts @@ -0,0 +1,22 @@ +import { occupancyWhereOnDate } from './room-occupancy-date'; + +describe('occupancyWhereOnDate', () => { + it('treats checkout date as the first day no longer occupying the old room', () => { + const where = occupancyWhereOnDate('2026-07-22', 10); + + expect(where).toHaveLength(2); + expect(where[0]).toEqual( + expect.objectContaining({ roomId: 10, checkInDate: expect.anything(), checkOutDate: expect.anything() }), + ); + expect(where[1]).toEqual( + expect.objectContaining({ roomId: 10, checkInDate: expect.anything(), checkOutDate: expect.anything() }), + ); + expect(String((where[1] as any).checkOutDate._type)).toBe('moreThan'); + expect((where[1] as any).checkOutDate._value).toBe('2026-07-22'); + }); + + it('can query all rooms for automatic settlement', () => { + const where = occupancyWhereOnDate('2026-07-22'); + expect(where.every((condition) => condition.roomId === undefined)).toBe(true); + }); +}); diff --git a/apps/server/src/rooms/room-occupancy-date.ts b/apps/server/src/rooms/room-occupancy-date.ts new file mode 100644 index 0000000..2949720 --- /dev/null +++ b/apps/server/src/rooms/room-occupancy-date.ts @@ -0,0 +1,13 @@ +import { FindOptionsWhere, IsNull, LessThanOrEqual, MoreThan } from 'typeorm'; +import { Occupancy } from '../entities/occupancy.entity'; + +export function occupancyWhereOnDate( + date: string, + roomId?: number, +): FindOptionsWhere[] { + const scope = roomId === undefined ? {} : { roomId }; + return [ + { ...scope, checkInDate: LessThanOrEqual(date), checkOutDate: IsNull() }, + { ...scope, checkInDate: LessThanOrEqual(date), checkOutDate: MoreThan(date) }, + ]; +} diff --git a/apps/server/src/rooms/rooms.service.ts b/apps/server/src/rooms/rooms.service.ts index 299bb69..cfcb104 100644 --- a/apps/server/src/rooms/rooms.service.ts +++ b/apps/server/src/rooms/rooms.service.ts @@ -8,7 +8,6 @@ import { Not, In, LessThanOrEqual, - MoreThanOrEqual, } from 'typeorm'; import { Room } from '../entities/room.entity'; @@ -20,6 +19,7 @@ import { CreateRoomDto, UpdateRoomDto } from './dto/room.dto'; import { CreateBedDto, UpdateBedDto, BatchCreateBedDto } from './dto/bed.dto'; import { CreateLockerDto, UpdateLockerDto, BatchCreateLockerDto } from './dto/locker.dto'; import { RoomInspectionsService } from './room-inspections.service'; +import { occupancyWhereOnDate } from './room-occupancy-date'; @Injectable() export class RoomsService { @@ -246,10 +246,7 @@ export class RoomsService { }); const occupancies = await this.occRepo.find({ - where: [ - { checkInDate: LessThanOrEqual(targetDate), checkOutDate: IsNull() }, - { checkInDate: LessThanOrEqual(targetDate), checkOutDate: MoreThanOrEqual(targetDate) }, - ], + where: occupancyWhereOnDate(targetDate), relations: ['student', 'student.organization', 'responsibleOrganization', 'bed'], order: { checkInDate: 'ASC' }, });