From 7da934399e934b7764753e5715b9daf8a21a9e35 Mon Sep 17 00:00:00 2001 From: Raykov-MS Date: Mon, 29 Jun 2026 17:17:28 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=B2=20=D1=81=D1=85=D0=B5=D0=BC=D0=B0=D1=85=20=D0=B8=20=D0=BB?= =?UTF-8?q?=D0=BE=D0=B3=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/alembic/versions/sql/0002_functions.sql | 25 +++++------------ api/src/api/v1/vsp.py | 12 ++++----- api/src/domain/schemas.py | 10 ++++--- api/src/repository/vsp_repository.py | 30 ++++++++++----------- api/src/services/vsp_service.py | 22 +++++++-------- api/tests/integration/test_vsp.py | 4 +-- 6 files changed, 46 insertions(+), 57 deletions(-) diff --git a/api/alembic/versions/sql/0002_functions.sql b/api/alembic/versions/sql/0002_functions.sql index 28f718a..cdf70dc 100644 --- a/api/alembic/versions/sql/0002_functions.sql +++ b/api/alembic/versions/sql/0002_functions.sql @@ -1123,9 +1123,9 @@ END; $function$ ; --- DROP FUNCTION v3.add_vsp(int4, varchar, varchar, varchar, date, varchar, int4, numeric, date, bool, bool, varchar, int4, varchar, text, varchar, int4, varchar, date); +-- DROP FUNCTION v3.add_vsp(int4, varchar, varchar, varchar, date, varchar, int4, numeric, date, bool, bool, varchar, int4, varchar, text, varchar, varchar, date); -CREATE OR REPLACE FUNCTION v3.add_vsp(p_branch_id integer, p_reg_number character varying DEFAULT NULL::character varying, p_address character varying DEFAULT NULL::character varying, p_format character varying DEFAULT NULL::character varying, p_opened_at date DEFAULT NULL::date, p_placement_type character varying DEFAULT NULL::character varying, p_staff_count integer DEFAULT NULL::integer, p_total_area numeric DEFAULT NULL::numeric, p_closed_at date DEFAULT NULL::date, p_is_active boolean DEFAULT true, p_is_deleted boolean DEFAULT false, p_system_code character varying DEFAULT NULL::character varying, p_created_by integer DEFAULT NULL::integer, p_vsp_type character varying DEFAULT NULL::character varying, p_notes text DEFAULT NULL::text, p_location_form character varying DEFAULT NULL::character varying, p_numbers integer DEFAULT NULL::integer, p_rent_contract_num character varying DEFAULT NULL::character varying, p_rent_end_date date DEFAULT NULL::date) +CREATE OR REPLACE FUNCTION v3.add_vsp(p_branch_id integer, p_reg_number character varying DEFAULT NULL::character varying, p_address character varying DEFAULT NULL::character varying, p_format character varying DEFAULT NULL::character varying, p_opened_at date DEFAULT NULL::date, p_placement_type character varying DEFAULT NULL::character varying, p_staff_count integer DEFAULT NULL::integer, p_total_area numeric DEFAULT NULL::numeric, p_closed_at date DEFAULT NULL::date, p_is_active boolean DEFAULT true, p_is_deleted boolean DEFAULT false, p_system_code character varying DEFAULT NULL::character varying, p_created_by integer DEFAULT NULL::integer, p_vsp_type character varying DEFAULT NULL::character varying, p_notes text DEFAULT NULL::text, p_location_form character varying DEFAULT NULL::character varying, p_rent_contract_num character varying DEFAULT NULL::character varying, p_rent_end_date date DEFAULT NULL::date) RETURNS integer LANGUAGE plpgsql AS $function$ @@ -1153,14 +1153,12 @@ BEGIN (branch_id, reg_number, address, format, opened_at, placement_type, staff_count, total_area, closed_at, is_active, is_deleted, system_code, created_by, - vsp_type, notes, location_form, numbers, - rent_contract_num, rent_end_date) + vsp_type, notes, location_form, rent_contract_num, rent_end_date) VALUES (p_branch_id, p_reg_number, p_address, p_format, p_opened_at, p_placement_type, p_staff_count, p_total_area, p_closed_at, p_is_active, p_is_deleted, p_system_code, p_created_by, - p_vsp_type, p_notes, p_location_form, p_numbers, - p_rent_contract_num, p_rent_end_date) + p_vsp_type, p_notes, p_location_form, p_rent_contract_num, p_rent_end_date) RETURNING id INTO v_id; PERFORM v3.log_event( @@ -1185,7 +1183,6 @@ BEGIN 'vsp_type', p_vsp_type, 'notes', p_notes, 'location_form', p_location_form, - 'numbers', p_numbers, 'rent_contract_num', p_rent_contract_num, 'rent_end_date', v3._diff_val(p_rent_end_date), 'user_email', v_actor_email, @@ -2738,9 +2735,9 @@ END; $function$ ; --- DROP FUNCTION v3.upd_vsp(int4, int4, varchar, varchar, varchar, date, varchar, int4, numeric, date, bool, bool, varchar, int4, varchar, text, varchar, int4, varchar, date); +-- DROP FUNCTION v3.upd_vsp(int4, int4, varchar, varchar, varchar, date, varchar, int4, numeric, date, bool, bool, varchar, int4, varchar, text, varchar, varchar, date); -CREATE OR REPLACE FUNCTION v3.upd_vsp(p_vsp_id integer, p_branch_id integer DEFAULT NULL::integer, p_reg_number character varying DEFAULT NULL::character varying, p_address character varying DEFAULT NULL::character varying, p_format character varying DEFAULT NULL::character varying, p_opened_at date DEFAULT NULL::date, p_placement_type character varying DEFAULT NULL::character varying, p_staff_count integer DEFAULT NULL::integer, p_total_area numeric DEFAULT NULL::numeric, p_closed_at date DEFAULT NULL::date, p_is_active boolean DEFAULT NULL::boolean, p_is_deleted boolean DEFAULT NULL::boolean, p_system_code character varying DEFAULT NULL::character varying, p_updated_by integer DEFAULT NULL::integer, p_vsp_type character varying DEFAULT NULL::character varying, p_notes text DEFAULT NULL::text, p_location_form character varying DEFAULT NULL::character varying, p_numbers integer DEFAULT NULL::integer, p_rent_contract_num character varying DEFAULT NULL::character varying, p_rent_end_date date DEFAULT NULL::date) +CREATE OR REPLACE FUNCTION v3.upd_vsp(p_vsp_id integer, p_branch_id integer DEFAULT NULL::integer, p_reg_number character varying DEFAULT NULL::character varying, p_address character varying DEFAULT NULL::character varying, p_format character varying DEFAULT NULL::character varying, p_opened_at date DEFAULT NULL::date, p_placement_type character varying DEFAULT NULL::character varying, p_staff_count integer DEFAULT NULL::integer, p_total_area numeric DEFAULT NULL::numeric, p_closed_at date DEFAULT NULL::date, p_is_active boolean DEFAULT NULL::boolean, p_is_deleted boolean DEFAULT NULL::boolean, p_system_code character varying DEFAULT NULL::character varying, p_updated_by integer DEFAULT NULL::integer, p_vsp_type character varying DEFAULT NULL::character varying, p_notes text DEFAULT NULL::text, p_location_form character varying DEFAULT NULL::character varying, p_rent_contract_num character varying DEFAULT NULL::character varying, p_rent_end_date date DEFAULT NULL::date) RETURNS void LANGUAGE plpgsql AS $function$ @@ -2758,8 +2755,7 @@ BEGIN SELECT v.branch_id, v.reg_number, v.address, v.format, v.opened_at, v.placement_type, v.staff_count, v.total_area, v.closed_at, v.is_active, v.is_deleted, v.system_code, - v.vsp_type, v.notes, v.location_form, v.numbers, - v.rent_contract_num, v.rent_end_date + v.vsp_type, v.notes, v.location_form, v.rent_contract_num, v.rent_end_date INTO v_old FROM v3.vsp v WHERE v.id = p_vsp_id; @@ -2899,13 +2895,6 @@ BEGIN 'after', v3._diff_val(p_location_form))); END IF; - IF p_numbers IS NOT NULL AND p_numbers IS DISTINCT FROM v_old.numbers THEN - UPDATE v3.vsp SET numbers = p_numbers WHERE id = p_vsp_id; - v_changes := v_changes || jsonb_build_object('numbers', - jsonb_build_object('before', v3._diff_val(v_old.numbers), - 'after', v3._diff_val(p_numbers))); - END IF; - IF p_rent_contract_num IS NOT NULL AND p_rent_contract_num IS DISTINCT FROM v_old.rent_contract_num THEN UPDATE v3.vsp SET rent_contract_num = p_rent_contract_num WHERE id = p_vsp_id; v_changes := v_changes || jsonb_build_object('rent_contract_num', diff --git a/api/src/api/v1/vsp.py b/api/src/api/v1/vsp.py index b4947f4..1cd34c6 100644 --- a/api/src/api/v1/vsp.py +++ b/api/src/api/v1/vsp.py @@ -28,8 +28,8 @@ async def get_vsp( open_date_start: date | None = None, open_date_end: date | None = None, location_form: str | None = None, - numbers_min: int | None = None, - numbers_max: int | None = None, + staff_count_min: int | None = None, + staff_count_max: int | None = None, db: AsyncSession = Depends(get_db), current_user: AppUser = Depends(require_executor), ): @@ -43,8 +43,8 @@ async def get_vsp( open_date_start=open_date_start, open_date_end=open_date_end, location_form=location_form, - numbers_min=numbers_min, - numbers_max=numbers_max, + staff_count_min=staff_count_min, + staff_count_max=staff_count_max, load_org_unit=True, with_count=True, ) @@ -90,8 +90,8 @@ async def export_info( open_date_start=body.open_date_start, open_date_end=body.open_date_end, location_form=body.location_form, - numbers_min=body.numbers_min, - numbers_max=body.numbers_max, + staff_count_min=body.staff_count_min, + staff_count_max=body.staff_count_max, ) return StreamingResponse( stream, diff --git a/api/src/domain/schemas.py b/api/src/domain/schemas.py index 261cba8..ce441d3 100644 --- a/api/src/domain/schemas.py +++ b/api/src/domain/schemas.py @@ -490,8 +490,9 @@ class VSPBase(BaseModel): serialization_alias='approved_format', ) notes: Optional[str] = Field(None, description="Примечания") + placement_type: Optional[str] = Field(None, description="Тип размещения") + staff_count: Optional[int] = Field(None, description="Штатная численность") location_form: Optional[str] = Field(None, description="Форма расположения") - numbers: Optional[int] = Field(None, description="Штатная численность") area: Optional[float] = Field( None, description="Арендная площадь", @@ -539,8 +540,9 @@ class VSPEditBase(BaseModel): serialization_alias='format', ) notes: Optional[str] = Field(None, description="Примечания") + placement_type: Optional[str] = Field(None, description="Тип размещения") + staff_count: Optional[int] = Field(None, description="Штатная численность") location_form: Optional[str] = Field(None, description="Форма расположения") - numbers: Optional[int] = Field(None, description="Штатная численность") total_area: Optional[float] = Field( None, description="Арендная площадь", @@ -612,8 +614,8 @@ class VSPExportRequest(BaseModel): open_date_start: Optional[date] = None open_date_end: Optional[date] = None location_form: Optional[str] = None - numbers_min: Optional[int] = None - numbers_max: Optional[int] = None + staff_count_min: Optional[int] = None + staff_count_max: Optional[int] = None class ExpenseItemBaseSchema(BaseModel): diff --git a/api/src/repository/vsp_repository.py b/api/src/repository/vsp_repository.py index 5740b9c..51ef4a0 100644 --- a/api/src/repository/vsp_repository.py +++ b/api/src/repository/vsp_repository.py @@ -37,8 +37,8 @@ class VSPRepository: open_date_start: date | None = None, open_date_end: date | None = None, location_form: str | None = None, - numbers_min: int | None = None, - numbers_max: int | None = None, + staff_count_min: int | None = None, + staff_count_max: int | None = None, is_active: bool | None = True, close_date_is_null: bool | None = None, load_org_unit: bool = False, @@ -56,8 +56,8 @@ class VSPRepository: ("location_form", location_form), ("open_date_start", open_date_start), ("open_date_end", open_date_end), - ("numbers_min", numbers_min), - ("numbers_max", numbers_max), + ("staff_count_min", staff_count_min), + ("staff_count_max", staff_count_max), ("is_active", is_active), ] for filter_name, filter_value in filters: @@ -73,10 +73,10 @@ class VSPRepository: queries.append(Vsp.opened_at >= value) case ("open_date_end", value) if value is not None: queries.append(Vsp.opened_at <= value) - case ("numbers_min", value) if value is not None: - queries.append(Vsp.numbers >= value) - case ("numbers_max", value) if value is not None: - queries.append(Vsp.numbers <= value) + case ("staff_count_min", value) if value is not None: + queries.append(Vsp.staff_count >= value) + case ("staff_count_max", value) if value is not None: + queries.append(Vsp.staff_count <= value) case ("is_active", value) if value is not None: queries.append(Vsp.is_active == value) case _: @@ -116,6 +116,7 @@ class VSPRepository: async def create(self, payload: VSPCreate, created_by: int, load_org_unit: bool = False) -> Vsp: data = payload.model_dump() + vsp_id = ( await self.db.execute( text(""" @@ -124,8 +125,7 @@ class VSPRepository: :p_opened_at, :p_placement_type, :p_staff_count, :p_total_area, :p_closed_at, :p_is_active, :p_is_deleted, :p_system_code, :p_created_by, :p_vsp_type, :p_notes, - :p_location_form, :p_numbers, :p_rent_contract_num, - :p_rent_end_date + :p_location_form, :p_rent_contract_num, :p_rent_end_date ) """), { @@ -145,7 +145,6 @@ class VSPRepository: "p_vsp_type": data.get("vsp_type"), "p_notes": data.get("notes"), "p_location_form": data.get("location_form"), - "p_numbers": data.get("numbers"), "p_rent_contract_num": data.get("rent_contract_num"), "p_rent_end_date": data.get("rent_end_date"), } @@ -176,9 +175,10 @@ class VSPRepository: "opened_at": "p_opened_at", "closed_at": "p_closed_at", "format": "p_format", + "placement_type": "p_placement_type", + "staff_count": "p_staff_count", "notes": "p_notes", "location_form": "p_location_form", - "numbers": "p_numbers", "total_area": "p_total_area", "rent_contract_num": "p_rent_contract_num", "rent_end_date": "p_rent_end_date", @@ -190,8 +190,7 @@ class VSPRepository: params = {"p_vsp_id": vsp.id, "p_updated_by": updated_by} for field, param in FIELD_TO_PARAM.items(): params[param] = data.get(field) - params.setdefault("p_placement_type", data.get("placement_type")) - params.setdefault("p_staff_count", data.get("staff_count")) + await self.db.execute( text(""" SELECT v3.upd_vsp( @@ -199,8 +198,7 @@ class VSPRepository: :p_format, :p_opened_at, :p_placement_type, :p_staff_count, :p_total_area, :p_closed_at, :p_is_active, :p_is_deleted, :p_system_code, :p_updated_by, :p_vsp_type, :p_notes, - :p_location_form, :p_numbers, :p_rent_contract_num, - :p_rent_end_date + :p_location_form, :p_rent_contract_num, :p_rent_end_date ) """), params, diff --git a/api/src/services/vsp_service.py b/api/src/services/vsp_service.py index 22f26d8..d84dd40 100644 --- a/api/src/services/vsp_service.py +++ b/api/src/services/vsp_service.py @@ -21,7 +21,7 @@ _info_close_sync_lock = asyncio.Lock() class VSPService: EXECUTOR_EDITABLE_FIELDS = { "location_form", - "numbers", + "staff_count", "total_area", "rent_contract_num", "rent_end_date", @@ -55,8 +55,8 @@ class VSPService: open_date_start: date | None = None, open_date_end: date | None = None, location_form: str | None = None, - numbers_min: int | None = None, - numbers_max: int | None = None, + staff_count_min: int | None = None, + staff_count_max: int | None = None, is_active: bool | None = None, load_org_unit: bool = False, with_count: bool = False, @@ -85,8 +85,8 @@ class VSPService: open_date_start=open_date_start, open_date_end=open_date_end, location_form=location_form, - numbers_min=numbers_min, - numbers_max=numbers_max, + staff_count_min=staff_count_min, + staff_count_max=staff_count_max, is_active=is_active, load_org_unit=load_org_unit, with_count=with_count, @@ -155,8 +155,8 @@ class VSPService: open_date_start: date | None = None, open_date_end: date | None = None, location_form: str | None = None, - numbers_min: int | None = None, - numbers_max: int | None = None, + staff_count_min: int | None = None, + staff_count_max: int | None = None, ) -> tuple[io.BytesIO, str]: data = await self.get_list( user=user, @@ -166,8 +166,8 @@ class VSPService: open_date_start=open_date_start, open_date_end=open_date_end, location_form=location_form, - numbers_min=numbers_min, - numbers_max=numbers_max, + staff_count_min=staff_count_min, + staff_count_max=staff_count_max, is_active=None, load_org_unit=True, ) @@ -189,7 +189,7 @@ class VSPService: "close_date", "notes", "location_form", - "numbers", + "staff_count", "area", "rent_contract_num", "rent_end_date", @@ -216,7 +216,7 @@ class VSPService: item.closed_at.isoformat() if item.closed_at else None, item.notes or None, item.location_form or None, - item.numbers if item.numbers is not None else None, + item.staff_count if item.staff_count is not None else None, float(item.total_area) if item.total_area is not None else None, item.rent_contract_num or None, item.rent_end_date.isoformat() if item.rent_end_date else None, diff --git a/api/tests/integration/test_vsp.py b/api/tests/integration/test_vsp.py index 4bdfebf..2dc5559 100644 --- a/api/tests/integration/test_vsp.py +++ b/api/tests/integration/test_vsp.py @@ -111,7 +111,7 @@ def test_vsp_create_with_all_fields(client, admin_tokens, auth_headers): "approved_format": "Стандарт", "notes": "Тестовое примечание", "location_form": "Встроенное", - "numbers": 10, + "staff_count": 10, "area": 150.5, "rent_contract_num": "Д-123/24", "rent_end_date": "2025-12-31", @@ -128,7 +128,7 @@ def test_vsp_create_with_all_fields(client, admin_tokens, auth_headers): assert payload["result"]["close_date"] == "2025-12-31" assert payload["result"]["approved_format"] == "Стандарт" assert payload["result"]["location_form"] == "Встроенное" - assert payload["result"]["numbers"] == 10 + assert payload["result"]["staff_count"] == 10 assert payload["result"]["area"] == 150.5 assert payload["result"]["rent_contract_num"] == "Д-123/24" assert payload["result"]["rent_end_date"] == "2025-12-31"