change status reserve if passed

This commit is contained in:
2026-07-09 21:07:39 +03:30
parent c485ee326c
commit 9dc1728edc
3 changed files with 60 additions and 2 deletions
@@ -0,0 +1,27 @@
import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import { ReservesService } from './reserves.service';
@Injectable()
export class ReserveAutomationService {
private readonly logger = new Logger(ReserveAutomationService.name);
constructor(private readonly reservesService: ReservesService) {}
/**
* Marks past reserves without a final status as completed once at least one
* full day has passed since the appointment date.
*/
@Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT, {
name: 'auto-complete-past-reserves',
})
async autoCompletePastReserves(): Promise<number> {
const updatedCount = await this.reservesService.autoCompletePastReserves();
this.logger.log(
`Auto-completed ${updatedCount} past reserves without a final status`,
);
return updatedCount;
}
}
+2 -1
View File
@@ -13,6 +13,7 @@ import { StylistsModule } from '../stylists/stylists.module';
import { ReserveItem } from './entities/reserve-item.entity'; import { ReserveItem } from './entities/reserve-item.entity';
import { ReserveStatusHistory } from './entities/reserve-status-history.entity'; import { ReserveStatusHistory } from './entities/reserve-status-history.entity';
import { Reserve } from './entities/reserve.entity'; import { Reserve } from './entities/reserve.entity';
import { ReserveAutomationService } from './reserve-automation.service';
import { ReservesController } from './reserves.controller'; import { ReservesController } from './reserves.controller';
import { ReservesService } from './reserves.service'; import { ReservesService } from './reserves.service';
@@ -35,7 +36,7 @@ import { ReservesService } from './reserves.service';
NotificationsModule, NotificationsModule,
], ],
controllers: [ReservesController], controllers: [ReservesController],
providers: [ReservesService], providers: [ReservesService, ReserveAutomationService],
exports: [ReservesService], exports: [ReservesService],
}) })
export class ReservesModule {} export class ReservesModule {}
+31 -1
View File
@@ -5,7 +5,7 @@ import {
NotFoundException, NotFoundException,
} from '@nestjs/common'; } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm'; import { In, LessThan, Repository } from 'typeorm';
import { AuthorizationService } from '../authorization/authorization.service'; import { AuthorizationService } from '../authorization/authorization.service';
import { ReservePolicy } from '../authorization/policies/reserve.policy'; import { ReservePolicy } from '../authorization/policies/reserve.policy';
import { AuthUser } from '../auth/interfaces/auth-user.interface'; import { AuthUser } from '../auth/interfaces/auth-user.interface';
@@ -292,6 +292,32 @@ export class ReservesService {
}); });
} }
async autoCompletePastReserves(): Promise<number> {
const today = this.getTodayDateString();
const reserves = await this.reservesRepository.find({
where: {
status: In([ReserveStatus.PENDING, ReserveStatus.CONFIRMED]),
appointmentDate: LessThan(today),
},
});
for (const reserve of reserves) {
await this.logStatusChange(
reserve.id,
reserve.status,
ReserveStatus.COMPLETED,
null,
);
reserve.status = ReserveStatus.COMPLETED;
}
if (reserves.length > 0) {
await this.reservesRepository.save(reserves);
}
return reserves.length;
}
async confirmDepositPayment( async confirmDepositPayment(
reserveId: string, reserveId: string,
changedByUserId: string | null, changedByUserId: string | null,
@@ -359,6 +385,10 @@ export class ReservesService {
return time.length === 5 ? `${time}:00` : time; return time.length === 5 ? `${time}:00` : time;
} }
private getTodayDateString(): string {
return new Date().toISOString().slice(0, 10);
}
private async validateItems(items: CreateReserveDto['items']): Promise<void> { private async validateItems(items: CreateReserveDto['items']): Promise<void> {
for (const item of items) { for (const item of items) {
const serviceExists = await this.servicesRepository.existsBy({ const serviceExists = await this.servicesRepository.existsBy({