← Документація / Посібники
Міграція з іншої системи
Переносьте бухгалтерські дані компанії одним запитом: план рахунків, контрагентів, початкові сальдо або повну історію, відкриті рахунки-фактури, основні засоби та запаси.
Коли компанія переходіть на Nordlet з іншої бухгалтерської програми, її облік не починається з нуля. Імпортер історичних облікових даних збирає все, що залишилося в старій системі, і записує це одним викликом, в одній транзакції бази даних: якщо хоча б один рядок не проходить перевірку, нічого не зберігається. Той самий пакет спочатку можна надіслати на кінцеву точку (endpoint) лише для перевірки, яка виконує повну валідність і здійснює відкат (rollback).
POST /v1/migration/books/validate # перевіряє все, нічого не записує
POST /v1/migration/books/import # записує все або нічого
У веб-додатку є дві аналогічні кнопки в розділі Рахунок → Міграція (вставте JSON або завантажте файл). API-ключ потребує дозволу ledger:write разом із правами на запис для кожного включеного розділу (partners:write, catalog:write, sales:write, purchases:write, assets:write, inventory:write). Обидві кінцеві точки приймають тіла запитів обсягом до 32 МБ.
Дата переходу (cut-over date)
Оберіть дату переходу (cut-over date): перший день ведення обліку компанії в Nordlet. Усе, що було до неї, залишається в старій системі (або переноситься як історія, див. нижче); усе, починаючи з цього дня, вводиться в Nordlet через стандартні кінцеві точки. Усі суми в пакеті подаються станом «на день перед датою переходу»: закритий оборотно-сальдовий баланс (trial balance), неоплачені рахунки-фактури, запаси на складі та основні засоби на балансі.
Перед імпортом виконайте в Nordlet такі дії:
- Створіть компанію та застосуйте шаблон плану рахунків (
ledger/accounts/apply-template) або перелічіть рахунки, які вам потрібні, у розділіaccountsпакета. - Створіть принаймні один склад (
inventory/warehouses/create), якщо ви імпортуєте запаси. - Пропустіть пакет через
migration/books/validate, доки він не повідомить про відсутність помилок і доки ви не погодитеся з його попередженнями.
Пакет
Кожен розділ є опціональним; включайте лише ті, які маєте. Усі зв'язки між розділами здійснюються за кодом (код рахунку, код контрагента, код номенклатури, код групи основних засобів, код складу), причому код може посилатися або на запис, який уже існує в Nordlet, або на створений у попередньому розділі того самого пакета.
{
"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" }
]
}
Суми подаються у вигляді рядків з десятковою крапкою (decimal strings), як і скрізь в API. source - довільна мітка, яка потрапляє в опис транзакції початкового сальдо та в примітки мігрованих рахунків-фактур.
accounts
Рядки плану рахунків: code, name, type (asset, liability, equity, income, expense), необов'язкові поля parentCode та isPostable. Рахунки, які вже існують, не чіпають, і вони враховуються як existing. Використовуйте цей розділ, якщо план рахунків старої системи відрізняється від шаблону, або пропустіть його та застосуйте шаблон попередньо.
partners та items
Клієнти, постачальники та позиції каталогу, ключем для яких є code. У Литві кодом контрагента зазвичай є код реєстрації компанії; для фізичних осіб використовуйте будь-який унікальний у межах компанії код. Наявні коди пропускаються і не оновлюються. Для елементів номенклатури приймаються поля type (product або service), unit, barcode, vatRatePercent, salePriceExclVat, purchasePriceExclVat.
openingBalances
Закритий оборотно-сальдовий баланс старої системи, по одному рядку на рахунок: accountCode із зазначенням або debit, або credit. Рядки проводяться як одна журнальна транзакція з датою openingBalances.date (за замовчуванням відповідає даті переходу) і типом документа migration_opening. Рядки мають посилатися на рахунки, на які дозволено проведення (postable accounts).
Транзакція має бути збалансованою. Якщо оборотно-сальдовий баланс старої системи не збалансований через заокруглення, нерозподілений прибуток, який ніколи не списувався на власний капітал, або пропущений рахунок, вкажіть balancingAccountCode (зазвичай це нерозподілений прибуток, рахунок 3410 у литовському шаблоні), і різниця буде зарахована на нього; у відповіді ця сума зазначається як balancingAmount.
Для кожної компанії може існувати лише одна транзакція початкового сальдо. Другий імпорт із блоком openingBalances відхиляється (код помилки 409). Виправлення заднім числом виконуються звичайними ручними журналами транзакцій (ledger/journal/transactions/create); проведені транзакції є незмінними, тому оригінальний запис залишається у вигляді імпортованого.
journal - повна історія замість сальдо або на додачу до них
Якщо ви хочете перенести транзакції зі старої системи в Nordlet (щоб звіти за попередні періоди працювали коректно), передайте їх тут: по одному об'єкту на транзакцію з полями date, необов'язковими description та reference, а також масивом entries, що містить accountCode + debit/credit. Кожна транзакція має бути збалансована самостійно. Вони проводяться з типом документа migration.
Дати мають бути перед датою переходу. Якщо пакет також містить openingBalances, історія має датуватися на дату openingBalances.date або пізніше (типовий сценарій: сальдо на початок попереднього фінансового року плюс транзакції цього ж року, а дата переходу встановлюється на перший день поточного року). Не надсилайте початкові сальдо та історію за той самий період, інакше сальдо буде враховане двічі.
Кожен місяць, якого стосуються початкові сальдо або історія, має бути відкритим обліковим періодом (інакше повертається помилка 409).
openReceivables та openPayables
Рахунки-фактури, які станом на дату переходу залишалися неоплаченими (повністю або частково). Вони створюються як виставлені рахунки покупцям та зареєстровані рахунки постачальників із параметром paidAmount = grossTotal − outstanding, завдяки чому звірка банківських виписок (bank/transactions/match, bank/transactions/suggest-matches), звіт про старіння заборгованості (debt-aging report) та вебхуки платежів працюють із ними так само, як і з будь-якими іншими рахунками.
outstandingза замовчуванням дорівнюєgrossTotal;vatTotalза замовчуванням дорівнює0(сума без ПДВ розраховується автоматично).dueDateза замовчуванням дорівнює даті документа.currencyза замовчуванням відповідає валюті рахунків-фактур компанії. Для будь-якої валюти, що відрізняється від базової валюти компанії, обов'язковим є полеfxRate- кількість одиниць цієї валюти за 1 одиницю базової валюти за тим самим принципом, що і в решті API. Воно зберігається в рахунку-фактурі, щоб подальші платежі коректно розраховували реалізовану курсову різницю.- Номер рахунку покупцю (
number) є повним номером зі старої системи і має бути унікальним у межах компанії. Рахунки постачальників є унікальними в розрізі контрагента та поляdocumentNumber. - Рахунки-фактури не проводяться повторно: їх сальдо дебіторської/кредиторської заборгованості вже є частиною початкових сальдо. Вони пов'язані з транзакцією початкового сальдо, тому розділ
openPayablesвимагає наявностіopeningBalancesу тому самому пакеті. - Рядки рахунків-фактур не імпортуються; рахунок містить лише підсумки. Стара система залишається джерелом деталізації рядків і регістрів ПДВ за періоди до переходу.
Якщо стара система відстежувала сальдо клієнтів без відкритих документів, створіть по одному рахунку на кожного контрагента на суму сальдо (наприклад, з номером OB-301111222), щоб у майбутньому його можна було закрити (звільнити).
Нумерація продовжується. Якщо імпортований номер рахунку покупця має форму PREFIX-N, а його дата виставлення припадає на рік переходу, нумерація для цього префікса та року встановлюється на значення N + 1 (і ніколи не знижується). У відповіді наводиться список результуючих серій номерів numberSeries; для інших випадків налаштуйте серію самостійно через reference/series/create ({ documentType: "sale_invoice", prefix, year, startAt }).
assetGroups та fixedAssets
Основні засоби переносяться разом із накопиченою на поточний момент амортизацією: acquisitionCost, salvageValue, accumulatedDepreciation, depreciatedMonths та usefulLifeMonths (або значення за замовчуванням для групи). Розрахунок амортизації за прямолінійним методом (assets/depreciation/post) триває виходячи із залишкової вартості та кількості місяців, що залишилися. Об'єкти, чия накопичена амортизація вже дорівнює амортизованій вартості, створюються зі статусом fully_depreciated. Жодних проведень не створюється - первісна вартість та накопичена амортизація вже є частиною початкових сальдо.
Групи ідентифікуються за кодом (code) і потребують наявності assetAccountCode та depreciationAccountCode (рахунок витрат за замовчуванням - 6206).
stock
Залишки товарів на складах у розрізі номенклатури: itemCode, quantity, unitCost (собівартість одиниці в євро) та опціонально warehouseCode (за замовчуванням використовується склад за замовчуванням), а також lotNumber і expiryDate для товарів, що відстежуються за партіями або серійними номерами. Кожен рядок перетворюється на вхідний рух запасів (stock movement) із датою на день переходу та типом документа migration, а також створює шар FIFO за цією собівартістю. Жодних проведень не створюється - вартість запасів вже є частиною початкових сальдо.
Перевірки та попередження
Кінцева точка валідації повертає помилку 422 у разі відсутності рахунків, використання рахунків, на які заборонено проведення, незбалансованих транзакцій, невідомих кодів партнерів/товарів/груп/складів, дублювання кодів чи номерів усередині пакета, суми відкритих заборгованостей, що перевищують загальну вартість (gross), накопиченої амортизації, що перевищує вартість, яка підлягає амортизації, а також у разі відсутності курсів валют. Номери або коди, які вже існують у Nordlet, призводять до помилки 409.
Крім цього, обидві кінцеві точки порівнюють аналітичні обліки (sub-ledgers) із записами головної книги в межах того самого пакета та повертають розбіжності у вигляді warnings (попереджень), а не помилок:
- загальна сума
openReceivablesпорівняно зі сальдо на рахунку дебіторської заборгованості (правило проведенняsales.receivable, за замовчуванням2410); - загальна сума
openPayablesпорівняно зі сальдо на рахунку кредиторської заборгованості (purchases.payables,4430); - загальна вартість
stockпорівняно зі рахунком запасів (inventory.stock,2040); - у розрізі кожної групи основних засобів: первісна вартість активів порівняно з балансовим рахунком активів групи та їх накопичена амортизація порівняно з рахунком амортизації.
Попередження означає, що аналітичний облік та головна книга старої системи не збігаються. Виправте пакет (або свідомо прийміть цю різницю) перед виконанням імпорту.
Відповідь
{
"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 вказує на те, що це був тестовий прогін перевірки; у цьому випадку journalTransactionId має значення null. Сам імпорт записується в журнал аудит-логу (audit log) із подією migration.imported та аналогічним зведеним звітом.
Після імпорту
- Закрийте періоди до дати переходу (
ledger/periods/lock), щоб випадково не провести жодних операцій у мігровану історію. - Перевірте оборотно-сальдовий баланс та баланс станом на дату переходу порівняно із закритими звітами старої системи.
- Продовжуйте роботу у звичайному режимі: виставляйте рахунки, імпортуйте банківські виписки, згортайте платежі - мігровані відкриті рахунки закриваються так само, як і будь-які інші.
Чого імпортер не охоплює: рядки рахунків-фактур та регістри ПДВ минулих періодів (зберігайте їх у старій системі або її архіві), історію заробітної плати, а також документи, що не є рахунками-фактурами (замовлення, накладні, договори).