from utils import logger, saveImage, safeFilename, deleteImage from db import CRUD from db.schemas import Toolkit from sqlalchemy import select from db.handlers import ServiceRecordsHandler def handleToolkitImage(imageData, title: str): title = safeFilename(title) fileName = f"tools/{title}.png" if not saveImage(imageData, fileName): return None return fileName class ToolkitHandler: async def add(toolkitData: dict, user_id: int = None): title = toolkitData.get("title", None) if not title: logger.error("Не указано название инструмента") return {} query = select(Toolkit).where(Toolkit.title == title) toolkit = await CRUD.read(query) if toolkit: logger.error("Инструмент с таким названием уже существует") return {} try: imageDict = {"main": "images/tools/default.png", "additional": []} if "image" in toolkitData: imageData = toolkitData.pop("image") mainImage = imageData.get("main") imageFileName = handleToolkitImage(mainImage, title) if imageFileName: imageDict["main"] = imageFileName additionalImages = imageData.get("additional", []) if len(additionalImages) > 0: for image in additionalImages: imageFileName = handleToolkitImage(image, title) if imageFileName: imageDict["additional"].append(imageFileName) toolkitData["image"] = imageDict newToolkit = await Toolkit(**toolkitData).save() except Exception as e: logger.error(f"Ошибка сохранения инструмента: {str(e)}") return {} if not newToolkit: logger.error("Инструмент не сохранен") return {} logger.info(f"Инструмент {newToolkit.title} успешно создан") await ServiceRecordsHandler.add( user_id, {"Добавлен инструмент": toolkitData.toDict()} ) return newToolkit.toDict() async def edit(toolkitId: int, **kwargs): query = select(Toolkit).where(Toolkit.id == toolkitId) toolkit = await CRUD.read(query) if not toolkit: logger.error("Инструмент не найден") return {} try: if "image" in kwargs: title = kwargs.get("title", toolkit.title) imageData = kwargs.pop("image") imageDict = {"main": "", "additional": []} existImagesList = [toolkit.image.get("main")] existImagesList.extend(toolkit.image.get("additional")) newImagesList = [imageData.get("main")] newImagesList.extend(imageData.get("additional")) for existImage in existImagesList: if existImage not in newImagesList: deleteImage(existImage) if toolkit.image.get("main") != imageData.get("main"): if imageData.get("main") in existImagesList: imageDict["main"] = imageData.get("main") else: imageFileName = handleToolkitImage(imageData.get("main"), title) if imageFileName: imageDict["main"] = imageFileName else: imageDict["main"] = "images/tools/default.png" imageDict["additional"].extend(imageData.get("additional")) uploadList = imageData.get("upload", []) if len(uploadList) > 0: for image in uploadList: imageFileName = handleToolkitImage(image, title) if imageFileName: imageDict["additional"].append(imageFileName) kwargs["image"] = imageDict user_id = kwargs.pop("user_id", None) editedToolkit = await toolkit.edit(**kwargs) except Exception as e: logger.error(f"Ошибка обновления инструмента: {str(e)}") return {} if not editedToolkit: logger.error("Инструмент не обновлен") return {} logger.info( f"Инструмент {editedToolkit.title} успешно обновлен, изменены данные: {kwargs.keys()}" ) await ServiceRecordsHandler.add( user_id, {f"Обновлен инструмент {toolkit.title}": editedToolkit.toDict()} ) return editedToolkit.toDict() async def getAll(): query = select(Toolkit) toolkits = await CRUD.read(query, True) return [toolkit.toDict() for toolkit in toolkits] if toolkits else [] async def get(toolkitId: int): query = select(Toolkit).where(Toolkit.id == toolkitId) toolkit = await CRUD.read(query) if not toolkit: logger.error("Инструмент не найден") return {} return toolkit.toDict() async def getSeveral(toolkitIds: list[int]) -> list[dict]: query = select(Toolkit).where(Toolkit.id.in_(toolkitIds)) toolkits = await CRUD.read(query, True) return [toolkit.toDict() for toolkit in toolkits] if toolkits else [] async def delete(toolkitId: int, user_id: int = None): query = select(Toolkit).where(Toolkit.id == toolkitId) toolkit = await CRUD.read(query) if not toolkit: logger.error("Инструмент не найден") return False try: toolkitTitle = toolkit.title result = await CRUD.delete(toolkit) except Exception as e: logger.error(f"Ошибка удаления инструмента: {str(e)}") return False logger.info( f"Инструмент {toolkitTitle} {'успешно удален' if result else 'не удален'}" ) await ServiceRecordsHandler.add( user_id, {"Удален инструмент": f"Название: {toolkitTitle}"} ) return result async def initialize(self): from .categories import CategoryHandler categoriesList = await CategoryHandler.getAll() categories = {category["title"]: category["id"] for category in categoriesList} baseToolkits = [ { "title": "Фреза №1", "description": "Фреза такая сякая этакая #1", "specifications": { "Диаметр": "10", "Длина": "20", "Ещё что-то": "Ещё столько-то", }, "category_id": categories["Фрезеровка"], "quantity_min": 20, "quantity_min_extra": 10, "external_link": "https://nazv.ru", }, { "title": "Фреза №2", "description": "Фреза такая сякая этакая #2", "specifications": { "Диаметр": "10", "Длина": "20", "Ещё что-то": "Ещё столько-то", }, "category_id": categories["Фрезеровка"], "quantity_min": 20, "quantity_min_extra": 10, "external_link": "https://nazv.ru", }, { "title": "Фреза №3", "description": "Фреза такая сякая этакая #3", "specifications": { "Диаметр": "10", "Длина": "20", "Ещё что-то": "Ещё столько-то", }, "category_id": categories["Фрезеровка"], "quantity_min": 20, "quantity_min_extra": 10, "external_link": "https://nazv.ru", }, { "title": "Псластина №1", "description": "Пластина такая сякая этакая #1", "specifications": { "Размер": "10", "Радиус": "0.4", "Ещё что-то": "Ещё столько-то", }, "category_id": categories["Токарка"], "quantity_min": 20, "quantity_min_extra": 10, "external_link": "https://nazv.ru", }, { "title": "Псластина №2", "description": "Пластина такая сякая этакая #2", "specifications": { "Размер": "10", "Радиус": "0.4", "Ещё что-то": "Ещё столько-то", }, "category_id": categories["Токарка"], "quantity_min": 20, "quantity_min_extra": 10, "external_link": "https://nazv.ru", }, { "title": "Псластина №3", "description": "Пластина такая сякая этакая #3", "specifications": { "Размер": "10", "Радиус": "0.4", "Ещё что-то": "Ещё столько-то", }, "category_id": categories["Токарка"], "quantity_min": 20, "quantity_min_extra": 10, "external_link": "https://nazv.ru", }, { "title": "Сверло №1", "description": "Сверло такое сякое этакое #1", "specifications": { "Длина": "30", "Диаметр": "5", "Ещё что-то": "Ещё столько-то", }, "category_id": categories["Слесарка"], "quantity_min": 20, "quantity_min_extra": 10, "external_link": "https://nazv.ru", }, { "title": "Сверло №2", "description": "Сверло такое сякое этакое #2", "specifications": { "Длина": "30", "Диаметр": "5", "Ещё что-то": "Ещё столько-то", }, "category_id": categories["Слесарка"], "quantity_min": 20, "quantity_min_extra": 10, "external_link": "https://nazv.ru", }, { "title": "Сверло №3", "description": "Сверло такое сякое этакое #3", "specifications": { "Длина": "30", "Диаметр": "5", "Ещё что-то": "Ещё столько-то", }, "category_id": categories["Слесарка"], "quantity_min": 20, "quantity_min_extra": 10, "external_link": "https://nazv.ru", }, ] for toolkit in baseToolkits: await self.add(toolkit) logger.info("Базовые инструменты успешно созданы") return