Nordlet

← Documentación / Guías

Migración desde otro sistema

Incorpore la contabilidad de una empresa en una sola llamada: plan contable, terceros, saldos de apertura o historial completo, facturas pendientes, inmovilizado y existencias.

Cuando una empresa se cambia a Nordlet desde otro programa de contabilidad, su contabilidad no empieza desde cero. El importador de libros históricos toma todo lo que el sistema anterior le deja y lo registra en una sola llamada y una única transacción de base de datos: si una sola fila no supera una comprobación, no se almacena nada. El mismo paquete se puede ejecutar primero a través de un extremo (endpoint) de solo comprobación, el cual realiza todas las validaciones y revierte los cambios.

POST /v1/migration/books/validate   # comprueba todo, no escribe nada
POST /v1/migration/books/import     # escribe todo o nada

La aplicación web cuenta con los mismos dos botones en Cuenta → Migración (pegar el JSON o cargar un archivo). La clave de API (API key) necesita el permiso ledger:write junto con el permiso de escritura de cada sección que incluya (partners:write, catalog:write, sales:write, purchases:write, assets:write, inventory:write). Ambos extremos aceptan cuerpos de hasta 32 MB.

La fecha de corte

Elija la fecha de corte: el primer día en que la empresa opera en Nordlet. Todo lo anterior permanece en el sistema anterior (o se incorpora como historial, véase más abajo); todo lo posterior a ese día se introduce en Nordlet a través de los extremos normales. Todos los importes del paquete se entienden "a fecha del día anterior al corte": el balance de comprobación de cierre, las facturas aún pendientes de cobro o pago, las existencias aún en el almacén y los activos aún en el registro.

Antes de importar, realice lo siguiente en Nordlet:

  1. Cree la empresa y aplique la plantilla de plan contable (ledger/accounts/apply-template), o bien enumere las cuentas que necesite en la sección accounts del paquete.
  2. Cree al menos un almacén (inventory/warehouses/create) si va a importar existencias.
  3. Ejecute el paquete a través de migration/books/validate hasta que no informe de ningún error y acepte sus advertencias.

El paquete

Cada sección es opcional; incluya las que tenga. Todas las referencias entre secciones se realizan mediante código (código de cuenta, código de tercero, código de artículo, código de grupo de activos, código de almacén), y un código puede referirse tanto a un registro que ya exista en Nordlet como a uno creado por una sección anterior del mismo paquete.

{
  "cutoverDate": "2026-01-01",
  "source": "Rivilė GAMA",
  "accounts": [
    { "code": "6210", "name": "Advertising expenses", "type": "expense", "parentCode": "6" }
  ],
  "partners": [
    { "code": "301111222", "name": "UAB Klientas", "vatCode": "LT100001112223", "isCustomer": true },
    { "code": "302222333", "name": "UAB Tiekėjas", "isCustomer": false, "isSupplier": true }
  ],
  "items": [
    { "code": "SKU-1", "name": "Widget", "type": "product", "unit": "vnt", "vatRatePercent": "21" }
  ],
  "assetGroups": [
    { "code": "TRANSP", "name": "Vehicles", "assetAccountCode": "1230", "depreciationAccountCode": "1239",
      "defaultUsefulLifeMonths": 60 }
  ],
  "openingBalances": {
    "balancingAccountCode": "3410",
    "entries": [
      { "accountCode": "2710", "debit": "5000.00" },
      { "accountCode": "2410", "debit": "1500.00" },
      { "accountCode": "2040", "debit": "300.00" },
      { "accountCode": "1230", "debit": "12000.00" },
      { "accountCode": "1239", "credit": "2400.00" },
      { "accountCode": "4430", "credit": "700.00" },
      { "accountCode": "3010", "credit": "10000.00" }
    ]
  },
  "openReceivables": [
    { "partnerCode": "301111222", "number": "SF-1050", "issueDate": "2025-12-10", "dueDate": "2026-01-09",
      "grossTotal": "1210.00", "vatTotal": "210.00" },
    { "partnerCode": "301111222", "number": "SF-1049", "issueDate": "2025-11-20",
      "grossTotal": "500.00", "outstanding": "290.00" }
  ],
  "openPayables": [
    { "partnerCode": "302222333", "documentNumber": "T-77", "documentDate": "2025-12-15", "grossTotal": "700.00" }
  ],
  "fixedAssets": [
    { "groupCode": "TRANSP", "code": "CAR-1", "name": "Delivery van", "acquisitionDate": "2025-01-01",
      "acquisitionCost": "12000.00", "accumulatedDepreciation": "2400.00", "depreciatedMonths": 12 }
  ],
  "stock": [
    { "itemCode": "SKU-1", "quantity": "30", "unitCost": "10" }
  ]
}

Los importes son cadenas de texto decimales, como en el resto de la API. source es una etiqueta libre que se incluye en la descripción del asiento de apertura y en las notas de las facturas migradas.

accounts

Filas del plan contable: code, name, type (asset, liability, equity, income, expense), y los campos opcionales parentCode y isPostable. Los códigos que ya existan no se modifican y se contabilizan como existing. Utilice esta opción cuando el plan del sistema anterior difiera de la plantilla, o sáltesela y aplique la plantilla primero.

partners y items

Clientes, proveedores y artículos del catálogo, organizados por code. En Lituania, el código de tercero suele ser el código de registro mercantil; para personas físicas, utilice cualquier código que sea único dentro de la empresa. Los códigos existentes se omiten y no se actualizan. Los artículos aceptan type (product o service), unit, barcode, vatRatePercent, salePriceExclVat, purchasePriceExclVat.

openingBalances

El balance de comprobación de cierre del sistema anterior, una fila por cuenta: accountCode con debit o credit. Las filas se registran como un único asiento de diario con fecha openingBalances.date (por defecto, la fecha de corte) y tipo de documento migration_opening. Las filas deben hacer referencia a cuentas con capacidad de asiento (postables).

El asiento debe cuadrar. Si el balance de comprobación del sistema anterior no cuadra -por redondeos, un beneficio que nunca se destinó a reservas, o una cuenta faltante-, indique balancingAccountCode (normalmente resultados acumulados, 3410 en la plantilla lituana) y la diferencia se registrará en dicha cuenta; la respuesta informará del importe como balancingAmount.

Solo puede existir un asiento de apertura por empresa. Una segunda importación con openingBalances será rechazada (409). Las correcciones posteriores se realizan mediante asientos manuales ordinarios (ledger/journal/transactions/create); los asientos contabilizados son inmutables, por lo que el original permanece tal como se importó.

journal - historial completo en lugar de, o además de, los saldos

Si desea incluir los asientos del sistema anterior en Nordlet (para que los informes de períodos anteriores funcionen), envíelos aquí: un objeto por asiento con date, description y reference opcionales, y las líneas (entries) compuestas por accountCode + debit/credit. Cada asiento debe cuadrar por sí mismo. Se registran con el tipo de documento migration.

Las fechas deben ser anteriores a la fecha de corte. Cuando el paquete también incluye openingBalances, el historial debe tener fecha igual o posterior a openingBalances.date. El patrón habitual consiste en incluir los saldos al inicio del ejercicio anterior más los asientos de dicho ejercicio, situando el corte en el primer día del año en curso. No envíe saldos e historial para el mismo período, ya que los saldos se contabilizarían dos veces.

Cada mes afectado por los saldos de apertura o por el historial debe ser un período contable abierto (de lo contrario, se devolverá un error 409).

openReceivables y openPayables

Facturas que aún estaban pendientes de cobro o pago (total o parcialmente) en la fecha de corte. Se crean como facturas de venta emitidas y facturas de compra registradas con paidAmount = grossTotal − outstanding, de modo que la conciliación bancaria (bank/transactions/match, bank/transactions/suggest-matches), el informe de antigüedad de deudas y los webhooks de pago funcionen en ellas igual que en cualquier otra factura.

  • outstanding toma por defecto el valor de grossTotal; vatTotal toma por defecto 0 (la base imponible se calcula automáticamente).
  • dueDate toma por defecto la fecha del documento.
  • currency toma por defecto la moneda de facturación de la empresa. Para cualquier moneda distinta de la moneda base de la empresa, es obligatorio indicar fxRate (unidades de esa moneda por cada 1 unidad de la moneda base, siguiendo la misma convención que en el resto de la API). Este tipo de cambio se almacena en la factura para que los pagos posteriores calculen correctamente la diferencia de cambio realizada.
  • El number de la factura de venta es el número completo del sistema anterior y debe ser único en la empresa. Las facturas de compra son únicas por cada combinación de partnerCode y documentNumber.
  • Las facturas no se vuelven a contabilizar: su saldo deudor o acreedor ya forma parte de los saldos de apertura. Están vinculadas al asiento de apertura, razón por la cual openPayables requiere que se incluya openingBalances en el mismo paquete.
  • No se importan las líneas de factura; la factura contiene únicamente los totales. El sistema anterior sigue siendo la fuente de los detalles de las líneas y de los registros de IVA de los períodos anteriores al corte.

Si el sistema anterior realizaba un seguimiento de los saldos de los clientes sin partidas abiertas, cree una factura por cada tercero para reflejar el saldo (por ejemplo, con el número OB-301111222) para que pueda liquidarse.

La numeración continúa. Cuando el número de una factura de venta importada tiene el formato PREFIX-N y su fecha de emisión se encuentra dentro del año de corte, la serie numérica para dicho prefijo y año se establece en N + 1 (nunca se reduce). La respuesta enumera el campo resultante numberSeries; para otros casos, configure la serie usted mismo mediante reference/series/create ({ documentType: "sale_invoice", prefix, year, startAt }).

assetGroups y fixedAssets

El inmovilizado se incorpora con su amortización acumulada a la fecha: acquisitionCost, salvageValue, accumulatedDepreciation, depreciatedMonths y usefulLifeMonths (o el valor predeterminado del grupo). El cálculo lineal (assets/depreciation/post) continúa a partir del valor pendiente de amortizar durante los meses restantes. Los activos cuya amortización acumulada ya sea igual a su valor amortizable se crean como fully_depreciated (totalmente amortizados). No se contabiliza nada; el coste y la amortización acumulada forman parte de los saldos de apertura.

Los grupos se organizan por code y requieren assetAccountCode y depreciationAccountCode (la cuenta de gasto por defecto es 6206).

stock

Existencias actuales por artículo: itemCode, quantity, unitCost (coste por unidad en EUR) y, opcionalmente, warehouseCode (por defecto, el almacén predeterminado), lotNumber y expiryDate para artículos con seguimiento por lotes o números de serie. Cada fila se convierte en un movimiento de entrada de existencias con fecha de corte y tipo de documento migration, e inicia una capa FIFO a dicho coste. No se contabiliza nada; el valor de las existencias forma parte de los saldos de apertura.

Comprobaciones y advertencias

El extremo de validación devuelve un error (422) en caso de cuentas faltantes, cuentas no postables, asientos descuadrados, códigos desconocidos de terceros, artículos, grupos o almacenes, códigos o números duplicados dentro del paquete, importes pendientes superiores al total bruto, amortización acumulada superior al valor amortizable y tipos de cambio (fxRate) faltantes. Los números o códigos que ya existan en Nordlet devuelven un error 409.

Además de esto, ambos extremos comparan los libros auxiliares (sub-ledgers) con los asientos del libro mayor incluidos en el mismo paquete y devuelven las diferencias como warnings (advertencias) en lugar de errores:

  • el total pendiente de openReceivables frente al saldo de la cuenta de deudores (regla de contabilización sales.receivable, por defecto 2410);
  • el total pendiente de openPayables frente al saldo de la cuenta de acreedores (purchases.payables, 4430);
  • el coste total de stock frente a la cuenta de existencias (inventory.stock, 2040);
  • por cada grupo de activos, el coste de los activos frente a la cuenta de activo del grupo y su amortización acumulada frente a la cuenta de amortización.

Una advertencia indica que el libro auxiliar y el libro mayor del sistema anterior no coinciden. Corrija el paquete (o acepte la diferencia conscientemente) antes de realizar la importación.

La respuesta

{
  "dryRun": false,
  "cutoverDate": "2026-01-01",
  "accounts": { "created": 1, "existing": 0 },
  "partners": { "created": 2, "existing": 0 },
  "items": { "created": 1, "existing": 0 },
  "assetGroups": { "created": 1, "existing": 0 },
  "openingBalances": { "journalTransactionId": "…", "date": "2026-01-01", "entries": 8,
                        "debitTotal": "18800.00", "creditTotal": "18800.00", "balancingAmount": "5700.00" },
  "journal": { "transactions": 0, "entries": 0 },
  "openReceivables": { "created": 2, "outstandingTotal": "1500.00" },
  "openPayables": { "created": 1, "outstandingTotal": "700.00" },
  "fixedAssets": { "created": 1, "costTotal": "12000.00", "accumulatedDepreciationTotal": "2400.00" },
  "stock": { "movements": 1, "costTotal": "300.00" },
  "numberSeries": [],
  "warnings": []
}

dryRun: true indica una ejecución de validación; en ese caso, journalTransactionId es null. Una importación se registra en el registro de auditoría (audit log) como migration.imported junto con el mismo resumen.

Después de la importación

  • Bloquee los períodos anteriores a la fecha de corte (ledger/periods/lock) para evitar que se contabilice por error cualquier operación en el historial migrado.
  • Compruebe el balance de comprobación y el balance de situación a la fecha de corte en comparación con los informes de cierre del sistema anterior.
  • Continúe con el flujo habitual: emita facturas, importe extractos bancarios, concilie pagos. Las facturas abiertas migradas se liquidarán igual que cualquier otra.

Aspectos que el importador no cubre: las líneas de factura y los registros de IVA de períodos anteriores (consérvelos en el sistema anterior o en su archivo), el historial de nóminas y los documentos distintos de las facturas (pedidos, albaranes, contratos).