feat(F-191): completed feature
This commit is contained in:
@@ -559,6 +559,46 @@ export async function registerPosRoutes(app: FastifyInstance, deps: PosRouteDeps
|
||||
},
|
||||
);
|
||||
|
||||
// F-191: get session by ID (includes closed sessions) with summary metrics
|
||||
app.get<{ Params: { id: string } }>(
|
||||
'/pos/sessions/:id',
|
||||
{
|
||||
schema: {
|
||||
tags: ['POS Terminal'],
|
||||
summary: 'Get session details and summary',
|
||||
params: { type: 'object', properties: { id: { type: 'string', format: 'uuid' } } },
|
||||
response: { 401: errorSchema, 404: errorSchema },
|
||||
} as FastifySchema,
|
||||
},
|
||||
async (request, reply) => {
|
||||
const user = await authenticate(request);
|
||||
requireAnyRole(user, ['admin', 'pos_manager', 'pos_cashier'] as ReadonlyArray<Role>);
|
||||
const { id } = parseJson(idParamSchema, request.params);
|
||||
const session = await sessionRepo.findById(id);
|
||||
if (!session) throw new AppError(404, 'SESSION_NOT_FOUND', 'Sesión no encontrada');
|
||||
|
||||
// Summary: sales count, revenue, pending count for this session
|
||||
const [salesResult, pendingResult] = await Promise.all([
|
||||
pool.query<{ cnt: string; total: string }>(
|
||||
`SELECT COUNT(*)::int AS cnt, COALESCE(SUM(total_cents), 0)::bigint AS total
|
||||
FROM orders_orders WHERE cash_session_id = $1 AND source = 'pos'`,
|
||||
[id],
|
||||
),
|
||||
pool.query<{ cnt: string }>(
|
||||
`SELECT COUNT(*)::int AS cnt FROM orders_orders
|
||||
WHERE cash_session_id = $1 AND source = 'pos' AND state = 'PENDING'`,
|
||||
[id],
|
||||
),
|
||||
]);
|
||||
return reply.send({
|
||||
...session,
|
||||
salesCount: parseInt(salesResult.rows[0]?.cnt ?? '0', 10),
|
||||
salesTotalCents: parseInt(salesResult.rows[0]?.total ?? '0', 10),
|
||||
pendingCount: parseInt(pendingResult.rows[0]?.cnt ?? '0', 10),
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
app.get(
|
||||
'/pos/catalog/touch',
|
||||
{
|
||||
@@ -1511,18 +1551,22 @@ export async function registerPosRoutes(app: FastifyInstance, deps: PosRouteDeps
|
||||
},
|
||||
);
|
||||
|
||||
// F-191: enhanced admin sessions listing with terminalId and date range filters
|
||||
app.get(
|
||||
'/pos/sessions',
|
||||
{
|
||||
schema: {
|
||||
tags: ['POS Admin'],
|
||||
summary: 'List cash sessions',
|
||||
summary: 'List cash sessions (admin)',
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
storeId: { type: 'string', format: 'uuid' },
|
||||
terminalId: { type: 'string', format: 'uuid' },
|
||||
status: { type: 'string', enum: ['OPEN', 'CLOSED'] },
|
||||
limit: { type: 'integer', minimum: 1, maximum: 50, default: 20 },
|
||||
dateFrom: { type: 'string', format: 'date' },
|
||||
dateTo: { type: 'string', format: 'date' },
|
||||
limit: { type: 'integer', minimum: 1, maximum: 100, default: 20 },
|
||||
},
|
||||
},
|
||||
response: { 401: errorSchema, 403: errorSchema },
|
||||
@@ -1533,19 +1577,22 @@ export async function registerPosRoutes(app: FastifyInstance, deps: PosRouteDeps
|
||||
requireRole(user, 'admin');
|
||||
const {
|
||||
storeId,
|
||||
terminalId,
|
||||
status,
|
||||
dateFrom,
|
||||
dateTo,
|
||||
limit = 20,
|
||||
} = request.query as { storeId?: string; status?: string; limit?: number };
|
||||
} = request.query as {
|
||||
storeId?: string; terminalId?: string; status?: string;
|
||||
dateFrom?: string; dateTo?: string; limit?: number;
|
||||
};
|
||||
const conditions: string[] = [];
|
||||
const params: unknown[] = [];
|
||||
if (storeId) {
|
||||
params.push(storeId);
|
||||
conditions.push(`store_id = $${params.length}`);
|
||||
}
|
||||
if (status) {
|
||||
params.push(status);
|
||||
conditions.push(`status = $${params.length}`);
|
||||
}
|
||||
if (storeId) { params.push(storeId); conditions.push(`s.store_id = $${params.length}`); }
|
||||
if (terminalId) { params.push(terminalId); conditions.push(`s.terminal_id = $${params.length}`); }
|
||||
if (status) { params.push(status); conditions.push(`s.status = $${params.length}`); }
|
||||
if (dateFrom) { params.push(dateFrom); conditions.push(`DATE(s.created_at) >= $${params.length}`); }
|
||||
if (dateTo) { params.push(dateTo); conditions.push(`DATE(s.created_at) <= $${params.length}`); }
|
||||
params.push(limit);
|
||||
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')} AND ` : 'WHERE ';
|
||||
const result = await pool.query(
|
||||
|
||||
Reference in New Issue
Block a user