97 lines
4.3 KiB
Python
97 lines
4.3 KiB
Python
from models import Module, Attribute
|
||
from repositories import ModuleRepository, AttributeRepository
|
||
from schemas.module import *
|
||
from services.mixins import *
|
||
from utils.exceptions import ForbiddenException
|
||
|
||
|
||
class ModuleService(
|
||
ServiceGetAllMixin[Module, ModuleSchema],
|
||
ServiceUpdateMixin[Module, UpdateModuleCommonInfoRequest],
|
||
ServiceDeleteMixin[Module],
|
||
):
|
||
schema_class = ModuleSchema
|
||
entity_updated_msg = "Модуль успешно обновлен"
|
||
entity_deleted_msg = "Модуль успешно удален"
|
||
|
||
def __init__(self, session: AsyncSession):
|
||
self.repository = ModuleRepository(session)
|
||
|
||
async def get_with_attributes(self) -> GetAllWithAttributesResponse:
|
||
result = await self.repository.get_with_attributes_as_tuples()
|
||
modules = self._build_modules_with_attributes(result)
|
||
return GetAllWithAttributesResponse(items=list(modules.values()))
|
||
|
||
async def get_by_id_with_attributes(self, pk: int) -> GetByIdWithAttributesResponse:
|
||
result = await self.repository.get_with_attributes_as_tuple_by_id(pk)
|
||
modules = self._build_modules_with_attributes(result)
|
||
module = next(iter(modules.values()), None)
|
||
if module is None:
|
||
raise ObjectNotFoundException(f"Модуль с ID {pk} не найден")
|
||
return GetByIdWithAttributesResponse(entity=module)
|
||
|
||
async def update_module_common_info(
|
||
self, module_id: int, request: UpdateModuleCommonInfoRequest
|
||
) -> UpdateModuleCommonInfoResponse:
|
||
module = await self.repository.get_by_id(module_id)
|
||
await self.repository.update_(module, request)
|
||
return UpdateModuleCommonInfoResponse(message="Данные модуля успешно сохранены")
|
||
|
||
def _build_modules_with_attributes(
|
||
self, result: list[tuple]
|
||
) -> dict[int, ModuleWithAttributesSchema]:
|
||
module_attrs_dict: dict[int, ModuleWithAttributesSchema] = {}
|
||
|
||
for module, attribute, attribute_label in result:
|
||
new_attr = None
|
||
|
||
if attribute:
|
||
original_label = attribute.label
|
||
label = attribute_label.label if attribute_label else original_label
|
||
attr_values = {
|
||
**attribute.__dict__,
|
||
"label": label,
|
||
"original_label": original_label,
|
||
}
|
||
new_attr = ModuleAttributeSchema(**attr_values)
|
||
|
||
module_schema = module_attrs_dict.get(module.id)
|
||
if not module_schema:
|
||
module_schema = ModuleWithAttributesSchema(
|
||
**module.__dict__,
|
||
attributes=[new_attr] if new_attr else [],
|
||
)
|
||
module_attrs_dict[module.id] = module_schema
|
||
elif new_attr:
|
||
module_schema.attributes.append(new_attr)
|
||
|
||
return module_attrs_dict
|
||
|
||
async def is_soft_delete(self, module: Module) -> bool:
|
||
if module.is_built_in:
|
||
raise ForbiddenException("Нельзя менять встроенный модуль")
|
||
return True
|
||
|
||
async def add_attribute(self, request: AddAttributeRequest) -> AddAttributeResponse:
|
||
module, attribute = await self._get_module_and_attr_from_request(request)
|
||
await self.repository.add_attribute_to_module(module, attribute)
|
||
return AddAttributeResponse(message="Аттрибут успешно добавлен к модулю")
|
||
|
||
async def delete_attribute(
|
||
self, request: DeleteAttributeRequest
|
||
) -> DeleteAttributeResponse:
|
||
module, attribute = await self._get_module_and_attr_from_request(request)
|
||
await self.repository.delete_attribute_from_module(module, attribute)
|
||
return DeleteAttributeResponse(message="Аттрибут успешно удален из модуля")
|
||
|
||
async def _get_module_and_attr_from_request(
|
||
self, request: AddAttributeRequest | DeleteAttributeRequest
|
||
) -> tuple[Module, Attribute]:
|
||
module = await self.repository.get_by_id(request.module_id)
|
||
if module.is_built_in:
|
||
raise ForbiddenException("Нельзя менять встроенный модуль")
|
||
|
||
attr_repo = AttributeRepository(self.repository.session)
|
||
attribute = await attr_repo.get_by_id(request.attribute_id)
|
||
return module, attribute
|