feat(parsers): implement arbitration and upload fixes
All checks were successful
CI/CD Pipeline / Quality Gate (push) Successful in 19s
CI/CD Pipeline / Build and Push Images (push) Successful in 6s
CI/CD Pipeline / Internal Notify (push) Successful in 1s
CI/CD Pipeline / Deploy Dev in Dokploy (push) Successful in 2s

This commit is contained in:
2026-04-29 00:52:12 +02:00
parent db824bf4fa
commit 8e29b9902d
7 changed files with 578 additions and 16 deletions

View File

@@ -5,6 +5,7 @@ from __future__ import annotations
import io
import os
import tempfile
import zipfile
from unittest.mock import Mock, patch
from apps.parsers.models import (
@@ -50,6 +51,14 @@ def _build_fns_excel_bytes() -> bytes:
return buf.getvalue()
def _build_fns_zip_bytes(file_map: dict[str, bytes]) -> bytes:
buf = io.BytesIO()
with zipfile.ZipFile(buf, "w", compression=zipfile.ZIP_DEFLATED) as archive:
for file_name, content in file_map.items():
archive.writestr(file_name, content)
return buf.getvalue()
def _create_procurement_record() -> ProcurementRecord:
return ProcurementRecord.objects.create(
load_batch=fake.random_int(min=1, max=1000),
@@ -411,6 +420,34 @@ class ParsersViewSetTest(APITestCase):
self.assertEqual(response.data["success"], True)
self.assertIn("message", response.data)
def test_fns_upload_accepts_zip_payload(self):
self.client.force_authenticate(self.admin)
external_id = _digits(5)
ogrn = _digits(13)
filename = f"fin_{external_id}_{ogrn}.xlsx"
upload = SimpleUploadedFile(
"fns_reports.zip",
_build_fns_zip_bytes({filename: _build_fns_excel_bytes()}),
content_type="application/zip",
)
with tempfile.TemporaryDirectory() as tmpdir:
watch_dir = os.path.join(tmpdir, "watch")
processed_dir = os.path.join(tmpdir, "processed")
failed_dir = os.path.join(tmpdir, "failed")
with self.settings(
FNS_WATCH_DIRECTORY=watch_dir,
FNS_PROCESSED_DIRECTORY=processed_dir,
FNS_FAILED_DIRECTORY=failed_dir,
):
url = reverse("api_v1:fns:fns-upload")
response = self.client.post(url, {"file": upload}, format="multipart")
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
self.assertEqual(response.data["queued"], 1)
self.assertEqual(response.data["skipped"], 0)
self.assertEqual(response.data["invalid"], 0)
self.assertEqual(FinancialReport.objects.count(), 1)
def test_parsing_settings_get_and_patch(self):
self.client.force_authenticate(self.admin)
url = reverse("api_v1:parsing:parsing-settings")