склади и инструмент готовы
This commit is contained in:
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.
Binary file not shown.
+16
-31
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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():
|
||||
|
||||
@@ -124,27 +124,18 @@ class DatabaseInitializer:
|
||||
async def _initialize_data(self, waiting: bool = False):
|
||||
"""Initialize required data"""
|
||||
|
||||
def waitForUser(waiting):
|
||||
if waiting:
|
||||
input("Для продолжения нажмите Enter...")
|
||||
|
||||
try:
|
||||
logger.info("Инициализация данных...")
|
||||
logger.warning("Инициализация Прав доступа...")
|
||||
await AccessLevelHandler.initialize()
|
||||
# waitForUser(waiting)
|
||||
logger.warning("Инициализация Пользователей...")
|
||||
await UserHandler.initialize()
|
||||
# waitForUser(waiting)
|
||||
logger.warning("Инициализация Туллбоксов...")
|
||||
await ToolboxHandler.initialize()
|
||||
# waitForUser(waiting)
|
||||
logger.warning("Инициализация Категорий...")
|
||||
await CategoryHandler.initialize()
|
||||
# waitForUser(waiting)
|
||||
logger.warning("Инициализация Инструментов...")
|
||||
await ToolkitHandler.initialize()
|
||||
# waitForUser(waiting)
|
||||
logger.warning("Инициализация Складов...")
|
||||
await StocksActions.initialize()
|
||||
logger.info("Данные успешно инициализированы")
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -40,5 +40,5 @@ class Toolkit(Base):
|
||||
async def save(self):
|
||||
return await CRUD.create(self, refresh=True)
|
||||
|
||||
async def edit(id: int, **kwargs):
|
||||
return await CRUD.update(Toolkit, id, **kwargs)
|
||||
async def edit(self, **kwargs):
|
||||
return await CRUD.update(Toolkit, self.id, **kwargs)
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ class User(Base):
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
login = Column(String, unique=True, index=True)
|
||||
username = Column(String, unique=True, index=True)
|
||||
photo = Column(String, default="images/users/default.png")
|
||||
photo = Column(String, default="static/images/users/default.png")
|
||||
hashed_password = Column(String)
|
||||
access_level_id = Column(Integer, ForeignKey("access_level.id", ondelete="CASCADE"))
|
||||
is_active = Column(Boolean, default=True)
|
||||
|
||||
Reference in New Issue
Block a user