← Documentazione / Guide
Migrazione da un altro sistema
Trasferisci la contabilità di un'azienda con una sola chiamata: piano dei conti, partner, saldi iniziali o storico completo, fatture aperte, cespiti e magazzino.
Quando un'azienda passa a Nordlet da un altro programma di contabilità, i suoi registri non partono da zero. L'importatore dei dati storici acquisisce tutto ciò che il vecchio sistema lascia in eredità e lo registra in una sola chiamata, in un'unica transazione di database: se una singola riga non supera un controllo, nulla viene salvato. Lo stesso pacchetto puo essere eseguito prima tramite un endpoint di sola verifica, che esegue tutte le convalide ed effettua il rollback.
POST /v1/migration/books/validate # verifica tutto, non scrive nulla
POST /v1/migration/books/import # scrive tutto o nulla
L'applicazione web dispone degli stessi due pulsanti nella sezione Account → Migration (incollando il JSON o caricando un file). La chiave API richiede il permesso ledger:write oltre al permesso di scrittura di ogni sezione inclusa (partners:write, catalog:write, sales:write, purchases:write, assets:write, inventory:write). Entrambi gli endpoint accettano corpi fino a 32 MB.
La data di transizione (cut-over)
Scegli la data di transizione (cut-over date): il primo giorno in cui l'azienda viene gestita su Nordlet. Tutto ciò che precede tale data rimane nel vecchio sistema (o viene importato come storico, vedi sotto), mentre tutto ciò che parte da quel giorno viene inserito in Nordlet tramite i normali endpoint. Tutti gli importi nel pacchetto sono intesi "alla data precedente la transizione": il bilancio di verifica di chiusura, le fatture ancora non saldate, le giacenze di magazzino, i cespiti presenti nel registro.
Prima di effettuare l'importazione, esegui queste operazioni in Nordlet:
- Crea l'azienda e applica il modello del piano dei conti (
ledger/accounts/apply-template), oppure elenca i conti necessari nella sezioneaccountsdel pacchetto. - Crea almeno un magazzino (
inventory/warehouses/create) se importi le giacenze di magazzino. - Esegui il pacchetto tramite
migration/books/validatefinché non segnala alcun errore e accetti i relativi avvisi.
Il pacchetto
Ogni sezione è facoltativa; includi quelle di cui disponi. Tutti i riferimenti tra le sezioni avvengono tramite codice (codice conto, codice partner, codice articolo, codice gruppo cespiti, codice magazzino) e un codice può fare riferimento a un record già esistente in Nordlet oppure creato da una sezione precedente dello stesso pacchetto.
{
"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" }
]
}
Gli importi sono stringhe decimali, come ovunque nell'API. source è un'etichetta descrittiva libera che viene inserita nella descrizione della transazione dei saldi iniziali e nelle note delle fatture migrate.
accounts
Righe del piano dei conti: code, name, type (asset, liability, equity, income, expense), oltre ai campi facoltativi parentCode e isPostable. I codici già esistenti vengono lasciati invariati e conteggiati come existing. Utilizza questa opzione se il piano dei conti del vecchio sistema differisce dal modello, oppure saltala e applica prima il modello.
partners e items
Clienti, fornitori e articoli di catalogo, indicizzati per code. In Lituania, il codice partner corrisponde normalmente al codice di registro dell'impresa; per le persone fisiche, utilizza qualsiasi codice che sia univoco all'interno dell'azienda. I codici esistenti vengono ignorati e non aggiornati. Gli articoli accettano i campi type (product o service), unit, barcode, vatRatePercent, salePriceExclVat, purchasePriceExclVat.
openingBalances
Il bilancio di verifica di chiusura del vecchio sistema, una riga per conto: accountCode con l'indicazione del debit o del credit. Le righe vengono registrate come un'unica transazione di prima nota datata openingBalances.date (per impostazione predefinita corrisponde alla data di transizione) con tipo di documento migration_opening. Le righe devono fare riferimento a conti movimentabili (postable).
La transazione deve essere in pareggio. Se il bilancio di verifica del vecchio sistema non lo è a causa di arrotondamenti, di un utile mai girato a riserva o di un conto mancante, specifica balancingAccountCode (solitamente utili portati a nuovo, 3410 nel modello lituano) e la differenza verrà registrata lì; la risposta indicherà l'importo alla voce balancingAmount.
Per ogni azienda può esistere una sola transazione di saldi iniziali. Una seconda importazione che include openingBalances viene rifiutata (409). Le correzioni successive devono essere effettuate tramite normali registrazioni manuali di prima nota (ledger/journal/transactions/create); le transazioni registrate sono immutabili, quindi l'originale rimane così come è stato importato.
journal - storico completo anziché, o in aggiunta ai, saldi
Se desideri inserire le transazioni del vecchio sistema in Nordlet (in modo che i report per i periodi precedenti funzionino), inviale qui: un oggetto per transazione con date, i campi facoltativi description e reference, e le entries composte da accountCode + debit/credit. Ciascuna transazione deve essere autonomamente in pareggio. Vengono registrate con il tipo di documento migration.
Le date devono essere precedenti alla data di transizione. Quando il pacchetto include anche openingBalances, lo storico deve avere una data successiva o uguale a openingBalances.date (lo schema tipico prevede i saldi all'inizio del precedente esercizio finanziario più le transazioni di quell'anno, con la transizione fissata al primo giorno dell'anno corrente). Non inviare saldi e storico per lo stesso periodo, altrimenti i saldi verrebbero conteggiati due volte.
Ogni mese interessato dai saldi iniziali o dallo storico deve essere un periodo contabile aperto (in caso contrario si riceve un errore 409).
openReceivables e openPayables
Fatture che risultavano ancora non saldate (totalmente o parzialmente) alla data di transizione. Vengono create come fatture di vendita emesse e fatture di acquisto registrate con paidAmount = grossTotal − outstanding, in modo che la riconciliazione bancaria (bank/transactions/match, bank/transactions/suggest-matches), il report sull'anzianità dei crediti e i webhook dei pagamenti funzionino esattamente come per qualsiasi altra fattura.
outstandingha come valore predefinitogrossTotal;vatTotalha come valore predefinito0(l'imponibile viene calcolato automaticamente).dueDateha come valore predefinito la data del documento.currencyha come valore predefinito la valuta di fatturazione dell'azienda. Per qualsiasi valuta diversa dalla valuta di base dell'azienda è richiesto il campofxRate(unità di quella valuta per 1 unità della valuta di base, secondo la stessa convenzione del resto dell'API) e viene memorizzato sulla fattura affinché i pagamenti successivi calcolino correttamente la differenza di cambio realizzata.- Il
numberdella fattura di vendita corrisponde al numero completo del vecchio sistema e deve essere univoco nell'azienda. Le fatture di acquisto sono univoche per combinazione di partner edocumentNumber. - Le fatture non vengono registrate nuovamente: il loro saldo attivo o passivo fa già parte dei saldi iniziali. Sono collegate alla transazione dei saldi iniziali, motivo per cui
openPayablesrichiedeopeningBalancesnello stesso pacchetto. - Le righe delle fatture non vengono importate; la fattura contiene solo i totali. Il vecchio sistema rimane la fonte di riferimento per il dettaglio delle righe e per i registri IVA dei periodi precedenti alla transizione.
Se il vecchio sistema teneva traccia dei saldi dei clienti senza fatture aperte, crea una fattura per partner per l'importo del saldo (ad esempio con numero OB-301111222) in modo che possa essere regolarizzata.
La numerazione continua. Quando il numero di una fattura di vendita importata ha il formato PREFIX-N e la sua data di emissione rientra nell'anno di transizione, la serie numerica per quel prefisso e quell'anno viene impostata a N + 1 (senza mai essere ridotta). La risposta elenca il campo risultante numberSeries; per gli altri casi, imposta la serie autonomamente con reference/series/create ({ documentType: "sale_invoice", prefix, year, startAt }).
assetGroups e fixedAssets
I cespiti vengono trasferiti insieme al loro fondo ammortamento maturato fino a quella data: acquisitionCost, salvageValue, accumulatedDepreciation, depreciatedMonths e usefulLifeMonths (o il valore predefinito del gruppo). Il calcolo a quote costanti (assets/depreciation/post) prosegue a partire dal valore residuo sui mesi rimanenti. I cespiti il cui fondo ammortamento è già pari al valore ammortizzabile vengono creati come fully_depreciated (completamente ammortizzati). Non viene registrato nulla: il costo storico e il fondo ammortamento fanno parte dei saldi iniziali.
I gruppi sono indicizzati per code e richiedono assetAccountCode e depreciationAccountCode (il conto di costo predefinito è 6206).
stock
Giacenze di magazzino per articolo: itemCode, quantity, unitCost (costo unitario in EUR) e facoltativamente warehouseCode (predefinito: magazzino predefinito), lotNumber e expiryDate per gli articoli gestiti a lotto o a numero di serie. Ciascuna riga diventa un movimento di carico di magazzino datato alla data di transizione con tipo di documento migration e avvia un layer FIFO a quel costo. Non viene registrato nulla: il valore delle scorte fa parte dei saldi iniziali.
Controlli e avvisi
L'endpoint di validazione restituisce un errore (422) in presenza di conti mancanti, conti non movimentabili, transazioni non in pareggio, codici di partner, articoli, gruppi o magazzini sconosciuti, codici o numeri duplicati all'interno del pacchetto, importi aperti superiori al totale lordo, fondi ammortamento superiori al valore ammortizzabile e tassi di cambio mancanti. Numeri o codici già esistenti in Nordlet restituiscono un errore 409.
Inoltre, entrambi gli endpoint confrontano i mastrini sezionali con le registrazioni di prima nota presenti nello stesso pacchetto e restituiscono le differenze sotto forma di warnings (avvisi) anziché di errori:
- totale aperto di
openReceivablesrispetto al saldo del conto crediti (regola di registrazionesales.receivable,2410per impostazione predefinita); - totale aperto di
openPayablesrispetto al conto debiti (purchases.payables,4430); - costo totale di
stockrispetto al conto di magazzino (inventory.stock,2040); - per ciascun gruppo di cespiti, il costo dei cespiti rispetto al conto immobilizzazioni del gruppo e il relativo fondo ammortamento rispetto al conto ammortamenti.
Un avviso indica che il mastrino sezionale del vecchio sistema e il libro mastro generale non coincidono. Correggi il pacchetto (o accetta consapevolmente la differenza) prima di procedere con l'importazione.
La risposta
{
"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": []
}
Il parametro dryRun: true contrassegna un'esecuzione di sola validazione; in tal caso journalTransactionId è null. Un'importazione viene registrata nel registro di audit (audit log) come migration.imported con il medesimo riepilogo.
Dopo l'importazione
- Blocca i periodi precedenti alla data di transizione (
ledger/periods/lock) in modo che nulla venga registrato accidentalmente nello storico migrato. - Verifica il bilancio di verifica e lo stato patrimoniale alla data di transizione confrontandoli con i report di chiusura del vecchio sistema.
- Prosegui con il flusso normale: emetti fatture, importa gli estratti conto bancari, riconcilia i pagamenti. Le fatture aperte migrate si salderanno come qualsiasi altra fattura.
Cosa non copre l'importatore: le righe delle fatture e i registri IVA dei periodi passati (da conservare nel vecchio sistema o nel relativo archivio), lo storico delle paghe e dei salari e i documenti diversi dalle fatture (ordini, bolle di consegna, contratti).