склади и инструмент готовы

This commit is contained in:
2025-12-07 19:36:28 +03:00
parent 54bf21d52d
commit 65a3bc1671
65 changed files with 3485 additions and 115 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+16 -31
View File
@@ -21,9 +21,7 @@ class StocksActions:
placement: str,
reason: str,
):
logger.info(
f"Оприходование инструмента {toolkit_id} на складе {toolbox_id} ..."
)
logger.info(f"Приход инструмента {toolkit_id} на складе {toolbox_id} ...")
newStocks = await StockHandler.add(
toolkit_id=toolkit_id,
toolbox_id=toolbox_id,
@@ -33,12 +31,12 @@ class StocksActions:
)
if newStocks is None:
logger.error(
f"Оприходование инструмента {toolkit_id} на складе {toolbox_id} не удалось"
f"Приход инструмента {toolkit_id} на складе {toolbox_id} не удалось"
)
return False
recorded = await StocksRecordsHandler.add(
action="Оприходование",
action="Приход",
source_stock_id=None,
target_stock_id=newStocks.get("id"),
source_toolbox_id=None,
@@ -51,7 +49,7 @@ class StocksActions:
return_record=True,
)
logger.info(
f"Оприходование инструмента {toolkit_id} на складе {toolbox_id} прошло {'успешно' if recorded else 'не успешно'}"
f"Приход инструмента {toolkit_id} на складе {toolbox_id} прошло {'успешно' if recorded else 'не успешно'}"
)
if recorded:
accepted = await StocksRecordsHandler.decide(
@@ -61,6 +59,11 @@ class StocksActions:
logger.error(
f"Принятие записи о оприходовании инструмента {toolkit_id} на складе {toolbox_id} не удалось"
)
refillUpdated = await ToolkitHandler.updateRefillDate(toolkit_id)
if not refillUpdated:
logger.error(
f"Обновление даты последнего заполнения инструмента {toolkit_id} не удалось"
)
return accepted
return False
@@ -70,8 +73,6 @@ class StocksActions:
target_toolbox_id: int,
toolkit_id: int,
quantity: int,
user_id: int,
reason: str,
target_placement: str = None,
):
logger.info(
@@ -169,27 +170,13 @@ class StocksActions:
f"Изменение остатков инструмента {toolkit_id} на склад {target_toolbox_id} по цене {stock['price']} успешно завершено"
)
# recorded = await StocksRecordsHandler.add(
# action=action,
# source_stock_id=stock["id"],
# target_stock_id=targetStock.get("id"),
# source_toolbox_id=source_toolbox_id,
# target_toolbox_id=target_toolbox_id,
# toolkit_id=toolkit_id,
# init_user_id=user_id,
# reason=reason,
# quantity=quantity,
# price=stock["price"],
# )
# if not recorded:
# logger.error(
# f"Ошибка создания записи о {action} инструмента {toolkit_id} со склада {source_toolbox_id} на склад {target_toolbox_id}"
# )
# return False
logger.info(
f"{action} инструмента {toolkit_id} со склада {source_toolbox_id} на склад {target_toolbox_id} прошло успешно"
)
moveUpdated = await ToolkitHandler.updateMovindDate(toolkit_id)
if not moveUpdated:
logger.error(f"Ошибка обновления даты движения инструмента {toolkit_id}")
return False
return movementsList
async def movingRequest(
@@ -220,7 +207,7 @@ class StocksActions:
return_record=return_record,
)
logger.info(
f"Запрос на {action} инструмента {toolkit_id} со склада {source_toolbox_id} в количестве {quantity} по цене {price} {'успешно завершен' if recorded else 'завершен с ошибкой'}"
f"Запрос на {action} инструмента {toolkit_id} со склада {source_toolbox_id} в количестве {quantity} по цене {price} {'успешно создан' if recorded else 'завершен с ошибкой'}"
)
return recorded
@@ -270,8 +257,6 @@ class StocksActions:
target_toolbox_id=target_toolbox_id,
toolkit_id=movingRecord.toolkit_id,
quantity=movingRecord.quantity,
user_id=user_id,
reason=movingRecord.reason,
)
if not stocksMovements:
logger.error(f"Ошибка при {movingRecord.action} инструмента")
@@ -388,10 +373,10 @@ class StocksActions:
for toolkit in toolkits:
if "Сверло" in toolkit.get("title"):
toolboxId = toolboxesDict.get("Шкаф")
placement = None
else:
toolboxId = toolboxesDict.get("Стеллаж")
placement = chr(65 + random.randint(0, 25)) + str(random.randint(1, 19))
placement = chr(65 + random.randint(0, 25)) + str(random.randint(1, 19))
registryCount = 5
+5
View File
@@ -58,6 +58,11 @@ class CategoryHandler:
categories = await CRUD.read(query, True)
return [category.toDict() for category in categories] if categories else []
async def getSeveral(categoryIds: list[int]) -> list[dict]:
query = select(Category).where(Category.id.in_(categoryIds))
categories = await CRUD.read(query, True)
return [category.toDict() for category in categories] if categories else []
async def delete(categoryId: int, user_id: int = None):
query = select(Category).where(Category.id == categoryId)
category = await CRUD.read(query)
+77 -21
View File
@@ -35,11 +35,11 @@ class StocksRecordsHandler:
"price": price,
}
try:
logger.info(f"Создание записи: {action} от {init_user_id}")
logger.debug(f"Создание записи: {action} от {init_user_id}")
logger.debug(recordData)
record = StocksRecords(**recordData)
await record.save()
logger.info(f"Запись успешно создана, id: {record.id}")
logger.debug(f"Запись успешно создана, id: {record.id}")
return True if not return_record else record
except Exception as e:
logger.error(f"Ошибка создания записи: {str(e)}")
@@ -54,7 +54,7 @@ class StocksRecordsHandler:
accept: bool = True,
):
try:
logger.info(
logger.debug(
f"{'Принятие' if accept else 'Отклонение'} записи {record.id} от {decision_user_id}"
)
record.decision_user_id = decision_user_id
@@ -64,7 +64,7 @@ class StocksRecordsHandler:
record.price = price
record.accepted = accept
await record.save()
logger.info(
logger.debug(
f"Запись {record.id} успешно {'принята' if accept else 'отклонена'} {decision_user_id} в {record.decided_at.strftime('%Y-%m-%d %H:%M:%S')}"
)
return True
@@ -83,16 +83,16 @@ class StocksRecordsHandler:
return recordDB
try:
logger.info(f"Обновление записи {record_id} от {edit_user_id}")
logger.debug(f"Обновление записи {record_id} от {edit_user_id}")
record = await StocksRecords.get(id=record_id)
record.edit_user_id = edit_user_id
record.edited_at = datetime.now()
logger.info("Вносим изменения в записи о движении инструмента")
logger.debug("Вносим изменения в записи о движении инструмента")
if record.source_stock_id:
logger.info(
logger.debug(
"Вносим изменения в записи о движении инструмента из исходного склада"
)
sourceStockRecord = await StockHandler.get(
@@ -103,12 +103,12 @@ class StocksRecordsHandler:
sourceStockRecord = updateStockRecord(sourceStockRecord, kwargs)
await sourceStockRecord.save()
logger.info(
logger.debug(
"Внесли изменения в записи о движении инструмента из исходного склада"
)
if record.target_stock_id:
logger.info(
logger.debug(
"Вносим изменения в записи о движении инструмента в целевой склад"
)
targetStockRecord = await StockHandler.get(
@@ -119,11 +119,11 @@ class StocksRecordsHandler:
targetStockRecord = updateStockRecord(targetStockRecord, kwargs)
await targetStockRecord.save()
logger.info(
logger.debug(
"Внесли изменения в записи о движении инструмента в целевой склад"
)
logger.info("Внесли изменения в записи о движении инструмента")
logger.debug("Внесли изменения в записи о движении инструмента")
edited = {}
for key, value in kwargs.items():
@@ -132,7 +132,7 @@ class StocksRecordsHandler:
edited[key] = {"original": originalValue, "new": value}
record.edited = edited
await record.save()
logger.info(
logger.debug(
f"Запись {record_id} успешно обновлена {edit_user_id} в {record.updated_at.strftime('%Y-%m-%d %H:%M:%S')}"
)
logger.debug(edited)
@@ -148,19 +148,23 @@ class StocksRecordsHandler:
try:
if user_id:
userInfo = f"пользователя {user_id} "
decided = "не решенных "
daysLimit = ""
query = select(StocksRecords).where(
StocksRecords.init_user_id == user_id,
StocksRecords.created_at > datetime.now() - timedelta(days=days),
StocksRecords.decision_user_id == None,
)
else:
userInfo = "всех пользователей "
decided = ""
daysLimit = f"за последние {days} дн."
query = select(StocksRecords).where(
StocksRecords.created_at > datetime.now() - timedelta(days=days),
)
logger.info(f"Получение всех записей {userInfo}за последние {days} дн.")
logger.debug(f"Получение всех {decided}записей {userInfo}{daysLimit}")
records = await CRUD.read(query, True)
logger.info(
f"{len(records)} записей {userInfo}за последние {days} дн. успешно получены"
logger.debug(
f"{len(records)} {decided}записей {userInfo}{daysLimit} успешно получены"
)
if len(records) == 0:
return []
@@ -176,28 +180,80 @@ class StocksRecordsHandler:
from db import CRUD
try:
logger.info(f"Получение записи {record_id}")
logger.debug(f"Получение записи {record_id}")
query = select(StocksRecords).where(StocksRecords.id == record_id)
stocksRecord = await CRUD.read(query)
if not stocksRecord:
logger.info(f"Запись {record_id} не найдена")
logger.debug(f"Запись {record_id} не найдена")
return False
logger.info(f"Запись {record_id} успешно получена")
logger.debug(f"Запись {record_id} успешно получена")
return stocksRecord.toDict() if not record else stocksRecord
except Exception as e:
logger.error(f"Ошибка получения записи: {str(e)}")
return False
async def getOriginalToolboxId(toolkitId: int, targetToolboxId: int):
from db import CRUD
try:
logger.debug(
f"Получение записи о перемещении инструмента {toolkitId} на склад {targetToolboxId}"
)
query = select(StocksRecords).where(
StocksRecords.toolkit_id == toolkitId,
StocksRecords.target_toolbox_id == targetToolboxId,
)
stocksRecord = await CRUD.read(query)
if not stocksRecord:
logger.debug(f"Запись {toolkitId} не найдена")
return False
logger.debug(f"Запись {toolkitId} успешно получена")
return stocksRecord.source_toolbox_id
except Exception as e:
logger.error(f"Ошибка получения записи: {str(e)}")
return False
class ServiceRecordsHandler:
async def add(user_id: int, details: dict):
try:
logger.info(f"Создание записи: {user_id}")
logger.debug(f"Создание записи: {user_id}")
logger.debug(details)
record = ServicesRecords(user_id=user_id, details=details)
await record.save()
logger.info(f"Запись успешно создана, id: {record.id}")
logger.debug(f"Запись успешно создана, id: {record.id}")
return True
except Exception as e:
logger.error(f"Ошибка создания записи: {str(e)}")
return False
async def get(user_id: int = None, days: int = 30):
from db import CRUD
try:
if user_id:
userInfo = f"пользователя {user_id} "
daysLimit = ""
query = select(ServicesRecords).where(
ServicesRecords.user_id == user_id,
)
else:
userInfo = "всех пользователей "
daysLimit = f"за последние {days} дн."
query = select(ServicesRecords).where(
ServicesRecords.created_at > datetime.now() - timedelta(days=days),
)
logger.debug(f"Получение всех записей {userInfo}{daysLimit}")
records = await CRUD.read(query, True)
logger.debug(
f"{len(records)} записей {userInfo}{daysLimit} успешно получены"
)
if len(records) == 0:
return []
records.sort(key=lambda x: x.created_at, reverse=True)
recordsData = [record.toDict() for record in records]
logger.debug(recordsData)
return recordsData
except Exception as e:
logger.error(f"Ошибка получения записей: {str(e)}")
return False
+5
View File
@@ -77,6 +77,11 @@ class ToolboxHandler:
toolboxes = await CRUD.read(query, True)
return [toolbox.toDict() for toolbox in toolboxes] if toolboxes else []
async def getIdByOwner(ownerId: int) -> int:
query = select(Toolbox).where(Toolbox.owner_id == ownerId)
toolbox = await CRUD.read(query)
return toolbox.id
async def delete(toolboxId: int, user_id: int = None):
query = select(Toolbox).where(Toolbox.id == toolboxId)
toolbox = await CRUD.read(query)
+25 -1
View File
@@ -1,3 +1,4 @@
from datetime import datetime
from utils import logger, saveImage, safeFilename, deleteImage
from db import CRUD
from db.schemas.toolkit import Toolkit
@@ -27,7 +28,7 @@ class ToolkitHandler:
return {}
try:
imageDict = {"main": "images/tools/default.png", "additional": []}
imageDict = {"main": "static/images/tools/default.png", "additional": []}
if "image" in toolkitData:
imageData = toolkitData.pop("image")
mainImage = imageData.get("main")
@@ -54,6 +55,21 @@ class ToolkitHandler:
await ServiceRecordsHandler.add(user_id, {"Добавлен инструмент": toolkitData})
return newToolkit
async def updateMovindDate(toolkitId: int):
editedToolkit = await ToolkitHandler.edit(toolkitId, moved_at=datetime.now())
if not editedToolkit:
logger.error("Инструмент не обновлен")
return False
return True
async def updateRefillDate(toolkitId: int):
logger.info(f"Обновление даты пополнения инструмента {toolkitId}...")
editedToolkit = await ToolkitHandler.edit(toolkitId, refilled_at=datetime.now())
if not editedToolkit:
logger.error("Инструмент не обновлен")
return False
return True
async def edit(toolkitId: int, **kwargs):
query = select(Toolkit).where(Toolkit.id == toolkitId)
toolkit = await CRUD.read(query)
@@ -98,6 +114,7 @@ class ToolkitHandler:
kwargs["image"] = imageDict
user_id = kwargs.pop("user_id", None)
logger.debug(f"Обновление инструмента {toolkit.title}...")
editedToolkit = await toolkit.edit(**kwargs)
except Exception as e:
logger.error(f"Ошибка обновления инструмента: {str(e)}")
@@ -208,6 +225,13 @@ class ToolkitHandler:
"Радиус": "0.4",
"Ещё что-то": "Ещё столько-то",
},
"image": {
"main": "static/images/tools/default.png",
"additional": [
"static/images/users/default.png",
"static/images/logo.png",
],
},
"category_id": categories["Токарка"],
"quantity_min": 20,
"quantity_min_extra": 10,
+8 -4
View File
@@ -59,7 +59,7 @@ class UserHandler:
return {}
if userAccessLevel.get("available_own_toolbox"):
newToolboxData = {
"title": f"Тулбокс {newUser.username}",
"title": f"Т{newUser.username}",
"description": f"Оборудование, полученное сотрудником {newUser.username}, под личную материальную ответственность",
"owner_id": newUser.id,
}
@@ -111,7 +111,7 @@ class UserHandler:
if editedUser.available_own_toolbox:
newToolboxData = {
"title": f"Тулбокс {editedUser.username}",
"description": f"Оборудование, полученное сотрудником {editedUser.username}, под личную материальную ответственность",
"description": f"Оборудование, полученное сотрудником '{editedUser.username}' под личную материальную ответственность",
"owner_id": editedUser.id,
}
newToolbox = await ToolboxHandler.addNewToolbox(newToolboxData)
@@ -177,16 +177,20 @@ class UserHandler:
query = select(User).where(User.login == login)
user = await CRUD.read(query)
if not user:
logger.error("Пользователь с таким логином не найден")
logger.error(f"Пользователь с логином {login} не найден")
return {}
if not pwd_verify(password, user.hashed_password):
logger.error("Неверный пароль")
logger.error(f"Неверный пароль пользователя {user.username}")
await ServiceRecordsHandler.add(
user.id, {"Неверный пароль пользователя": user.username}
)
return {}
userData = user.toDict()
userData.pop("hashed_password")
await ServiceRecordsHandler.add(
user.id, {"Авторизован пользователь": user.username}
)
logger.info(f"Пользователь {user.username} успешно авторизован")
return userData
async def initialize():