This commit is contained in:
Emmanuel Rojas committed 2026-09-30 14:45:10 -05:00
1 parent 90125aede9
commit 2d6c29a1f3
404 files changed
+126983 -85

No files matched your search

@@ -0,0 +1,12 @@
import type { IRepository } from "../../../common/repository.interface.js";
import type { OperatingDay, OperatingDayKey } from "../../../entities/operating-day.entity.js";
import type { CreateOperatingDayInput, UpdateOperatingDayInput } from "../../../dtos/operating-day.dto.js";
export const OPERATING_DAY_REPOSITORY = Symbol("OPERATING_DAY_REPOSITORY");
export type IOperatingDayRepository = IRepository<
OperatingDay,
CreateOperatingDayInput,
UpdateOperatingDayInput,
OperatingDayKey
>;
@@ -0,0 +1,12 @@
import type { IService } from "../../../common/service.interface.js";
import type { OperatingDay, OperatingDayKey } from "../../../entities/operating-day.entity.js";
import type { CreateOperatingDayInput, UpdateOperatingDayInput } from "../../../dtos/operating-day.dto.js";
export const OPERATING_DAY_SERVICE = Symbol("OPERATING_DAY_SERVICE");
export type IOperatingDayService = IService<
OperatingDay,
CreateOperatingDayInput,
UpdateOperatingDayInput,
OperatingDayKey
>;
@@ -0,0 +1,37 @@
import { Body, Controller, Delete, Get, Inject, Param, ParseIntPipe, Patch, Post } from "@nestjs/common";
import type { CreateOperatingDayInput, UpdateOperatingDayInput } from "../../dtos/operating-day.dto.js";
import { OPERATING_DAY_SERVICE } from "./interfaces/operating-day-service.interface.js";
import type { IOperatingDayService } from "./interfaces/operating-day-service.interface.js";
@Controller("operating-days")
export class OperatingDayController {
constructor(
@Inject(OPERATING_DAY_SERVICE)
private readonly operatingDayService: IOperatingDayService,
) {}
@Get()
findAll() {
return this.operatingDayService.findAll();
}
@Get(":id")
findOne(@Param("id", ParseIntPipe) id: number) {
return this.operatingDayService.findById({ id });
}
@Post()
create(@Body() body: CreateOperatingDayInput) {
return this.operatingDayService.create(body);
}
@Patch(":id")
update(@Param("id", ParseIntPipe) id: number, @Body() body: UpdateOperatingDayInput) {
return this.operatingDayService.update({ id }, body);
}
@Delete(":id")
remove(@Param("id", ParseIntPipe) id: number) {
return this.operatingDayService.delete({ id });
}
}
@@ -0,0 +1,18 @@
import { Module } from "@nestjs/common";
import { CashRegisterSessionModule } from "../cash-register-session/cash-register-session.module.js";
import { OPERATING_DAY_REPOSITORY } from "./interfaces/operating-day-repository.interface.js";
import { OPERATING_DAY_SERVICE } from "./interfaces/operating-day-service.interface.js";
import { OperatingDayController } from "./operating-day.controller.js";
import { OperatingDayRepository } from "./operating-day.repository.js";
import { OperatingDayService } from "./operating-day.service.js";
@Module({
imports: [CashRegisterSessionModule],
controllers: [OperatingDayController],
providers: [
{ provide: OPERATING_DAY_REPOSITORY, useClass: OperatingDayRepository },
{ provide: OPERATING_DAY_SERVICE, useClass: OperatingDayService },
],
exports: [OPERATING_DAY_SERVICE],
})
export class OperatingDayModule {}
@@ -0,0 +1,17 @@
import { Injectable } from "@nestjs/common";
import { BaseRepository } from "../../common/base.repository.js";
import type { CreateOperatingDayInput, UpdateOperatingDayInput } from "../../dtos/operating-day.dto.js";
import type { OperatingDay, OperatingDayKey } from "../../entities/operating-day.entity.js";
import type { IOperatingDayRepository } from "./interfaces/operating-day-repository.interface.js";
@Injectable()
export class OperatingDayRepository
extends BaseRepository<OperatingDay, CreateOperatingDayInput, UpdateOperatingDayInput, OperatingDayKey>
implements IOperatingDayRepository
{
protected readonly columns = ["id", "date", "status", "openedById", "closedById", "openedAt", "closedAt"] as const;
protected get model() {
return this.db.orm.public.OperatingDay;
}
}
@@ -0,0 +1,65 @@
import { BadRequestException, Inject, Injectable } from "@nestjs/common";
import { BaseService } from "../../common/base.service.js";
import type { CreateOperatingDayInput, UpdateOperatingDayInput } from "../../dtos/operating-day.dto.js";
import type { OperatingDay, OperatingDayKey } from "../../entities/operating-day.entity.js";
import {
CASH_REGISTER_SESSION_SERVICE,
type ICashRegisterSessionService,
} from "../cash-register-session/interfaces/cash-register-session-service.interface.js";
import { OPERATING_DAY_REPOSITORY, type IOperatingDayRepository } from "./interfaces/operating-day-repository.interface.js";
import type { IOperatingDayService } from "./interfaces/operating-day-service.interface.js";
@Injectable()
export class OperatingDayService
extends BaseService<OperatingDay, CreateOperatingDayInput, UpdateOperatingDayInput, OperatingDayKey>
implements IOperatingDayService
{
constructor(
@Inject(OPERATING_DAY_REPOSITORY)
private readonly operatingDayRepository: IOperatingDayRepository,
@Inject(CASH_REGISTER_SESSION_SERVICE)
private readonly sessionService: ICashRegisterSessionService,
) {
super(operatingDayRepository);
}
override async create(data: CreateOperatingDayInput): Promise<OperatingDay> {
const all = await this.operatingDayRepository.findAll();
const alreadyOpen = all.some((d) => d.status === "open");
if (alreadyOpen) {
throw new BadRequestException("Ya hay una fecha de operación abierta");
}
return this.operatingDayRepository.create(data);
}
override async update(where: OperatingDayKey, data: UpdateOperatingDayInput): Promise<OperatingDay> {
const current = await this.findById(where);
if (data.status === "closed") {
if (current.status === "closed") {
throw new BadRequestException("Esta fecha de operación ya está cerrada");
}
const sessions = await this.sessionService.findAll();
const hasOpenSession = sessions.some((s) => s.status === "open");
if (hasOpenSession) {
throw new BadRequestException("No se puede cerrar el día de operación con cajas abiertas");
}
if (!data.closedById) {
throw new BadRequestException("Falta indicar quién cierra la fecha de operación");
}
const closed = await this.operatingDayRepository.update(where, {
...data,
closedAt: data.closedAt ?? new Date().toISOString(),
});
await this.operatingDayRepository.create({ openedById: data.closedById });
return closed;
}
return this.operatingDayRepository.update(where, data);
}
protected override notFoundMessage(where: OperatingDayKey): string {
return `OperatingDay ${where.id} not found`;
}
}