fix: replace stale financial report lines
All checks were successful
All checks were successful
This commit is contained in:
@@ -1168,6 +1168,7 @@ class ExchangePackageImportService:
|
|||||||
skipped_count = 0
|
skipped_count = 0
|
||||||
created_lines_count = 0
|
created_lines_count = 0
|
||||||
updated_lines_count = 0
|
updated_lines_count = 0
|
||||||
|
deleted_lines_count = 0
|
||||||
|
|
||||||
for row in rows:
|
for row in rows:
|
||||||
organization = cls._resolve_organization(
|
organization = cls._resolve_organization(
|
||||||
@@ -1218,6 +1219,7 @@ class ExchangePackageImportService:
|
|||||||
)
|
)
|
||||||
created_lines_count += line_result["created"]
|
created_lines_count += line_result["created"]
|
||||||
updated_lines_count += line_result["updated"]
|
updated_lines_count += line_result["updated"]
|
||||||
|
deleted_lines_count += line_result["deleted"]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"created": created_count,
|
"created": created_count,
|
||||||
@@ -1225,6 +1227,7 @@ class ExchangePackageImportService:
|
|||||||
"skipped": skipped_count,
|
"skipped": skipped_count,
|
||||||
"created_lines": created_lines_count,
|
"created_lines": created_lines_count,
|
||||||
"updated_lines": updated_lines_count,
|
"updated_lines": updated_lines_count,
|
||||||
|
"deleted_lines": deleted_lines_count,
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -1234,7 +1237,7 @@ class ExchangePackageImportService:
|
|||||||
lines: Any,
|
lines: Any,
|
||||||
) -> dict[str, int]:
|
) -> dict[str, int]:
|
||||||
if lines is None:
|
if lines is None:
|
||||||
return {"created": 0, "updated": 0}
|
return {"created": 0, "updated": 0, "deleted": 0}
|
||||||
if not isinstance(lines, list):
|
if not isinstance(lines, list):
|
||||||
raise ExchangeImportError(
|
raise ExchangeImportError(
|
||||||
"Поле lines финансового отчета должно быть списком"
|
"Поле lines финансового отчета должно быть списком"
|
||||||
@@ -1242,6 +1245,7 @@ class ExchangePackageImportService:
|
|||||||
|
|
||||||
created_count = 0
|
created_count = 0
|
||||||
updated_count = 0
|
updated_count = 0
|
||||||
|
expected_keys: set[tuple[str, str, int]] = set()
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if not isinstance(line, dict):
|
if not isinstance(line, dict):
|
||||||
raise ExchangeImportError(
|
raise ExchangeImportError(
|
||||||
@@ -1252,6 +1256,7 @@ class ExchangePackageImportService:
|
|||||||
if not form_code or not line_code:
|
if not form_code or not line_code:
|
||||||
continue
|
continue
|
||||||
year = cls._parse_int_value(line.get("year"), field_name="year")
|
year = cls._parse_int_value(line.get("year"), field_name="year")
|
||||||
|
expected_keys.add((form_code, line_code, year))
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
"line_name": cls._clean_string(line.get("line_name")),
|
"line_name": cls._clean_string(line.get("line_name")),
|
||||||
@@ -1281,7 +1286,22 @@ class ExchangePackageImportService:
|
|||||||
elif state == "updated":
|
elif state == "updated":
|
||||||
updated_count += 1
|
updated_count += 1
|
||||||
|
|
||||||
return {"created": created_count, "updated": updated_count}
|
stale_line_ids = [
|
||||||
|
line.pk
|
||||||
|
for line in report.lines.all()
|
||||||
|
if (line.form_code, line.line_code, line.year) not in expected_keys
|
||||||
|
]
|
||||||
|
deleted_count = 0
|
||||||
|
if stale_line_ids:
|
||||||
|
deleted_count = FinancialReportLine.objects.filter(
|
||||||
|
pk__in=stale_line_ids
|
||||||
|
).delete()[0]
|
||||||
|
|
||||||
|
return {
|
||||||
|
"created": created_count,
|
||||||
|
"updated": updated_count,
|
||||||
|
"deleted": deleted_count,
|
||||||
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _upsert_arbitration_cases(
|
def _upsert_arbitration_cases(
|
||||||
|
|||||||
@@ -769,6 +769,51 @@ class ExchangePackageApiTest(APITestCase):
|
|||||||
duplicate_import = ExchangePackageImport.objects.order_by("-created_at").first()
|
duplicate_import = ExchangePackageImport.objects.order_by("-created_at").first()
|
||||||
self.assertIsNotNone(duplicate_import.duplicate_of)
|
self.assertIsNotNone(duplicate_import.duplicate_of)
|
||||||
|
|
||||||
|
def test_upload_replaces_stale_financial_report_lines(self):
|
||||||
|
first_payload = build_exchange_payload()
|
||||||
|
first_archive = build_exchange_archive(
|
||||||
|
package_id="pkg-financial-year-2025",
|
||||||
|
data=first_payload,
|
||||||
|
)
|
||||||
|
first_response = self.client.post(
|
||||||
|
self.url,
|
||||||
|
{"file": first_archive},
|
||||||
|
format="multipart",
|
||||||
|
HTTP_X_EXCHANGE_TOKEN=TEST_TOKEN,
|
||||||
|
)
|
||||||
|
self.assertEqual(first_response.status_code, status.HTTP_201_CREATED)
|
||||||
|
self.assertEqual(
|
||||||
|
list(FinancialReportLine.objects.values_list("year", flat=True)),
|
||||||
|
[2025],
|
||||||
|
)
|
||||||
|
|
||||||
|
second_payload = build_exchange_payload()
|
||||||
|
second_payload["financial_reports"][0]["lines"][0]["year"] = 2026
|
||||||
|
second_archive = build_exchange_archive(
|
||||||
|
package_id="pkg-financial-year-2026",
|
||||||
|
data=second_payload,
|
||||||
|
)
|
||||||
|
second_response = self.client.post(
|
||||||
|
self.url,
|
||||||
|
{"file": second_archive},
|
||||||
|
format="multipart",
|
||||||
|
HTTP_X_EXCHANGE_TOKEN=TEST_TOKEN,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(second_response.status_code, status.HTTP_201_CREATED)
|
||||||
|
self.assertEqual(
|
||||||
|
list(FinancialReportLine.objects.values_list("year", flat=True)),
|
||||||
|
[2026],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
second_response.data["result"]["financial_reports"]["created_lines"],
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
second_response.data["result"]["financial_reports"]["deleted_lines"],
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
def test_cli_import_uses_same_pipeline(self):
|
def test_cli_import_uses_same_pipeline(self):
|
||||||
archive = build_exchange_archive(
|
archive = build_exchange_archive(
|
||||||
package_id="pkg-cli-001",
|
package_id="pkg-cli-001",
|
||||||
|
|||||||
Reference in New Issue
Block a user