Nordlet

← Документация / Руководства

Перенос данных из другой системы

Перенос бухгалтерской базы компании за один запрос: план счетов, контрагенты, входящие сальдо или полная история, открытые счета, основные средства и складские остатки.

При переходе компании в Nordlet из другой учетной программы бухгалтерия не начинает работу с нуля. Модуль импорта исторических данных собирает все, что осталось от старой системы, и записывает это одним запросом в рамках одной транзакции базы данных: если хотя бы одна строка не пройдет проверку, в систему не будет записано ничего. Тот же пакет можно сначала запустить через эндпоинт проверки (check-only), который выполняет все валидации и выполняет откат изменений.

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)

Выберите дату перехода (cut-over date) - первый день ведения учета компании в Nordlet. Всё, что было до этой даты, остается в старой системе (или переносится как история, см. ниже); всё, что происходит начиная с этого дня, вносится в Nordlet через стандартные эндпоинты. Все суммы в пакете указываются «состояние на день перед датой перехода»: закрытый оборотно-сальдовый баланс, неоплаченные счета, остатки товаров на складе, основные средства на учете.

Перед выполнением импорта выполните следующие действия в Nordlet:

  1. Создайте компанию и примените шаблон плана счетов (ledger/accounts/apply-template) либо перечислите необходимые счета в разделе accounts пакета данных.
  2. Создайте хотя бы один склад (inventory/warehouses/create), если вы импортируете товарные остатки.
  3. Запустите пакет через 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" }
  ]
}

Суммы передаются в виде строк с десятичными знаками, как и везде в 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).

Проводка должна быть сбалансированной. Если сальдо в старой системе не сходится (округления, нераспределенная прибыль, которая никогда не закрывалась на капитал, пропущенный счет), укажите 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) и вебхуки платежей работают с ними так же, как и с любыми другими счетами.

  • Поле 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 для товаров, учитываемых по партиям или серийным номерам. Каждая строка преобразуется в приходное движение по складу с датой перехода, типом документа migration и инициализирует партию FIFO по указанной себестоимости. Проводки не создаются - стоимость запасов входит в состав входящего сальдо.

Проверки и предупреждения

Эндпоинт проверки возвращает ошибку 422 в следующих случаях: отсутствующие счета, счета без разрешения на проводки, несбалансированные операции, неизвестные коды контрагентов, номенклатуры, групп или складов, дублирующиеся коды или номера внутри пакета, сумма остатка, превышающая общую сумму, накопленная амортизация, превышающая амортизируемую стоимость, а также отсутствие курсов обмена валют. Коды или номера, которые уже существуют в 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), чтобы случайно не провести операции в перенесенную историю.
  • Сверьте оборотно-сальдовую ведомость и баланс по состоянию на дату перехода с отчетами о закрытии периода из старой системы.
  • Продолжайте работу в стандартном режиме: выставляйте счета, импортируйте банковские выписки, сопоставляйте платежи - перенесенные открытые счета погашаются точно так же, как и любые другие.

Что не входит в возможности импорта: строки счетов и регистры НДС за прошлые периоды (храните их в старой системе или ее архиве), история начислений заработной платы, а также любые документы, кроме счетов (заказы, накладные, договоры).