From 54bf21d52de3c7031b1778aa25b71fd705075265 Mon Sep 17 00:00:00 2001 From: Macbook Date: Sat, 6 Dec 2025 13:48:42 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BE=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B?= =?UTF-8?q?=20=D1=81=20=D0=91=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/__init__.py | 34 +++---- db/__pycache__/__init__.cpython-313.pyc | Bin 8358 -> 8362 bytes .../__pycache__/actions.cpython-313.pyc | Bin 24929 -> 25671 bytes .../__pycache__/records.cpython-313.pyc | Bin 12175 -> 11965 bytes db/handlers/__pycache__/user.cpython-313.pyc | Bin 14726 -> 14669 bytes db/handlers/actions.py | 94 +++++++++++------- db/handlers/records.py | 14 +-- db/handlers/user.py | 1 - 8 files changed, 80 insertions(+), 63 deletions(-) diff --git a/db/__init__.py b/db/__init__.py index a292f80..5c2ae57 100644 --- a/db/__init__.py +++ b/db/__init__.py @@ -22,47 +22,47 @@ class CRUD: is_lst = isinstance(db_data, list) async with SessionLocal() as db: if is_lst: - logger.info(f"Создаю {len(db_data)} записей") + logger.debug(f"Создаю {len(db_data)} записей") try: db.add_all(db_data) except InvalidRequestError: for data in db_data: await db.merge(data) else: - logger.info("Создаю запись") + logger.debug("Создаю запись") db.add(db_data) await db.commit() if refresh: if is_lst: - logger.info(f"Обновляю {len(db_data)} записей") + logger.debug(f"Обновляю {len(db_data)} записей") for data in db_data: await db.refresh(data) else: - logger.info("Обновляю запись") + logger.debug("Обновляю запись") await db.refresh(db_data) - logger.info("Запись создана") + logger.debug("Запись создана") return db_data if refresh else None except Exception as e: - logger.error(f"Ошибка создания: {str(e)}", exc_info=True) + logger.error(f"Ошибка создания: {str(e)}", exc_debug=True) return None async def read(query, all: bool = False): try: async with SessionLocal() as db: - logger.info(f"Чтение записей. Все: {all}") + logger.debug(f"Чтение записей. Все: {all}") results = await db.execute(query) - logger.info(f"Чтение завершено") + logger.debug(f"Чтение завершено") return ( results.unique().scalars().all() if all else results.unique().scalars().first() ) except Exception as e: - logger.error(f"Ошибка чтения: {str(e)}", exc_info=True) + logger.error(f"Ошибка чтения: {str(e)}", exc_debug=True) return None async def delete(db_data) -> bool: - def itemInfo(instance): + def itemdebug(instance): from sqlalchemy import inspect state = inspect(instance) @@ -78,7 +78,7 @@ class CRUD: return {"key": pKey, "value": pValue, "class": instance.__class__} async def deleteFromDB(data, db): - itemData = itemInfo(data) + itemData = itemdebug(data) query = delete(itemData["class"]).where( getattr(itemData["class"], itemData["key"]) == itemData["value"] ) @@ -87,18 +87,18 @@ class CRUD: async with SessionLocal() as db: try: if isinstance(db_data, list): - logger.info(f"Удаляю записей: {len(db_data)}") + logger.debug(f"Удаляю записей: {len(db_data)}") for data in db_data: await deleteFromDB(data, db) else: - logger.info("Удаляю запись") + logger.debug("Удаляю запись") await deleteFromDB(db_data, db) await db.commit() - logger.info("Запись удалена") + logger.debug("Запись удалена") return True except Exception as e: await db.rollback() - logger.error(f"Ошибка удаления: {str(e)}", exc_info=True) + logger.error(f"Ошибка удаления: {str(e)}", exc_debug=True) return False async def update(db_data, id, **kwargs): @@ -107,9 +107,9 @@ class CRUD: query = update(db_data).where(db_data.id == id).values(**kwargs) item = await db.execute(query) await db.commit() - logger.info("Запись обновлена") + logger.debug("Запись обновлена") return await db.get(db_data, id) except Exception as e: await db.rollback() - logger.error(f"Ошибка обновления: {str(e)}", exc_info=True) + logger.error(f"Ошибка обновления: {str(e)}", exc_debug=True) return None diff --git a/db/__pycache__/__init__.cpython-313.pyc b/db/__pycache__/__init__.cpython-313.pyc index 2cf4a0b0fd2ba6eab211b1745d6dfafba3027b6a..9a1d819711988b8104d89c0f5160f552e8800fc8 100644 GIT binary patch delta 408 zcmZ4HxXO|DGcPX}0}xF7XPh~6Bd;<$7iVfka(qf^Qfc~ROLh%5RtPhV{eh{^B%cMg zTZA`+Zw$YgUdfucLc; zWhvw9BE}a)jBkiZOwXK{IXU~ffZ_!KMVPA~UOFT0#~K`dNg!ggyu@7=h+l!uwV%u? R8^IbLeMul@bCRqJGXNn4l7s*N delta 375 zcmZ4GxXh9FGcPX}0}vQ}G|ueU$g9lG$&p%-9G{t&mOt5wU4xYc%*tSYAnHBIdx7p2 z<_+$fc~;czh`*rVdqu==ax8~9Cs5{sg7p;3@=C+-VqR+&OM3yf{f)A0jtT3 zoaHPjmw19V*KpRe=z+xLoDVo3Fufq-c}2kMhJw;^u7zAHOfM@KUY9bQzz)+aXM07! zezGQC4U5Vp9{5cgvZ j3cDl_zFAq~E(=5g=pehvoU#$DVNsU^qBp0>x-bI(IQxW` diff --git a/db/handlers/__pycache__/actions.cpython-313.pyc b/db/handlers/__pycache__/actions.cpython-313.pyc index 074fb587daaf6132f1ce5fabecae82beb59c8249..ad721f5b712a7713bdf5ce30dd40a2f2c94db373 100644 GIT binary patch delta 5434 zcmbU_YfxO*dFR}{`+l%bU>Ekq@>)P3gpfc;z#<-!U>Ct^C2V0y2-aw|VzKTnvL!dh zl4nwlW>Q-|PUARf?8MH*nNAbQ#0}Qec91-_sz~m|))Y+T*W^b>O*;d6L~*BW`h90X z507Wk>7BXX88=BBk+7jvo?`Ca@v$npFUkSR2(HyZFkN# zvt;&>d{RWBIv0uR>je}gM6!(1pyBi@$4tg(W_&oA?vD?TOCxEPM}71bYoHsblci}b zb+Mn))sr6LA<=@Ubx@3o@Y)77QTw27ttRSlk%QtvD(RuWFlvB4BfJ8WpO6Pdk<5um4fgpUP> z3GL3|#v`yIu(7qu7izF)!H`IS{6sn~!63>0fZT#nif1OI)Lsdv$^KLM64kNqs%qFj zs@#HPXTMW@hvu-u>bC`#haLCiv6E^u+oidtFGMw71U}ZRtrUKtVtwA=)C<}kN{85& zIvag>>bCBu)L2f)ZV<~ptk!Q|3rp^ZDNH0P#3(>R%m~mJ(?(57kTQ`vO+C$u`$!iJ zYe0d>`f@yM#?V4fGinUbTvlSNVMqK9mM~gq9(&TbndY;1jZMK^u2~Ti9@H6i)~O%R zdWq|CaXo*b&t)e~KdE&6pT-K|5ki>P+_b6SeoJG9Vxl2kiinsNd?YQTw2vY$M9Kit z$YUIOG$iuv^@>Mnu#o-090tp;n>(n5)mTm%`L?-W;z24|*n5^Z%(B9|suG(d3j&mw z2mz2^o_$(=N1m2{Ex!TySMv1iiP__`&$7v$GU1Gm#jR^#IbO8B&VFVq(ikOl11Z2} zZ56bH{g`&5ed+0`TE~k*;+i@4d#2}2^SQg^f&KEXVR`t-A|X%EtpcFO z={7{$gkeM@!efYrg~Nyr3#|%3Aw?%5SYO2wa=pm4Dz+nX^eJvB1dH{CiddXem-D=o z-kJLM`~WrH!RDo2f#eq5I>yeqwoVQ!gnZpsH%!F6jov5~T&5fAgnZKtlgevdDph!` zU!@O#)h9NF9rPU<7Q}ZOftqPBg_WA~sx~(;?*(XBr+Tlr4SPOt)38zXfhS}K=HeO} zHmfeywK;+Lt$~JZs^1zz>wvkUR3S7{3nDW`XhSF!O`R=hr>@nwuC)m25UfRzhoFGv zxOWa@HxPO729n(+U3QoF-eesSyKq0U8)Qa`AF3jxf&kK}=iX+)Hofhxp%>VHxStnX zW#Hex3RHl^f{I6jkzo;-l?UU?Gw|NDv+Z7RR|PmWe@49E4TZ(*eXmo~OJjQ&6_%cUawGRMxEe5;nJZ~6L^VvK^sYSAtLI&9*oZHX zBOQWJ6;nlXqeLV&vgMD2q_pg8z`tUpmemFv?0>)vkv(9qLhP?Vy8#z*`?Hd03Q`{S zYH^-I7t^t~i))oSnAVCWt*}hq6YVQ;pw)V?+DAq;F-`v}u2RQNm+Yk)wp8NC+QSM; z3up~nU+Ncbn^|qIjoxOd(p?aT-Y-4p{WD(AUM_3i^k6i)j)7V#01#A45kL#(k@#>T z4f*PB!f~SrKbBVJD&IHx;8|W!kH#}?N4JhhB`Al-Pr~Jv?i+?Ix6OytMg#@~T?qKm z=T5-GQYp5rM}VPB@*`*hupk~BPox$UW9+}nH6?l}j2+xX_$RsThOzM@5EQc+AM#pB zu)3fH<+$(Yfx72AK5(9~V6F9c(3(D>AmloEn%puFZ4UcIaDBxebj0qur69JlIcxPt z*6P=fP8WY{ZJ9H)$cC0LEP0D+qILYiK+J{gPr(E&WQmGDLdf1<`H@gm%GOnRgn|Iu zS@mPhm_UrJ^ahAkc_-Bo4V}@_aDzCbYbyul0z{l9@j_i&J}~d=X}DQ@-_WK2=3)+w zQ1POfi(P7<5m9xiG30=r%O)C8sV?V)DuB7tL=iS4{E%`ea;QQ$tcKaGJO;x4W|dml zCP1PupZai>hN5rlc%DTURWez~qegVS5;CwWYHCz$B~fw!*5(NPt|Fo|kQ5xvyJ4f8 zyQLwf<{@IBW+UR#yXy3H$`xOOGp&Zixd87YJbC7@b2WR+YrwMmVrCvIU+ro9GiMlw z+>41$U^}IHfD=CO1{eGO>Xu2$4{}hwoHcO-KW*Je@k7de;1OVh+T{`myZ9OWhVZ+f z&kQBw{qe&S@pOhC@U#}>?;a(o61c3;4yf%|cdbX&0e+Q!jg8m-71mvUsvX<+%cp++ zlw92`H>c$BqjKt)eC#RNFbQc-tGlHluCh62{j9V8%*b???5vla19P^4lbX+R@~#=I z&-R?^nYXSv)AZ}+v(56FHn~lb)8CS%ryzAs(kLcb%MMn%#y(m7`jcP(4sIHCESYHtfbA!5;{cwT+IP)_Z3mmIu+z-&$zcG6%ud z6>~+&?i%*_W;X=3&o}3rFcPN-@IPm>Ybev`%qPjQz4>NC`WV@}fjvSIi3%TbAYS z^O~4<6OFcQ7$9T_GP#dL8&bYr3$$&%ugwQ->S#M}f&3AM@XBU8{4CY!vpfgi@PBPD z>>GCZR(yB}21K{^(&#oYpgZR8U!C2w`{7;Fdg@f{tlvTFFhb}_%oFp){Lyfu$i^G| zbda5HDB2MF|EaD9)j3^x`WuAkVV-bl=)k3&jNDtZ(FQ2Mb&*$=i*x!Yl;}Pz(}ChW zdCR<#^V-Nq(5i_v0aQocTJE#(K6NDhfUGhy4N{88_aQ$0HIGldkp*QYkr5BYB^Udo z>o|>0?cSoL%a^LDXSQylkaB0Xz2m)CxP4RjaIznDH_&=E*Zm3YXJ>nUtm=oQl~%KX z@P=X@>G-I7O1>6;il+WPyqeP8>|Z0^$rKEoSO-9UMLq*JhqG{hctbuXpYhEem*0ge z#BsPvoP+lbAM~D)-^DuyZ+yd7U0p35!B68=PRbyd05F06z%L`y@;}IL%5U>`T7J_9 zW8a)Txy-(WYs59kHMoJ|IE4JCqt3 zA6rl(PNXstcnn!k0yi25G(M3U$)kKJ?jW*Shp+gYw zvz16TU$7^(KjyY!FWk9D6OapzZU)tv1)5kXkCc6n#nGAJ6Jf>1BJ*RZV!lpls^Zhqu#pw;HhB zbjl>>wO-YP=I#DDd+Dsbbk1IWvKwDeLcYjvfI9sqvZi&gRo$}5RIi8%0r)J|Rd1QQ%kjH2b=9jS0hp0#BN7OIu zLgXC4q~pki99ObtuDEr!xOKj$blz7s?+?y9}=IWaz$kY*E-d>{?lGjuzCq)&(;+Ai!wv{N{U z$eqM5J6$(b#8-0DO}y>&mW{ZZmej-%yt|@{P@d&+>t2o#!&X`m{&e&Z^g*daO1mO8R7qpzOrAdu=ehmtq-%yd% zix-Nq{X#QMn#Bt(ov79$5vvuGDNC8y}fC6mORP4tgPKkaQJW WJ>+#%eM<80sCu;2euE(7WBwPI)f{{P delta 4722 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 diff --git a/db/handlers/__pycache__/records.cpython-313.pyc b/db/handlers/__pycache__/records.cpython-313.pyc index d09f9069deb0d09d8d83d11cbb23b7c8ca850997..16a62bf58c6a6feb336aa6585c868b387ea027d4 100644 GIT binary patch delta 1646 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 V;~aM1LxA@)f{fjNAO_kd{{awPf zL~b&#*>Wd$Mg|$%pP!hR#JN7&G4N{qEY<}Y&}8V$%ea}*nT2Hw2avT#$eE4hAfKZc vkbOvn(V3g=kg5WZeVC2SnRoMdvkXQ?_00(u;*9*E%#8e>7(ir^IM5sbC1EAZ delta 174 zcmX?G)K<*a zOpKC~>r8_LzpycI^7nIhaZm8R!l7_OSa$MN)8)>dj0`fiKR+=siF18)U}WIc_*twA zG`PvoS($M&qq7vt77ie5kC3wr%RxRz9U%LV6{E8v+aYTOAp5Wko3rxfeP$Vqj2fHO UEyNl5!n+a diff --git a/db/handlers/actions.py b/db/handlers/actions.py index 7900fde..97d1956 100644 --- a/db/handlers/actions.py +++ b/db/handlers/actions.py @@ -6,6 +6,7 @@ from db.handlers.user import UserHandler from db.handlers.access import AccessLevelHandler from db.handlers.records import StocksRecordsHandler +from db.schemas.records import StocksRecords from utils import logger @@ -47,7 +48,7 @@ class StocksActions: reason=reason, quantity=quantity, price=price, - return_record_id=True, + return_record=True, ) logger.info( f"Оприходование инструмента {toolkit_id} на складе {toolbox_id} прошло {'успешно' if recorded else 'не успешно'}" @@ -124,6 +125,9 @@ class StocksActions: ) if not target_toolbox_id: + logger.warning( + f"Производится списание инструмента {toolkit_id} со склада {source_toolbox_id} в количестве {takeQuantity} по цене {stock['price']}" + ) continue existing = await StockHandler.getByToolboxIdAndToolkitIdAndQPrice( @@ -165,23 +169,23 @@ 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 + # 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} прошло успешно" @@ -197,7 +201,7 @@ class StocksActions: reason: str, user_id: int, price: int = 0, - return_record_id: bool = False, + return_record: bool = False, ): logger.info( f"Запрос на {action} инструмента {toolkit_id} со склада {source_toolbox_id} в количестве {quantity} по цене {price} ..." @@ -213,18 +217,28 @@ class StocksActions: reason=reason, quantity=quantity, price=price, - return_record_id=return_record_id, + return_record=return_record, ) logger.info( f"Запрос на {action} инструмента {toolkit_id} со склада {source_toolbox_id} в количестве {quantity} по цене {price} {'успешно завершен' if recorded else 'завершен с ошибкой'}" ) return recorded - async def movingDecision(record_id: int, user_id: int, accepted: bool = True): + async def movingDecision( + record_id: int, + user_id: int, + accepted: bool = True, + record: StocksRecords = None, + ): logger.info( - f"{'Принятие' if accepted else 'Отклонение'} записи о движении инструмента {record_id} ..." + f"{'Принятие' if accepted else 'Отклонение'} записи {record_id if not record else record.id} о движении инструмента {'' if not record else record.toolkit_id} ..." ) - movingRecord = await StocksRecordsHandler.getById(record_id, True) + movingRecord = ( + await StocksRecordsHandler.getById(record_id, True) + if not record + else record + ) + if not movingRecord: logger.error(f"Запись {record_id} не найдена") return False @@ -235,7 +249,7 @@ class StocksActions: return False if not accepted: return await StocksRecordsHandler.decide( - record_id, + movingRecord, user_id, movingRecord.source_stock_id, movingRecord.quantity, @@ -264,7 +278,7 @@ class StocksActions: return False accept = await StocksRecordsHandler.decide( - record_id, + movingRecord, user_id, stocksMovements[0].get("id"), stocksMovements[0].get("quantity"), @@ -288,12 +302,12 @@ class StocksActions: reason=movingRecord.reason, quantity=stock.get("quantity"), price=stock.get("price"), - return_record_id=True, + return_record=True, ) if not recorded: return False accept = await StocksRecordsHandler.decide( - record_id=recorded, + record=recorded, decision_user_id=user_id, source_stock_id=stock.get("id"), quantity=stock.get("quantity"), @@ -329,7 +343,7 @@ class StocksActions: user_id=user_id, reason=reason, price=price, - return_record_id=True, + return_record=True, ) if not takeRequest: logger.error( @@ -340,16 +354,16 @@ class StocksActions: f"Формирование запроса на получение инструмента {toolkit_id} успешно завершено" ) logger.info( - f"Принятие запроса {takeRequest} на получение инструмента {toolkit_id} ..." + f"Принятие запроса {takeRequest.id} на получение инструмента {toolkit_id} ..." ) - accepted = await StocksActions.movingDecision(takeRequest, user_id) + accepted = await StocksActions.movingDecision(None, user_id, record=takeRequest) if not accepted: logger.error( - f"Принятие запроса {takeRequest} на получение инструмента {toolkit_id} не удалось" + f"Принятие запроса {takeRequest.id} на получение инструмента {toolkit_id} не удалось" ) return False logger.info( - f"Принятие запроса {takeRequest} на получение инструмента {toolkit_id} успешно завершено" + f"Принятие запроса {takeRequest.id} на получение инструмента {toolkit_id} успешно завершено" ) return True @@ -498,7 +512,7 @@ class StocksActions: quantity=random.randint(3, 5), reason=f"{action} инструмента {toolkit.get('title')}. После выполнения заказа", user_id=user.get("id"), - return_record_id=True, + return_record=True, ) if not success: logger.error( @@ -522,6 +536,7 @@ class StocksActions: "manager": {"accept": [], "reject": [], "ignore": []}, "storekeeper": {"accept": [], "reject": [], "ignore": []}, } + logger.info("Разбивка списоков запросов ...") for recordsList in requestsDict.values(): managerList, storekeeperList = ( recordsList[: len(recordsList) // 2], @@ -550,9 +565,12 @@ class StocksActions: storekeeperList[len(storekeeperList) // 3 * 2 :], ) + logger.warning("Применение решений ...") for role in decisionsDict.keys(): + logger.warning(f"Принятие записей пользователем {role} ...") user_id = usersDict.get(role) for decision in decisionsDict.get(role).keys(): + logger.warning(f"Принятие решения {decision} пользователем {role} ...") match decision: case "accept": accepted = True @@ -560,15 +578,19 @@ class StocksActions: accepted = False case "ignore": continue - for record_id in decisionsDict.get(role).get(decision): + for record in decisionsDict.get(role).get(decision): + logger.info( + f"{'Принятие' if accepted else 'Отклонение'} записи {record.id} пользователем {role} ... " + ) success = await StocksActions.movingDecision( - record_id=record_id, + record_id=None, user_id=user_id, accepted=accepted, + record=record, ) if not success: logger.error( - f"Принятие записи {record_id} пользователем {role} не удалось" + f"{'Принятие' if accepted else 'Отклонение'} записи {record.id} пользователем {role} не удалось" ) return False diff --git a/db/handlers/records.py b/db/handlers/records.py index d17ae2a..818c0a3 100644 --- a/db/handlers/records.py +++ b/db/handlers/records.py @@ -20,7 +20,7 @@ class StocksRecordsHandler: price: float, source_toolbox_id: int = None, target_toolbox_id: int = None, - return_record_id: bool = False, + return_record: bool = False, ): recordData = { "action": action, @@ -40,13 +40,13 @@ class StocksRecordsHandler: record = StocksRecords(**recordData) await record.save() logger.info(f"Запись успешно создана, id: {record.id}") - return True if not return_record_id else record.id + return True if not return_record else record except Exception as e: logger.error(f"Ошибка создания записи: {str(e)}") return False async def decide( - record_id: int, + record: StocksRecords, decision_user_id: int, source_stock_id: int, quantity: int, @@ -55,12 +55,8 @@ class StocksRecordsHandler: ): try: logger.info( - f"{'Принятие' if accept else 'Отклонение'} записи {record_id} от {decision_user_id}" + 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 @@ -69,7 +65,7 @@ class StocksRecordsHandler: record.accepted = accept await record.save() logger.info( - f"Запись {record_id} успешно {'принята' if accept else 'отклонена'} {decision_user_id} в {record.decided_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: diff --git a/db/handlers/user.py b/db/handlers/user.py index ce2e82d..c38bc77 100644 --- a/db/handlers/user.py +++ b/db/handlers/user.py @@ -197,7 +197,6 @@ class UserHandler: acessLevels = { accessLevel["title"]: accessLevel["id"] for accessLevel in accessLevelsList } - logger.info(acessLevels) password = "Alex0172" baseUsers = { "admin": {