Merge pull request 'feat(seed): полный план счетов 1С (488 строк)' (#25) from feat/23-chart-seed-1c into main
Reviewed-on: #25
This commit is contained in:
commit
dd8bae9952
110
api/scripts/convert_chart_1c.py
Normal file
110
api/scripts/convert_chart_1c.py
Normal file
@ -0,0 +1,110 @@
|
||||
"""Одноразовый конвертер плана счетов 1С (xlsx) в `seed/core/chart_of_accounts.csv` (issue #23).
|
||||
|
||||
Источник — `fixtures/directories/chart-of-accounts-1c.xlsx` (данные, не код). Колонки ищутся по заголовкам:
|
||||
«Код счета», «Наименование счета», «Вид» (А/П/АП), «Заб.» (Да/Нет). Порядок строк — как в выгрузке.
|
||||
|
||||
ASSUMPTION(OQ-113): выгрузка считается полным планом счетов заказчика.
|
||||
|
||||
Запуск (из `arm-core/api`)::
|
||||
|
||||
.venv/bin/python -I -m scripts.convert_chart_1c <chart-of-accounts-1c.xlsx> <chart_of_accounts.csv>
|
||||
|
||||
`-I` отключает подхват кода из текущего каталога; пути — абсолютные.
|
||||
"""
|
||||
|
||||
import csv
|
||||
import sys
|
||||
from collections.abc import Iterable, Mapping
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
from openpyxl import load_workbook
|
||||
|
||||
CSV_COLUMNS = ["code", "parent_code", "name", "kind", "row_type", "is_off_balance"]
|
||||
KIND_BY_1C = {"А": "A", "П": "P", "АП": "AP"} # кириллица, как в выгрузке
|
||||
ROW_TYPE_BY_DEPTH = ("account", "subaccount", "analytic")
|
||||
HEADERS = {"code": "Код счета", "name": "Наименование счета", "kind": "Вид", "off_balance": "Заб."}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ChartRow:
|
||||
code: str
|
||||
parent_code: str
|
||||
name: str
|
||||
kind: str
|
||||
row_type: str
|
||||
is_off_balance: bool
|
||||
|
||||
|
||||
def convert(records: Iterable[Mapping[str, object]]) -> list[ChartRow]:
|
||||
"""Строки выгрузки (словари по заголовкам) -> строки seed; иерархия — по структуре кода."""
|
||||
raw = [
|
||||
(
|
||||
str(r[HEADERS["code"]]).strip(),
|
||||
" ".join(str(r[HEADERS["name"]]).split()),
|
||||
str(r[HEADERS["kind"]]).strip(),
|
||||
str(r[HEADERS["off_balance"]]).strip(),
|
||||
)
|
||||
for r in records
|
||||
]
|
||||
codes = [code for code, *_ in raw]
|
||||
known = set(codes)
|
||||
if len(known) != len(codes):
|
||||
raise ValueError("в выгрузке повторяются коды счетов")
|
||||
rows: list[ChartRow] = []
|
||||
for code, name, kind_1c, off_balance in raw:
|
||||
if kind_1c not in KIND_BY_1C:
|
||||
raise ValueError(f"{code}: неизвестный вид «{kind_1c}» (ожидались А, П, АП)")
|
||||
if off_balance not in ("Да", "Нет"):
|
||||
raise ValueError(f"{code}: «Заб.» должно быть Да или Нет, получено «{off_balance}»")
|
||||
if not name:
|
||||
raise ValueError(f"{code}: пустое наименование")
|
||||
depth = code.count(".")
|
||||
if depth >= len(ROW_TYPE_BY_DEPTH):
|
||||
raise ValueError(f"{code}: глубина кода больше {len(ROW_TYPE_BY_DEPTH) - 1} точек")
|
||||
parent = code.rsplit(".", 1)[0] if depth else ""
|
||||
if parent and parent not in known:
|
||||
# Сирота: родителя нет в выгрузке (например, «Я68.01» без «Я68») — родителей не выдумываем,
|
||||
# но предков выше быть не должно, иначе иерархия в выгрузке неполная
|
||||
ancestors = {code.rsplit(".", i)[0] for i in range(2, depth + 1)}
|
||||
if ancestors & known:
|
||||
raise ValueError(f"{code}: нет родителя «{parent}», но есть более дальний предок")
|
||||
parent = ""
|
||||
rows.append(ChartRow(code, parent, name, KIND_BY_1C[kind_1c], ROW_TYPE_BY_DEPTH[depth], off_balance == "Да"))
|
||||
return rows
|
||||
|
||||
|
||||
def read_xlsx(path: Path) -> list[dict[str, object]]:
|
||||
"""Первый лист: заголовки — первая строка, колонки ищутся по названию."""
|
||||
workbook = load_workbook(path, read_only=True, data_only=True)
|
||||
try:
|
||||
lines = list(workbook.worksheets[0].iter_rows(values_only=True))
|
||||
finally:
|
||||
workbook.close()
|
||||
header = [str(cell).strip() if cell is not None else "" for cell in lines[0]]
|
||||
missing = [title for title in HEADERS.values() if title not in header]
|
||||
if missing:
|
||||
raise ValueError(f"в выгрузке нет колонок: {', '.join(missing)}")
|
||||
return [dict(zip(header, line, strict=False)) for line in lines[1:] if any(cell is not None for cell in line)]
|
||||
|
||||
|
||||
def write_csv(rows: Iterable[ChartRow], path: Path) -> None:
|
||||
with path.open("w", encoding="utf-8", newline="") as stream:
|
||||
writer = csv.writer(stream, lineterminator="\n")
|
||||
writer.writerow(CSV_COLUMNS)
|
||||
for r in rows:
|
||||
writer.writerow(
|
||||
[r.code, r.parent_code, r.name, r.kind, r.row_type, "true" if r.is_off_balance else "false"]
|
||||
)
|
||||
|
||||
|
||||
def main(argv: list[str]) -> int:
|
||||
if len(argv) != 3: # noqa: PLR2004
|
||||
print(__doc__, file=sys.stderr)
|
||||
return 2
|
||||
write_csv(convert(read_xlsx(Path(argv[1]))), Path(argv[2]))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main(sys.argv))
|
||||
@ -144,22 +144,36 @@ def _load_role_permissions(
|
||||
|
||||
|
||||
CHART_COLUMNS = ["code", "parent_code", "name", "kind", "row_type", "is_off_balance"]
|
||||
#: нормализованный код: NN или NNN (забалансовый), NN.MM, NN.MM.K (K без ведущего нуля: 76.07.1, как в ТЗ; 60.1 — нет)
|
||||
_ACCOUNT_CODE = re.compile(r"^\d{2,3}(\.\d{2}(\.[1-9]\d?)?)?$")
|
||||
#: нормализованный код. Цифровые: NN, NNN, NN.MM, NN.MM.K (K без ведущего нуля: 76.07.1, как в ТЗ; 60.1 — нет),
|
||||
#: буквенные субсчета: 01.К, 76.АВ, 62.ОТ.1, 99.02.И, 004.К. Буквенные корни плана 1С: МЦ, НЕ, ГТД, РВ.1, Я68.01 —
|
||||
#: буквы кириллицей, как в выгрузке 1С (issue #23, ASSUMPTION(OQ-113): выгрузка полна).
|
||||
_LETTER = "[А-ЯЁ]"
|
||||
_ANALYTIC = rf"(?:\.[1-9]\d?|\.{_LETTER})"
|
||||
_ACCOUNT_CODE = re.compile(
|
||||
rf"^(?:\d{{2,3}}(?:\.(?:\d{{2}}|{_LETTER}{{1,2}}){_ANALYTIC}?)?"
|
||||
rf"|(?:{_LETTER}{{2,3}}|Я\d{{2}})(?:\.(?:\d{{1,2}}|{_LETTER}{{1,2}}){_ANALYTIC}?)?)$"
|
||||
)
|
||||
_ROW_TYPE_BY_DEPTH = (AccountRowType.account, AccountRowType.subaccount, AccountRowType.analytic)
|
||||
_OFF_BALANCE_ROOTS = {f"{n:03d}" for n in range(1, 12)}
|
||||
_OFF_BALANCE_CODE_LENGTH = 3 # забалансовые счета — трёхзначные (001–011), балансовые синтетические — двузначные
|
||||
#: забалансовые счета 1С: 001–012 и буквенные корни (МЦ, НЕ, ГТД, ИНВ, КВ, ОТ, РВ, УСН); 000 и «Я…» — балансовые
|
||||
_OFF_BALANCE_DIGIT_ROOTS = {f"{n:03d}" for n in range(1, 13)}
|
||||
_LETTER_ROOT = re.compile(rf"^{_LETTER}{{2,3}}$")
|
||||
_THREE_DIGIT_ROOTS = {f"{n:03d}" for n in range(0, 13)}
|
||||
_OFF_BALANCE_CODE_LENGTH = 3 # трёхзначные корни — 000–012, балансовые синтетические — двузначные
|
||||
|
||||
|
||||
def _is_off_balance_root(root: str) -> bool:
|
||||
return root in _OFF_BALANCE_DIGIT_ROOTS or _LETTER_ROOT.match(root) is not None
|
||||
|
||||
|
||||
def _chart_row(row: dict[str | None, Any], where: str, code: str) -> AccountSeed:
|
||||
"""Проверка одной строки плана счетов, не требующая других строк."""
|
||||
where = f"{where} ({code})"
|
||||
if not _ACCOUNT_CODE.match(code):
|
||||
raise SeedError(f"{where}: код не нормализован, ожидается вид 60, 001, 60.01 или 76.07.1")
|
||||
raise SeedError(f"{where}: код не нормализован, ожидается вид 60, 001, 60.01, 76.07.1, 01.К или МЦ.04")
|
||||
root = code.split(".", maxsplit=1)[0]
|
||||
off_balance_root = len(root) == _OFF_BALANCE_CODE_LENGTH
|
||||
if off_balance_root and root not in _OFF_BALANCE_ROOTS:
|
||||
raise SeedError(f"{where}: трёхзначные коды допустимы только для 001–011")
|
||||
if len(root) == _OFF_BALANCE_CODE_LENGTH and root.isdigit() and root not in _THREE_DIGIT_ROOTS:
|
||||
raise SeedError(f"{where}: трёхзначные коды допустимы только для 000–012")
|
||||
off_balance_root = _is_off_balance_root(root)
|
||||
if root == "00":
|
||||
raise SeedError(f"{where}: счёта 00 не существует")
|
||||
kind_text = str(row["kind"]).strip()
|
||||
@ -186,7 +200,7 @@ def _chart_row(row: dict[str | None, Any], where: str, code: str) -> AccountSeed
|
||||
if off_balance_root and not is_off_balance:
|
||||
raise SeedError(f"{where}: забалансовый счёт должен иметь is_off_balance=true")
|
||||
if not off_balance_root and is_off_balance:
|
||||
raise SeedError(f"{where}: is_off_balance=true допустим только для счетов 001–011")
|
||||
raise SeedError(f"{where}: is_off_balance=true допустим только для счетов 001–012 и буквенных (МЦ, НЕ, ГТД…)")
|
||||
if row_type is AccountRowType.account and kind is None:
|
||||
raise SeedError(f"{where}: у синтетического счёта должен быть задан kind")
|
||||
name = str(row["name"]).strip()
|
||||
@ -196,6 +210,12 @@ def _chart_row(row: dict[str | None, Any], where: str, code: str) -> AccountSeed
|
||||
return AccountSeed(code, parent_text or None, name, kind, row_type, is_off_balance)
|
||||
|
||||
|
||||
def _has_ancestor(code: str, accounts: dict[str, AccountSeed]) -> bool:
|
||||
"""Есть ли в плане хотя бы один код-предок (по префиксу сегментов)."""
|
||||
parts = code.split(".")
|
||||
return any(".".join(parts[:n]) in accounts for n in range(1, len(parts)))
|
||||
|
||||
|
||||
def load_chart_of_accounts(core: Path, seed_dir: Path) -> dict[str, AccountSeed]:
|
||||
"""План счетов из `chart_of_accounts.csv` (UTF-8): проверка до записи, порядок файла сохраняется."""
|
||||
path = core / "chart_of_accounts.csv"
|
||||
@ -226,6 +246,8 @@ def load_chart_of_accounts(core: Path, seed_dir: Path) -> dict[str, AccountSeed]
|
||||
if account.parent_code != expected_parent:
|
||||
if expected_parent is None:
|
||||
raise SeedError(f"{where}: у синтетического счёта parent_code должен быть пустым")
|
||||
if account.parent_code is None and not _has_ancestor(code, accounts):
|
||||
continue # сирота выгрузки 1С («Я68.01» без «Я68»): родителей не выдумываем
|
||||
raise SeedError(f"{where}: родитель должен быть «{expected_parent}», указан «{account.parent_code or ''}»")
|
||||
if account.parent_code is not None and account.parent_code not in accounts:
|
||||
raise SeedError(f"{where}: родитель «{account.parent_code}» не найден в файле")
|
||||
|
||||
@ -1,123 +1,489 @@
|
||||
code,parent_code,name,kind,row_type,is_off_balance
|
||||
000,,Вспомогательный счет,AP,account,false
|
||||
01,,Основные средства,A,account,false
|
||||
01.01,01,Основные средства в организации,A,subaccount,false
|
||||
01.03,01,Арендованное имущество,A,subaccount,false
|
||||
01.05,01,Затраты на ремонт основных средств,A,subaccount,false
|
||||
01.08,01,"Объекты недвижимости, права собственности на которые не зарегистрированы",A,subaccount,false
|
||||
01.09,01,Выбытие основных средств,A,subaccount,false
|
||||
01.11,01,Групповые объекты основных средств,A,subaccount,false
|
||||
01.К,01,Корректировка стоимости арендованного имущества,A,subaccount,false
|
||||
02,,Амортизация основных средств,P,account,false
|
||||
02.01,02,"Амортизация основных средств, учитываемых на счете 01",P,subaccount,false
|
||||
02.02,02,"Амортизация основных средств, учитываемых на счете 03",P,subaccount,false
|
||||
02.03,02,Амортизация арендованного имущества,P,subaccount,false
|
||||
02.04,02,"Обесценение основных средств, учитываемых на счете 01",P,subaccount,false
|
||||
02.05,02,Амортизация затрат на ремонт основных средств,P,subaccount,false
|
||||
02.11,02,Амортизация групповых объектов основных средств,P,subaccount,false
|
||||
03,,Доходные вложения в материальные ценности,A,account,false
|
||||
03.01,03,Материальные ценности в организации,A,subaccount,false
|
||||
03.02,03,Материальные ценности предоставленные во временное владение и пользование,A,subaccount,false
|
||||
03.03,03,Материальные ценности предоставленные во временное пользование,A,subaccount,false
|
||||
03.04,03,Прочие доходные вложения,A,subaccount,false
|
||||
03.09,03,Выбытие материальных ценностей,A,subaccount,false
|
||||
04,,Нематериальные активы,A,account,false
|
||||
04.01,04,Нематериальные активы организации,A,subaccount,false
|
||||
04.02,04,"Расходы на научно-исследовательские, опытно-конструкторские и технологические работы",A,subaccount,false
|
||||
04.09,04,Выбытие нематериальных активов,A,subaccount,false
|
||||
05,,Амортизация нематериальных активов,P,account,false
|
||||
05.01,05,Амортизация нематериальных активов,P,subaccount,false
|
||||
05.02,05,Обесценение нематериальных активов,P,subaccount,false
|
||||
07,,Оборудование к установке,A,account,false
|
||||
08,,Вложения во внеоборотные активы,A,account,false
|
||||
08.01,08,Приобретение земельных участков,A,subaccount,false
|
||||
08.01.1,08.01,Приобретение земельных участков с доп. расходами,A,analytic,false
|
||||
08.01.2,08.01,Приобретение земельных участков без доп. расходов,A,analytic,false
|
||||
08.02,08,Приобретение объектов природопользования,A,subaccount,false
|
||||
08.03,08,Строительство объектов основных средств,A,subaccount,false
|
||||
08.04,08,Приобретение объектов основных средств,A,subaccount,false
|
||||
08.04.1,08.04,Приобретение компонентов основных средств,A,analytic,false
|
||||
08.04.2,08.04,Приобретение основных средств,A,analytic,false
|
||||
08.04.5,08.04,Вложения в ремонты основных средств,A,analytic,false
|
||||
08.05,08,Приобретение нематериальных активов,A,subaccount,false
|
||||
08.06,08,Перевод молодняка животных в основное стадо,A,subaccount,false
|
||||
08.07,08,Приобретение взрослых животных,A,subaccount,false
|
||||
08.08,08,"Выполнение научно-исследовательских, опытно-конструкторских и технологических работ",A,subaccount,false
|
||||
08.11,08,Нематериальные поисковые активы,A,subaccount,false
|
||||
08.12,08,Материальные поисковые активы,A,subaccount,false
|
||||
09,,Отложенные налоговые активы,A,account,false
|
||||
10,,Материалы,A,account,false
|
||||
10.01,10,Сырье и материалы,A,subaccount,false
|
||||
10.02,10,"Покупные полуфабрикаты и комплектующие изделия, конструкции и детали",A,subaccount,false
|
||||
10.03,10,Топливо,A,subaccount,false
|
||||
10.03.1,10.03,Топливо на складе,A,analytic,false
|
||||
10.03.2,10.03,Топливо в баке,A,analytic,false
|
||||
10.04,10,Тара и тарные материалы,A,subaccount,false
|
||||
10.05,10,Запасные части,A,subaccount,false
|
||||
10.06,10,Прочие материалы,A,subaccount,false
|
||||
10.07,10,"Материалы, переданные в переработку на сторону",A,subaccount,false
|
||||
10.08,10,Строительные материалы,A,subaccount,false
|
||||
10.09,10,Инвентарь и хозяйственные принадлежности,A,subaccount,false
|
||||
10.10,10,Специальная оснастка и специальная одежда на складе,A,subaccount,false
|
||||
10.11,10,Специальная оснастка и специальная одежда в эксплуатации,A,subaccount,false
|
||||
10.11.1,10.11,Специальная одежда в эксплуатации,A,analytic,false
|
||||
10.11.2,10.11,Специальная оснастка в эксплуатации,A,analytic,false
|
||||
10.21,10,Малоценное оборудование и запасы,A,subaccount,false
|
||||
10.21.1,10.21,Приобретение малоценного оборудования и запасов,A,analytic,false
|
||||
10.21.2,10.21,Выбытие малоценного оборудования и запасов,P,analytic,false
|
||||
11,,Животные на выращивании и откорме,A,account,false
|
||||
14,,Резервы под снижение стоимости материальных ценностей,P,account,false
|
||||
14.01,14,Резервы под снижение стоимости материалов,P,subaccount,false
|
||||
14.02,14,Резервы под снижение стоимости товаров,P,subaccount,false
|
||||
14.03,14,Резервы под снижение стоимости готовой продукции,P,subaccount,false
|
||||
14.04,14,Резервы под снижение стоимости незавершенного производства,P,subaccount,false
|
||||
15,,Заготовление и приобретение материальных ценностей,A,account,false
|
||||
15.01,15,Заготовление и приобретение материалов,A,subaccount,false
|
||||
15.02,15,Приобретение товаров,A,subaccount,false
|
||||
16,,Отклонение в стоимости материальных ценностей,AP,account,false
|
||||
19,,Налог на добавленную стоимость по приобретенным ценностям,A,account,false
|
||||
16.01,16,Отклонение в стоимости материалов,AP,subaccount,false
|
||||
16.02,16,Отклонение в стоимости товаров,AP,subaccount,false
|
||||
19,,НДС по приобретенным ценностям,A,account,false
|
||||
19.01,19,НДС при приобретении основных средств,A,subaccount,false
|
||||
19.02,19,НДС по приобретенным нематериальным активам,A,subaccount,false
|
||||
19.03,19,НДС по приобретенным материально-производственным запасам,A,subaccount,false
|
||||
19.04,19,НДС по приобретенным услугам,A,subaccount,false
|
||||
19.05,19,"НДС, уплаченный при ввозе товаров на территорию Российской Федерации",A,subaccount,false
|
||||
19.06,19,Акцизы по оплаченным материальным ценностям,A,subaccount,false
|
||||
19.07,19,"НДС по товарам, реализованным по ставке 0% (экспорт)",A,subaccount,false
|
||||
19.08,19,НДС при строительстве основных средств,A,subaccount,false
|
||||
19.09,19,НДС по уменьшению стоимости реализации,A,subaccount,false
|
||||
19.10,19,"НДС, уплачиваемый при импорте из Таможенного союза",A,subaccount,false
|
||||
20,,Основное производство,A,account,false
|
||||
20.01,20,Основное производство,A,subaccount,false
|
||||
20.02,20,Производство продукции из давальческого сырья,A,subaccount,false
|
||||
20.04,20,Собственные исследования и разработки,A,subaccount,false
|
||||
21,,Полуфабрикаты собственного производства,A,account,false
|
||||
23,,Вспомогательные производства,A,account,false
|
||||
23.01,23,Вспомогательные производства,A,subaccount,false
|
||||
23.05,23,Выполнение ремонтов основных средств,A,subaccount,false
|
||||
25,,Общепроизводственные расходы,A,account,false
|
||||
26,,Общехозяйственные расходы,A,account,false
|
||||
28,,Брак в производстве,A,account,false
|
||||
29,,Обслуживающие производства и хозяйства,A,account,false
|
||||
40,,"Выпуск продукции (работ, услуг)",AP,account,false
|
||||
41,,Товары,A,account,false
|
||||
41.01,41,Товары на складах,A,subaccount,false
|
||||
41.02,41,Товары в розничной торговле (по покупной стоимости),A,subaccount,false
|
||||
41.03,41,Тара под товаром и порожняя,A,subaccount,false
|
||||
41.04,41,Покупные изделия,A,subaccount,false
|
||||
41.11,41,Товары в розничной торговле (в АТТ по продажной стоимости),A,subaccount,false
|
||||
41.12,41,Товары в розничной торговле (в НТТ по продажной стоимости),A,subaccount,false
|
||||
41.К,41,Корректировка товаров прошлого периода,A,subaccount,false
|
||||
42,,Торговая наценка,P,account,false
|
||||
42.01,42,Торговая наценка в автоматизированных торговых точках,P,subaccount,false
|
||||
42.02,42,Торговая наценка в неавтоматизированных торговых точках,P,subaccount,false
|
||||
43,,Готовая продукция,A,account,false
|
||||
44,,Расходы на продажу,A,account,false
|
||||
44.01,44,"Издержки обращения в организациях, осуществляющих торговую деятельность",A,subaccount,false
|
||||
44.02,44,"Коммерческие расходы в организациях, осуществляющих промышленную и иную производственную деятельность",A,subaccount,false
|
||||
45,,Товары отгруженные,A,account,false
|
||||
45.01,45,Покупные товары отгруженные,A,subaccount,false
|
||||
45.02,45,Готовая продукция отгруженная,A,subaccount,false
|
||||
45.03,45,Прочие товары отгруженные,A,subaccount,false
|
||||
45.04,45,Переданные объекты недвижимости,A,subaccount,false
|
||||
46,,Выполненные этапы по незавершенным работам,A,account,false
|
||||
50,,Касса,A,account,false
|
||||
50.01,50,Касса организации,A,subaccount,false
|
||||
50.02,50,Операционная касса,A,subaccount,false
|
||||
50.03,50,Денежные документы,A,subaccount,false
|
||||
50.04,50,Касса по деятельности платежного агента,A,subaccount,false
|
||||
50.21,50,Касса организации (в валюте),A,subaccount,false
|
||||
50.23,50,Денежные документы (в валюте),A,subaccount,false
|
||||
51,,Расчетные счета,A,account,false
|
||||
52,,Валютные счета,A,account,false
|
||||
53,,Счет цифрового рубля,A,account,false
|
||||
55,,Специальные счета в банках,A,account,false
|
||||
55.01,55,Аккредитивы,A,subaccount,false
|
||||
55.02,55,Чековые книжки,A,subaccount,false
|
||||
55.03,55,Депозитные счета,A,subaccount,false
|
||||
55.04,55,Прочие специальные счета,A,subaccount,false
|
||||
55.21,55,Аккредитивы (в валюте),A,subaccount,false
|
||||
55.23,55,Депозитные счета (в валюте),A,subaccount,false
|
||||
55.24,55,Прочие специальные счета (в валюте),A,subaccount,false
|
||||
57,,Переводы в пути,A,account,false
|
||||
57.01,57,Переводы в пути,A,subaccount,false
|
||||
57.02,57,Приобретение иностранной валюты,A,subaccount,false
|
||||
57.03,57,Продажи по платежным картам,A,subaccount,false
|
||||
57.21,57,Переводы в пути (в валюте),A,subaccount,false
|
||||
57.22,57,Реализация иностранной валюты,A,subaccount,false
|
||||
58,,Финансовые вложения,A,account,false
|
||||
58.01,58,Паи и акции,A,subaccount,false
|
||||
58.01.1,58.01,Паи,A,analytic,false
|
||||
58.01.2,58.01,Акции,A,analytic,false
|
||||
58.02,58,Долговые ценные бумаги,A,subaccount,false
|
||||
58.03,58,Предоставленные займы,A,subaccount,false
|
||||
58.04,58,Вклады по договору простого товарищества,A,subaccount,false
|
||||
58.05,58,Приобретенные права в рамках оказания финансовых услуг,A,subaccount,false
|
||||
59,,Резервы под обесценение финансовых вложений,P,account,false
|
||||
60,,Расчеты с поставщиками и подрядчиками,AP,account,false
|
||||
60.01,60,Расчеты с поставщиками и подрядчиками,AP,subaccount,false
|
||||
60.02,60,Расчеты по авансам выданным,AP,subaccount,false
|
||||
60.03,60,Расчеты по векселям выданным,AP,subaccount,false
|
||||
60.21,60,Расчеты с поставщиками и подрядчиками (в валюте),AP,subaccount,false
|
||||
60.22,60,Расчеты по авансам выданным (в валюте),AP,subaccount,false
|
||||
60.31,60,Расчеты с поставщиками и подрядчиками (в условных единицах),AP,subaccount,false
|
||||
60.32,60,Расчеты по авансам выданным (в условных единицах),AP,subaccount,false
|
||||
60.01,60,Расчеты с поставщиками и подрядчиками,P,subaccount,false
|
||||
60.02,60,Расчеты по авансам выданным,A,subaccount,false
|
||||
60.03,60,Векселя выданные,P,subaccount,false
|
||||
60.21,60,Расчеты с поставщиками и подрядчиками (в валюте),P,subaccount,false
|
||||
60.22,60,Расчеты по авансам выданным (в валюте),A,subaccount,false
|
||||
60.31,60,Расчеты с поставщиками и подрядчиками (в у.е.),P,subaccount,false
|
||||
60.32,60,Расчеты по авансам выданным (в у.е.),A,subaccount,false
|
||||
62,,Расчеты с покупателями и заказчиками,AP,account,false
|
||||
62.01,62,Расчеты с покупателями и заказчиками,AP,subaccount,false
|
||||
62.02,62,Расчеты по авансам полученным,AP,subaccount,false
|
||||
62.03,62,Расчеты по векселям полученным,AP,subaccount,false
|
||||
62.21,62,Расчеты с покупателями и заказчиками (в валюте),AP,subaccount,false
|
||||
62.22,62,Расчеты по авансам полученным (в валюте),AP,subaccount,false
|
||||
62.31,62,Расчеты с покупателями и заказчиками (в условных единицах),AP,subaccount,false
|
||||
62.32,62,Расчеты по авансам полученным (в условных единицах),AP,subaccount,false
|
||||
62.01,62,Расчеты с покупателями и заказчиками,A,subaccount,false
|
||||
62.02,62,Расчеты по авансам полученным,P,subaccount,false
|
||||
62.03,62,Векселя полученные,A,subaccount,false
|
||||
62.21,62,Расчеты с покупателями и заказчиками (в валюте),A,subaccount,false
|
||||
62.22,62,Расчеты по авансам полученным (в валюте),P,subaccount,false
|
||||
62.31,62,Расчеты с покупателями и заказчиками (в у.е.),A,subaccount,false
|
||||
62.32,62,Расчеты по авансам полученным (в у.е.),P,subaccount,false
|
||||
62.ОТ,62,Расчеты по авансам полученным в счет отгрузки,P,subaccount,false
|
||||
62.ОТ.1,62.ОТ,Расчеты по авансам полученным в счет отгрузки,P,analytic,false
|
||||
62.ОТ.2,62.ОТ,Расчеты по авансам полученным (в валюте) в счет отгрузки,P,analytic,false
|
||||
62.ОТ.3,62.ОТ,Расчеты по авансам полученным (в у.е.) в счет отгрузки,P,analytic,false
|
||||
62.Р,62,Расчеты с розничными покупателями,A,subaccount,false
|
||||
63,,Резервы по сомнительным долгам,P,account,false
|
||||
66,,Расчеты по краткосрочным кредитам и займам,P,account,false
|
||||
66.01,66,Краткосрочные кредиты,P,subaccount,false
|
||||
66.02,66,Проценты по краткосрочным кредитам,P,subaccount,false
|
||||
66.03,66,Краткосрочные займы,P,subaccount,false
|
||||
66.04,66,Проценты по краткосрочным займам,P,subaccount,false
|
||||
66.06,66,Проценты по краткосрочным кредитам и займам (субсчет 06),P,subaccount,false
|
||||
66.22,66,Проценты по краткосрочным кредитам и займам (субсчет 22),P,subaccount,false
|
||||
66.24,66,Проценты по краткосрочным кредитам и займам (субсчет 24),P,subaccount,false
|
||||
66.26,66,Проценты по краткосрочным кредитам и займам (субсчет 26),P,subaccount,false
|
||||
66.05,66,Краткосрочные долговые ценные бумаги,P,subaccount,false
|
||||
66.06,66,Проценты по краткосрочным долговым ценным бумагам,P,subaccount,false
|
||||
66.21,66,Краткосрочные кредиты (в валюте),P,subaccount,false
|
||||
66.22,66,Проценты по краткосрочным кредитам (в валюте),P,subaccount,false
|
||||
66.23,66,Краткосрочные займы (в валюте),P,subaccount,false
|
||||
66.24,66,Проценты по краткосрочным займам (в валюте),P,subaccount,false
|
||||
66.25,66,Краткосрочные долговые ценные бумаги (в валюте),P,subaccount,false
|
||||
66.26,66,Проценты по краткосрочным долговым ценным бумагам (в валюте),P,subaccount,false
|
||||
67,,Расчеты по долгосрочным кредитам и займам,P,account,false
|
||||
67.01,67,Долгосрочные кредиты,P,subaccount,false
|
||||
67.02,67,Проценты по долгосрочным кредитам,P,subaccount,false
|
||||
67.03,67,Долгосрочные займы,P,subaccount,false
|
||||
67.04,67,Проценты по долгосрочным займам,P,subaccount,false
|
||||
67.06,67,Проценты по долгосрочным кредитам и займам (субсчет 06),P,subaccount,false
|
||||
67.22,67,Проценты по долгосрочным кредитам и займам (субсчет 22),P,subaccount,false
|
||||
67.24,67,Проценты по долгосрочным кредитам и займам (субсчет 24),P,subaccount,false
|
||||
67.26,67,Проценты по долгосрочным кредитам и займам (субсчет 26),P,subaccount,false
|
||||
67.05,67,Долгосрочные долговые ценные бумаги,P,subaccount,false
|
||||
67.06,67,Проценты по долгосрочным долговым ценным бумагам,P,subaccount,false
|
||||
67.21,67,Долгосрочные кредиты (в валюте),P,subaccount,false
|
||||
67.22,67,Проценты по долгосрочным кредитам (в валюте),P,subaccount,false
|
||||
67.23,67,Долгосрочные займы (в валюте),P,subaccount,false
|
||||
67.24,67,Проценты по долгосрочным займам (в валюте),P,subaccount,false
|
||||
67.25,67,Долгосрочные долговые ценные бумаги (в валюте),P,subaccount,false
|
||||
67.26,67,Проценты по долгосрочным долговым ценным бумагам (в валюте),P,subaccount,false
|
||||
68,,Расчеты по налогам и сборам,AP,account,false
|
||||
Я68.01,,(Не используется) НДФЛ при исполнении обязанностей налогового агента,AP,subaccount,false
|
||||
68.01,68,НДФЛ исчисленный налоговым агентом,AP,subaccount,false
|
||||
68.02,68,Налог на добавленную стоимость,AP,subaccount,false
|
||||
68.03,68,Акцизы,AP,subaccount,false
|
||||
68.04,68,Налог на прибыль,AP,subaccount,false
|
||||
68.04.1,68.04,Расчеты с бюджетом,AP,analytic,false
|
||||
68.04.2,68.04,Расчет налога на прибыль,AP,analytic,false
|
||||
68.06,68,Земельный налог,AP,subaccount,false
|
||||
68.07,68,Транспортный налог,AP,subaccount,false
|
||||
68.08,68,Налог на имущество,AP,subaccount,false
|
||||
68.09,68,Налог на рекламу,AP,subaccount,false
|
||||
68.10,68,Прочие налоги и сборы,AP,subaccount,false
|
||||
68.11,68,Единый налог на вмененный доход,AP,subaccount,false
|
||||
68.12,68,Налог при упрощенной системе налогообложения,AP,subaccount,false
|
||||
68.13,68,Торговый сбор,AP,subaccount,false
|
||||
68.14,68,Налог при патентной системе налогообложения,AP,subaccount,false
|
||||
68.15,68,Налог при Автоматизированной упрощенной системе налогообложения,AP,subaccount,false
|
||||
68.16,68,Налог на профессиональный доход,AP,subaccount,false
|
||||
68.17,68,Туристический налог,AP,subaccount,false
|
||||
68.21,68,НДФЛ индивидуального предпринимателя,AP,subaccount,false
|
||||
68.22,68,НДС по экспорту к возмещению,A,subaccount,false
|
||||
68.32,68,НДС при исполнении обязанностей налогового агента,P,subaccount,false
|
||||
68.34,68,Налог на прибыль при исполнении обязанностей налогового агента,AP,subaccount,false
|
||||
68.42,68,НДС при импорте товаров из Таможенного союза,P,subaccount,false
|
||||
68.52,68,НДС налогового агента по отдельным видам товаров,AP,subaccount,false
|
||||
68.90,68,Единый налоговый счет,AP,subaccount,false
|
||||
69,,Расчеты по социальному страхованию и обеспечению,AP,account,false
|
||||
70,,Расчеты с персоналом по оплате труда,P,account,false
|
||||
69.01,69,Расчеты по социальному страхованию,AP,subaccount,false
|
||||
69.02,69,Расчеты по пенсионному обеспечению,AP,subaccount,false
|
||||
69.02.1,69.02,Страховая часть трудовой пенсии,AP,analytic,false
|
||||
69.02.2,69.02,Накопительная часть трудовой пенсии,AP,analytic,false
|
||||
69.02.3,69.02,Взносы на доплату к пенсии членам летных экипажей,AP,analytic,false
|
||||
69.02.4,69.02,Взносы на доплату к пенсии работникам организаций угольной промышленности,AP,analytic,false
|
||||
69.02.5,69.02,"Дополнительные взносы на страховую часть пенсии работникам, занятым на работах с вредными условиями труда",AP,analytic,false
|
||||
69.02.6,69.02,"Дополнительные взносы на страховую часть пенсии работникам, занятым на работах с тяжелыми условиями труда",AP,analytic,false
|
||||
69.02.7,69.02,Обязательное пенсионное страхование,AP,analytic,false
|
||||
69.03,69,Расчеты по обязательному медицинскому страхованию,AP,subaccount,false
|
||||
69.03.1,69.03,Федеральный фонд ОМС,AP,analytic,false
|
||||
69.03.2,69.03,Территориальный фонд ОМС,AP,analytic,false
|
||||
69.04,69,"ЕСН в части, перечисляемой в Федеральный бюджет",AP,subaccount,false
|
||||
69.05,69,Добровольные взносы на накопительную часть трудовой пенсии,AP,subaccount,false
|
||||
69.05.1,69.05,Взносы за счет работодателя,AP,analytic,false
|
||||
69.05.2,69.05,"Взносы, удерживаемые из доходов работника",AP,analytic,false
|
||||
69.06,69,"Расчеты по страховым взносам, уплачиваемым исходя из стоимости страхового года",AP,subaccount,false
|
||||
69.06.1,69.06,Взносы в ПФР (страховая часть),AP,analytic,false
|
||||
69.06.2,69.06,Взносы в ПФР (накопительная часть),AP,analytic,false
|
||||
69.06.3,69.06,Взносы в ФОМС,AP,analytic,false
|
||||
69.06.4,69.06,Взносы в ФСС,AP,analytic,false
|
||||
69.06.5,69.06,Обязательное пенсионное страхование предпринимателя,AP,analytic,false
|
||||
69.06.6,69.06,Страховые взносы единый тариф ИП,AP,analytic,false
|
||||
69.09,69,Страховые взносы по единому тарифу,AP,subaccount,false
|
||||
69.11,69,Расчеты по обязательному социальному страхованию от несчастных случаев на производстве и профессиональных заболеваний,AP,subaccount,false
|
||||
69.12,69,Расчеты по добровольным взносам в ФСС на страхование работников на случай временной нетрудоспособности,AP,subaccount,false
|
||||
69.13,69,"Расчеты по средствам ФСС для страхователей, применяющих специальные режимы налогообложения",AP,subaccount,false
|
||||
69.13.1,69.13,"Расчеты по средствам ФСС для страхователей, уплачивающих ЕНВД",AP,analytic,false
|
||||
69.13.2,69.13,"Расчеты по средствам ФСС для страхователей, применяющих УСН",AP,analytic,false
|
||||
70,,Расчеты с персоналом по оплате труда,AP,account,false
|
||||
71,,Расчеты с подотчетными лицами,AP,account,false
|
||||
71.01,71,Расчеты с подотчетными лицами,AP,subaccount,false
|
||||
71.21,71,Расчеты с подотчетными лицами (в валюте),AP,subaccount,false
|
||||
73,,Расчеты с персоналом по прочим операциям,AP,account,false
|
||||
73.01,73,Расчеты по предоставленным займам,A,subaccount,false
|
||||
73.02,73,Расчеты по возмещению материального ущерба,A,subaccount,false
|
||||
73.03,73,Расчеты по прочим операциям,AP,subaccount,false
|
||||
75,,Расчеты с учредителями,AP,account,false
|
||||
75.01,75,Расчеты по вкладам в уставный (складочный) капитал,A,subaccount,false
|
||||
75.02,75,Расчеты по выплате доходов,P,subaccount,false
|
||||
76,,Расчеты с разными дебиторами и кредиторами,AP,account,false
|
||||
76.01,76,"Расчеты по имущественному, личному и добровольному страхованию",AP,subaccount,false
|
||||
76.01.1,76.01,Расчеты по имущественному и личному страхованию,AP,analytic,false
|
||||
76.01.2,76.01,Платежи (взносы) по добровольному страхованию на случай смерти и причинения вреда здоровью,A,analytic,false
|
||||
76.01.9,76.01,Платежи (взносы) по прочим видам страхования,A,analytic,false
|
||||
76.02,76,Расчеты по претензиям,A,subaccount,false
|
||||
76.03,76,Расчеты по причитающимся дивидендам и другим доходам,AP,subaccount,false
|
||||
76.04,76,Расчеты по депонированным суммам,P,subaccount,false
|
||||
76.05,76,Расчеты с прочими поставщиками и подрядчиками,AP,subaccount,false
|
||||
76.07,76,Расчеты по лизингу,AP,subaccount,false
|
||||
76.07.1,76.07,Обязательства по лизингу,AP,analytic,false
|
||||
76.07.2,76.07,Прочие расчеты по лизингу (подсубсчет 2),AP,analytic,false
|
||||
76.07.5,76.07,Проценты по лизингу,AP,analytic,false
|
||||
76.07.9,76.07,Активы по лизингу,AP,analytic,false
|
||||
76.08,76,Расчеты по процентам,AP,subaccount,false
|
||||
76.06,76,Расчеты с прочими покупателями и заказчиками,AP,subaccount,false
|
||||
76.07,76,Расчеты по аренде,AP,subaccount,false
|
||||
76.07.1,76.07,Арендные обязательства,P,analytic,false
|
||||
76.07.2,76.07,Задолженность по арендным платежам,AP,analytic,false
|
||||
76.07.5,76.07,Проценты по аренде,A,analytic,false
|
||||
76.07.9,76.07,НДС по арендным обязательствам,A,analytic,false
|
||||
76.08,76,Проценты по рассрочке,A,subaccount,false
|
||||
76.09,76,Прочие расчеты с разными дебиторами и кредиторами,AP,subaccount,false
|
||||
76.28,76,Расчеты по процентам (в валюте),AP,subaccount,false
|
||||
76.38,76,Расчеты по процентам (в условных единицах),AP,subaccount,false
|
||||
76.10,76,Прочие расчеты с физическими лицами,AP,subaccount,false
|
||||
76.13,76,Расчеты с факторинговыми компаниями,A,subaccount,false
|
||||
76.14,76,Приобретение билетов для командировок,A,subaccount,false
|
||||
76.15,76,Приобретение по топливным картам,P,subaccount,false
|
||||
76.16,76,Расчеты с самозанятыми по реестрам выплат,P,subaccount,false
|
||||
76.17,76,Расчеты по налогам с третьими лицами,AP,subaccount,false
|
||||
76.18,76,Приобретение прав на использование результатов интеллектуальной деятельности,A,subaccount,false
|
||||
76.21,76,Расчеты по имущественному и личному страхованию (в валюте),AP,subaccount,false
|
||||
76.22,76,Расчеты по претензиям (в валюте),A,subaccount,false
|
||||
76.25,76,Расчеты с прочими поставщиками и подрядчиками (в валюте),AP,subaccount,false
|
||||
76.26,76,Расчеты с прочими покупателями и заказчиками (в валюте),AP,subaccount,false
|
||||
76.27,76,Расчеты по аренде (в валюте),AP,subaccount,false
|
||||
76.27.1,76.27,Арендные обязательства (в валюте),P,analytic,false
|
||||
76.27.2,76.27,Задолженность по арендным платежам (в валюте),AP,analytic,false
|
||||
76.27.5,76.27,Проценты по аренде (в валюте),A,analytic,false
|
||||
76.27.9,76.27,НДС по арендным обязательствам (в валюте),A,analytic,false
|
||||
76.28,76,Проценты по рассрочке (в валюте),A,subaccount,false
|
||||
76.29,76,Прочие расчеты с разными дебиторами и кредиторами (в валюте),AP,subaccount,false
|
||||
76.32,76,Расчеты по претензиям (в у.е.),A,subaccount,false
|
||||
76.35,76,Расчеты с прочими поставщиками и подрядчиками (в у.е.),AP,subaccount,false
|
||||
76.36,76,Расчеты с прочими покупателями и заказчиками (в у.е.),AP,subaccount,false
|
||||
76.37,76,Расчеты по аренде (в у.е.),AP,subaccount,false
|
||||
76.37.1,76.37,Арендные обязательства (в у.е.),P,analytic,false
|
||||
76.37.2,76.37,Задолженность по арендным платежам (в у.е.),AP,analytic,false
|
||||
76.37.5,76.37,Проценты по аренде (в у.е.),A,analytic,false
|
||||
76.37.9,76.37,НДС по арендным обязательствам (в у.е.),A,analytic,false
|
||||
76.38,76,Проценты по рассрочке (в у.е.),A,subaccount,false
|
||||
76.39,76,Прочие расчеты с разными дебиторами и кредиторами (в у.е.),AP,subaccount,false
|
||||
76.41,76,Расчеты по исполнительным документам работников,AP,subaccount,false
|
||||
76.49,76,Расчеты по прочим удержаниям из заработной платы работников,AP,subaccount,false
|
||||
76.АВ,76,НДС по авансам и предоплатам,A,subaccount,false
|
||||
76.ВА,76,НДС по авансам и предоплатам выданным,P,subaccount,false
|
||||
76.К,76,Корректировка расчетов прошлого периода,AP,subaccount,false
|
||||
76.Н,76,"Расчеты по НДС, отложенному для уплаты в бюджет",P,subaccount,false
|
||||
76.НА,76,Расчеты по НДС при исполнении обязанностей налогового агента,AP,subaccount,false
|
||||
76.ОТ,76,"НДС, начисленный по отгрузке",A,subaccount,false
|
||||
77,,Отложенные налоговые обязательства,P,account,false
|
||||
79,,Внутрихозяйственные расчеты,AP,account,false
|
||||
79.01,79,Расчеты по выделенному имуществу,AP,subaccount,false
|
||||
79.02,79,Расчеты по текущим операциям,AP,subaccount,false
|
||||
79.03,79,Расчеты по договору доверительного управления имуществом,AP,subaccount,false
|
||||
80,,Уставный капитал,P,account,false
|
||||
80.01,80,Обыкновенные акции,P,subaccount,false
|
||||
80.02,80,Привилегированные акции,P,subaccount,false
|
||||
80.09,80,Прочий капитал,P,subaccount,false
|
||||
81,,Собственные акции (доли),A,account,false
|
||||
81.01,81,Обыкновенные акции,A,subaccount,false
|
||||
81.02,81,Привилегированные акции,A,subaccount,false
|
||||
81.09,81,Прочий капитал,A,subaccount,false
|
||||
82,,Резервный капитал,P,account,false
|
||||
82.01,82,"Резервы, образованные в соответствии с законодательством",P,subaccount,false
|
||||
82.02,82,"Резервы, образованные в соответствии с учредительными документами",P,subaccount,false
|
||||
83,,Добавочный капитал,P,account,false
|
||||
83.01,83,Прирост стоимости внеоборотных активов по переоценке,P,subaccount,false
|
||||
83.01.1,83.01,Прирост стоимости основных средств,P,analytic,false
|
||||
83.01.2,83.01,Прирост стоимости нематериальных активов,P,analytic,false
|
||||
83.01.3,83.01,Прирост стоимости прочих внеоборотных активов,P,analytic,false
|
||||
83.02,83,Эмиссионный доход от выпуска обыкновенных акций,P,subaccount,false
|
||||
83.03,83,Эмиссионный доход от выпуска привилегированных акций,P,subaccount,false
|
||||
83.09,83,Другие источники,P,subaccount,false
|
||||
84,,Нераспределенная прибыль (непокрытый убыток),AP,account,false
|
||||
84.01,84,"Прибыль, подлежащая распределению",P,subaccount,false
|
||||
84.02,84,"Убыток, подлежащий покрытию",A,subaccount,false
|
||||
84.03,84,Нераспределенная прибыль в обращении,P,subaccount,false
|
||||
84.04,84,Нераспределенная прибыль использованная,P,subaccount,false
|
||||
86,,Целевое финансирование,P,account,false
|
||||
86.01,86,Целевое финансирование из бюджета,P,subaccount,false
|
||||
86.02,86,Прочее целевое финансирование и поступления,P,subaccount,false
|
||||
90,,Продажи,AP,account,false
|
||||
90.01,90,Выручка,AP,subaccount,false
|
||||
90.02,90,Себестоимость продаж,AP,subaccount,false
|
||||
90.03,90,Налог на добавленную стоимость,AP,subaccount,false
|
||||
90.04,90,Акцизы,AP,subaccount,false
|
||||
90.09,90,Прибыль (убыток) от продаж,AP,subaccount,false
|
||||
90.01,90,Выручка,P,subaccount,false
|
||||
90.01.1,90.01,Выручка по деятельности с основной системой налогообложения,P,analytic,false
|
||||
90.01.2,90.01,Выручка по отдельным видам деятельности с особым порядком налогообложения,P,analytic,false
|
||||
90.02,90,Себестоимость продаж,A,subaccount,false
|
||||
90.02.1,90.02,Себестоимость продаж по деятельности с основной системой налогообложения,A,analytic,false
|
||||
90.02.2,90.02,Себестоимость продаж по отдельным видам деятельности с особым порядком налогообложения,A,analytic,false
|
||||
90.03,90,Налог на добавленную стоимость,A,subaccount,false
|
||||
90.04,90,Акцизы,A,subaccount,false
|
||||
90.05,90,Экспортные пошлины,A,subaccount,false
|
||||
90.07,90,Расходы на продажу,A,subaccount,false
|
||||
90.07.1,90.07,Расходы на продажу по деятельности с основной системой налогообложения,A,analytic,false
|
||||
90.07.2,90.07,Расходы на продажу по отдельным видам деятельности с особым порядком налогообложения,A,analytic,false
|
||||
90.08,90,Управленческие расходы,A,subaccount,false
|
||||
90.08.1,90.08,Управленческие расходы по деятельности с основной системой налогообложения,A,analytic,false
|
||||
90.08.2,90.08,Управленческие расходы по отдельным видам деятельности с особым порядком налогообложения,A,analytic,false
|
||||
90.09,90,Прибыль / убыток от продаж,AP,subaccount,false
|
||||
91,,Прочие доходы и расходы,AP,account,false
|
||||
91.01,91,Прочие доходы,AP,subaccount,false
|
||||
91.02,91,Прочие расходы,AP,subaccount,false
|
||||
91.01,91,Прочие доходы,P,subaccount,false
|
||||
91.02,91,Прочие расходы,A,subaccount,false
|
||||
91.09,91,Сальдо прочих доходов и расходов,AP,subaccount,false
|
||||
94,,Недостачи и потери от порчи ценностей,A,account,false
|
||||
96,,Резервы предстоящих расходов,P,account,false
|
||||
96,,Резервы предстоящих расходов,AP,account,false
|
||||
96.01,96,Оценочные обязательства по вознаграждениям работникам,P,subaccount,false
|
||||
96.01.1,96.01,Оценочные обязательства по вознаграждениям,P,analytic,false
|
||||
96.01.2,96.01,Оценочные обязательства по страховым взносам,P,analytic,false
|
||||
96.09,96,Резервы предстоящих расходов прочие,AP,subaccount,false
|
||||
97,,Расходы будущих периодов,A,account,false
|
||||
97.01,97,Расходы на оплату труда будущих периодов,A,subaccount,false
|
||||
97.02,97,Расходы будущих периодов на добровольное страхование работников,A,subaccount,false
|
||||
97.11,97,Убытки прошлых лет по налогу на прибыль,A,subaccount,false
|
||||
97.12,97,Убытки от реализации основных средств,A,subaccount,false
|
||||
97.21,97,Прочие расходы будущих периодов,A,subaccount,false
|
||||
97.КР,97,Отложенные расходы по курсовым разницам,A,subaccount,false
|
||||
98,,Доходы будущих периодов,P,account,false
|
||||
98.01,98,"Доходы, полученные в счет будущих периодов",P,subaccount,false
|
||||
98.02,98,Безвозмездные поступления,P,subaccount,false
|
||||
98.03,98,"Предстоящие поступления по недостачам, выявленным за прошлые годы",P,subaccount,false
|
||||
98.04,98,"Разница между суммой, подлежащей взысканию с виновных лиц, и балансовой стоимостью по недостачам ценностей",P,subaccount,false
|
||||
98.КР,98,Отложенные доходы по курсовым разницам,P,subaccount,false
|
||||
99,,Прибыли и убытки,AP,account,false
|
||||
99.01,99,Прибыли и убытки от хозяйственной деятельности (за исключением налога на прибыль),AP,subaccount,false
|
||||
99.01.1,99.01,Прибыли и убытки по деятельности с основной системой налогообложения,AP,analytic,false
|
||||
99.01.2,99.01,Прибыли и убытки по отдельным видам деятельности с особым порядком налогообложения,AP,analytic,false
|
||||
99.02,99,Налог на прибыль,AP,subaccount,false
|
||||
99.02.1,99.02,Условный расход по налогу на прибыль,A,analytic,false
|
||||
99.02.2,99.02,Условный доход по налогу на прибыль,P,analytic,false
|
||||
99.02.3,99.02,Постоянный налоговый расход (доход),AP,analytic,false
|
||||
99.02.4,99.02,Пересчет отложенных налоговых активов и обязательств,AP,analytic,false
|
||||
99.02.И,99.02,Инвестиционный вычет по налогу на прибыль,P,analytic,false
|
||||
99.02.О,99.02,Отложенный налог на прибыль,AP,analytic,false
|
||||
99.02.Т,99.02,Текущий налог на прибыль,A,analytic,false
|
||||
99.09,99,Прочие прибыли и убытки,AP,subaccount,false
|
||||
001,,Арендованные основные средства,A,account,true
|
||||
002,,"Товарно-материальные ценности, принятые на ответственное хранение",A,account,true
|
||||
003,,"Материалы, принятые в переработку",A,account,true
|
||||
003.01,003,Материалы на складе,A,subaccount,true
|
||||
003.02,003,"Материалы, переданные в производство",A,subaccount,true
|
||||
004,,"Товары, принятые на комиссию",A,account,true
|
||||
004.01,004,Товары на складе,A,subaccount,true
|
||||
004.02,004,"Товары, переданные на комиссию",A,subaccount,true
|
||||
004.К,004,Корректировка комиссионных товаров прошлого периода,A,subaccount,true
|
||||
005,,"Оборудование, принятое для монтажа",A,account,true
|
||||
006,,Бланки строгой отчетности,A,account,true
|
||||
007,,Списанная в убыток задолженность неплатежеспособных дебиторов,A,account,true
|
||||
008,,Обеспечения обязательств и платежей полученные,A,account,true
|
||||
008.01,008,Обеспечения обязательств и платежей полученные,A,subaccount,true
|
||||
008.21,008,Обеспечения обязательств и платежей полученные (в валюте),A,subaccount,true
|
||||
009,,Обеспечения обязательств и платежей выданные,A,account,true
|
||||
009.01,009,Обеспечения обязательств и платежей выданные,A,subaccount,true
|
||||
009.21,009,Обеспечения обязательств и платежей выданные (в валюте),A,subaccount,true
|
||||
010,,Износ основных средств,A,account,true
|
||||
011,,"Основные средства, сданные в аренду",A,account,true
|
||||
012,,Возвратная тара,A,account,true
|
||||
012.01,012,Возвратная тара на складе,A,subaccount,true
|
||||
012.02,012,Возвратная тара у покупателя,A,subaccount,true
|
||||
ГТД,,Учет импортных товаров по номерам ГТД,A,account,true
|
||||
ИНВ,,Инвестиционный налоговый вычет,A,account,true
|
||||
ИНВ.Ф,ИНВ,Федеральный инвестиционный налоговый вычет,A,subaccount,true
|
||||
КВ,,Амортизационная премия,A,account,true
|
||||
МЦ,,Материальные ценности в эксплуатации,A,account,true
|
||||
МЦ.02,МЦ,Спецодежда в эксплуатации,A,subaccount,true
|
||||
МЦ.03,МЦ,Спецоснастка в эксплуатации,A,subaccount,true
|
||||
МЦ.04,МЦ,Инвентарь и хозяйственные принадлежности в эксплуатации,A,subaccount,true
|
||||
НЕ,,"Доходы и расходы, не учитываемые в целях налогообложения",AP,account,true
|
||||
НЕ.01,НЕ,"Расходы, которые не учтены на основании пунктов 1 - 48 статьи 270 НК",AP,subaccount,true
|
||||
НЕ.01.1,НЕ.01,Выплаты в пользу физических лиц,AP,analytic,true
|
||||
НЕ.01.9,НЕ.01,Другие выплаты,AP,analytic,true
|
||||
НЕ.02,НЕ,"Расходы, которые не учтены на основании пункта 49 статьи 270 НК",AP,subaccount,true
|
||||
НЕ.02.1,НЕ.02,Выплаты в пользу физических лиц,AP,analytic,true
|
||||
НЕ.02.9,НЕ.02,Другие выплаты,AP,analytic,true
|
||||
НЕ.03,НЕ,"Внереализационные расходы, не учитываемые в целях налогообложения",AP,subaccount,true
|
||||
НЕ.04,НЕ,"Доходы, не учитываемые в целях налогообложения",AP,subaccount,true
|
||||
ОТ,,"Расчеты для целей НДС по товарам, отгруженным без перехода права собственности",A,account,true
|
||||
ОТ.01,ОТ,"Расчеты для целей НДС по товарам, отгруженным без перехода права собственности",A,subaccount,true
|
||||
ОТ.02,ОТ,"Расчеты для целей НДС по товарам (в валюте), отгруженным без перехода права собственности",A,subaccount,true
|
||||
ОТ.03,ОТ,"Расчеты для целей НДС по товарам (в у.е.), отгруженным без перехода права собственности",A,subaccount,true
|
||||
РВ,,Розничная выручка,A,account,true
|
||||
РВ.1,РВ,Наличная нераспределенная розничная выручка,A,subaccount,true
|
||||
РВ.2,РВ,НДС в наличной нераспределенной розничной выручке,A,subaccount,true
|
||||
РВ.3,РВ,Безналичная нераспределенная розничная выручка,A,subaccount,true
|
||||
РВ.4,РВ,НДС в безналичной нераспределенной розничной выручке,A,subaccount,true
|
||||
УСН,,Вспомогательные счета по упрощенной системе налогообложения,AP,account,true
|
||||
УСН.01,УСН,Расчеты с покупателями по деятельности ЕНВД,AP,subaccount,true
|
||||
УСН.02,УСН,Расчеты с покупателями за товары комитента,AP,subaccount,true
|
||||
УСН.03,УСН,Расчеты с покупателями по деятельности на патенте,AP,subaccount,true
|
||||
УСН.04,УСН,Расчеты с покупателями по деятельности на торговом сборе,AP,subaccount,true
|
||||
УСН.21,УСН,Расчеты с покупателями в валюте по деятельности ЕНВД,AP,subaccount,true
|
||||
УСН.22,УСН,Расчеты с покупателями в валюте за товары комитента,AP,subaccount,true
|
||||
УСН.23,УСН,Расчеты с покупателями в валюте по деятельности на патенте,AP,subaccount,true
|
||||
УСН.24,УСН,Расчеты с покупателями в валюте по деятельности на торговом сборе,AP,subaccount,true
|
||||
Я68.01.2,Я68.01,"(Не используется) НДФЛ с доходов свыше предельной величины, исчисленный налоговым агентом",AP,analytic,false
|
||||
Я68.21,,(Не используется) НДФЛ предпринимателя,AP,subaccount,false
|
||||
Я68.21.2,Я68.21,(Не используется) НДФЛ индивидуального предпринимателя свыше предельной величины,AP,analytic,false
|
||||
Я01.К,,не используется,A,subaccount,false
|
||||
Я69.06.5,,(не используется) Обязательное пенсионное страхование предпринимателя,AP,analytic,false
|
||||
Я96.01,Я96,не используется,P,subaccount,false
|
||||
Я96,,не используется,P,account,false
|
||||
Я81.01,Я81,(Не используется) Обыкновенные акции,A,subaccount,false
|
||||
Я81.09,Я81,(Не используется) Прочий капитал,A,subaccount,false
|
||||
Я81.02,Я81,(Не используется) Привилегированные акции,A,subaccount,false
|
||||
Я75.01,Я75,(Не используется) Расчеты по вкладам в уставный (складочный) капитал,A,subaccount,false
|
||||
Я75.02,Я75,(Не используется) Расчеты по выплате доходов,P,subaccount,false
|
||||
Я80.09,Я80,(Не используется) Прочий капитал,P,subaccount,false
|
||||
Я80.02,Я80,(Не используется) Привилегированные акции,P,subaccount,false
|
||||
Я80.01,Я80,(Не используется) Обыкновенные акции,P,subaccount,false
|
||||
Я68.32,,(Не используется) НДС при исполнении обязанностей налогового агента,P,subaccount,false
|
||||
Я68.42,,(Не используется) НДС при импорте товаров из Таможенного союза,P,subaccount,false
|
||||
Я75,,(Не используется) Расчеты с учредителями,AP,account,false
|
||||
Я80,,(Не используется) Уставный капитал,P,account,false
|
||||
Я81,,(Не используется) Собственные акции (доли),A,account,false
|
||||
|
||||
|
73
api/tests/test_convert_chart_1c.py
Normal file
73
api/tests/test_convert_chart_1c.py
Normal file
@ -0,0 +1,73 @@
|
||||
"""Конвертер плана счетов 1С в csv seed (issue #23): иерархия по структуре кода, kind и забалансовость из выгрузки."""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from scripts.convert_chart_1c import ChartRow, convert, read_xlsx, write_csv
|
||||
from scripts.seed import load_seed
|
||||
|
||||
API_DIR = Path(__file__).resolve().parent.parent
|
||||
SEED_DIR = API_DIR / "seed"
|
||||
CHART_SIZE = 488
|
||||
XLSX = API_DIR.parent.parent / "fixtures" / "directories" / "chart-of-accounts-1c.xlsx"
|
||||
|
||||
|
||||
def _rec(code: str, name: str = "Счёт", kind: str = "АП", off: str = "Нет") -> dict[str, object]:
|
||||
return {"Код счета": code, "Наименование счета": name, "Вид": kind, "Заб.": off}
|
||||
|
||||
|
||||
def test_convert_builds_hierarchy_kind_and_row_type() -> None:
|
||||
rows = convert(
|
||||
[_rec("01", kind="А"), _rec("01.К", kind="А"), _rec("76", kind="АП"), _rec("76.07"), _rec("76.07.1", kind="П")]
|
||||
)
|
||||
assert rows == [
|
||||
ChartRow("01", "", "Счёт", "A", "account", False),
|
||||
ChartRow("01.К", "01", "Счёт", "A", "subaccount", False),
|
||||
ChartRow("76", "", "Счёт", "AP", "account", False),
|
||||
ChartRow("76.07", "76", "Счёт", "AP", "subaccount", False),
|
||||
ChartRow("76.07.1", "76.07", "Счёт", "P", "analytic", False),
|
||||
]
|
||||
|
||||
|
||||
def test_convert_off_balance_from_column_and_name_whitespace_collapsed() -> None:
|
||||
(row,) = convert([_rec("МЦ", name=" Материальные ценности ", kind="А", off="Да")])
|
||||
assert row.is_off_balance is True
|
||||
assert row.name == "Материальные ценности"
|
||||
|
||||
|
||||
def test_convert_orphan_without_any_ancestor_gets_empty_parent() -> None:
|
||||
rows = convert([_rec("Я68.01"), _rec("Я69.06.5")])
|
||||
assert [(r.code, r.parent_code, r.row_type) for r in rows] == [
|
||||
("Я68.01", "", "subaccount"),
|
||||
("Я69.06.5", "", "analytic"),
|
||||
]
|
||||
|
||||
|
||||
def test_convert_rejects_gap_in_hierarchy() -> None:
|
||||
with pytest.raises(ValueError, match="более дальний предок"):
|
||||
convert([_rec("76"), _rec("76.07.1")])
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("records", "message"),
|
||||
[
|
||||
([_rec("01"), _rec("01")], "повторяются"),
|
||||
([_rec("01", kind="Х")], "неизвестный вид"),
|
||||
([_rec("01", off="да?")], "Да или Нет"),
|
||||
([_rec("01", name=" ")], "пустое наименование"),
|
||||
([_rec("01.01.1.1")], "глубина"),
|
||||
],
|
||||
)
|
||||
def test_convert_rejects_bad_rows(records: list[dict[str, object]], message: str) -> None:
|
||||
with pytest.raises(ValueError, match=message):
|
||||
convert(records)
|
||||
|
||||
|
||||
@pytest.mark.skipif(not XLSX.is_file(), reason="fixtures/directories/chart-of-accounts-1c.xlsx недоступен")
|
||||
def test_repository_seed_matches_1c_export(tmp_path: Path) -> None:
|
||||
"""Дрейф: seed/core/chart_of_accounts.csv побайтно равен результату конвертера на выгрузке 1С."""
|
||||
out = tmp_path / "chart.csv"
|
||||
write_csv(convert(read_xlsx(XLSX)), out)
|
||||
assert out.read_text(encoding="utf-8") == (SEED_DIR / "core" / "chart_of_accounts.csv").read_text(encoding="utf-8")
|
||||
assert len(load_seed(SEED_DIR).accounts) == CHART_SIZE
|
||||
@ -193,7 +193,7 @@ def test_build_entries_on_golden_osv_66(fixtures_dir: Path) -> None:
|
||||
assert by_id[first.parent_id].row_value == "66.03"
|
||||
assert first.account_root == "66"
|
||||
assert first.account_id == chart["66.03"]
|
||||
assert by_number[13].account_id is None # 66.01 нет в seed-плане счетов
|
||||
assert by_number[13].account_id == chart["66.01"] # 66.01 в плане счетов seed с выгрузкой 1С (issue #23)
|
||||
for entry in sheet.entries:
|
||||
assert (entry.level == 0) == (entry.parent_id is None)
|
||||
assert len(entry.sums) == SUM_COUNT
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
Инварианты: строк `osv_entry` = строк результата без `TOTAL`; у каждой строки уровня > 0 есть родитель (строка того же
|
||||
документа с `row_number = parent_row_number`); шесть сумм равны снимку; `account_id` = строка плана счетов seed для
|
||||
нормализованного кода, а для кодов вне плана — NULL (часть кодов golden в плане seed отсутствует — это норма).
|
||||
нормализованного кода, а для кодов вне плана — NULL (вне плана 1С остаётся только «60.АВ» синтетического снимка).
|
||||
"""
|
||||
|
||||
import json
|
||||
@ -157,6 +157,8 @@ async def test_all_golden_snapshots_mapped(seeded: AsyncSession, fixtures_dir: P
|
||||
f"{sorted(missing_codes)}"
|
||||
)
|
||||
assert problems == []
|
||||
# план счетов seed = выгрузка 1С (issue #23): вне плана остаётся только «60.АВ» синтетического снимка s09
|
||||
assert missing_codes <= {"60.АВ"}
|
||||
assert with_kind > 0 # есть сопоставленные строки: проверка «kind ⇔ counterparty_id» не вырождена
|
||||
assert with_account > 0 # строки со счётом плана счетов есть — сверка account_id не вырождена
|
||||
assert mapping_seconds <= TIME_BUDGET_SECONDS
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
"""Seed плана счетов (spec reference-data-seed, задача 13; design D-9, OQ-47).
|
||||
|
||||
План счетов — полная выгрузка 1С заказчика (issue #23, ASSUMPTION(OQ-113): выгрузка полна, 488 строк).
|
||||
Перечень счетов из §4/§6 правил (`docs/context/05-domain-rules.md`) переписан в тест заново, независимо от
|
||||
`seed/core/chart_of_accounts.csv` и от yaml правил (он появится в задаче 14).
|
||||
"""
|
||||
@ -47,7 +48,16 @@ SYNTHETIC_94N = {
|
||||
} # fmt: skip
|
||||
SYNTHETIC_94N_COUNT = 62
|
||||
MAX_CODE_DOTS = 2 # NN.MM.K
|
||||
OFF_BALANCE = {f"{n:03d}" for n in range(1, 12)}
|
||||
OFF_BALANCE = {f"{n:03d}" for n in range(1, 13)} # 001–012
|
||||
OFF_BALANCE_LETTER = {"ГТД", "ИНВ", "КВ", "МЦ", "НЕ", "ОТ", "РВ", "УСН"} # буквенные забалансовые корни 1С
|
||||
# Балансовые корни выгрузки 1С вне Плана счетов 94н: вспомогательный 000, 53 (в 94н не активен) и «Я…» (не используется)
|
||||
EXTRA_ON_BALANCE_ROOTS = {"000", "53", "Я75", "Я80", "Я81", "Я96"}
|
||||
CHART_SIZE = 488
|
||||
# Субсчета реальных ОСВ, которых не было в seed из 122 строк (OQ-113: 19 кодов с account_id = NULL)
|
||||
OSV_SUBACCOUNTS_FORMERLY_MISSING = {"01.01", "66.01", "76.01", "76.ОТ"}
|
||||
# «60.АВ» есть только в синтетическом снимке s09 (fixtures/golden), в плане 1С его нет: account_id = NULL
|
||||
ORPHANS_1C = {"Я68.01", "Я68.21", "Я68.32", "Я68.42", "Я01.К", "Я69.06.5"} # без родителя в выгрузке
|
||||
NOT_IN_1C_PLAN = {"60.АВ"}
|
||||
|
||||
|
||||
def _write_chart(tmp_path: Path, lines: list[str]) -> Path:
|
||||
@ -73,32 +83,64 @@ def test_repository_chart_is_valid() -> None:
|
||||
for code, account in accounts.items():
|
||||
assert account.code == code
|
||||
assert account.parent_code is None or account.parent_code in accounts
|
||||
if account.row_type is AccountRowType.account:
|
||||
assert account.kind is not None, f"у синтетического счёта {code} не задан kind"
|
||||
else:
|
||||
parent = accounts[str(account.parent_code)]
|
||||
assert account.kind is parent.kind, f"субсчёт {code} должен наследовать kind родителя"
|
||||
assert "." not in code or code == f"{account.parent_code}.{code.rsplit('.', 1)[1]}"
|
||||
# kind берётся из «Вида» 1С и у субсчёта может отличаться от родителя (60.01 — П при 60 — АП)
|
||||
assert account.kind is not None, f"у счёта {code} не задан kind"
|
||||
if account.parent_code is not None:
|
||||
assert code == f"{account.parent_code}.{code.rsplit('.', 1)[1]}"
|
||||
assert accounts[account.parent_code].is_off_balance == account.is_off_balance
|
||||
assert len(accounts) == CHART_SIZE
|
||||
assert all(code.count(".") <= MAX_CODE_DOTS for code in accounts)
|
||||
assert "60.01" in accounts
|
||||
assert "60.1" not in accounts
|
||||
|
||||
|
||||
def test_repository_chart_off_balance_flag_only_for_001_011() -> None:
|
||||
def test_repository_chart_has_no_parent_cycles_and_orphans_are_only_unused_copies() -> None:
|
||||
accounts = load_seed(SEED_DIR).accounts
|
||||
assert {c for c, a in accounts.items() if a.is_off_balance} == OFF_BALANCE
|
||||
for code in accounts:
|
||||
seen, current = {code}, accounts[code].parent_code
|
||||
while current is not None:
|
||||
assert current not in seen, f"цикл в иерархии через {current}"
|
||||
seen.add(current)
|
||||
current = accounts[current].parent_code
|
||||
orphans = {c for c, a in accounts.items() if a.parent_code is None and a.row_type is not AccountRowType.account}
|
||||
# в выгрузке 1С нет родителей «Я68», «Я01», «Я69.06»: родителей не выдумываем
|
||||
assert orphans == {"Я68.01", "Я68.21", "Я68.32", "Я68.42", "Я01.К", "Я69.06.5"}
|
||||
|
||||
|
||||
def test_repository_chart_keeps_letter_and_off_balance_accounts_of_1c() -> None:
|
||||
accounts = load_seed(SEED_DIR).accounts
|
||||
assert {"01.К", "004.К", "62.ОТ", "МЦ.04", "ГТД", "Я68.01", "Я96", "99.02.И", "НЕ.01.1", "РВ.1"} <= set(accounts)
|
||||
assert accounts["01.К"].parent_code == "01"
|
||||
assert accounts["62.ОТ.1"].parent_code == "62.ОТ"
|
||||
assert accounts["003.01"].is_off_balance and accounts["МЦ.02"].is_off_balance
|
||||
assert not accounts["000"].is_off_balance and not accounts["Я68.01"].is_off_balance
|
||||
assert accounts["60.01"].kind is AccountKind.P and accounts["60.02"].kind is AccountKind.A
|
||||
|
||||
|
||||
def test_repository_chart_resolves_subaccounts_formerly_missing() -> None:
|
||||
codes = set(load_seed(SEED_DIR).accounts)
|
||||
assert OSV_SUBACCOUNTS_FORMERLY_MISSING <= codes
|
||||
assert not NOT_IN_1C_PLAN & codes
|
||||
|
||||
|
||||
def test_repository_chart_off_balance_flag_only_for_001_012_and_letter_roots() -> None:
|
||||
accounts = load_seed(SEED_DIR).accounts
|
||||
roots = OFF_BALANCE | OFF_BALANCE_LETTER
|
||||
assert {c for c, a in accounts.items() if a.is_off_balance and a.parent_code is None} == roots
|
||||
assert {c for c, a in accounts.items() if a.is_off_balance} == {c for c in accounts if c.split(".")[0] in roots}
|
||||
assert all(
|
||||
accounts[c].row_type is AccountRowType.account and accounts[c].kind is AccountKind.A for c in OFF_BALANCE
|
||||
)
|
||||
|
||||
|
||||
def test_repository_chart_has_exactly_the_94n_synthetic_accounts() -> None:
|
||||
def test_repository_chart_has_the_94n_synthetic_accounts_and_1c_extras() -> None:
|
||||
accounts = load_seed(SEED_DIR).accounts
|
||||
synthetic_on_balance = {
|
||||
c for c, a in accounts.items() if a.row_type is AccountRowType.account and not a.is_off_balance
|
||||
}
|
||||
assert synthetic_on_balance == SYNTHETIC_94N
|
||||
assert len(synthetic_on_balance) == SYNTHETIC_94N_COUNT
|
||||
assert synthetic_on_balance == SYNTHETIC_94N | EXTRA_ON_BALANCE_ROOTS
|
||||
assert SYNTHETIC_94N_COUNT == len(SYNTHETIC_94N) == 62 # noqa: PLR2004
|
||||
assert SYNTHETIC_94N <= synthetic_on_balance
|
||||
|
||||
|
||||
def test_repository_chart_contains_accounts_of_rules_s4_s6_and_checklist() -> None:
|
||||
@ -140,7 +182,8 @@ def test_validator_rejects_not_normalized_code(tmp_path: Path) -> None:
|
||||
["60,,Расчеты,AP,account,false", "60.1,60,Расчеты (руб),AP,subaccount,false"],
|
||||
)
|
||||
assert message == (
|
||||
"core/chart_of_accounts.csv, строка 3 (60.1): код не нормализован, ожидается вид 60, 001, 60.01 или 76.07.1"
|
||||
"core/chart_of_accounts.csv, строка 3 (60.1): "
|
||||
"код не нормализован, ожидается вид 60, 001, 60.01, 76.07.1, 01.К или МЦ.04"
|
||||
)
|
||||
|
||||
|
||||
@ -181,14 +224,45 @@ def test_validator_rejects_off_balance_flag_missing_for_off_balance_account(tmp_
|
||||
|
||||
def test_validator_rejects_off_balance_flag_for_on_balance_account(tmp_path: Path) -> None:
|
||||
message = _chart_error(tmp_path, ["60,,Расчеты,AP,account,true"])
|
||||
assert (
|
||||
message == "core/chart_of_accounts.csv, строка 2 (60): is_off_balance=true допустим только для счетов 001–011"
|
||||
assert message == (
|
||||
"core/chart_of_accounts.csv, строка 2 (60): "
|
||||
"is_off_balance=true допустим только для счетов 001–012 и буквенных (МЦ, НЕ, ГТД…)"
|
||||
)
|
||||
|
||||
|
||||
def test_validator_rejects_three_digit_code_outside_off_balance_range(tmp_path: Path) -> None:
|
||||
message = _chart_error(tmp_path, ["012,,Неизвестный,A,account,true"])
|
||||
assert message == "core/chart_of_accounts.csv, строка 2 (012): трёхзначные коды допустимы только для 001–011"
|
||||
message = _chart_error(tmp_path, ["013,,Неизвестный,A,account,true"])
|
||||
assert message == "core/chart_of_accounts.csv, строка 2 (013): трёхзначные коды допустимы только для 000–012"
|
||||
|
||||
|
||||
def test_validator_accepts_letter_codes_orphans_and_auxiliary_000(tmp_path: Path) -> None:
|
||||
core = _write_chart(
|
||||
tmp_path,
|
||||
[
|
||||
"000,,Вспомогательный счет,AP,account,false",
|
||||
"01,,Основные средства,A,account,false",
|
||||
"01.К,01,Корректировка,A,subaccount,false",
|
||||
"МЦ,,Материальные ценности,A,account,true",
|
||||
"МЦ.04,МЦ,Инвентарь,A,subaccount,true",
|
||||
"РВ,,Розничная выручка,A,account,true",
|
||||
"РВ.1,РВ,Наличная выручка,A,subaccount,true",
|
||||
"Я68.01,,(Не используется) НДС,P,subaccount,false",
|
||||
],
|
||||
)
|
||||
accounts = load_chart_of_accounts(core, tmp_path)
|
||||
assert accounts["Я68.01"].parent_code is None
|
||||
assert accounts["01.К"].parent_code == "01"
|
||||
assert accounts["МЦ.04"].is_off_balance is True
|
||||
|
||||
|
||||
def test_validator_rejects_empty_parent_when_ancestor_exists(tmp_path: Path) -> None:
|
||||
message = _chart_error(tmp_path, ["60,,Расчеты,AP,account,false", "60.01,,Расчеты (руб),AP,subaccount,false"])
|
||||
assert message == "core/chart_of_accounts.csv, строка 3 (60.01): родитель должен быть «60», указан «»"
|
||||
|
||||
|
||||
def test_validator_rejects_letter_root_without_off_balance_flag(tmp_path: Path) -> None:
|
||||
message = _chart_error(tmp_path, ["МЦ,,Материальные ценности,A,account,false"])
|
||||
assert message == "core/chart_of_accounts.csv, строка 2 (МЦ): забалансовый счёт должен иметь is_off_balance=true"
|
||||
|
||||
|
||||
def test_validator_rejects_account_without_kind(tmp_path: Path) -> None:
|
||||
@ -262,18 +336,20 @@ async def test_run_seed_inserts_chart_with_hierarchy(db_session: AsyncSession) -
|
||||
root_codes = set(
|
||||
(await db_session.scalars(select(ChartOfAccount.code).where(ChartOfAccount.parent_id.is_(None)))).all()
|
||||
)
|
||||
assert root_codes == SYNTHETIC_94N | OFF_BALANCE
|
||||
assert root_codes == SYNTHETIC_94N | EXTRA_ON_BALANCE_ROOTS | OFF_BALANCE | OFF_BALANCE_LETTER | ORPHANS_1C
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
async def test_chart_columns_stored_as_in_file(db_session: AsyncSession) -> None:
|
||||
await run_seed(db_session)
|
||||
rows = {c.code: c for c in (await db_session.scalars(select(ChartOfAccount))).all()}
|
||||
assert rows["60"].kind is AccountKind.AP
|
||||
assert rows["60"].kind is AccountKind.AP and rows["60.01"].kind is AccountKind.P
|
||||
assert rows["01"].kind is AccountKind.A and rows["02"].kind is AccountKind.P
|
||||
assert rows["76.07.1"].row_type is AccountRowType.analytic
|
||||
assert rows["60.01"].row_type is AccountRowType.subaccount
|
||||
assert {c for c, r in rows.items() if r.is_off_balance} == OFF_BALANCE
|
||||
assert {c for c, r in rows.items() if r.is_off_balance} == {
|
||||
c for c in rows if c.split(".")[0] in OFF_BALANCE | OFF_BALANCE_LETTER
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
|
||||
@ -51,8 +51,11 @@ dev-данные загружаются из файлов репозитория
|
||||
### Requirement: Счета правил и чек-листа существуют в плане счетов
|
||||
Все коды счетов, на которые ссылаются `elimination_rules_v1.yaml` и `required_document_rules.yaml`, SHALL резолвиться в
|
||||
`chart_of_account.code` после seed; `elimination_rule_account.is_excluded = true` SHALL быть у исключений вида
|
||||
«76 кроме 76.07.5, 76.07.9»; `chart_of_account.kind` SHALL быть задан для всех синтетических счетов, `is_off_balance = true`
|
||||
для 001–011.
|
||||
«76 кроме 76.07.5, 76.07.9»; `chart_of_account.kind` SHALL быть задан для всех счетов, `is_off_balance = true`
|
||||
для забалансовых счетов 001–012 и буквенных корней плана 1С (МЦ, НЕ, ГТД, ИНВ, КВ, ОТ, РВ, УСН) со всеми их субсчетами.
|
||||
`chart_of_accounts.csv` SHALL содержать полный план счетов 1С заказчика (`fixtures/directories/chart-of-accounts-1c.xlsx`,
|
||||
488 строк, включая буквенные субсчета `01.К`, `62.ОТ`, `76.АВ`; ASSUMPTION(OQ-113): выгрузка полна); `kind` строки — «Вид»
|
||||
1С (у субсчёта может отличаться от родителя); субсчёт без родителя в выгрузке (`Я68.01`) загружается с пустым `parent_code`.
|
||||
|
||||
#### Scenario: Правило № 6 (основная пара)
|
||||
- **WHEN** seed завершён
|
||||
@ -60,6 +63,11 @@ dev-данные загружаются из файлов репозитория
|
||||
76.07.5, 76.07.9; сторона 2 — 60.01, 60.03, 60.21, 60.31, 62.02, 62.22, 62.32, 76 и исключение 76.07.1;
|
||||
`elimination_mode = min`, `measure = closing`, `side_1 = D`
|
||||
|
||||
#### Scenario: Субсчета реальных ОСВ в плане счетов
|
||||
- **WHEN** seed завершён
|
||||
- **THEN** в `chart_of_account` есть `01.01`, `66.01`, `76.01`, `76.ОТ`, `01.К` и `МЦ.04` (строки ОСВ с этими кодами получают
|
||||
`account_id`); `60.АВ` в плане 1С нет, `account_id` таких строк остаётся `NULL`
|
||||
|
||||
#### Scenario: Ссылка на несуществующий счёт
|
||||
- **WHEN** в файл правил добавлен счёт, которого нет в `chart_of_accounts.csv`
|
||||
- **THEN** seed падает до записи в БД с сообщением, какой счёт и в каком правиле не найден
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user