vsp-dropdown-form: добавил фильтрацию по form_id в dropdown всп

This commit is contained in:
tsygankoviva 2026-06-24 13:22:17 +03:00
parent 63ae001a23
commit ab21b0e496
4 changed files with 35 additions and 11 deletions

View File

@ -59,12 +59,13 @@ async def get_vsp(
@router.get("/dropdown", response_model=BaseListResponse[VSPInDB]) @router.get("/dropdown", response_model=BaseListResponse[VSPInDB])
async def get_vsp_dropdown( async def get_vsp_dropdown(
ssp_id: int | None = None, ssp_id: int | None = None,
form_id: int | None = None,
db: AsyncSession = Depends(get_db), db: AsyncSession = Depends(get_db),
current_user: AppUser = Depends(require_executor), current_user: AppUser = Depends(require_executor),
): ):
"""Получение записей для выпадающего списка INFO.""" """Получение записей для выпадающего списка INFO."""
service = VSPService(db) service = VSPService(db)
result = await service.get_dropdown(user=current_user, ssp_id=ssp_id, with_count=True) result = await service.get_dropdown(user=current_user, ssp_id=ssp_id, form_id=form_id, with_count=True)
return BaseListResponse( return BaseListResponse(
success=True, success=True,
message="Список INFO для выпадающего списка", message="Список INFO для выпадающего списка",

View File

@ -7,6 +7,7 @@ from openpyxl import Workbook
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from src.repository.budget_form_repository import BudgetFormRepository
from src.core.errors import AccessDeniedException, ValidationException from src.core.errors import AccessDeniedException, ValidationException
from src.db.models import AppUser, UserRoleEnum, Vsp from src.db.models import AppUser, UserRoleEnum, Vsp
from src.domain.schemas import VSPCreate, VSPUpdate from src.domain.schemas import VSPCreate, VSPUpdate
@ -29,6 +30,7 @@ class VSPService:
def __init__(self, db: AsyncSession): def __init__(self, db: AsyncSession):
self.db = db self.db = db
self.vsp_repo = VSPRepository(db) self.vsp_repo = VSPRepository(db)
self.form_repo = BudgetFormRepository(db)
self.user_repo = UserRepository(db) self.user_repo = UserRepository(db)
async def get(self, vsp_id: int, user: AppUser, load_org_unit: bool = False) -> Optional[Vsp]: async def get(self, vsp_id: int, user: AppUser, load_org_unit: bool = False) -> Optional[Vsp]:
@ -94,19 +96,27 @@ class VSPService:
self, self,
user: AppUser, user: AppUser,
ssp_id: int | None = None, ssp_id: int | None = None,
form_id: int | None = None,
with_count: bool = False, with_count: bool = False,
) -> list[Vsp]: ) -> list[Vsp]:
ssp_ids = await self._get_scoped_ssp_ids(user=user) ssp_ids = await self._get_scoped_ssp_ids(user=user)
checking_ssps = set()
if ssp_id is not None: if ssp_id is not None:
checking_ssps.add(ssp_id)
if form_id is not None:
form = await self.form_repo.get(budget_form_id=form_id)
if form is not None:
checking_ssps.add(form.org_unit_id)
if checking_ssps:
if ssp_ids is None: if ssp_ids is None:
ssp_ids = [ssp_id] ssp_ids = list(checking_ssps)
elif ssp_id not in set(ssp_ids): elif not checking_ssps & set(ssp_ids):
if with_count: if with_count:
return 0, [] return 0, []
return [] return []
else: else:
ssp_ids = [ssp_id] ssp_ids = list(checking_ssps & set(ssp_ids))
return await self.vsp_repo.get_list( return await self.vsp_repo.get_list(
ssp_ids=ssp_ids, ssp_ids=ssp_ids,

View File

@ -37,14 +37,25 @@ def test_vsp_dropdown_smoke(client, admin_tokens, auth_headers):
assert isinstance(payload["result"], list) assert isinstance(payload["result"], list)
def test_vsp_dropdown_with_ssp_filter(client, admin_tokens, auth_headers): @pytest.mark.parametrize(
"params, count",
[
([("ssp_id", 2)], 1),
([("form_id", 1)], 0),
([("form_id", 2)], 1),
([("ssp_id", 2), ("form_id", 1)], 1),
]
)
def test_vsp_dropdown_with_filter(client, admin_tokens, auth_headers, params, count):
filters = "&".join([f"{el[0]}={el[1]}" for el in params])
response = client.get( response = client.get(
"/api/v1/dict/info/dropdown?ssp_id=1", f"/api/v1/dict/info/dropdown?{filters}",
headers=auth_headers(admin_tokens), headers=auth_headers(admin_tokens),
) )
assert response.status_code == 200 assert response.status_code == 200
payload = response.json() payload = response.json()
assert isinstance(payload["result"], list) assert isinstance(payload["result"], list)
assert len(payload["result"]) == count
def test_vsp_get_by_id(client, admin_tokens, auth_headers): def test_vsp_get_by_id(client, admin_tokens, auth_headers):

View File

@ -15,8 +15,9 @@ INSERT INTO v3.user_org (id,user_id,org_unit_id) VALUES
SELECT setval('v3.user_org_id_seq', 3); SELECT setval('v3.user_org_id_seq', 3);
INSERT INTO v3.budget_form (id,form_type_code,"year",created_by,created_at,updated_by,updated_at,org_unit_id) VALUES INSERT INTO v3.budget_form (id,form_type_code,"year",created_by,created_at,updated_by,updated_at,org_unit_id) VALUES
(1,'FORM_1',2027,NULL,'2026-05-06 16:57:38.066371',NULL,'2026-06-11 14:35:53.783017',1); (1,'FORM_1',2027,NULL,'2026-05-06 16:57:38.066371',NULL,'2026-06-11 14:35:53.783017',1),
SELECT setval('v3.budget_form_id_seq', 1); (4,'FORM_2',2026,NULL,'2026-05-08 09:08:12.230445',NULL,'2026-05-08 09:08:12.230445',2);
SELECT setval('v3.budget_form_id_seq', 4);
INSERT INTO v3.budget_line (id,budget_form_id,expense_item_id,"name",internal_order,vsp_id,project_id,justification,created_by,created_at,updated_by,updated_at,direction) VALUES INSERT INTO v3.budget_line (id,budget_form_id,expense_item_id,"name",internal_order,vsp_id,project_id,justification,created_by,created_at,updated_by,updated_at,direction) VALUES
(1,1,88,'1234',NULL,NULL,NULL,NULL,NULL,'2026-05-06 16:58:05.793083',NULL,'2026-06-22 17:41:54.255313','Support'); (1,1,88,'1234',NULL,NULL,NULL,NULL,NULL,'2026-05-06 16:58:05.793083',NULL,'2026-06-22 17:41:54.255313','Support');
@ -26,5 +27,6 @@ INSERT INTO v3.form_phase (budget_form_id,sheet,phase_code,"role",column_keys,op
(1,'AHR','test','DFIP','{{plan.q1}}','2026-05-05 03:00:00+03','2026-06-06 03:00:00+03'); (1,'AHR','test','DFIP','{{plan.q1}}','2026-05-05 03:00:00+03','2026-06-06 03:00:00+03');
INSERT INTO v3.vsp (id,branch_id,reg_number,address,format,opened_at,placement_type,staff_count,total_area,closed_at,is_active,updated_at,is_deleted,created_at,created_by,system_code,updated_by,vsp_type,notes,location_form,numbers,rent_contract_num,rent_end_date) VALUES INSERT INTO v3.vsp (id,branch_id,reg_number,address,format,opened_at,placement_type,staff_count,total_area,closed_at,is_active,updated_at,is_deleted,created_at,created_by,system_code,updated_by,vsp_type,notes,location_form,numbers,rent_contract_num,rent_end_date) VALUES
(1,2,'Тестовый всп 1','Тестовая 12','укукк','2026-05-07','ывс',2026,230,'2026-06-16',false,'2026-06-18 15:46:38.611903',false,'2026-06-04 14:36:59.737727',1,'1233',91,'','','встроенное помещение',NULL,'',NULL); (1,2,'Тестовый всп 1','Тестовая 12','укукк','2026-05-07','ывс',2026,230,'2026-06-16',false,'2026-06-18 15:46:38.611903',false,'2026-06-04 14:36:59.737727',1,'1233',91,'','','встроенное помещение',NULL,'',NULL),
SELECT setval('v3.vsp_id_seq', 1); (2,2,'Test12 -----','Тестовая 125','формат 15 ','2026-06-08',NULL,NULL,58,NULL,true,'2026-06-16 18:53:17.986651',false,'2026-06-09 09:04:33.29858',91,'123-1234',91,'субаренда','Работает ','аренда',155,'12-45','2026-10-02');
SELECT setval('v3.vsp_id_seq', 2);