Создание и первичная инициализация базы даных успешно завершена. Наполнение демо-данными прошло без ошибок

This commit is contained in:
2025-12-06 12:58:42 +03:00
parent f378de38da
commit f07843de5a
49 changed files with 734 additions and 353 deletions
-45
View File
@@ -1,45 +0,0 @@
from .user import *
from .access import *
from .toolbox import *
from .categories import *
from .stock import *
from .toolkit import *
from .records import *
from .actions import *
class InitializeDatabase:
def __init__(self):
self.userHandler = UserHandler()
self.accessHandler = AccessLevelHandler()
self.toolboxHandler = ToolboxHandler()
self.categoryHandler = CategoryHandler()
self.stockHandler = StockHandler()
self.toolkitHandler = ToolkitHandler()
self.stocksRecordHandler = StocksRecordsHandler()
self.servicesRecordHandler = ServiceRecordsHandler()
self.actionsHandler = StocksActions()
async def initialize(self):
await self.accessHandler.initialize()
await self.userHandler.initialize()
await self.toolboxHandler.initialize()
await self.categoryHandler.initialize()
await self.toolkitHandler.initialize()
await self.actionsHandler.initialize()
__all__ = [
"UserHandler",
"AccessLevelHandler",
"ToolboxHandler",
"CategoryHandler",
"StockHandler",
"ToolkitHandler",
"StocksRecords",
"ServicesRecords",
"StocksRecordsHandler",
"ServiceRecordsHandler",
"StocksActions",
"InitializeDatabase",
]
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.
Binary file not shown.
+8 -8
View File
@@ -1,13 +1,13 @@
from sqlalchemy import select
from utils import logger
from db import CRUD
from db.schemas import AccessLevel
from db.handlers import ServiceRecordsHandler
from db.schemas.access import AccessLevel
from db.handlers.records import ServiceRecordsHandler
class AccessLevelHandler:
async def add(**kwargs):
title = kwargs.get("title", None)
async def add(newData):
title = newData.get("title", None)
if not title:
logger.error("Не указано название уровня доступа")
return {}
@@ -17,8 +17,8 @@ class AccessLevelHandler:
return {}
try:
logger.info(f"Создание уровня доступа {title}")
user_id = kwargs.pop("user_id", None)
accessData = await AccessLevel(**kwargs).save()
user_id = newData.pop("user_id", None)
accessData = await AccessLevel(**newData).save()
await ServiceRecordsHandler.add(
user_id, {"Добавлен уровень доступа": accessData.toDict()}
)
@@ -85,7 +85,7 @@ class AccessLevelHandler:
)
return result
async def initialize(self):
async def initialize():
baseAcessLevels = {
"admin": {
"title": "Администратор",
@@ -149,7 +149,7 @@ class AccessLevelHandler:
logger.info("Инициализация уровней доступа")
for accessLevel in baseAcessLevels.values():
await self.add(**accessLevel)
await AccessLevelHandler.add(accessLevel)
logger.info("Уровни доступа успешно инициализированы")
return
+290 -43
View File
@@ -1,4 +1,11 @@
from db.handlers import StockHandler, StocksRecordsHandler
import random
from db.handlers.stock import StockHandler
from db.handlers.toolbox import ToolboxHandler
from db.handlers.toolkit import ToolkitHandler
from db.handlers.user import UserHandler
from db.handlers.access import AccessLevelHandler
from db.handlers.records import StocksRecordsHandler
from utils import logger
@@ -32,7 +39,7 @@ class StocksActions:
recorded = await StocksRecordsHandler.add(
action="Оприходование",
source_stock_id=None,
target_stock_id=newStocks.id,
target_stock_id=newStocks.get("id"),
source_toolbox_id=None,
target_toolbox_id=toolbox_id,
toolkit_id=toolkit_id,
@@ -46,7 +53,7 @@ class StocksActions:
f"Оприходование инструмента {toolkit_id} на складе {toolbox_id} прошло {'успешно' if recorded else 'не успешно'}"
)
if recorded:
accepted = await StocksRecordsHandler.accept(
accepted = await StocksRecordsHandler.decide(
recorded, user_id, None, quantity, price
)
if not accepted:
@@ -84,7 +91,7 @@ class StocksActions:
return False
totalTakeQuantity = 0
writeDownList = []
movementsList = []
for stock in availability:
if quantity == totalTakeQuantity:
@@ -108,14 +115,15 @@ class StocksActions:
f"Списание инструмента {toolkit_id} со склада {source_toolbox_id} на склад {target_toolbox_id} в количестве {takeQuantity} по цене {stock['price']} успешно завершена"
)
movementsList.append(
{
"id": sourceEdit["id"],
"quantity": takeQuantity,
"price": stock["price"],
}
)
if not target_toolbox_id:
writeDownList.append(
{
"id": sourceEdit["id"],
"quantity": takeQuantity,
"price": stock["price"],
}
)
continue
existing = await StockHandler.getByToolboxIdAndToolkitIdAndQPrice(
@@ -168,7 +176,6 @@ class StocksActions:
reason=reason,
quantity=quantity,
price=stock["price"],
target_placement=target_placement,
)
if not recorded:
logger.error(
@@ -179,7 +186,7 @@ class StocksActions:
logger.info(
f"{action} инструмента {toolkit_id} со склада {source_toolbox_id} на склад {target_toolbox_id} прошло успешно"
)
return True if target_toolbox_id else writeDownList
return movementsList
async def movingRequest(
action: str,
@@ -213,29 +220,50 @@ class StocksActions:
)
return recorded
async def movingAcceptance(self, record_id: int, user_id: int):
logger.info(f"Принятие записи о движении инструмента {record_id} ...")
writeDownARecord = await StocksRecordsHandler.getById(record_id, True)
if not writeDownARecord:
async def movingDecision(record_id: int, user_id: int, accepted: bool = True):
logger.info(
f"{'Принятие' if accepted else 'Отклонение'} записи о движении инструмента {record_id} ..."
)
movingRecord = await StocksRecordsHandler.getById(record_id, True)
if not movingRecord:
logger.error(f"Запись {record_id} не найдена")
return False
if writeDownARecord.accepted_at is not None:
logger.error(f"Запись {record_id} уже была принята")
if movingRecord.accepted is not None:
logger.error(
f"Запись {record_id} уже была {'принята' if movingRecord.accepted else 'отклонена'}"
)
return False
stocksMovements = await self.moving(
action=writeDownARecord.action,
source_toolbox_id=writeDownARecord.source_toolbox_id,
target_toolbox_id=writeDownARecord.target_toolbox_id,
toolkit_id=writeDownARecord.toolkit_id,
quantity=writeDownARecord.quantity,
if not accepted:
return await StocksRecordsHandler.decide(
record_id,
user_id,
movingRecord.source_stock_id,
movingRecord.quantity,
movingRecord.price,
accepted,
)
target_toolbox_id = (
movingRecord.target_toolbox_id
if movingRecord.action != "Списание"
else None
)
logger.warning(f"{target_toolbox_id = }, {movingRecord.action = }")
stocksMovements = await StocksActions.moving(
action=movingRecord.action,
source_toolbox_id=movingRecord.source_toolbox_id,
target_toolbox_id=target_toolbox_id,
toolkit_id=movingRecord.toolkit_id,
quantity=movingRecord.quantity,
user_id=user_id,
reason=writeDownARecord.reason,
reason=movingRecord.reason,
)
if not stocksMovements:
logger.error(f"Ошибка при {writeDownARecord.action} инструмента")
logger.error(f"Ошибка при {movingRecord.action} инструмента")
return False
accept = await StocksRecordsHandler.accept(
accept = await StocksRecordsHandler.decide(
record_id,
user_id,
stocksMovements[0].get("id"),
@@ -250,23 +278,23 @@ class StocksActions:
if len(stocksMovements) > 1:
for stock in stocksMovements[1:]:
recorded = await StocksRecordsHandler.add(
action=writeDownARecord.action,
action=movingRecord.action,
source_stock_id=stock.get("id"),
target_stock_id=None,
source_toolbox_id=writeDownARecord.source_toolbox_id,
target_toolbox_id=writeDownARecord.target_toolbox_id,
toolkit_id=writeDownARecord.toolkit_id,
init_user_id=writeDownARecord.init_user_id,
reason=writeDownARecord.reason,
source_toolbox_id=movingRecord.source_toolbox_id,
target_toolbox_id=target_toolbox_id,
toolkit_id=movingRecord.toolkit_id,
init_user_id=movingRecord.init_user_id,
reason=movingRecord.reason,
quantity=stock.get("quantity"),
price=stock.get("price"),
return_record_id=True,
)
if not recorded:
return False
accept = await StocksRecordsHandler.accept(
accept = await StocksRecordsHandler.decide(
record_id=recorded,
accept_user_id=user_id,
decision_user_id=user_id,
source_stock_id=stock.get("id"),
quantity=stock.get("quantity"),
price=stock.get("price"),
@@ -276,12 +304,11 @@ class StocksActions:
totalRecordsIds.append(recorded)
logger.info(
f"Записи {', '.join(map(str, totalRecordsIds))} о {writeDownARecord.action} инструмента успешно приняты {user_id}"
f"Записи {', '.join(map(str, totalRecordsIds))} о {movingRecord.action} инструмента успешно приняты {user_id}"
)
return True
async def takeToolkit(
self,
source_toolbox_id: int,
target_toolbox_id: int,
toolkit_id: int,
@@ -293,7 +320,7 @@ class StocksActions:
logger.info(
f"Формирование запроса на получение инструмента {toolkit_id} на склад {target_toolbox_id} со склада {source_toolbox_id} в количестве {quantity} ..."
)
takeRequest = await self.movingRequest(
takeRequest = await StocksActions.movingRequest(
action="Получение",
source_toolbox_id=source_toolbox_id,
target_toolbox_id=target_toolbox_id,
@@ -315,7 +342,7 @@ class StocksActions:
logger.info(
f"Принятие запроса {takeRequest} на получение инструмента {toolkit_id} ..."
)
accepted = await self.movingAcceptance(takeRequest, user_id)
accepted = await StocksActions.movingDecision(takeRequest, user_id)
if not accepted:
logger.error(
f"Принятие запроса {takeRequest} на получение инструмента {toolkit_id} не удалось"
@@ -327,6 +354,226 @@ class StocksActions:
return True
async def initialize():
# TODO прописать наполнение общих складов, получение на личные, возвраты и списания.
# Не все запросы на возвраты и списания нужно принять автоматически, нужно оставить несколько для демонстрации
pass
toolboxes = await ToolboxHandler.getAll()
toolboxesDict = {
toolbox.get("title"): toolbox.get("id") for toolbox in toolboxes
}
toolboxesOwners = {
toolbox.get("owner_id"): toolbox.get("id")
for toolbox in toolboxes
if toolbox.get("owner_id")
}
users = await UserHandler.getAll()
usersDict = {user.get("login"): user.get("id") for user in users}
toolkits = await ToolkitHandler.getAll()
logger.warning("Наполнение складов ...")
for toolkit in toolkits:
if "Сверло" in toolkit.get("title"):
toolboxId = toolboxesDict.get("Шкаф")
else:
toolboxId = toolboxesDict.get("Стеллаж")
placement = chr(65 + random.randint(0, 25)) + str(random.randint(1, 19))
registryCount = 5
logger.warning(
f">> Наполнение склада {toolboxId} инструментом {toolkit.get('title')}"
)
for i in range(registryCount):
quantity = random.randint(20, 30)
price = round(300 + random.random() * 500, 2)
logger.warning(f">>>> Количество: {quantity}, Цена: {price}")
success = await StocksActions.registration(
toolkit_id=toolkit.get("id"),
toolbox_id=toolboxId,
user_id=usersDict.get("storekeeper"),
quantity=quantity,
price=price,
placement=placement,
reason=f"Приход инструмента {toolkit.get('title')}. Счёт-фактура № {random.randint(1000, 10000)}-{i+1}",
)
if not success:
logger.error(f"Приход инструмента {toolkit.get('title')} не удался")
return False
logger.warning("Наполнение складов завершено")
logger.warning("Получение инструментов из общих складов ...")
accessLevels = await AccessLevelHandler.getAll()
accessLevelsDict = {
accessLevel.get("id"): accessLevel.get("available_own_toolbox")
for accessLevel in accessLevels
}
users = await UserHandler.getAll()
usersDict = {user.get("login"): user.get("id") for user in users}
for user in users:
userAccessLevelId = user.get("access_level_id")
if not accessLevelsDict.get(userAccessLevelId):
continue
own_toolbox_id = toolboxesOwners.get(user.get("id"))
logger.warning(
f"Получение инструментов из общего склада пользователем {user.get('login')} ..."
)
for toolkit in toolkits:
logger.warning(
f">> Выдача инструмента {toolkit.get('title')} пользователю {user.get('login')} ..."
)
if "Сверло" in toolkit.get("title"):
main_toolbox_id = toolboxesDict.get("Шкаф")
else:
main_toolbox_id = toolboxesDict.get("Стеллаж")
actionsCount = random.randint(3, 5)
for i in range(actionsCount):
success = await StocksActions.takeToolkit(
source_toolbox_id=main_toolbox_id,
target_toolbox_id=own_toolbox_id,
toolkit_id=toolkit.get("id"),
quantity=random.randint(10, 19),
reason=f"Получение инструмента {toolkit.get('title')}. Для выполнения заказа № {random.randint(1000, 10000)}",
user_id=user.get("id"),
)
if not success:
logger.error(
f"Получение инструмента {toolkit.get('title')} пользователю {user.get('login')} не удалось"
)
return False
logger.warning(
f">>>> Получение инструмента {toolkit.get('title')} пользователю {user.get('login')} успешно завершено"
)
logger.warning("Получение инструментов из общих складов завершено")
logger.warning("Направление запросов на возврат и списание инструментов ...")
requestsDict = {"Списание": [], "Возврат": []}
for user in users:
userAccessLevelId = user.get("access_level_id")
if not accessLevelsDict.get(userAccessLevelId):
continue
own_toolbox_id = toolboxesOwners.get(user.get("id"))
logger.warning(
f"Направление запросов на возврат и списание инструмента от пользователя {user.get('login')} ..."
)
for action in requestsDict.keys():
for toolkit in toolkits:
if action == "Списание":
main_toolbox_id = None
else:
if "Сверло" in toolkit.get("title"):
main_toolbox_id = toolboxesDict.get("Шкаф")
else:
main_toolbox_id = toolboxesDict.get("Стеллаж")
actionsCount = random.randint(1, 3)
for i in range(actionsCount):
success = await StocksActions.movingRequest(
action=action,
toolkit_id=toolkit.get("id"),
source_toolbox_id=own_toolbox_id,
target_toolbox_id=main_toolbox_id,
quantity=random.randint(3, 5),
reason=f"{action} инструмента {toolkit.get('title')}. После выполнения заказа",
user_id=user.get("id"),
return_record_id=True,
)
if not success:
logger.error(
f"{action} инструмента {toolkit.get('title')} пользователю {user.get('login')} не удалось"
)
return False
requestsDict.get(action).append(success)
logger.warning(
f">>>> {action} инструмента пользователю {user.get('login')} успешно завершено"
)
logger.warning(
"Направление запросов на возврат и списание инструментов завершено"
)
logger.warning("Обработка запросов на возврат и списание инструментов ...")
decisionsDict = {
"manager": {"accept": [], "reject": [], "ignore": []},
"storekeeper": {"accept": [], "reject": [], "ignore": []},
}
for recordsList in requestsDict.values():
managerList, storekeeperList = (
recordsList[: len(recordsList) // 2],
recordsList[len(recordsList) // 2 :],
)
(
decisionsDict["manager"]["accept"],
decisionsDict["manager"]["reject"],
decisionsDict["manager"]["ignore"],
) = (
managerList[: len(managerList) // 3],
managerList[len(managerList) // 3 : len(managerList) // 3 * 2],
managerList[len(managerList) // 3 * 2 :],
)
(
decisionsDict["storekeeper"]["accept"],
decisionsDict["storekeeper"]["reject"],
decisionsDict["storekeeper"]["ignore"],
) = (
storekeeperList[: len(storekeeperList) // 3],
storekeeperList[
len(storekeeperList) // 3 : len(storekeeperList) // 3 * 2
],
storekeeperList[len(storekeeperList) // 3 * 2 :],
)
for role in decisionsDict.keys():
user_id = usersDict.get(role)
for decision in decisionsDict.get(role).keys():
match decision:
case "accept":
accepted = True
case "reject":
accepted = False
case "ignore":
continue
for record_id in decisionsDict.get(role).get(decision):
success = await StocksActions.movingDecision(
record_id=record_id,
user_id=user_id,
accepted=accepted,
)
if not success:
logger.error(
f"Принятие записи {record_id} пользователем {role} не удалось"
)
return False
logger.warning(
"Обработка запросов на возврат и списание инструментов завершено"
)
return True
+2 -2
View File
@@ -1,8 +1,8 @@
from sqlalchemy import select
from utils import logger
from db import CRUD
from db.schemas import Category
from db.handlers import ServiceRecordsHandler
from db.schemas.categories import Category
from db.handlers.records import ServiceRecordsHandler
class CategoryHandler:
+19 -11
View File
@@ -2,7 +2,8 @@ from datetime import datetime, timedelta
from sqlalchemy import select
from db.schemas import StocksRecords, ServicesRecords
from db.handlers.stock import StockHandler
from db.schemas.records import StocksRecords, ServicesRecords
from utils import logger
@@ -44,28 +45,37 @@ class StocksRecordsHandler:
logger.error(f"Ошибка создания записи: {str(e)}")
return False
async def accept(
async def decide(
record_id: int,
accept_user_id: int,
decision_user_id: int,
source_stock_id: int,
quantity: int,
price: float,
accept: bool = True,
):
try:
logger.info(f"Принятие записи {record_id} от {accept_user_id}")
record = await StocksRecords.get(id=record_id)
record.accept_user_id = accept_user_id
record.accepted_at = datetime.now()
logger.info(
f"{'Принятие' if accept else 'Отклонение'} записи {record_id} от {decision_user_id}"
)
record = await StocksRecordsHandler.getById(record_id, record=True)
if not record:
logger.error(f"Запись {record_id} не найдена")
return False
record.decision_user_id = decision_user_id
record.decided_at = datetime.now()
record.source_stock_id = source_stock_id
record.quantity = quantity
record.price = price
record.accepted = accept
await record.save()
logger.info(
f"Запись {record_id} успешно принята {accept_user_id} в {record.accepted_at.strftime('%Y-%m-%d %H:%M:%S')}"
f"Запись {record_id} успешно {'принята' if accept else 'отклонена'} {decision_user_id} в {record.decided_at.strftime('%Y-%m-%d %H:%M:%S')}"
)
return True
except Exception as e:
logger.error(f"Ошибка принятия записи: {str(e)}")
logger.error(
f"Ошибка {'принятия' if accept else 'отклонения'} записи: {str(e)}"
)
return False
async def edit(record_id: int, edit_user_id: int, **kwargs):
@@ -77,8 +87,6 @@ class StocksRecordsHandler:
return recordDB
try:
from db.handlers.stock import StockHandler
logger.info(f"Обновление записи {record_id} от {edit_user_id}")
record = await StocksRecords.get(id=record_id)
+2 -2
View File
@@ -1,5 +1,5 @@
from sqlalchemy import select
from db.schemas import Stock
from db.schemas.stock import Stock
from utils import logger
@@ -45,7 +45,7 @@ class StockHandler:
stock = await CRUD.read(select(Stock).where(Stock.id == stockId))
if not stock:
logger.error("Запись об остатках не найдена")
logger.error(f"Запись {stockId} об остатках не найдена")
return {}
return filterQuantity(stock, filtered) if not record else stock
+2 -2
View File
@@ -1,8 +1,8 @@
from utils import logger
from db import CRUD
from db.schemas import Toolbox
from db.schemas.toolbox import Toolbox
from sqlalchemy import or_, select
from db.handlers import ServiceRecordsHandler
from db.handlers.records import ServiceRecordsHandler
class ToolboxHandler:
+9 -11
View File
@@ -1,8 +1,8 @@
from utils import logger, saveImage, safeFilename, deleteImage
from db import CRUD
from db.schemas import Toolkit
from db.schemas.toolkit import Toolkit
from sqlalchemy import select
from db.handlers import ServiceRecordsHandler
from db.handlers.records import ServiceRecordsHandler
def handleToolkitImage(imageData, title: str):
@@ -51,10 +51,8 @@ class ToolkitHandler:
return {}
logger.info(f"Инструмент {newToolkit.title} успешно создан")
await ServiceRecordsHandler.add(
user_id, {"Добавлен инструмент": toolkitData.toDict()}
)
return newToolkit.toDict()
await ServiceRecordsHandler.add(user_id, {"Добавлен инструмент": toolkitData})
return newToolkit
async def edit(toolkitId: int, **kwargs):
query = select(Toolkit).where(Toolkit.id == toolkitId)
@@ -155,7 +153,7 @@ class ToolkitHandler:
)
return result
async def initialize(self):
async def initialize():
from .categories import CategoryHandler
logger.info("Инициализация инструментов")
@@ -203,7 +201,7 @@ class ToolkitHandler:
"external_link": "https://nazv.ru",
},
{
"title": "Псластина №1",
"title": "Пластина №1",
"description": "Пластина такая сякая этакая #1",
"specifications": {
"Размер": "10",
@@ -216,7 +214,7 @@ class ToolkitHandler:
"external_link": "https://nazv.ru",
},
{
"title": "Псластина №2",
"title": "Пластина №2",
"description": "Пластина такая сякая этакая #2",
"specifications": {
"Размер": "10",
@@ -229,7 +227,7 @@ class ToolkitHandler:
"external_link": "https://nazv.ru",
},
{
"title": "Псластина №3",
"title": "Пластина №3",
"description": "Пластина такая сякая этакая #3",
"specifications": {
"Размер": "10",
@@ -283,7 +281,7 @@ class ToolkitHandler:
]
for toolkit in baseToolkits:
await self.add(toolkit)
await ToolkitHandler.add(toolkit)
logger.info("Базовые инструменты успешно созданы")
return
+26 -17
View File
@@ -1,9 +1,10 @@
from sqlalchemy import or_, select
from db import CRUD
from db.handlers.toolbox import addNewToolbox
from db.handlers.access import AccessLevelHandler
from db.handlers.toolbox import ToolboxHandler
from utils import logger, pwd_hash, saveImage, safeFilename, deleteImage, pwd_verify
from db.schemas import User
from db.handlers import ServiceRecordsHandler
from db.schemas.user import User
from db.handlers.records import ServiceRecordsHandler
def handleUserPhoto(imageData, login: str):
@@ -52,20 +53,26 @@ class UserHandler:
logger.info(
f"Пользователь {newUser.username} успешно добавлен, id: {newUser.id}"
)
if newUser.available_own_toolbox:
userAccessLevel = await AccessLevelHandler.get(newUser.access_level_id)
if not userAccessLevel:
logger.error("Уровень доступа не найден")
return {}
if userAccessLevel.get("available_own_toolbox"):
newToolboxData = {
"title": f"Тулбокс {newUser.username}",
"description": f"Оборудование, полученное сотрудником {newUser.username}, под личную материальную ответственность",
"owner_id": newUser.id,
}
newToolbox = await addNewToolbox(newToolboxData)
newToolbox = await ToolboxHandler.add(newToolboxData)
logger.info(
f"Тулбокс {newToolbox['title']} успешно создан и закреплен за пользователем {newUser.username}"
)
await ServiceRecordsHandler.add(
user_id, {"Добавлен пользователь": newUser.toDict()}
)
return newUser.toDict()
newUserData = newUser.toDict()
newUserData["access_level_data"] = userAccessLevel
return newUserData
async def edit(userData: dict, user_id: int = None) -> dict:
id = userData.get("id", None)
@@ -107,7 +114,7 @@ class UserHandler:
"description": f"Оборудование, полученное сотрудником {editedUser.username}, под личную материальную ответственность",
"owner_id": editedUser.id,
}
newToolbox = await addNewToolbox(newToolboxData)
newToolbox = await ToolboxHandler.addNewToolbox(newToolboxData)
logger.info(
f"Тулбокс {newToolbox['title']} успешно создан и закреплен за пользователем {editedUser.username}"
)
@@ -182,7 +189,7 @@ class UserHandler:
)
return userData
async def initialize(self):
async def initialize():
from .access import AccessLevelHandler
logger.info("Инициализация пользователей")
@@ -190,34 +197,36 @@ class UserHandler:
acessLevels = {
accessLevel["title"]: accessLevel["id"] for accessLevel in accessLevelsList
}
logger.info(acessLevels)
password = "Alex0172"
baseUsers = {
"admin": {
"login": "admin",
"username": "Администратор",
"password": "Alex0172",
"username": "Администратор - Demo",
"password": password,
"access_level_id": acessLevels["Администратор"],
},
"manager": {
"login": "manager",
"username": "Менеджер",
"password": "Alex0172",
"username": "Менеджер - Demo",
"password": password,
"access_level_id": acessLevels["Менеджер"],
},
"storekeeper": {
"login": "storekeeper",
"username": "Кладовщик",
"password": "Alex0172",
"username": "Кладовщик - Demo",
"password": password,
"access_level_id": acessLevels["Кладовщик"],
},
"employee": {
"login": "employee",
"username": "Сотрудник",
"password": "Alex0172",
"username": "Сотрудник - Demo",
"password": password,
"access_level_id": acessLevels["Сотрудник"],
},
}
for user in baseUsers.values():
await self.add(user)
await UserHandler.add(user)
logger.info("Инициализация пользователей завершена")
return