Перейти до основного контенту
База знань · виробничий облік USD41,42 ПДВ20% МЗП8 000

Облік · Просунутий

Курсові різниці на дату балансу — як їх рахує Odoo

Перерахунок монетарних статей у валюті на 31 число за курсом НБУ. Що таке монетарна стаття за П(С)БО 21, які рахунки переоцінюються, як працює Currency Revaluation в Odoo і які типові граблі чекають при першому закритті.

Час
35 хв читання, 30 хв на сам перерахунок
Модуль Odoo
Accounting → Operations → Unrealized Currency Gains/Losses
Читання
~10 хв
  • курсові різниці
  • П(С)БО 21
  • НБУ
  • currency revaluation
  • валютні рахунки
  • 362
  • 316

Наприкінці місяця у вас на балансі лежать валютні залишки, дебіторка й кредиторка в USD чи EUR — а курс НБУ за місяць зрушив. Поки ви їх не перерахуєте за курсом на 31-ше число, баланс показує валютні активи й зобов’язання в застарілій гривневій оцінці. Тут ви проженете в Odoo переоцінку монетарних статей, визнаєте курсові різниці доходом чи витратою періоду — і не зачепите аванси, які за П(С)БО 21 лишаються за історичним курсом. Головна пастка чекає саме на авансах і на поділі операційних курсових від фінансових, тож пройдемо це покроково.

Результат

Після цієї процедури:

  • Усі монетарні статті у валюті (валютні рахунки в банку, валютна дебіторка/кредиторка, валютні позики) на 31-ше число перераховані за курсом НБУ на дату балансу.
  • Курсові різниці визнані доходом (714/744) або витратою (945/974) періоду — операційні окремо від неопераційних.
  • Немонетарні статті у валюті (наприклад, аванси за товар чи запаси, оплачені в EUR) не переоцінюються — лежать за історичним курсом.
  • Баланс на 31-ше показує реальну гривневу оцінку валютних активів і зобов’язань.

Передумови

  • Odoo 17/18 з налаштованим multi-currency (Settings → Accounting → Multi-Currency).
  • На res.company.currency_id стоїть UAH.
  • currency_provider = 'nbu', cron Update Currency Rate запускається щодня без помилок.
  • У res.currency.rate є курси за всі дні місяця (особливо 31-ше — критично).
  • На кожному валютному рахунку плану (362, 316, 314, валютні субрахунки 632) у account.account стоїть currency_id = USD/EUR або False для multi.
  • У налаштуваннях компанії заповнені поля:
    • income_currency_exchange_account_id — рахунок 714 (доходи від операційних курсових).
    • expense_currency_exchange_account_id — рахунок 945 (втрати від операційних курсових).
    • Окремо для неопераційних — 744 і 974.

Як це зробити

1. Розберіться, що переоцінюється, а що ні

Це базове правило, без якого Odoo налаштувати правильно неможливо. Сила законуП(С)БО 21 ділить статті у валюті на дві категорії.

Монетарні статті — переоцінюються на кожну дату балансу.

Це права отримати або обов’язки сплатити фіксовану суму грошей. Конкретно:

  • 314 — Поточний рахунок в іноземній валюті.
  • 316 — Спеціальні рахунки в іноземній валюті.
  • 312 — Поточний рахунок в банку за межами України.
  • 302 — Готівка в іноземній валюті (каса).
  • 362 — Розрахунки з покупцями у валюті (валютна дебіторка).
  • 632 (валютний субрахунок) — Розрахунки з постачальниками у валюті (валютна кредиторка).
  • 506 / 507 — Інші довгострокові позики у валюті.
  • 602 / 612 — Короткострокові кредити банків у валюті.

Немонетарні статті — НЕ переоцінюються.

Це активи й зобов’язання, які стануть товаром/послугою, а не грошима. Конкретно:

  • 371 (аванси видані постачальникам у валюті за товар) — лежать за курсом на дату перерахування.
  • 681 (аванси одержані від покупців у валюті) — лежать за курсом на дату отримання.
  • 201, 281 (запаси, оприбутковані у валютних інвойсах) — за курсом на дату оприбуткування.
  • 152 (капінвестиції в обладнання, придбане за валюту) — за курсом на дату введення в експлуатацію.

Перша граблиця Odoo для українського обліку — саме 371 і 681 у валюті. За замовчуванням Odoo ставить на них currency_id і вмикає revaluation, тож переоцінює аванси як монетарні. За П(С)БО 21 це неправильно: аванс віддасться товаром, а не грошима. На 371 і 681 явно поставте currency_revaluation = False — або тримайте їх узагалі без currency_id, тоді Odoo сам виключить їх із переоцінки.

2. Перевірте курс НБУ на 31-ше число

Accounting → Configuration → Currencies → USD → Rates (або EUR). На 31 травня має бути запис з provider = NBU. Якщо немає:

  • Cron Update Currency Rate не пройшов — подивіться Settings → Technical → Scheduled Actions його лог.
  • Курс НБУ на 31-ше може бути взагалі відсутнім, якщо 31-ше — субота/неділя/свято. Тоді діє курс попереднього робочого дня. Положення про встановлення офіційного курсу, постанова НБУ № 309 від 12.11.2003 Завантажте курс п’ятниці вручну з полем name = 2026-05-31.

3. Запустіть Currency Revaluation

Accounting → Operations → Unrealized Currency Gains/Losses.

Вкажіть:

  • journal_id — Журнал «Курсові різниці» (заведіть окремий, тип general).
  • expense_provision_account_id — рахунок 945.
  • income_provision_account_id — рахунок 714.
  • Дата — 31.05.2026.

Натисніть «Adjust Balance». Odoo:

  1. Для кожного валютного рахунку (з currency_id ≠ False і currency_revaluation = True) обчислює:

    revalued_uah = amount_currency × rate_31_may current_uah = sum(debit) − sum(credit) diff = revalued_uah − current_uah

  2. Створює account.move з типом Misc на дату 31.05 з рядками для кожного рахунку, де diff ≠ 0.

  3. Для дебіторки в USD з ростом курсу (наприклад, з 41,2 до 41,8):

Дт 362 / Кт 714 — за різницею · ревальвація валютної дебіторки
  1. Для кредиторки в USD з ростом курсу (нам платити більше):
Дт 945 / Кт 632 — за різницею · девальвація валютних зобов'язань
  1. Для валюти на рахунку в банку з падінням курсу:
Дт 945 / Кт 314 — за різницею · втрати від падіння курсу залишку

4. Розділіть операційні і неопераційні курсові

Сила законуП(С)БО 21 п.8 ділить курсові на операційні (від основної діяльності) і неопераційні (від інвестиційної та фінансової). Це впливає на P&L:

  • Операційні курсові (з основної дебіторки/кредиторки, валютних залишків) → 714 / 945. У P&L це «Інші операційні доходи/витрати».
  • Неопераційні курсові (з кредитів, інвестиційних позик, депозитів) → 744 / 974. У P&L це «Фінансові доходи/витрати».

Odoo з коробки не розділяє — wizard кидає все на один pair 714 / 945. Тож або:

  • Варіант А. Запускаєте wizard двічі — окремо для операційних рахунків (362, 632, 314), окремо для фінансових (506, 602, 612). Перед другим запуском у налаштуваннях компанії тимчасово міняєте expense/income_currency_exchange_account_id на 974/744.
  • Варіант Б. Запускаєте один раз, потім ручкою переносите account.move.line з 714/945 на 744/974 за фінансовими рахунками. Через Misc move.

ТОВ «УкрПром-Тех» працює за Варіантом А — менше ручної роботи на місяць, чисто в обліковій політиці.

5. Перевірте, що ревальвація сторнується наступного періоду

Odoo має параметр currency_exchange_journal_id.refund_sequence і auto_reverseaccount.move курсових різниць має автоматично сторнуватися 1-го числа наступного місяця. Це щоб не задвоювати курсові: на 31-ше визнали різницю до балансу, 1-го сторнували, а реальна різниця визнається на дату фактичного руху коштів.

Перевірте: на account.move курсових різниць у полі auto_post = 'at_date', reversal_date = 2026-06-01. Якщо ні — встановіть руками.

6. Перевірте баланс після ревальвації

Через Reporting → Balance Sheet на 31.05.

  • Сума за 314 у гривні має дорівнювати amount_currency_USD × 41,80 (за останнім курсом НБУ).
  • Сума за 362 у гривні — те саме.
  • Сума за 632 у гривні — те саме.
  • Аванси на 371/681 — лишаються за історичним курсом, не за курсом 31-го.

Якщо щось не сходиться — або revaluation не пройшов по всіх рахунках, або хтось ставить currency_revaluation = False на монетарний рахунок (або True на немонетарний — і Odoo переоцінив 371, як буває).

Перевірка

  • Курс НБУ на 31-ше число завантажено в res.currency.rate (для робочого дня — за фактом, для вихідного — за попередньою п’ятницею).
  • На 371, 681, 201, 281 у плані рахунків currency_revaluation = False (або currency_id = False).
  • На 314, 316, 362, 632 (валютному), 506, 602 у плані рахунків — currency_id = USD/EUR і currency_revaluation = True.
  • Заведений окремий журнал «Курсові різниці» з auto_reverse = True і reversal_date = 01.06.2026.
  • Запущено wizard Unrealized Currency Gains/Losses на 31.05.
  • Операційні курсові пішли на 714 / 945, неопераційні — на 744 / 974.
  • Гривнева оцінка валютних залишків у Balance Sheet = amount_currency × rate_31_may.
  • Створений account.move ревальвації має reversal_move_id на 01.06.

Якщо щось пішло не так

Wizard не створив жодного account.move. Найімовірніше, на валютних рахунках стоїть currency_revaluation = False за замовчуванням після міграції. Перевірте через Accounting → Configuration → Chart of Accounts → 314 → дивитись поле. Або курс на 31-ше = курсу попереднього перерахунку — тоді diff = 0 і Odoo нічого не створює (нормально).

Wizard переоцінив 371 (аванси у валюті) — а не повинен був. Тимчасово на 371 стояло currency_id, бо хтось завів партнера як USD-постачальника без розділення «авансу» і «розрахунків». Виправте: currency_revaluation = False на 371, сторнуйте помилкову проводку, повторно запустіть.

Курс НБУ на 31-ше — субота. Cron взяв курс п’ятниці, але присвоїв йому дату суботи. Це коректно для постанови НБУ № 309 (вихідні = курс попереднього робочого дня). Перевірте name = 2026-05-31, rate = 41,80 — це і є офіційний курс на 31-ше.

Ревальвація створила проводку, але на наступний місяць вона не сторнувалась. На account.journal не виставлено auto_reverse. Виправте налаштування і вручну створіть зворотній move на 01.06 (через Action → Reverse Entries). Альтернативно — встановіть reversal_date на ручному проведенні account.move.

Операційні і фінансові курсові злилися на 714/945. За одне закриття — переживете, перенесіть ручкою на 744/974 з тим самим datum 31.05. На наступне закриття — окремо запускайте wizard з тимчасово зміненими expense/income_currency_exchange_account_id.

Експорт у валюті: ПЗ декларуються за курсом МД, а курсові обліку — за курсом 31-го. Не плутайте. Курс МД фіксує ПДВ-зобов’язання для декларації (за ПКУ 187.1). Курсові різниці на 362 рахуються від курсу інвойсу до курсу 31-го. Це різні курси, різні проводки. Деталі — у статті Експорт ГП із 0%.

На 506 (валютний кредит) курсова за весь рік накопичилась до 1,2 млн ₴ збитку. Чи це нормально? Так, це механізм: кредит у валюті — це «зашита» курсова експозиція. Якщо гривня ослабла на 10% — ваше зобов’язання збільшилось на 10% у гривневому еквіваленті, і це зараз визнається як збиток у P&L (974). Управлінсько — це повідомлення про FX-ризик, який треба хеджувати. Інакше курсові «з’їдять» прибуток від основної діяльності.

Дотичне