feat: módulo Finanzas (plan de cuentas y asientos contables con cancelación)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
GeorgeandClaude Sonnet 5.5 committed 2026-10-16 14:36:24 -05:00
1 parent c9d1a714c9
commit 8bbd05d07b
23 files changed
+708 -29

No files matched your search

+16 -3
View File
@@ -18,7 +18,7 @@ describe('recursos del Service Layer', () => {
});
it('dimensiones, proyectos y cuentas son catálogos de solo lectura', () => {
for (const name of ['FactoringIndicators', 'DistributionRules', 'Projects', 'ChartOfAccounts', 'AdditionalExpenses', 'ItemGroups', 'BusinessPartnerGroups']) {
for (const name of ['FactoringIndicators', 'DistributionRules', 'Projects', 'AdditionalExpenses', 'ItemGroups', 'BusinessPartnerGroups']) {
const r = SL_RESOURCE_MAP.get(name)!;
expect(r.methods, name).toEqual(['GET']);
expect(r.read, name).toBeNull();
@@ -43,8 +43,8 @@ describe('recursos del Service Layer', () => {
}
});
it('solo los pagos tienen acciones sobre un registro', () => {
expect(SL_RESOURCES.filter((r) => r.actions?.length).map((r) => r.name)).toEqual(['IncomingPayments', 'VendorPayments']);
it('solo los pagos y los asientos tienen acciones sobre un registro', () => {
expect(SL_RESOURCES.filter((r) => r.actions?.length).map((r) => r.name)).toEqual(['IncomingPayments', 'VendorPayments', 'JournalEntries']);
});
it('las facturas y notas de crédito se pueden consultar desde la pantalla de pagos, sin poder modificarlas', () => {
@@ -64,4 +64,17 @@ describe('recursos del Service Layer', () => {
expect(SL_RESOURCE_MAP.get('Banks')!.methods).toEqual(['GET']);
expect(SL_RESOURCE_MAP.get('CreditCards')!.methods).toEqual(['GET']);
});
it('el plan de cuentas se lee desde cualquier sesión y solo se modifica desde Finanzas', () => {
const r = SL_RESOURCE_MAP.get('ChartOfAccounts')!;
expect(r.read).toBeNull();
expect(r.write).toBe('/finanzas/plan-de-cuentas');
});
it('los asientos se crean y se cancelan, no se modifican', () => {
const r = SL_RESOURCE_MAP.get('JournalEntries')!;
expect(r.methods).toEqual(['GET', 'POST']);
expect(r.actions).toEqual(['Cancel']);
expect(r.write).toBe('/finanzas/asientos');
});
});
+5 -1
View File
@@ -80,6 +80,9 @@ export const SL_RESOURCES: readonly SlResource[] = [
{ ...document('IncomingPayments', '/bancos/pagos-recibidos'), methods: ['GET', 'POST'], actions: ['Cancel'] },
{ ...document('VendorPayments', '/bancos/pagos-efectuados'), methods: ['GET', 'POST'], actions: ['Cancel'] },
// Finanzas: los asientos manuales se crean y se cancelan (`Cancel` genera el asiento de reverso), no se modifican.
{ ...document('JournalEntries', '/finanzas/asientos'), methods: ['GET', 'POST'], actions: ['Cancel'] },
// Maestros (consulta para cualquier sesión; escritura según el módulo)
catalog('BusinessPartners', 'string', ['/socios/clientes', '/socios/proveedores']),
catalog('Items', 'string', '/inventario/articulos'),
@@ -101,7 +104,8 @@ export const SL_RESOURCES: readonly SlResource[] = [
catalog('FactoringIndicators', 'string'),
catalog('DistributionRules', 'string'),
catalog('Projects', 'string'),
catalog('ChartOfAccounts', 'string'),
// Plan de cuentas: se consulta desde cualquier documento y se mantiene en Finanzas.
catalog('ChartOfAccounts', 'string', '/finanzas/plan-de-cuentas'),
// Series de numeración válidas de un tipo de documento.
queryAction('SeriesService_GetDocumentSeries'),
// Gastos adicionales de un documento (el flete): se leen para elegir el código de gasto.