# RF-FIN-003: Periodos Contables

## Identificacion

| Campo | Valor |
|-------|-------|
| **ID** | RF-FIN-003 |
| **Modulo** | MGN-010 Financial |
| **Titulo** | Periodos Contables |
| **Prioridad** | P0 - Critica |
| **Estado** | Draft |
| **Fecha** | 2025-12-05 |

---

## Descripcion

El sistema debe gestionar años fiscales y periodos contables, controlando la apertura y cierre de periodos, y restringiendo el registro de movimientos fuera de periodos activos.

---

## Requisitos Funcionales

### RF-FIN-003.1: Estructura de Año Fiscal

```typescript
interface FiscalYear {
  id: UUID;
  tenantId: UUID;
  name: string;             // "Ejercicio 2025"
  code: string;             // "2025"
  startDate: Date;          // "2025-01-01"
  endDate: Date;            // "2025-12-31"
  status: FiscalYearStatus;
  closedAt?: TIMESTAMPTZ;
  closedBy?: UUID;
  createdAt: TIMESTAMPTZ;
}

enum FiscalYearStatus {
  DRAFT = 'draft',         // En preparacion
  OPEN = 'open',           // Activo
  CLOSING = 'closing',     // En proceso de cierre
  CLOSED = 'closed'        // Cerrado
}
```

### RF-FIN-003.2: Estructura de Periodo

```typescript
interface FiscalPeriod {
  id: UUID;
  fiscalYearId: UUID;
  number: number;           // 1-12 o 1-13
  name: string;             // "Enero 2025"
  startDate: Date;
  endDate: Date;
  status: PeriodStatus;
  closedAt?: TIMESTAMPTZ;
  closedBy?: UUID;
}

enum PeriodStatus {
  FUTURE = 'future',       // Aun no inicia
  OPEN = 'open',           // Activo para movimientos
  CLOSED = 'closed',       // Cerrado
  LOCKED = 'locked'        // Bloqueado definitivamente
}
```

### RF-FIN-003.3: Tipos de Periodos

| Tipo | Periodos | Uso |
|------|----------|-----|
| Mensual | 12 | Mas comun |
| Bimestral | 6 | Algunos paises |
| Trimestral | 4 | Reportes |
| Semestral | 2 | Simplificado |
| Anual | 1 | Muy simplificado |
| Mensual + 13 | 13 | Con periodo de ajuste |

### RF-FIN-003.4: Periodo de Ajuste

Periodo especial para asientos de cierre:

```typescript
interface AdjustmentPeriod extends FiscalPeriod {
  number: 13;                // Periodo 13
  name: "Ajustes 2025";
  isAdjustment: true;
  // Fecha = ultimo dia del año
  startDate: "2025-12-31";
  endDate: "2025-12-31";
}
```

### RF-FIN-003.5: Control de Fechas

```typescript
// Validar si fecha permite movimientos
function canPostToDate(date: Date, tenantId: UUID): ValidationResult {
  const period = findPeriodByDate(date, tenantId);

  if (!period) {
    return { valid: false, error: 'No existe periodo para esta fecha' };
  }

  if (period.status === 'closed') {
    return { valid: false, error: 'Periodo cerrado' };
  }

  if (period.status === 'locked') {
    return { valid: false, error: 'Periodo bloqueado permanentemente' };
  }

  if (period.status === 'future') {
    return { valid: false, error: 'Periodo aun no abierto' };
  }

  return { valid: true };
}
```

### RF-FIN-003.6: Proceso de Cierre de Periodo

```typescript
interface PeriodCloseProcess {
  periodId: UUID;
  steps: CloseStep[];
  currentStep: number;
  status: 'pending' | 'in_progress' | 'completed' | 'failed';
  startedAt?: TIMESTAMPTZ;
  completedAt?: TIMESTAMPTZ;
}

interface CloseStep {
  name: string;
  description: string;
  status: 'pending' | 'running' | 'completed' | 'skipped' | 'failed';
  isRequired: boolean;
  error?: string;
}

// Pasos tipicos de cierre
const CLOSE_STEPS = [
  { name: 'validate_balances', description: 'Validar saldos cuadrados', required: true },
  { name: 'check_pending', description: 'Verificar documentos pendientes', required: false },
  { name: 'calculate_depreciation', description: 'Calcular depreciaciones', required: false },
  { name: 'accrue_expenses', description: 'Registrar provisiones', required: false },
  { name: 'close_temporary', description: 'Cerrar cuentas temporales', required: true },
  { name: 'generate_balances', description: 'Generar saldos de cierre', required: true }
];
```

### RF-FIN-003.7: Cierre de Año Fiscal

Al cerrar el año:

1. Cerrar ultimo periodo
2. Generar asiento de cierre (P&L -> Utilidades)
3. Generar saldos iniciales del nuevo año
4. Marcar año como cerrado

```typescript
interface YearCloseResult {
  fiscalYearId: UUID;
  closingEntryId: UUID;
  openingEntryId: UUID;      // En nuevo año
  retainedEarnings: Decimal; // Utilidad/perdida del ejercicio
  newFiscalYearId: UUID;     // Nuevo año creado
}
```

---

## Operaciones

### Listar Años Fiscales

```typescript
GET /api/v1/financial/fiscal-years

Response:
{
  "data": [
    {
      "id": "uuid",
      "name": "Ejercicio 2025",
      "startDate": "2025-01-01",
      "endDate": "2025-12-31",
      "status": "open",
      "periodsCount": 12,
      "openPeriodsCount": 1
    }
  ]
}
```

### Obtener Periodos del Año

```typescript
GET /api/v1/financial/fiscal-years/:id/periods

Response:
{
  "fiscalYear": { "id": "...", "name": "2025" },
  "periods": [
    { "number": 1, "name": "Enero", "status": "closed" },
    { "number": 2, "name": "Febrero", "status": "closed" },
    // ...
    { "number": 12, "name": "Diciembre", "status": "open" }
  ]
}
```

### Crear Año Fiscal

```typescript
POST /api/v1/financial/fiscal-years
{
  "name": "Ejercicio 2026",
  "startDate": "2026-01-01",
  "endDate": "2026-12-31",
  "periodType": "monthly",
  "includeAdjustment": true
}
```

### Cerrar Periodo

```typescript
POST /api/v1/financial/periods/:id/close

Response:
{
  "periodId": "uuid",
  "status": "closed",
  "closedAt": "2025-12-05T10:00:00Z",
  "validationResults": [
    { "check": "balances_match", "passed": true },
    { "check": "no_pending_docs", "passed": true }
  ]
}
```

### Reabrir Periodo (Excepcion)

```typescript
POST /api/v1/financial/periods/:id/reopen
{
  "reason": "Correccion de asiento",
  "approvedBy": "uuid-supervisor"
}

// Requiere permiso especial
// Genera registro en audit log
```

---

## Reglas de Negocio

| ID | Regla | Severidad |
|----|-------|-----------|
| BR-001 | No registrar movimientos en periodos cerrados | Error |
| BR-002 | Solo un periodo abierto por defecto | Warning |
| BR-003 | No cerrar periodo con documentos pendientes | Warning |
| BR-004 | Cierre de año genera asientos automaticos | Info |
| BR-005 | Reabrir periodo requiere autorizacion | Security |

---

## Criterios de Aceptacion

- [ ] CRUD de años fiscales
- [ ] Generacion automatica de periodos
- [ ] Control de fechas de contabilizacion
- [ ] Proceso de cierre de periodo
- [ ] Proceso de cierre de año
- [ ] Generacion de saldos iniciales
- [ ] Reabrir periodo con autorizacion

---

## Historial

| Version | Fecha | Autor | Cambios |
|---------|-------|-------|---------|
| 1.0 | 2025-12-05 | Requirements-Analyst | Creacion inicial |
