feat(organizations): generate complete test statements
This commit is contained in:
@@ -37,6 +37,76 @@ TEST_FINANCIAL_HISTORY_YEARS = 4
|
|||||||
TEST_COMPANY_NAMESPACE = UUID("59b36ae9-bcf8-4b7c-b77a-77578f485a01")
|
TEST_COMPANY_NAMESPACE = UUID("59b36ae9-bcf8-4b7c-b77a-77578f485a01")
|
||||||
TEST_RECORD_PREFIX = "mostovik-test-company"
|
TEST_RECORD_PREFIX = "mostovik-test-company"
|
||||||
|
|
||||||
|
TEST_BALANCE_LINE_NAMES = {
|
||||||
|
"1110": "Нематериальные активы",
|
||||||
|
"1120": "Результаты исследований и разработок",
|
||||||
|
"1130": "Нематериальные поисковые активы",
|
||||||
|
"1140": "Материальные поисковые активы",
|
||||||
|
"1150": "Основные средства",
|
||||||
|
"1160": "Доходные вложения в материальные ценности",
|
||||||
|
"1170": "Финансовые вложения",
|
||||||
|
"1180": "Отложенные налоговые активы",
|
||||||
|
"1190": "Прочие внеоборотные активы",
|
||||||
|
"1100": "Итого по разделу I",
|
||||||
|
"1210": "Запасы",
|
||||||
|
"1220": "НДС по приобретенным ценностям",
|
||||||
|
"1230": "Дебиторская задолженность",
|
||||||
|
"1240": "Финансовые вложения (за исключением денежных эквивалентов)",
|
||||||
|
"1250": "Денежные средства и денежные эквиваленты",
|
||||||
|
"1260": "Прочие оборотные активы",
|
||||||
|
"1200": "Итого по разделу II",
|
||||||
|
"1600": "БАЛАНС (актив)",
|
||||||
|
"1310": "Уставный капитал",
|
||||||
|
"1320": "Собственные акции, выкупленные у акционеров",
|
||||||
|
"1340": "Переоценка внеоборотных активов",
|
||||||
|
"1350": "Добавочный капитал (без переоценки)",
|
||||||
|
"1360": "Резервный капитал",
|
||||||
|
"1370": "Нераспределенная прибыль (непокрытый убыток)",
|
||||||
|
"1300": "Итого по разделу III",
|
||||||
|
"1410": "Заемные средства",
|
||||||
|
"1420": "Отложенные налоговые обязательства",
|
||||||
|
"1430": "Оценочные обязательства",
|
||||||
|
"1450": "Прочие обязательства",
|
||||||
|
"1400": "Итого по разделу IV",
|
||||||
|
"1510": "Заемные средства",
|
||||||
|
"1520": "Кредиторская задолженность",
|
||||||
|
"1530": "Доходы будущих периодов",
|
||||||
|
"1540": "Оценочные обязательства",
|
||||||
|
"1550": "Прочие обязательства",
|
||||||
|
"1500": "Итого по разделу V",
|
||||||
|
"1700": "БАЛАНС (пассив)",
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_PROFIT_LOSS_LINE_NAMES = {
|
||||||
|
"2110": "Выручка",
|
||||||
|
"2120": "Себестоимость продаж",
|
||||||
|
"2100": "Валовая прибыль (убыток)",
|
||||||
|
"2210": "Коммерческие расходы",
|
||||||
|
"2220": "Управленческие расходы",
|
||||||
|
"2200": "Прибыль (убыток) от продаж",
|
||||||
|
"2310": "Доходы от участия в других организациях",
|
||||||
|
"2320": "Проценты к получению",
|
||||||
|
"2330": "Проценты к уплате",
|
||||||
|
"2340": "Прочие доходы",
|
||||||
|
"2350": "Прочие расходы",
|
||||||
|
"2300": "Прибыль (убыток) до налогообложения",
|
||||||
|
"2410": "Налог на прибыль",
|
||||||
|
"2411": "Текущий налог на прибыль",
|
||||||
|
"2412": "Отложенный налог на прибыль",
|
||||||
|
"2460": "Прочее",
|
||||||
|
"2400": "Чистая прибыль (убыток)",
|
||||||
|
"2510": "Результат от переоценки внеоборотных активов",
|
||||||
|
"2520": "Результат от прочих операций",
|
||||||
|
"2530": "Налог на прибыль от операций вне чистой прибыли",
|
||||||
|
"2500": "Совокупный финансовый результат периода",
|
||||||
|
"2900": "Базовая прибыль (убыток) на акцию",
|
||||||
|
"2910": "Разводненная прибыль (убыток) на акцию",
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_FINANCIAL_LINES_PER_YEAR = len(TEST_BALANCE_LINE_NAMES) + len(
|
||||||
|
TEST_PROFIT_LOSS_LINE_NAMES
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class TestCompanyDatasetResult:
|
class TestCompanyDatasetResult:
|
||||||
@@ -452,7 +522,9 @@ class TestCompanyDatasetService:
|
|||||||
"file_hash": sha256(
|
"file_hash": sha256(
|
||||||
f"financial:{organization.ogrn}".encode()
|
f"financial:{organization.ogrn}".encode()
|
||||||
).hexdigest(),
|
).hexdigest(),
|
||||||
"lines_count": 4,
|
"lines_count": (
|
||||||
|
TEST_FINANCIAL_LINES_PER_YEAR * TEST_FINANCIAL_HISTORY_YEARS
|
||||||
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ParserLoadLog.Source.PROCUREMENTS: cls._procurement_values(
|
ParserLoadLog.Source.PROCUREMENTS: cls._procurement_values(
|
||||||
@@ -670,57 +742,215 @@ class TestCompanyDatasetService:
|
|||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _refresh_financial_lines(*, record, legacy_report, index: int) -> None:
|
def _test_amount(
|
||||||
|
*,
|
||||||
|
base: int,
|
||||||
|
index: int,
|
||||||
|
year: int,
|
||||||
|
per_company: int,
|
||||||
|
annual_growth: int,
|
||||||
|
) -> int:
|
||||||
|
"""Return a stable amount for the same company and calendar year."""
|
||||||
|
return base + index * per_company + (year - 2020) * annual_growth
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _balance_values(cls, *, index: int, year: int) -> dict[str, int]:
|
||||||
|
"""Build a balanced form 0710001 in thousands of rubles."""
|
||||||
|
|
||||||
|
def amount(base: int, per_company: int, annual_growth: int) -> int:
|
||||||
|
return cls._test_amount(
|
||||||
|
base=base,
|
||||||
|
index=index,
|
||||||
|
year=year,
|
||||||
|
per_company=per_company,
|
||||||
|
annual_growth=annual_growth,
|
||||||
|
)
|
||||||
|
|
||||||
|
values = {
|
||||||
|
"1110": amount(350, 7, 25),
|
||||||
|
"1120": amount(220, 5, 18),
|
||||||
|
"1130": amount(80, 2, 6),
|
||||||
|
"1140": amount(70, 2, 5),
|
||||||
|
"1150": amount(4_800, 60, 240),
|
||||||
|
"1160": amount(300, 8, 22),
|
||||||
|
"1170": amount(900, 18, 70),
|
||||||
|
"1180": amount(180, 4, 12),
|
||||||
|
"1190": amount(140, 3, 10),
|
||||||
|
"1210": amount(3_400, 45, 190),
|
||||||
|
"1220": amount(240, 5, 12),
|
||||||
|
"1230": amount(3_800, 55, 220),
|
||||||
|
"1240": amount(1_100, 20, 90),
|
||||||
|
"1250": amount(1_500, 30, 120),
|
||||||
|
"1260": amount(260, 6, 16),
|
||||||
|
"1310": amount(3_500, 30, 100),
|
||||||
|
"1320": -amount(120, 2, 5),
|
||||||
|
"1340": amount(320, 4, 15),
|
||||||
|
"1350": amount(280, 3, 12),
|
||||||
|
"1360": amount(240, 3, 10),
|
||||||
|
"1410": amount(2_300, 32, 110),
|
||||||
|
"1420": amount(220, 4, 12),
|
||||||
|
"1430": amount(180, 3, 9),
|
||||||
|
"1450": amount(240, 4, 11),
|
||||||
|
"1510": amount(1_600, 25, 80),
|
||||||
|
"1520": amount(3_200, 40, 150),
|
||||||
|
"1530": amount(120, 2, 6),
|
||||||
|
"1540": amount(250, 4, 12),
|
||||||
|
"1550": amount(320, 5, 15),
|
||||||
|
}
|
||||||
|
|
||||||
|
values["1100"] = sum(
|
||||||
|
values[code]
|
||||||
|
for code in (
|
||||||
|
"1110",
|
||||||
|
"1120",
|
||||||
|
"1130",
|
||||||
|
"1140",
|
||||||
|
"1150",
|
||||||
|
"1160",
|
||||||
|
"1170",
|
||||||
|
"1180",
|
||||||
|
"1190",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
values["1200"] = sum(
|
||||||
|
values[code] for code in ("1210", "1220", "1230", "1240", "1250", "1260")
|
||||||
|
)
|
||||||
|
values["1600"] = values["1100"] + values["1200"]
|
||||||
|
values["1400"] = sum(values[code] for code in ("1410", "1420", "1430", "1450"))
|
||||||
|
values["1500"] = sum(
|
||||||
|
values[code] for code in ("1510", "1520", "1530", "1540", "1550")
|
||||||
|
)
|
||||||
|
equity_without_retained = sum(
|
||||||
|
values[code] for code in ("1310", "1320", "1340", "1350", "1360")
|
||||||
|
)
|
||||||
|
values["1370"] = (
|
||||||
|
values["1600"] - equity_without_retained - values["1400"] - values["1500"]
|
||||||
|
)
|
||||||
|
values["1300"] = equity_without_retained + values["1370"]
|
||||||
|
values["1700"] = values["1300"] + values["1400"] + values["1500"]
|
||||||
|
return values
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _profit_loss_values(cls, *, index: int, year: int) -> dict[str, int]:
|
||||||
|
"""Build a form 0710002 whose calculated rows reconcile."""
|
||||||
|
|
||||||
|
def amount(base: int, per_company: int, annual_growth: int) -> int:
|
||||||
|
return cls._test_amount(
|
||||||
|
base=base,
|
||||||
|
index=index,
|
||||||
|
year=year,
|
||||||
|
per_company=per_company,
|
||||||
|
annual_growth=annual_growth,
|
||||||
|
)
|
||||||
|
|
||||||
|
revenue = amount(32_000, 800, 2_400)
|
||||||
|
cost_of_sales = revenue * 61 // 100
|
||||||
|
gross_profit = revenue - cost_of_sales
|
||||||
|
commercial_expenses = revenue * 5 // 100
|
||||||
|
management_expenses = revenue * 8 // 100
|
||||||
|
sales_profit = gross_profit - commercial_expenses - management_expenses
|
||||||
|
participation_income = amount(180, 6, 14)
|
||||||
|
interest_income = amount(220, 5, 16)
|
||||||
|
interest_expense = amount(310, 7, 20)
|
||||||
|
other_income = amount(760, 15, 45)
|
||||||
|
other_expense = amount(620, 12, 38)
|
||||||
|
profit_before_tax = (
|
||||||
|
sales_profit
|
||||||
|
+ participation_income
|
||||||
|
+ interest_income
|
||||||
|
- interest_expense
|
||||||
|
+ other_income
|
||||||
|
- other_expense
|
||||||
|
)
|
||||||
|
current_tax = profit_before_tax * 19 // 100
|
||||||
|
deferred_tax = profit_before_tax // 100
|
||||||
|
income_tax = current_tax + deferred_tax
|
||||||
|
other_tax_effects = amount(25, 1, 2)
|
||||||
|
net_profit = profit_before_tax - income_tax - other_tax_effects
|
||||||
|
revaluation_result = amount(90, 3, 7)
|
||||||
|
other_operations_result = amount(55, 2, 5)
|
||||||
|
other_operations_tax = amount(18, 1, 1)
|
||||||
|
comprehensive_result = (
|
||||||
|
net_profit
|
||||||
|
+ revaluation_result
|
||||||
|
+ other_operations_result
|
||||||
|
- other_operations_tax
|
||||||
|
)
|
||||||
|
basic_eps = max(1, net_profit // 1_000)
|
||||||
|
diluted_eps = max(1, basic_eps - 1)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"2110": revenue,
|
||||||
|
"2120": cost_of_sales,
|
||||||
|
"2100": gross_profit,
|
||||||
|
"2210": commercial_expenses,
|
||||||
|
"2220": management_expenses,
|
||||||
|
"2200": sales_profit,
|
||||||
|
"2310": participation_income,
|
||||||
|
"2320": interest_income,
|
||||||
|
"2330": interest_expense,
|
||||||
|
"2340": other_income,
|
||||||
|
"2350": other_expense,
|
||||||
|
"2300": profit_before_tax,
|
||||||
|
"2410": income_tax,
|
||||||
|
"2411": current_tax,
|
||||||
|
"2412": deferred_tax,
|
||||||
|
"2460": other_tax_effects,
|
||||||
|
"2400": net_profit,
|
||||||
|
"2510": revaluation_result,
|
||||||
|
"2520": other_operations_result,
|
||||||
|
"2530": other_operations_tax,
|
||||||
|
"2500": comprehensive_result,
|
||||||
|
"2900": basic_eps,
|
||||||
|
"2910": diluted_eps,
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _financial_line_definitions(cls, *, index: int, year: int):
|
||||||
|
forms = (
|
||||||
|
(
|
||||||
|
"1",
|
||||||
|
TEST_BALANCE_LINE_NAMES,
|
||||||
|
cls._balance_values,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"2",
|
||||||
|
TEST_PROFIT_LOSS_LINE_NAMES,
|
||||||
|
cls._profit_loss_values,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
for form_code, names, value_factory in forms:
|
||||||
|
period_start_values = value_factory(index=index, year=year - 1)
|
||||||
|
period_end_values = value_factory(index=index, year=year)
|
||||||
|
for line_code, line_name in names.items():
|
||||||
|
yield (
|
||||||
|
form_code,
|
||||||
|
line_code,
|
||||||
|
line_name,
|
||||||
|
period_start_values[line_code],
|
||||||
|
period_end_values[line_code],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _refresh_financial_lines(cls, *, record, legacy_report, index: int) -> None:
|
||||||
current_year = timezone.localdate().year
|
current_year = timezone.localdate().year
|
||||||
report_years = range(
|
report_years = range(
|
||||||
current_year - TEST_FINANCIAL_HISTORY_YEARS + 1,
|
current_year - TEST_FINANCIAL_HISTORY_YEARS + 1,
|
||||||
current_year + 1,
|
current_year + 1,
|
||||||
)
|
)
|
||||||
expected = (
|
|
||||||
(
|
|
||||||
"1",
|
|
||||||
"1600",
|
|
||||||
"Баланс (актив)",
|
|
||||||
10_000_000 + index * 100_000,
|
|
||||||
300_000 + index * 2_000,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"1",
|
|
||||||
"1300",
|
|
||||||
"Капитал и резервы",
|
|
||||||
4_000_000 + index * 50_000,
|
|
||||||
120_000 + index * 1_000,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"2",
|
|
||||||
"2110",
|
|
||||||
"Выручка",
|
|
||||||
20_000_000 + index * 200_000,
|
|
||||||
750_000 + index * 5_000,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"2",
|
|
||||||
"2400",
|
|
||||||
"Чистая прибыль",
|
|
||||||
2_000_000 + index * 25_000,
|
|
||||||
80_000 + index * 500,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
expected_keys = set()
|
expected_keys = set()
|
||||||
for report_year in report_years:
|
for report_year in report_years:
|
||||||
years_before_current = current_year - report_year
|
|
||||||
for (
|
for (
|
||||||
form_code,
|
form_code,
|
||||||
line_code,
|
line_code,
|
||||||
line_name,
|
line_name,
|
||||||
current_period_end,
|
period_start,
|
||||||
annual_change,
|
period_end,
|
||||||
) in expected:
|
) in cls._financial_line_definitions(index=index, year=report_year):
|
||||||
period_end = current_period_end - annual_change * years_before_current
|
|
||||||
expected_keys.add((form_code, line_code, report_year))
|
expected_keys.add((form_code, line_code, report_year))
|
||||||
defaults = {
|
defaults = {
|
||||||
"line_name": line_name,
|
"line_name": line_name,
|
||||||
"period_start": period_end - annual_change,
|
"period_start": period_start,
|
||||||
"period_end": period_end,
|
"period_end": period_end,
|
||||||
}
|
}
|
||||||
OrganizationSourceFinancialLine.objects.update_or_create(
|
OrganizationSourceFinancialLine.objects.update_or_create(
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ from organizations.models import (
|
|||||||
SourceGroup,
|
SourceGroup,
|
||||||
)
|
)
|
||||||
from organizations.test_companies import (
|
from organizations.test_companies import (
|
||||||
|
TEST_BALANCE_LINE_NAMES,
|
||||||
TEST_FINANCIAL_HISTORY_YEARS,
|
TEST_FINANCIAL_HISTORY_YEARS,
|
||||||
|
TEST_FINANCIAL_LINES_PER_YEAR,
|
||||||
|
TEST_PROFIT_LOSS_LINE_NAMES,
|
||||||
TEST_RECORD_PREFIX,
|
TEST_RECORD_PREFIX,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -92,7 +95,7 @@ class TestCompaniesCommandsTest(TestCase):
|
|||||||
OrganizationSourceFinancialLine.objects.filter(
|
OrganizationSourceFinancialLine.objects.filter(
|
||||||
source_record__extension__organization__in=companies
|
source_record__extension__organization__in=companies
|
||||||
).count(),
|
).count(),
|
||||||
20 * 4 * TEST_FINANCIAL_HISTORY_YEARS,
|
20 * TEST_FINANCIAL_LINES_PER_YEAR * TEST_FINANCIAL_HISTORY_YEARS,
|
||||||
)
|
)
|
||||||
current_year = timezone.localdate().year
|
current_year = timezone.localdate().year
|
||||||
expected_financial_years = set(
|
expected_financial_years = set(
|
||||||
@@ -124,7 +127,7 @@ class TestCompaniesCommandsTest(TestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
FinancialReportLine.objects.count(),
|
FinancialReportLine.objects.count(),
|
||||||
20 * 4 * TEST_FINANCIAL_HISTORY_YEARS,
|
20 * TEST_FINANCIAL_LINES_PER_YEAR * TEST_FINANCIAL_HISTORY_YEARS,
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
set(FinancialReportLine.objects.values_list("year", flat=True)),
|
set(FinancialReportLine.objects.values_list("year", flat=True)),
|
||||||
@@ -250,14 +253,10 @@ class TestCompaniesCommandsTest(TestCase):
|
|||||||
self.assertEqual(len(reports), 20)
|
self.assertEqual(len(reports), 20)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
sum(len(report["lines"]) for report in reports),
|
sum(len(report["lines"]) for report in reports),
|
||||||
20 * 4 * TEST_FINANCIAL_HISTORY_YEARS,
|
20 * TEST_FINANCIAL_LINES_PER_YEAR * TEST_FINANCIAL_HISTORY_YEARS,
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
{
|
{line["year"] for report in reports for line in report["lines"]},
|
||||||
line["year"]
|
|
||||||
for report in reports
|
|
||||||
for line in report["lines"]
|
|
||||||
},
|
|
||||||
set(
|
set(
|
||||||
range(
|
range(
|
||||||
timezone.localdate().year - TEST_FINANCIAL_HISTORY_YEARS + 1,
|
timezone.localdate().year - TEST_FINANCIAL_HISTORY_YEARS + 1,
|
||||||
@@ -266,6 +265,138 @@ class TestCompaniesCommandsTest(TestCase):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_financial_statements_are_complete_balanced_and_periodic(self):
|
||||||
|
call_command("create_test_companies", stdout=StringIO())
|
||||||
|
|
||||||
|
company = Organization.objects.get(name="Тестовая компания 1")
|
||||||
|
record = OrganizationSourceRecord.objects.get(
|
||||||
|
extension__organization=company,
|
||||||
|
source=ParserLoadLog.Source.FNS_REPORTS,
|
||||||
|
)
|
||||||
|
lines = list(
|
||||||
|
OrganizationSourceFinancialLine.objects.filter(
|
||||||
|
source_record=record
|
||||||
|
).order_by("year", "form_code", "line_code")
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
len(lines),
|
||||||
|
TEST_FINANCIAL_LINES_PER_YEAR * TEST_FINANCIAL_HISTORY_YEARS,
|
||||||
|
)
|
||||||
|
self.assertTrue(
|
||||||
|
all(
|
||||||
|
line.period_start is not None and line.period_end is not None
|
||||||
|
for line in lines
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
lines_by_year = {}
|
||||||
|
for line in lines:
|
||||||
|
lines_by_year.setdefault(line.year, {})[
|
||||||
|
(line.form_code, line.line_code)
|
||||||
|
] = line
|
||||||
|
|
||||||
|
expected_codes = {
|
||||||
|
*(("1", code) for code in TEST_BALANCE_LINE_NAMES),
|
||||||
|
*(("2", code) for code in TEST_PROFIT_LOSS_LINE_NAMES),
|
||||||
|
}
|
||||||
|
ordered_years = sorted(lines_by_year)
|
||||||
|
for year in ordered_years:
|
||||||
|
year_lines = lines_by_year[year]
|
||||||
|
self.assertEqual(set(year_lines), expected_codes)
|
||||||
|
values = {key: line.period_end for key, line in year_lines.items()}
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
values[("1", "1100")],
|
||||||
|
sum(
|
||||||
|
values[("1", code)]
|
||||||
|
for code in (
|
||||||
|
"1110",
|
||||||
|
"1120",
|
||||||
|
"1130",
|
||||||
|
"1140",
|
||||||
|
"1150",
|
||||||
|
"1160",
|
||||||
|
"1170",
|
||||||
|
"1180",
|
||||||
|
"1190",
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
values[("1", "1200")],
|
||||||
|
sum(
|
||||||
|
values[("1", code)]
|
||||||
|
for code in ("1210", "1220", "1230", "1240", "1250", "1260")
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
values[("1", "1600")],
|
||||||
|
values[("1", "1100")] + values[("1", "1200")],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
values[("1", "1300")],
|
||||||
|
sum(
|
||||||
|
values[("1", code)]
|
||||||
|
for code in ("1310", "1320", "1340", "1350", "1360", "1370")
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
values[("1", "1400")],
|
||||||
|
sum(values[("1", code)] for code in ("1410", "1420", "1430", "1450")),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
values[("1", "1500")],
|
||||||
|
sum(
|
||||||
|
values[("1", code)]
|
||||||
|
for code in ("1510", "1520", "1530", "1540", "1550")
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(values[("1", "1600")], values[("1", "1700")])
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
values[("2", "2100")],
|
||||||
|
values[("2", "2110")] - values[("2", "2120")],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
values[("2", "2200")],
|
||||||
|
values[("2", "2100")] - values[("2", "2210")] - values[("2", "2220")],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
values[("2", "2300")],
|
||||||
|
values[("2", "2200")]
|
||||||
|
+ values[("2", "2310")]
|
||||||
|
+ values[("2", "2320")]
|
||||||
|
- values[("2", "2330")]
|
||||||
|
+ values[("2", "2340")]
|
||||||
|
- values[("2", "2350")],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
values[("2", "2410")],
|
||||||
|
values[("2", "2411")] + values[("2", "2412")],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
values[("2", "2400")],
|
||||||
|
values[("2", "2300")] - values[("2", "2410")] - values[("2", "2460")],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
values[("2", "2500")],
|
||||||
|
values[("2", "2400")]
|
||||||
|
+ values[("2", "2510")]
|
||||||
|
+ values[("2", "2520")]
|
||||||
|
- values[("2", "2530")],
|
||||||
|
)
|
||||||
|
|
||||||
|
for previous_year, current_year in zip(
|
||||||
|
ordered_years,
|
||||||
|
ordered_years[1:],
|
||||||
|
strict=False,
|
||||||
|
):
|
||||||
|
for key, current_line in lines_by_year[current_year].items():
|
||||||
|
self.assertEqual(
|
||||||
|
current_line.period_start,
|
||||||
|
lines_by_year[previous_year][key].period_end,
|
||||||
|
)
|
||||||
|
|
||||||
def test_delete_removes_only_the_fixed_twenty_companies(self):
|
def test_delete_removes_only_the_fixed_twenty_companies(self):
|
||||||
untouched = Organization.objects.create(
|
untouched = Organization.objects.create(
|
||||||
name="Тестовая компания 99",
|
name="Тестовая компания 99",
|
||||||
|
|||||||
Reference in New Issue
Block a user