Files
toolbox/db/handlers/actions.py
T

333 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from db.handlers import StockHandler, StocksRecordsHandler
from utils import logger
class StocksActions:
async def registration(
toolkit_id: int,
toolbox_id: int,
user_id: int,
quantity: int,
price: int,
placement: str,
reason: str,
):
logger.info(
f"Оприходование инструмента {toolkit_id} на складе {toolbox_id} ..."
)
newStocks = await StockHandler.add(
toolkit_id=toolkit_id,
toolbox_id=toolbox_id,
quantity=quantity,
price=price,
placement=placement,
)
if newStocks is None:
logger.error(
f"Оприходование инструмента {toolkit_id} на складе {toolbox_id} не удалось"
)
return False
recorded = await StocksRecordsHandler.add(
action="Оприходование",
source_stock_id=None,
target_stock_id=newStocks.id,
source_toolbox_id=None,
target_toolbox_id=toolbox_id,
toolkit_id=toolkit_id,
init_user_id=user_id,
reason=reason,
quantity=quantity,
price=price,
return_record_id=True,
)
logger.info(
f"Оприходование инструмента {toolkit_id} на складе {toolbox_id} прошло {'успешно' if recorded else 'не успешно'}"
)
if recorded:
accepted = await StocksRecordsHandler.accept(
recorded, user_id, None, quantity, price
)
if not accepted:
logger.error(
f"Принятие записи о оприходовании инструмента {toolkit_id} на складе {toolbox_id} не удалось"
)
return accepted
return False
async def moving(
action: str,
source_toolbox_id: int,
target_toolbox_id: int,
toolkit_id: int,
quantity: int,
user_id: int,
reason: str,
target_placement: str = None,
):
logger.info(
f"{action} инструмента {toolkit_id} со склада {source_toolbox_id} на склад {target_toolbox_id} ..."
)
availability = await StockHandler.getByToolboxIdAndToolkitId(
source_toolbox_id, toolkit_id
)
if len(availability) == 0:
logger.error(f"На складе {source_toolbox_id} нет инструмента {toolkit_id}")
return False
totalQuantity = sum([stock["quantity"] for stock in availability])
if quantity > totalQuantity:
logger.error(
f"На складе {source_toolbox_id} нет в количестве {quantity} инструмента {toolkit_id}"
)
return False
totalTakeQuantity = 0
writeDownList = []
for stock in availability:
if quantity == totalTakeQuantity:
break
takeQuantity = min(stock["quantity"], quantity - totalTakeQuantity)
totalTakeQuantity += takeQuantity
logger.info(
f"Списание инструмента {toolkit_id} со склада {source_toolbox_id} на склад {target_toolbox_id} в количестве {takeQuantity} по цене {stock['price']} ..."
)
sourceEdit = await StockHandler.edit(
stock["id"], quantity=stock["quantity"] - takeQuantity
)
if not sourceEdit:
logger.error(
f"Ошибка обновления записи об остатках инструмента {toolkit_id} на складе {source_toolbox_id}"
)
return False
logger.info(
f"Списание инструмента {toolkit_id} со склада {source_toolbox_id} на склад {target_toolbox_id} в количестве {takeQuantity} по цене {stock['price']} успешно завершена"
)
if not target_toolbox_id:
writeDownList.append(
{
"id": sourceEdit["id"],
"quantity": takeQuantity,
"price": stock["price"],
}
)
continue
existing = await StockHandler.getByToolboxIdAndToolkitIdAndQPrice(
target_toolbox_id, toolkit_id, stock["price"]
)
if len(existing) == 0:
logger.info(
f"Добавление инструмента {toolkit_id} на склад {target_toolbox_id} по цене {stock['price']} ..."
)
targetStock = await StockHandler.add(
toolkit_id=toolkit_id,
toolbox_id=target_toolbox_id,
quantity=takeQuantity,
price=stock["price"],
placement=target_placement,
)
if not targetStock:
logger.error(
f"Ошибка добавления инструмента {toolkit_id} на склад {target_toolbox_id}"
)
return False
logger.info(
f"Добавление инструмента {toolkit_id} на склад {target_toolbox_id} по цене {stock['price']} успешно завершено"
)
else:
logger.info(
f"Изменение остатков инструмента {toolkit_id} на склад {target_toolbox_id} по цене {stock['price']} ..."
)
targetStock = await StockHandler.edit(
existing[0]["id"],
quantity=existing[0]["quantity"] + takeQuantity,
)
if not targetStock:
logger.error(
f"Ошибка обновления записи об остатках инструмента {toolkit_id} на складе {target_toolbox_id}"
)
return False
logger.info(
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"],
target_placement=target_placement,
)
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} прошло успешно"
)
return True if target_toolbox_id else writeDownList
async def movingRequest(
action: str,
toolkit_id: int,
source_toolbox_id: int,
target_toolbox_id: int,
quantity: int,
reason: str,
user_id: int,
price: int = 0,
return_record_id: bool = False,
):
logger.info(
f"Запрос на {action} инструмента {toolkit_id} со склада {source_toolbox_id} в количестве {quantity} по цене {price} ..."
)
recorded = await StocksRecordsHandler.add(
action=action,
source_stock_id=None,
target_stock_id=None,
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=price,
return_record_id=return_record_id,
)
logger.info(
f"Запрос на {action} инструмента {toolkit_id} со склада {source_toolbox_id} в количестве {quantity} по цене {price} {'успешно завершен' if recorded else 'завершен с ошибкой'}"
)
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:
logger.error(f"Запись {record_id} не найдена")
return False
if writeDownARecord.accepted_at is not None:
logger.error(f"Запись {record_id} уже была принята")
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,
user_id=user_id,
reason=writeDownARecord.reason,
)
if not stocksMovements:
logger.error(f"Ошибка при {writeDownARecord.action} инструмента")
return False
accept = await StocksRecordsHandler.accept(
record_id,
user_id,
stocksMovements[0].get("id"),
stocksMovements[0].get("quantity"),
stocksMovements[0].get("price"),
)
if not accept:
return accept
totalRecordsIds = [record_id]
if len(stocksMovements) > 1:
for stock in stocksMovements[1:]:
recorded = await StocksRecordsHandler.add(
action=writeDownARecord.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,
quantity=stock.get("quantity"),
price=stock.get("price"),
return_record_id=True,
)
if not recorded:
return False
accept = await StocksRecordsHandler.accept(
record_id=recorded,
accept_user_id=user_id,
source_stock_id=stock.get("id"),
quantity=stock.get("quantity"),
price=stock.get("price"),
)
if not accept:
return False
totalRecordsIds.append(recorded)
logger.info(
f"Записи {', '.join(map(str, totalRecordsIds))} о {writeDownARecord.action} инструмента успешно приняты {user_id}"
)
return True
async def takeToolkit(
self,
source_toolbox_id: int,
target_toolbox_id: int,
toolkit_id: int,
quantity: int,
reason: str,
user_id: int,
price: int = 0,
):
logger.info(
f"Формирование запроса на получение инструмента {toolkit_id} на склад {target_toolbox_id} со склада {source_toolbox_id} в количестве {quantity} ..."
)
takeRequest = await self.movingRequest(
action="Получение",
source_toolbox_id=source_toolbox_id,
target_toolbox_id=target_toolbox_id,
toolkit_id=toolkit_id,
quantity=quantity,
user_id=user_id,
reason=reason,
price=price,
return_record_id=True,
)
if not takeRequest:
logger.error(
f"Формирование запроса на получение инструмента {toolkit_id} не удалось"
)
return False
logger.info(
f"Формирование запроса на получение инструмента {toolkit_id} успешно завершено"
)
logger.info(
f"Принятие запроса {takeRequest} на получение инструмента {toolkit_id} ..."
)
accepted = await self.movingAcceptance(takeRequest, user_id)
if not accepted:
logger.error(
f"Принятие запроса {takeRequest} на получение инструмента {toolkit_id} не удалось"
)
return False
logger.info(
f"Принятие запроса {takeRequest} на получение инструмента {toolkit_id} успешно завершено"
)
return True
async def initialize():
# TODO прописать наполнение общих складов, получение на личные, возвраты и списания.
# Не все запросы на возвраты и списания нужно принять автоматически, нужно оставить несколько для демонстрации
pass