feat(POS-003): completed feature
This commit is contained in:
22
project/src/modules/pos/application/close-cash-session.ts
Normal file
22
project/src/modules/pos/application/close-cash-session.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import type { PosCashSessionRepository } from '../domain/ports.js';
|
||||
import type { PosCashSession } from '../domain/cash-session.js';
|
||||
import { CashSessionNotOpenError } from '../domain/errors.js';
|
||||
|
||||
export interface CloseCashSessionInput {
|
||||
sessionId: string;
|
||||
closingCashCents: number;
|
||||
actualCashCents: number;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export class CloseCashSessionUseCase {
|
||||
constructor(private readonly sessionRepo: PosCashSessionRepository) {}
|
||||
|
||||
async execute(input: CloseCashSessionInput): Promise<PosCashSession> {
|
||||
const existing = await this.sessionRepo.findById(input.sessionId);
|
||||
if (!existing) throw new CashSessionNotOpenError(input.sessionId);
|
||||
if (existing.status === 'CLOSED') throw new CashSessionNotOpenError(input.sessionId);
|
||||
|
||||
return this.sessionRepo.close(input);
|
||||
}
|
||||
}
|
||||
36
project/src/modules/pos/application/get-pos-config.ts
Normal file
36
project/src/modules/pos/application/get-pos-config.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { PosStoreRepository } from '../domain/ports.js';
|
||||
import type { PosTerminalRepository } from '../domain/ports.js';
|
||||
import type { PosPaymentMethodRepository } from '../infrastructure/pg-payment-method-repository.js';
|
||||
import type { PosCashSessionRepository } from '../domain/ports.js';
|
||||
import type { PosStore } from '../domain/store.js';
|
||||
import type { PosTerminal } from '../domain/terminal.js';
|
||||
import type { PosPaymentMethod } from '../infrastructure/pg-payment-method-repository.js';
|
||||
|
||||
export interface PosConfig {
|
||||
store: PosStore;
|
||||
terminal: PosTerminal;
|
||||
paymentMethods: PosPaymentMethod[];
|
||||
sessionOpen: boolean;
|
||||
}
|
||||
|
||||
export class GetPosConfigUseCase {
|
||||
constructor(
|
||||
private readonly storeRepo: PosStoreRepository,
|
||||
private readonly terminalRepo: PosTerminalRepository,
|
||||
private readonly paymentMethodRepo: PosPaymentMethodRepository,
|
||||
private readonly sessionRepo: PosCashSessionRepository,
|
||||
) {}
|
||||
|
||||
async execute(terminalId: string): Promise<PosConfig> {
|
||||
const terminal = await this.terminalRepo.findById(terminalId);
|
||||
if (!terminal) throw new Error(`Terminal ${terminalId} not found`);
|
||||
const store = await this.storeRepo.findById(terminal.storeId);
|
||||
if (!store) throw new Error(`Store ${terminal.storeId} not found`);
|
||||
const [paymentMethods, openSession] = await Promise.all([
|
||||
this.paymentMethodRepo.listByStore(terminal.storeId),
|
||||
this.sessionRepo.findOpenByTerminal(terminalId),
|
||||
]);
|
||||
await this.terminalRepo.updateLastSeen(terminalId);
|
||||
return { store, terminal, paymentMethods, sessionOpen: !!openSession };
|
||||
}
|
||||
}
|
||||
10
project/src/modules/pos/application/list-stores.ts
Normal file
10
project/src/modules/pos/application/list-stores.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { PosStoreRepository } from '../domain/ports.js';
|
||||
import type { PosStore, ListStoresOptions } from '../domain/store.js';
|
||||
|
||||
export class ListStoresUseCase {
|
||||
constructor(private readonly storeRepo: PosStoreRepository) {}
|
||||
|
||||
async execute(options?: ListStoresOptions): Promise<{ stores: PosStore[]; total: number }> {
|
||||
return this.storeRepo.list(options);
|
||||
}
|
||||
}
|
||||
10
project/src/modules/pos/application/list-terminals.ts
Normal file
10
project/src/modules/pos/application/list-terminals.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { PosTerminalRepository } from '../domain/ports.js';
|
||||
import type { PosTerminal, ListTerminalsOptions } from '../domain/terminal.js';
|
||||
|
||||
export class ListTerminalsUseCase {
|
||||
constructor(private readonly terminalRepo: PosTerminalRepository) {}
|
||||
|
||||
async execute(options?: ListTerminalsOptions): Promise<{ terminals: PosTerminal[]; total: number }> {
|
||||
return this.terminalRepo.list(options);
|
||||
}
|
||||
}
|
||||
28
project/src/modules/pos/application/open-cash-session.ts
Normal file
28
project/src/modules/pos/application/open-cash-session.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { PosCashSessionRepository, PosTerminalRepository } from '../domain/ports.js';
|
||||
import type { PosCashSession } from '../domain/cash-session.js';
|
||||
import { CashSessionAlreadyOpenError, TerminalNotBoundError, TerminalDisabledError } from '../domain/errors.js';
|
||||
|
||||
export interface OpenCashSessionInput {
|
||||
terminalId: string;
|
||||
userId: string;
|
||||
openingCashCents: number;
|
||||
}
|
||||
|
||||
export class OpenCashSessionUseCase {
|
||||
constructor(
|
||||
private readonly sessionRepo: PosCashSessionRepository,
|
||||
private readonly terminalRepo: PosTerminalRepository,
|
||||
) {}
|
||||
|
||||
async execute(input: OpenCashSessionInput): Promise<PosCashSession> {
|
||||
const terminal = await this.terminalRepo.findById(input.terminalId);
|
||||
if (!terminal) throw new Error(`Terminal ${input.terminalId} not found`);
|
||||
if (terminal.status === 'disabled') throw new TerminalDisabledError(input.terminalId);
|
||||
if (!terminal.bindingCode) throw new TerminalNotBoundError(input.terminalId);
|
||||
|
||||
const existing = await this.sessionRepo.findOpenByTerminal(input.terminalId);
|
||||
if (existing) throw new CashSessionAlreadyOpenError(input.terminalId);
|
||||
|
||||
return this.sessionRepo.open(input);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user