Руководство по миграции из QuickBooks в Beancount
Этап 1: Экспорт данных из QuickBooks
Миграция данных за пять лет начинается с выгрузки всех записей из QuickBooks в удобном для использования формате. QuickBooks Desktop и QuickBooks Online имеют разные опции экспорта:
1.1 QuickBooks Desktop – Варианты экспорта
IIF (Intuit Interchange Format): QuickBooks Desktop может экспортировать списки (такие как план счетов, клиенты, поставщики) в текстовые файлы формата .IIF. В QuickBooks Desktop перейдите в Файл → Утилиты → Экспорт → Списки в IIF (File → Utilities → Export → Lists to IIF), затем выберите нужные списки (например, План счетов, Клиенты, Поставщики). В результате вы получите текстовый файл, содержащий названия счетов, их типы и данные из списков. IIF — это проприетарный, но текстовый формат, который относительно легко разобрать. Используйте его, чтобы получить ваш План счетов и списки контактов для дальнейшего использования в Beancount.
Главная книга/Журнал через CSV: Для экспорта транзакций QuickBooks Desktop не предоставляет полного экспорта в один клик, но можно использовать отчёты. Рекомендуемый метод — экспорт Главного журнала (всех транзакций) за желаемый период. В QuickBooks Desktop откройте Отчёты → Бухгалтер и налоги → Журнал (Reports → Accountant & Taxes → Journal), установите Даты с самой ранней транзакции до сегодняшнего дня и нажмите Экспорт → Excel. Сохраните результат как CSV, предварительно удалив все заголовки/подвалы отчёта и пустые столбцы. Убедитесь, что числовые данные чистые: содержат центы (например, 3.00, а не 3), без лишних кавычек, символов валют или двойных минусов в CSV. CSV-файл должен иметь столбцы, такие как Дата, № транз., Имя, Счёт, Заметка, Дебет, Кредит, Остаток (или один столбец "Сумма" в зависимости от формата отчёта).
Совет: QuickBooks Desktop 2015+ также может экспортировать транзакции через диалоговое окно Найти (Find). Используйте Правка → Найти → Расширенный поиск (Edit → Find → Advanced), установите диапазон дат на пять лет, а затем экспортируйте результаты в CSV. Предупреждение: Некоторые версии ограничивают экспорт 32 768 строками. Если у вас очень большой объём данных, экспортируйте по годам (или меньшими частями), чтобы избежать усечения, а затем объедините их. Убедитесь, что диапазоны дат не пересекаются, чтобы избежать дубликатов.
Другие форматы (QBO/QFX/QIF): QuickBooks Desktop может импортировать банковские транзакции через файлы .QBO (Web Connect) или .QFX/.OFX, но для экспорта из QuickBooks они обычно не используются. Если ваша цель — извлечь только банковские транзакции, они у вас уже могут быть в формате QBO/OFX от вашего банка. Однако для полного экспорта главной книги придерживайтесь IIF и CSV. QuickBooks Desktop не может напрямую экспортировать в QIF (Quicken Interchange Format) без сторонних инструментов. Если вы найдёте способ получить QIF, учтите, что некоторые инструменты для учёта (старые версии Ledger 2.x) могли читать QIF, но в нашем процессе лучше работать с CSV.
1.2 QuickBooks Online – Варианты экспорта
Встроенный экспорт в Excel/CSV: QuickBooks Online (QBO) предоставляет инструмент Экспорт данных. Перейдите в Настройки ⚙ → Инструменты → Экспорт данных (Settings ⚙ → Tools → Export Data). В диалоговом окне экспорта используйте вкладку Отчёты для выбора данных (например, Главная книга или Список транзакций) и вкладку Списки для списков (план счетов и т.д.), выберите Все даты и экспортируйте в Excel. QuickBooks Online загрузит ZIP-архив, содержащий несколько файлов Excel для выбранных отчётов и списков (например, Отчёт о прибылях и убытках, Балансовый отчёт, Главная книга, Клиенты, Поставщики, План счетов и т.д.). Затем вы можете преобразовать эти файлы Excel в CSV для обработки.
Отчёт о детализации транзакций: Если стандартный экспорт QBO не включает единый файл Главной книги, вы можете вручную создать детализированный отчёт:
- Перейдите в Отчёты и найдите Детализация транзакций по счетам (Transaction Detail by Account) или Главная книга (General Ledger) в некоторых версиях QBO.
- Установите Отчётный период на полный пятилетний диапазон.
- В опциях отчёта у становите Группировать по = Нет (чтобы отобразить отдельные транзакции без промежуточных итогов).
- Настройте столбцы, чтобы включить как минимум: Дату, Тип транзакции, Номер, Имя (Получатель/Клиент), Заметка/Описание, Счёт, Дебет, Кредит (или один столбец "Сумма") и Остаток. Включите класс или местоположение, если они используются.
- Сформируйте отчёт, а затем Экспортируйте в Excel.
Это даст детализированную главную книгу всех транзакций. Сохраните её как CSV. Каждая строка будет представлять одну проводку транзакции. Позже вам нужно будет сгруппировать строки по транзакциям для конвертации.
План счетов и другие списки: QuickBooks Online может экспортировать план счетов через Учёт → План счетов → Пакетные действия → Экспорт в Excel (Accounting → Chart of Accounts → Batch Actions → Export to Excel). Сделайте это, чтобы получить названия и типы счетов. Аналогично, экспортируйте Клиентов, Поставщиков и т.д., если хотите перенести имена для метаданных.
QuickBooks Online API (Необязательно): Для программного подхода Intuit предоставляет REST API для данных QBO. Продвинутые поль зователи могут создать приложение QuickBooks Online (требуется аккаунт разработчика) и использовать API для получения данных в формате JSON. Например, вы можете запросить эндпоинт Account для плана счетов и эндпоинты отчётов JournalEntry или GeneralLedger для транзакций. Существуют Python SDK, такие как python-quickbooks, которые являются обёртками над API. Однако использование API включает в себя аутентификацию по OAuth и является излишним для одноразовой миграции, если вы не предпочитаете автоматизацию. В большинстве случаев ручной экспорт в CSV/Excel проще и менее подвержен ошибкам.
Этап 2: Трансформация и очистка данных
Когда у вас есть данные из QuickBooks в формате CSV (и/или IIF), следующий шаг — преобразовать их в текстовый формат главной книги Beancount. Это включает разбор экспортированных файлов, сопоставление счетов QuickBooks с планом счетов Beancount и форматирование транзакций в синтаксисе Beancount.
2.1 Разбор экспортов из QuickBooks с помощью Python
Использование Python обеспечит точность и воспроизводимость трансформации. Мы наметим скрипты для двух ключевых задач: импорт плана счетов и конвертация транзакций.
Импорт и сопоставление счетов: Крайне важно настроить ваши счета в Beancount перед добавлением транзакций. Счета QuickBooks имеют типы (Банк, Дебиторская задолженность, Расходы и т.д.), которые мы сопоставим с иерархией Beancount (Активы, Обязательства, Доходы, Расходы и т.д.). Например, мы можем использовать такое сопоставление:
# Сопоставление типа счёта QuickBooks с корневой категорией Beancount
AccountTypeMap = {
'BANK': 'Assets',
'CCARD': 'Liabilities',
'AR': 'Assets', # Дебиторская задолженность как актив
'AP': 'Liabilities', # Кредиторская задолженность как обязательство
'FIXASSET': 'Assets',
'OASSET': 'Assets', # Прочие активы
'OCASSET': 'Assets', # Прочие оборотные активы
'LTLIAB': 'Liabilities', # Долгосрочные обязательства
'OCLIAB': 'Liabilities', # Прочие текущие обязательства
'EQUITY': 'Equity',
'INC': 'Income',
'EXP': 'Expenses',
'EXINC': 'Income', # Прочие доходы
'EXEXP': 'Expenses', # Прочие расходы
}
Используя экспорт IIF из QuickBooks Desktop или CSV-файл со списком счетов из QBO, мы получаем имя и тип каждого счёта. Затем:
-
Создайте имена счетов Beancount: QuickBooks иногда использует двоеточия (
:) в именах счетов для обозначения субсчетов (например, "Current Assets:Checking"). Beancount использует ту же нотацию с двоеточием для иерархии. Часто можно использовать имя напрямую. Если имена счетов QuickBooks не начинаются с категории, добавьте сопоставленную категорию в начало. Например, счёт QuickBooks типаBANKс названием "Checking" станетAssets:Checkingв Beancount. СчётEXP(расход) "Meals" станетExpenses:Mealsи т.д. -
Обеспечьте корректность именования: Удалите или замените любые символы, которые могут сбить Beancount с толку. QuickBooks допускает символы вроде
&или/в именах. Разумно вырезать или заменить специальные символы (например, заменить&наand, удалить слэши или пробелы). Также убедитесь, что все имена счетов уникальны после трансформации – QuickBooks мог позволять одинаковые имена субсчетов у разных родительских счетов, что нормально, но в Beancount полное имя (с родителями) должно быть уникальным. При необходимости переименуйте или добавьте квалификатор для их р азличения. -
Выведите открытия счетов: В Beancount каждый используемый счёт должен быть открыт с помощью директивы
open. Вы можете выбрать дату до вашей первой транзакции (например, если вы мигрируете данные за 2019–2023 годы, используйте2018-12-31или даже более раннюю дату для всех открытий). Скрипт запишет строки вида:2018-12-31 open Assets:Checking USD2018-12-31 open Expenses:Meals USDдля каждого счёта (предполагая, что основная валюта — USD). Используйте соответствующую валюту для каждого счёта (см. заметки о мультивалютности ниже).
Конвертация транзакций: Основная задача — преобразовать экспорт транзакций QuickBooks (CSV) в записи Beancount. Каждая транзакция QuickBooks (счёт-фактура, счёт, чек, журнальная запись и т.д.) может иметь несколько проводок (строк), которые необходимо собрать в одну транзакцию Beancount.
Мы будем использовать CSV-ридер Python для итерации по экспортированным строкам и накопления проводок:
import csv
from collections import defaultdict
# Чтение всех строк из CSV-файла журнала QuickBooks
rows = []
with open('quickbooks_exported_journal.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for line in reader:
rows.append(line)
# Группировка строк по транзакциям (предполагая, что 'Trans #' идентифицирует транзакции)
transactions = defaultdict(list)
for line in rows:
trans_id = line.get('Trans #') or line.get('Transaction ID') or line.get('Num')
transactions[trans_id].append(line)
Теперь transactions — это словарь, где каждый ключ — это ID/номер транзакции, а значение — список проводок для этой транзакции. Далее мы конвертируем каждую группу в формат Beancount:
def format_date(qb_date):
# Даты в QuickBooks могут быть в формате "12/31/2019"
m, d, y = qb_date.split('/')
return f"{y}-{int(m):02d}-{int(d):02d}"
output_lines = []
for trans_id, splits in transactions.items():
# Сортировка проводок по порядку строк, если необходимо (обычно они уже упорядочены)
splits = sorted(splits, key=lambda x: x.get('Line') or 0)
first = splits[0]
date = format_date(first['Date'])
payee = first.get('Name', "").strip()
memo = first.get('Memo', "").strip()
# Заголовок транзакции
output_lines.append(f"{date} * \"{payee}\" \"{memo}\"")
if first.get('Num'): # включаем номер ссылки, если доступен
output_lines.append(f" number: \"{first['Num']}\"")
# Цикл по каждой проводке/постингу
for split in splits:
acct_name = split['Account'].strip()
# Сопоставляем имя счёта QuickBooks со счётом Beancount (используя предыдущее сопоставление)
beancount_acct = account_map.get(acct_name, acct_name)
# Определяем сумму со знаком:
amount = split.get('Amount') or ""
debit = split.get('Debit') or ""
credit = split.get('Credit') or ""
if amount:
# Некоторые экспорты имеют один столбец Amount (отрицательный для кредитов)
amt_str = amount
else:
# Если отдельные столбцы Debit/Credit
amt_str = debit if debit else f"-{credit}"
# Для безопасности удаляем все запятые в числах
amt_str = amt_str.replace(",", "")
# Добавляем валюту
currency = split.get('Currency') or "USD"
amt_str = f"{amt_str} {currency}"
# Заметка/описание для проводки
line_memo = split.get('Memo', "").strip()
comment = f" ; {line_memo}" if line_memo else ""
output_lines.append(f" {beancount_acct:<40} {amt_str}{comment}")
# Конец транзакции – пустая строка
output_lines.append("")
Эта логика скрипта выполняет следующее:
-
Форматирует дату в YYYY-MM-DD для Beancount.
-
Использует получателя (Name) и заметку (Memo) для описания транзакции. Например:
2020-05-01 * "ACME Corp" "Оплата счёта-фактуры"(Если получателя нет, можно использовать Тип транзакции из QuickBooks или оставить кавычки пустыми). -
Добавляет метаданные
number, если есть номер ссылки (№ чека, № счёта-фактуры и т.д.). -
Итерирует по каждой строке проводки:
- Сопоставляет имя счёта QuickBooks со счётом Beancount, используя словарь
account_map(заполненный на шаге с планом счетов). - Определяет сумму. В зависимости от вашего экспорта, у вас может быть один столбец Сумма (с положительными/отрицательными значениями) или отдельные столбцы Дебет и Кредит. Приведённый выше код обрабатывает оба случая. Он гарантирует, что кредиты представляются как отрицательные суммы для Beancount (так как в Beancount для каждой проводки используется одно число со знаком).
- Прикрепляет валюту (предполагая USD, если не указан другой столбец с валютой).
- Записывает строку проводки Beancount со счётом, су ммой и комментарием с заметкой из строки. Например:
Assets:Checking 500.00 USD ; ДепозитIncome:Sales -500.00 USD ; ДепозитЭто отражает депозит в $500 (с Доходов на Расчётный счёт).
- Сопоставляет имя счёта QuickBooks со счётом Beancount, используя словарь
-
После перечисления всех проводок пустая строка разделяет транзакции.
Обработка мультивалютности: Если ваши данные в QuickBooks включают несколько валют, указывайте код валюты в каждой проводке (как показано выше). Убедитесь, что счета в иностранных валютах открыты с этой валютой. Например, если у вас есть банковский счёт в EUR, вы должны вывести open Assets:Bank:Checking EUR, и транзакции на этом счёте будут использовать EUR. Beancount поддерживает мультивалютные главные книги и будет отслеживать неявные конвертации, но вам может понадобиться добавить записи о ценах для курсов обмена, если вы хотите конвертировать в базовую валюту в отчётах. Также рекомендуется объявить вашу основную операционную валюту вверху файла Beancount (например, option "operating_currency" "USD").
Запуск конвертации: Сохраните скрипт Python (например, как qb_to_beancount.py) и запустите его на ваших экспортированных файлах. Он должен создать файл .beancount, содержащий все счета и транзакции.
2.2 Обработка крайних случаев и очистка данных
Во время трансформации помните об этих распространённых подводных камнях и способах их решения:
-
Несоответствия в названиях счетов: В QuickBooks могут быть имена счетов, которые конфликтуют с иерархическими именами Beancount. Например, в QuickBooks могут быть два разных родительских счёта, у каждого из которых есть субсчёт с названием "Страхование". В Beancount
Expenses:Insuranceдолжно быть уникальным. Решите это, переименовав один из них (например, "Страхование-Автомобиль" против "Страхование-Здоровье") перед экспортом или сопоставьте их с уникальными счетами Beancount в вашем скрипте. Последовательные соглашения об именах (без специальных символов и с использованием иерархии) с экономят вам головную боль. При необходимости используйте подход с файлом пересопоставления: ведите CSV или словарь "старое имя → новое имя Beancount" и применяйте его во время конвертации (наш пример кода используетaccount_mapи мог бы загружать переопределения из файла). -
Даты и форматы: Убедитесь, что все даты отформатированы последовательно. Приведённый выше скрипт нормализует M/D/Y в формат ISO. Также следите за проблемами с финансовым и календарным годом, если ваш пятилетний период пересекает конец года. Beancount не волнуют границы финансового года, но позже вы можете захотеть разделить файлы по годам для удобства.
-
Числовая точность: QuickBooks обрабатывает валюту с центами, поэтому работа в центах обычно подходит. Все суммы в идеале должны иметь два десятичных знака в CSV. Если какие-то суммы превратились в целые числа (без десятичной части) или содержат запятые/скобки (для отрицательных чисел), очистите их в скрипте (удалите запятые, преобразуйте
(100.00)в-100.00и т.д.). Экспорт в CSV, если он выполнен правильно (согласно инструкциям), должен был уже избежа ть этих проблем с форматированием. -
Отрицательные суммы и знаки: Отчёты QuickBooks иногда показывают отрицательные числа как
-100.00,(100.00)или даже--100.00в некоторых экспортах в Excel. Шаг очистки должен справиться с этим. Убедитесь, что дебеты и кредиты каждой транзакции в сумме дают ноль. Beancount будет это проверять (если не сбалансировано, он выдаст ошибку при импорте). -
Дубликаты транзакций: Если вам пришлось экспортировать транзакции частями (например, по годам или по счетам), будьте осторожны при их объединении, чтобы избежать пересечений. Проверьте, что первая транзакция года не является также последней из предыдущей партии и т.д. Легко случайно продублировать несколько транзакций на границах. Если вы подозреваете дубликаты, вы можете отсортировать итоговые записи Beancount по дате и поискать идентичные записи, или использовать уникальные теги транзакций Beancount для их отлова. Одна из стратегий — включить номера транзакций QuickBooks в метаданные (например, использовать
Trans #или номер счёта-фактуры как тегtxnили метаданныеquickbooks_id), а затем убедиться в отсутствии дубликатов этих ID. -
Несбалансированные проводки / Временные счета: В QuickBooks могут быть странные случаи, например, транзакция с дисбалансом, который QuickBooks автоматически скорректировал на счёт "Начальный капитал" или "Нераспределённая прибыль". Например, при настройке начальных остатков счетов QuickBooks часто проводит разницы на счёт Капитала. Они появятся в экспортированных транзакциях. Beancount потребует явной балансировки. Вам может понадобиться ввести счёт Капитала для начальных остатков (обычно
Equity:Opening-Balances), чтобы отразить логику QuickBooks. Хорошей практикой является создание записи о начальных остатках в первый день вашей главной книги, которая устанавливает стартовые балансы всех счетов (см. Этап 5). -
Крайние случаи с мультивалютностью: При использовании нескольких валют экспорт из QuickBooks может перечислять все суммы в домашней валюте или в их родной валюте. В идеале, получите данные в родной валюте для каждого счёта (отчёты QuickBooks Online обычно так и делают). В Beancount каждая проводка несёт в себе валюту. Если QuickBooks предоставил курсы об мена или конвертацию в домашнюю валюту, вы можете проигнорировать их и полагаться на записи о ценах в Beancount. Если QuickBooks не экспортировал курсы обмена, вы можете захотеть вручную добавить записи о ценах (например, используя директиву
priceв Beancount) для ключевых дат, чтобы соответствовать оценке. Однако для базовой целостности главной книги достаточно, чтобы транзакции сходились в своих исходных валютах – нереализованные прибыли/убытки не нужно явно записывать, если вы не хотите получить те же отчёты. -
Дебиторская / Кредиторская задолженность: QuickBooks отслеживает детали счетов-фактур и счетов (сроки оплаты, статус оплаты и т.д.), которые не будут полностью перенесены в простую главную книгу. Вы получите транзакции по дебиторской и кредиторской задолженности (счета-фактуры увеличивают ДЗ, платежи уменьшают ДЗ и т.д.), но не документы счетов-фактур или балансы клиентов по счетам. В результате после миграции вы должны проверить, что балансы ваших счетов ДЗ и КЗ в Beancount равны открытым остаткам клиентов/поставщиков в QuickBooks. Если вам нужно отслеживать счета-фактуры, вы можете использовать метаданные Beancount (например, включить тег
invoiceили ссылку). Номера счетов-фактур из QuickBooks должны были перейти в поляNumилиMemo– наш скрипт сохраняетNumкакnumber: "..."в метаданных транзакции. -
Неактивные или закрытые счета: Экспорт IIF может включать неактивные счета (если вы выбрали их включение). Их можно импортировать (у них просто не будет транзакций и будет нулевой баланс, если они действительно неактивны). Вы можете пометить их как закрытые в Beancount после даты последней транзакции с помощью директивы
close. Это поддерживает порядок в вашей главной книге. Например:2023-12-31 close Expenses:OldAccount ; закрыт после миграцииЭто необязательно и в основном для чистоты.
Тщательно очистив и сопоставив данные, как описано выше, вы получите файл главной книги Beancount, который структурно отражает ваши данные из QuickBooks. Следующий шаг — убедиться, что он также численно отражает QuickBooks.
Этап 3: Проверка и сверка данных
Проверка — это критически важный этап в миграции бухгалтерских данных. Нам нужно убедиться, что главная книга Beancount совпадает с книгами QuickBooks до копейки. Для этого можно использовать несколько стратегий и инструментов:
3.1 Сверка по оборотно-сальдовой ведомости
Оборотно-сальдовая ведомость — это отчёт, в котором перечислены конечные остатки по всем счетам (с указанием дебетов и кредитов или положительных/отрицательных значений), и который должен сходиться к нулю. Запуск оборотно-сальдовой ведомости в обеих системах на одну и ту же дату — самый быстрый способ подтвердить общую точность.
-
В QuickBooks: Запустите отчёт Оборотно-сальдовая ведомость (Trial Balance) на последний день последнего года (например, 31 декабря 2023 года). Этот отчёт показывает баланс каждого счёта. Экспортируйте его или запишите ключевые цифры.
-
В Beancount: Используйте отчётность Beancount для генерации оборотно-сальдовой ведомости. Один из простых способов — через командную строку:
bean-report migrated.beancount balancesОтчёт
balances— это оборотно-сальдовая ведомость, перечисляющая все счета и их остатки. Вы также можете открыть файл в Fava (веб-интерфейс Beancount) и посмотреть раздел Balances или Balance Sheet. Каждый остаток по счёту в Beancount должен совпадать с оборотно-сальдовой ведомостью QuickBooks. Например, если QuickBooks показывает Дебиторская задолженность = 5,000 (дебет). ЕслиДоход от продаж = 200,000 (кредит, что может отображаться как -200,000, если используется оборотно-сальдовая ведомость, представляющая кредиты как отрицательные числа).
Если есть расхождения, найдите их:
- Проверьте, не отсутствует ли целый счёт или не добавлен ли лишний (мы забыли счёт или включили тот, который был закрыт до периода миграции?).
- Если остаток не сходится, углубитесь: QuickBooks может запустить Быстрый отчёт по счёту (Account QuickReport) или детализацию главной книги для этого счёта, и вы можете сравнить это с регистром Beancount для этого счёта (
bean-report migrated.beancount register -a ИмяСчёта). Иногда различия возникают из-за пропущенной или дублирующейся транзакции.
Также проверьте, что сумма всех счетов равна нулю в оборотно-сальдовой ведомости Beancount (она выводит итог, который должен быть равен нулю или очень б лизок к нему). Beancount применяет двойную запись, поэтому если у вас есть ненулевой дисбаланс, это означает, что активы минус обязательства-капитал не сошлись к нулю, что указывает на проблему (которую QuickBooks обычно не допускает, но это может произойти, если некоторые данные были утеряны).
3.2 Сравнение остатков по счетам
Помимо оборотно-сальдовой ведомости, вы можете сравнить конкретные финансовые отчёты:
-
Балансовый отчёт: Запустите Балансовый отчёт в QuickBooks на конечную дату и балансовый отчёт в Beancount (
bean-report migrated.beancount balsheet). Это похоже на оборотно-сальдовую ведомость, но организовано по Активам, Обязательствам, Капиталу. Цифры должны совпадать по категориям. Для более детальной проверки сравните итоговые суммы по основным счетам: денежные средства, ДЗ, основные средства, кредиторская задолженность, капитал и т.д. -
Отчёт о прибылях и убытках: Зап устите Отчёт о прибылях и убытках за пятилетний период (или по годам) в QuickBooks и в Beancount (
bean-report migrated.beancount incomeдля отчёта о прибылях и убытках за весь период). Чистая прибыль из Beancount должна быть равна чистой прибыли из QuickBooks за каждый период. Если вы мигрировали все пять лет, совокупная чистая прибыль должна совпадать. Вы также можете сравнить отдельные итоговые суммы доходов и расходов, чтобы убедиться, что ни одна категория не была пропущена или продублирована. -
Выборочная проверка транзакций: Выберите несколько случайных транзакций (особенно из каждого года и каждого крупного счёта) и проверьте, что они мигрировали правильно. Например, найдите счёт-фактуру трёхлетней давности в QuickBooks, а затем найдите его сумму или заметку в файле Beancount (поскольку все транзакции текстовые, вы можете открыть файл
.beancountв текстовом редакторе или использовать инструменты поиска). Проверьте, что дата, суммы и счета совпадают. Это помогает выявить проблемы с форматированием дат или неправильно сопоставленные счета.