ADM-009: Tablas Fiscales (IVA + IIBB) — append-only versioned ref data #22

Merged
dmolinari merged 36 commits from feature/ADM-009 into main 2026-04-18 11:45:13 +00:00
2 changed files with 142 additions and 0 deletions
Showing only changes of commit ea16d57646 - Show all commits

View File

@@ -0,0 +1,68 @@
// ADM-009 — API client tipado para fiscal/iva
import { axiosClient } from '@/api/axiosClient'
import type {
TipoDeIva,
CreateTipoDeIvaRequest,
UpdateTipoDeIvaRequest,
NuevaVersionTipoDeIvaRequest,
NuevaVersionResponse,
HistorialCadenaEntry,
TipoDeIvaFilter,
PagedResponse,
} from '../types/tipoDeIva.types'
const BASE = '/api/v1/admin/fiscal/iva'
export async function listTiposDeIva(
params: TipoDeIvaFilter,
): Promise<PagedResponse<TipoDeIva>> {
const p = new URLSearchParams()
if (params.page !== undefined) p.set('page', String(params.page))
if (params.pageSize !== undefined) p.set('pageSize', String(params.pageSize))
if (params.codigo !== undefined) p.set('codigo', params.codigo)
if (params.activo !== undefined) p.set('activo', String(params.activo))
const res = await axiosClient.get<PagedResponse<TipoDeIva>>(BASE, { params: p })
return res.data
}
export async function getTipoDeIvaById(id: number): Promise<TipoDeIva> {
const res = await axiosClient.get<TipoDeIva>(`${BASE}/${id}`)
return res.data
}
export async function getHistorialTipoDeIva(id: number): Promise<HistorialCadenaEntry[]> {
const res = await axiosClient.get<HistorialCadenaEntry[]>(`${BASE}/${id}/historial`)
return res.data
}
export async function createTipoDeIva(body: CreateTipoDeIvaRequest): Promise<TipoDeIva> {
const res = await axiosClient.post<TipoDeIva>(BASE, body)
return res.data
}
export async function updateTipoDeIva(
id: number,
body: UpdateTipoDeIvaRequest,
): Promise<TipoDeIva> {
const res = await axiosClient.patch<TipoDeIva>(`${BASE}/${id}`, body)
return res.data
}
export async function nuevaVersionTipoDeIva(
id: number,
body: NuevaVersionTipoDeIvaRequest,
): Promise<NuevaVersionResponse> {
const res = await axiosClient.post<NuevaVersionResponse>(`${BASE}/${id}/nueva-version`, body)
return res.data
}
export async function deactivateTipoDeIva(id: number): Promise<TipoDeIva> {
const res = await axiosClient.post<TipoDeIva>(`${BASE}/${id}/deactivate`)
return res.data
}
export async function reactivateTipoDeIva(id: number): Promise<TipoDeIva> {
const res = await axiosClient.post<TipoDeIva>(`${BASE}/${id}/reactivate`)
return res.data
}

View File

@@ -0,0 +1,74 @@
// ADM-009 — Tipos TS para feature fiscal/iva
// Alineados con TipoDeIvaDto / FiscalContracts.cs del backend
export interface TipoDeIva {
id: number
codigo: string
descripcion: string
porcentaje: number
vigenciaDesde: string // ISO date "yyyy-MM-dd"
vigenciaHasta: string | null
activo: boolean
aplicaIVA: boolean
predecesorId: number | null
}
export interface CreateTipoDeIvaRequest {
codigo: string
descripcion: string
porcentaje: number
vigenciaDesde: string
aplicaIVA: boolean
}
// UpdateTipoDeIvaRequest — SIN porcentaje (inmutable, usar NuevaVersion para cambiar)
export interface UpdateTipoDeIvaRequest {
codigo: string
descripcion: string
aplicaIVA: boolean
activo: boolean
}
export interface NuevaVersionTipoDeIvaRequest {
porcentaje: number
vigenciaDesde: string // "yyyy-MM-dd"
}
export interface NuevaVersionResponse {
predecesorId: number
nuevaId: number
nuevoPorcentaje: number
vigenciaDesde: string
predecesorVigenciaHasta: string
}
export interface HistorialCadenaEntry {
id: number
codigo: string
porcentaje: number
vigenciaDesde: string
vigenciaHasta: string | null
activo: boolean
predecesorId: number | null
depth: number
}
export interface TipoDeIvaFilter {
page?: number
pageSize?: number
codigo?: string
activo?: boolean
}
export interface PagedResponse<T> {
items: T[]
page: number
pageSize: number
total: number
}
// ApiError — contrato unificado { error, message } de ADM-008/ADM-009
export interface ApiError {
error: string
message: string
}