POS vista lista, modulo Tickets para gerencia con cancelacion auditada, y saldo a favor (recargas de anticipo desde expediente y agenda, canje en POS)

This commit is contained in:
2026-09-18 04:25:33 +00:00
parent cebf8d663d
commit d75411f0d9
19 changed files with 1278 additions and 30 deletions

View File

@@ -454,6 +454,11 @@ export interface Sale {
cancelled_at?: string | null;
cancel_points_reversed?: number;
cancel_points_restored?: number;
/** Cobro: quién cobró y con qué método (módulo Tickets) */
payment_method?: string;
user_login?: string;
/** Pagos ligados al ticket (los nuevos; los antiguos no tienen vínculo) */
pagos?: Payment[];
}
// "Repetir última venta" (POS): línea de la última venta con el precio vigente
@@ -823,9 +828,28 @@ export interface ReceiptData {
aplicado: ReceiptApplied[];
operator: string;
wallet_points: number;
/** Recibo de recarga de saldo a favor (tipo 'deposito') */
tipo?: 'pago' | 'deposito';
saldo_favor?: number;
nota?: string;
}
export type WalletTxType = 'accrual' | 'redemption' | 'adjustment' | 'expiration';
export type WalletTxType = 'deposito' | 'accrual' | 'redemption' | 'adjustment' | 'reversion' | 'expiration';
/** Saldo a favor del paciente (monedero: 1 pt = $1 MXN) */
export interface PatientWallet {
status: string;
patient_id: number;
patient: string;
wallet_id: number | null;
points: number;
equivalent_mxn: number;
equivalent_usd: number | null;
rate: number | null;
depositado: number;
movimientos: WalletTransaction[];
message?: string;
}
export interface WalletTransaction {
id: number;
@@ -1654,6 +1678,18 @@ export const odooApi = {
},
// Cancelación con nota de crédito (permiso admin/gerencia)
/** Saldo a favor del paciente + movimientos narrados. */
async getPatientWallet(patientId: number): Promise<PatientWallet> {
const { data } = await axios.get(`${ODOO_BASE}/skeen/frontend/v1/patients/${patientId}/wallet`);
return data;
},
/** Recarga de saldo a favor (anticipo). Permiso: recepción o más. */
async depositPatientWallet(patientId: number, payload: { amount: number; payment_method: string; notes?: string; cita_id?: number }): Promise<{ status: string; movimiento: WalletTransaction; wallet: { id: number; points: number; equivalent_mxn: number; equivalent_usd: number | null }; receipt: ReceiptData; message?: string }> {
const { data } = await axios.post(`${ODOO_BASE}/skeen/frontend/v1/patients/${patientId}/deposit`, payload);
return data;
},
async cancelSale(id: number, payload: { reason: string; restore_stock?: boolean }): Promise<{ status: string; sale: Sale; result: { points_reversed: number; points_restored: number; stock_moves: number } }> {
const { data } = await axios.post(`${ODOO_BASE}/skeen/frontend/v1/sales/${id}/cancel`, payload);
return data;