diff --git a/api/__pycache__/__init__.cpython-313.pyc b/api/__pycache__/__init__.cpython-313.pyc index d59b572..30102f8 100644 Binary files a/api/__pycache__/__init__.cpython-313.pyc and b/api/__pycache__/__init__.cpython-313.pyc differ diff --git a/api/routers/__init__.py b/api/routers/__init__.py index e539751..7885478 100644 --- a/api/routers/__init__.py +++ b/api/routers/__init__.py @@ -4,12 +4,16 @@ from db.handlers.categories import CategoryHandler from utils import render, requestDict, logger from .user import router as user from .stocks import router as stocks +from .toolbox import router as toolbox +from .toolkit import router as toolkit router = APIRouter() router.include_router(user, prefix="/user", tags=["user"]) router.include_router(stocks, prefix="/stocks", tags=["stocks"]) +router.include_router(toolbox, prefix="/toolbox", tags=["toolbox"]) +router.include_router(toolkit, prefix="/toolkit", tags=["toolkit"]) @router.get("/") diff --git a/api/routers/__pycache__/__init__.cpython-313.pyc b/api/routers/__pycache__/__init__.cpython-313.pyc index 210f87a..d0e02ed 100644 Binary files a/api/routers/__pycache__/__init__.cpython-313.pyc and b/api/routers/__pycache__/__init__.cpython-313.pyc differ diff --git a/api/routers/__pycache__/stocks.cpython-313.pyc b/api/routers/__pycache__/stocks.cpython-313.pyc index a82c2e0..e75b551 100644 Binary files a/api/routers/__pycache__/stocks.cpython-313.pyc and b/api/routers/__pycache__/stocks.cpython-313.pyc differ diff --git a/api/routers/__pycache__/toolbox.cpython-313.pyc b/api/routers/__pycache__/toolbox.cpython-313.pyc new file mode 100644 index 0000000..eb7f388 Binary files /dev/null and b/api/routers/__pycache__/toolbox.cpython-313.pyc differ diff --git a/api/routers/__pycache__/toolkit.cpython-313.pyc b/api/routers/__pycache__/toolkit.cpython-313.pyc new file mode 100644 index 0000000..f6e933b Binary files /dev/null and b/api/routers/__pycache__/toolkit.cpython-313.pyc differ diff --git a/api/routers/stocks.py b/api/routers/stocks.py index 1214e36..8a9d990 100644 --- a/api/routers/stocks.py +++ b/api/routers/stocks.py @@ -11,16 +11,17 @@ from utils import requestDict, logger router = APIRouter() -@router.post("/") +@router.post("/", summary="Получение инструментов для тулбокса") async def post_requests( request_data: dict = Depends(requestDict), ): toolboxId = request_data.get("body").get("toolboxId") logger.info(f"Получение инструментов для тулбокса {toolboxId}") - response = {"status": "error", "data": {}} + response = {"status": "error", "data": []} stocksData = await StockHandler.getByToolboxId(toolboxId) if not stocksData: + response["status"] = "ok" return response toolkitsIds = set(stock["toolkit_id"] for stock in stocksData) toolkitsData = await ToolkitHandler.getSeveral(list(toolkitsIds)) @@ -107,42 +108,3 @@ async def post_requests( if result: resonse["status"] = "ok" return resonse - - -@router.post("/toolkit", summary="Запрос остатка инструмента") -async def toolkit_request( - request_data: dict = Depends(requestDict), -): - response = {"status": "error", "data": {}} - logger.info(f"Получение запроса остатка инструмента") - # logger.info(request_data) - toolkitId = request_data.get("body").get("toolkitId") - stocks = await StockHandler.getByToolkitId(toolkitId) - if not stocks: - return response - userId = request_data.get("body").get("userId") - allToolboxes = request_data.get("body").get("allToolboxes") - toolboxes = ( - await ToolboxHandler.getByOwner(userId) - if not allToolboxes - else await ToolboxHandler.getAll() - ) - if not toolboxes: - return response - toolboxesTitles = {toolbox["id"]: toolbox["title"] for toolbox in toolboxes} - stocksData = {"count": 0, "toolboxes": {}} - for stock in stocks: - toolboxTitle = toolboxesTitles.get(stock["toolbox_id"], None) - if not toolboxTitle: - continue - stocksData["count"] += stock["quantity"] - if toolboxTitle not in stocksData["toolboxes"]: - stocksData["toolboxes"][toolboxTitle] = { - "count": stock["quantity"], - "placement": stock["placement"], - } - else: - stocksData["toolboxes"][toolboxTitle]["count"] += stock["quantity"] - response["status"] = "ok" - response["data"] = stocksData - return response diff --git a/api/routers/toolbox.py b/api/routers/toolbox.py new file mode 100644 index 0000000..c930989 --- /dev/null +++ b/api/routers/toolbox.py @@ -0,0 +1,38 @@ +from fastapi import APIRouter, Depends +from db.handlers.stock import StockHandler +from db.handlers.toolbox import ToolboxHandler +from utils import requestDict, logger + + +router = APIRouter() + + +@router.post("/", summary="Добавление ящика") +async def add_toolbox(reqDict=Depends(requestDict)): + logger.info(f"Добавление ящика") + response = {"status": "error"} + userId = reqDict.get("body").get("userId") + toolboxData = reqDict.get("body").get("toolboxData") + result = await ToolboxHandler.add(toolboxData, userId) + if result: + response["status"] = "ok" + logger.info(response) + return response + + +@router.delete("/", summary="Удаление ящика") +async def delete_toolbox(reqDict=Depends(requestDict)): + toolboxId = reqDict.get("body").get("toolboxId") + logger.info(f"Удаление ящика #{toolboxId}") + response = {"status": "error"} + stocksData = await StockHandler.getByToolboxId(toolboxId, False) + if stocksData: + response["message"] = ( + "Через этот склад были проведены операции, удаление невозможно" + ) + return response + userId = reqDict.get("body").get("userId") + result = await ToolboxHandler.delete(toolboxId, userId) + if result: + response["status"] = "ok" + return response diff --git a/api/routers/toolkit.py b/api/routers/toolkit.py new file mode 100644 index 0000000..b3cf6e5 --- /dev/null +++ b/api/routers/toolkit.py @@ -0,0 +1,46 @@ +from fastapi import APIRouter, Depends +from db.handlers.stock import StockHandler +from db.handlers.toolbox import ToolboxHandler +from utils import requestDict, logger + + +router = APIRouter() + + +@router.post("/", summary="Запрос остатка инструмента") +async def toolkit_request( + request_data: dict = Depends(requestDict), +): + response = {"status": "error", "data": {}} + logger.info(f"Получение запроса остатка инструмента") + # logger.info(request_data) + toolkitId = request_data.get("body").get("toolkitId") + stocks = await StockHandler.getByToolkitId(toolkitId) + if not stocks: + return response + userId = request_data.get("body").get("userId") + allToolboxes = request_data.get("body").get("allToolboxes") + toolboxes = ( + await ToolboxHandler.getByOwner(userId) + if not allToolboxes + else await ToolboxHandler.getAll() + ) + if not toolboxes: + return response + toolboxesTitles = {toolbox["id"]: toolbox["title"] for toolbox in toolboxes} + stocksData = {"count": 0, "toolboxes": {}} + for stock in stocks: + toolboxTitle = toolboxesTitles.get(stock["toolbox_id"], None) + if not toolboxTitle: + continue + stocksData["count"] += stock["quantity"] + if toolboxTitle not in stocksData["toolboxes"]: + stocksData["toolboxes"][toolboxTitle] = { + "count": stock["quantity"], + "placement": stock["placement"], + } + else: + stocksData["toolboxes"][toolboxTitle]["count"] += stock["quantity"] + response["status"] = "ok" + response["data"] = stocksData + return response diff --git a/api/static/css/index.css b/api/static/css/index.css index 13675d3..d314205 100644 --- a/api/static/css/index.css +++ b/api/static/css/index.css @@ -342,4 +342,118 @@ tr:hover .action-buttons { .toolkit-card-img { height: 150px; } +} + +/* Стили для модального окна добавления склада */ +.modal-content { + border-radius: 12px; + border: 1px solid rgba(0, 0, 0, 0.08); + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); +} + +.modal-header { + background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); + border-bottom: 1px solid rgba(0, 0, 0, 0.08); + border-radius: 12px 12px 0 0; + padding: 1.25rem 1.5rem; +} + +.modal-title { + color: #495057; + font-weight: 600; +} + +.modal-body { + padding: 1.5rem; +} + +.modal-footer { + border-top: 1px solid rgba(0, 0, 0, 0.08); + padding: 1rem 1.5rem; +} + +/* Стили для обязательных полей */ +.form-label.required::after { + content: " *"; + color: #dc3545; +} + +/* Кастомные стили для переключателя */ +.form-switch .form-check-input { + width: 3em; + height: 1.5em; + cursor: pointer; + transition: all 0.3s ease; +} + +.form-switch .form-check-input:checked { + background-color: #0d6efd; + border-color: #0d6efd; +} + +.form-switch .form-check-input:focus { + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} + +.form-switch .form-check-label { + font-weight: 500; + cursor: pointer; +} + +/* Стили для текстовых полей в фокусе */ +.form-control:focus { + border-color: #86b7fe; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); + transition: all 0.3s ease; +} + +/* Стили для валидации */ +.form-control.is-valid { + border-color: #198754; + padding-right: calc(1.5em + 0.75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} + +.form-control.is-invalid { + border-color: #dc3545; + padding-right: calc(1.5em + 0.75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} + +/* Стили для текста подсказки */ +.form-text { + color: #6c757d; + font-size: 0.875em; + margin-top: 0.25rem; +} + +/* Стили для кнопок в модальном окне */ +.modal-footer .btn { + min-width: 100px; + font-weight: 500; +} + +/* Адаптивность для мобильных */ +@media (max-width: 576px) { + .modal-dialog { + margin: 0.5rem; + } + + .modal-content { + border-radius: 8px; + } + + .modal-body { + padding: 1rem; + } + + .modal-footer { + padding: 0.75rem 1rem; + } } \ No newline at end of file diff --git a/api/static/js/api.js b/api/static/js/api.js index 0cabd47..b4360b1 100644 --- a/api/static/js/api.js +++ b/api/static/js/api.js @@ -1,8 +1,6 @@ // api.js export async function apiRequest(url, payload = {}, method = 'POST') { - const finalUrl = new URL(url, window.location.origin).toString(); - - const res = await fetch(finalUrl, { + const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json', diff --git a/api/static/js/index.js b/api/static/js/index.js index 9d3ae75..8a2290f 100644 --- a/api/static/js/index.js +++ b/api/static/js/index.js @@ -1,5 +1,6 @@ import { getCookie } from '/static/js/cookies.js'; import { apiRequest } from '/static/js/api.js'; +import { showInfo } from '/static/js//toast.js'; let accessData; let userData; @@ -112,9 +113,9 @@ function prepareTabs() {
-
-
+ +
@@ -128,19 +129,19 @@ function prepareTabs() {
-
+
-
-
-
- Загрузка... -
+ +
+
+
+ Загрузка...
-
+
- +
`).join('')}
@@ -462,6 +463,249 @@ function setupFilters(tabId, tools, categoriesMap) { } } +function addToolbox() { + // Проверяем, существует ли уже модальное окно + let modal = document.getElementById('addToolboxModal'); + + if (modal) { + modal.remove(); + } + + // Создаем модальное окно + modal = document.createElement('div'); + modal.className = 'modal fade'; + modal.id = 'addToolboxModal'; + modal.tabIndex = -1; + modal.setAttribute('aria-hidden', 'true'); + + modal.innerHTML = ` + + `; + + document.body.appendChild(modal); + + // Инициализация модального окна + const bsModal = new bootstrap.Modal(modal); + + // Получаем элементы формы + const form = modal.querySelector('#addToolboxForm'); + const titleInput = modal.querySelector('#toolboxTitle'); + const descriptionInput = modal.querySelector('#toolboxDescription'); + const submitBtn = modal.querySelector('#submitToolboxBtn'); + const spinner = modal.querySelector('#submitToolboxSpinner'); + + // Функция валидации формы + function validateForm() { + let isValid = true; + + // Валидация названия + if (titleInput.value.length < 3) { + titleInput.classList.add('is-invalid'); + isValid = false; + } else { + titleInput.classList.remove('is-invalid'); + titleInput.classList.add('is-valid'); + } + + // Валидация описания (необязательно, но если заполнено - проверяем) + if (descriptionInput.value.length > 0 && descriptionInput.value.length < 3) { + descriptionInput.classList.add('is-invalid'); + isValid = false; + } else if (descriptionInput.value.length >= 3) { + descriptionInput.classList.remove('is-invalid'); + descriptionInput.classList.add('is-valid'); + } else { + descriptionInput.classList.remove('is-invalid', 'is-valid'); + } + + submitBtn.disabled = !isValid; + return isValid; + } + + // Слушатели событий для валидации в реальном времени + titleInput.addEventListener('input', function () { + if (this.value.length >= 3) { + this.classList.remove('is-invalid'); + this.classList.add('is-valid'); + } else { + this.classList.remove('is-valid'); + if (this.value.length > 0) { + this.classList.add('is-invalid'); + } else { + this.classList.remove('is-invalid'); + } + } + validateForm(); + }); + + descriptionInput.addEventListener('input', function () { + if (this.value.length === 0) { + this.classList.remove('is-invalid', 'is-valid'); + } else if (this.value.length >= 3) { + this.classList.remove('is-invalid'); + this.classList.add('is-valid'); + } else { + this.classList.add('is-invalid'); + this.classList.remove('is-valid'); + } + validateForm(); + }); + + // Обработчик отправки формы + form.addEventListener('submit', async function (e) { + e.preventDefault(); + + if (!validateForm()) { + return; + } + + // Показываем индикатор загрузки и отключаем кнопку + submitBtn.disabled = true; + spinner.style.display = 'inline-block'; + + // Собираем данные + const toolboxData = { + title: titleInput.value.trim(), + description: descriptionInput.value.trim(), + monitoring: modal.querySelector('#toolboxMonitoring').checked + }; + + const userId = userData.id; + + try { + // Отправка данных (замените на ваш реальный endpoint) + const response = await apiRequest("/toolbox/", { toolboxData, userId }); + + if (response.status !== 'ok') { + throw new Error('Ошибка при добавлении склада'); + } + + // Успешная отправка + bsModal.hide(); + + // Показываем уведомление об успехе + showInfo('Склад успешно добавлен', 'success'); + + // Здесь можно добавить обновление списка складов + await uploadTab('toolbox'); + + } catch (error) { + console.error('Ошибка при добавлении склада:', error); + + // Возвращаем кнопку в исходное состояние + submitBtn.disabled = false; + spinner.style.display = 'none'; + + // Показываем сообщение об ошибке + showInfo('Ошибка при добавлении склада. Попробуйте еще раз.', 'error'); + + // Можно добавить более детальное сообщение об ошибке + const errorDiv = document.createElement('div'); + errorDiv.className = 'alert alert-danger mt-3'; + errorDiv.innerHTML = ` + Ошибка! Не удалось добавить склад. + Проверьте соединение и попробуйте еще раз. + `; + + const modalBody = modal.querySelector('.modal-body'); + if (!modalBody.querySelector('.alert')) { + modalBody.appendChild(errorDiv); + + // Убираем сообщение через 5 секунд + setTimeout(() => { + if (errorDiv.parentNode) { + errorDiv.remove(); + } + }, 5000); + } + } + }); + + // Очистка при закрытии модального окна + modal.addEventListener('hidden.bs.modal', () => { + // Сбрасываем форму + form.reset(); + + // Убираем стили валидации + titleInput.classList.remove('is-valid', 'is-invalid'); + descriptionInput.classList.remove('is-valid', 'is-invalid'); + + // Включаем кнопку + submitBtn.disabled = false; + spinner.style.display = 'none'; + + // Убираем сообщения об ошибках + const alerts = modal.querySelectorAll('.alert'); + alerts.forEach(alert => alert.remove()); + + // Удаляем модальное окно из DOM + setTimeout(() => { + if (modal.parentNode) { + modal.remove(); + } + }, 300); + }); + + // Показываем модальное окно + bsModal.show(); + + // Фокусируемся на первом поле + setTimeout(() => { + titleInput.focus(); + }, 500); +} + function renderToolboxTab(tabData) { currentToolboxData = tabData; const tabContent = document.getElementById(`toolbox-tab-content`); @@ -479,10 +723,11 @@ function renderToolboxTab(tabData) { } // Создаем навигацию по складам + const toolboxNav = `
${tabData.map((toolbox, index) => ` - +
+
+ `; + if (!toolboxInfo.owner_id && accessData.manage_toolboxes) { + document.getElementById('deleteToolbox').addEventListener('click', function (e) { + e.preventDefault(); + deleteToolbox(toolboxId); + }); + } else { + document.getElementById('deleteToolbox').remove(); + } + return; + } // Находим информацию о выбранном складе - const toolboxInfo = currentToolboxData.find(t => t.id === toolboxId); + const toolboxOwn = toolboxInfo.owner_id === userData.id ? 'Мой склад' : toolboxInfo.owner_id ? 'Склад сотрудника' : 'Общий склад'; const quantityMonitoring = toolboxInfo.monitoring && accessData.view_all_toolboxes; @@ -649,6 +935,182 @@ async function loadToolboxContent(toolboxId) { } } +async function deleteToolbox(toolboxId) { + // Находим информацию о складе + const toolboxInfo = currentToolboxData.find(t => t.id === toolboxId); + if (!toolboxInfo) { + showInfo('Склад не найден', 'error'); + return; + } + + // Проверяем, существует ли уже модальное окно + let modal = document.getElementById('deleteToolboxModal'); + + if (modal) { + modal.remove(); + } + + // Создаем модальное окно подтверждения + modal = document.createElement('div'); + modal.className = 'modal fade'; + modal.id = 'deleteToolboxModal'; + modal.tabIndex = -1; + modal.setAttribute('aria-hidden', 'true'); + + modal.innerHTML = ` + + `; + + document.body.appendChild(modal); + + // Инициализация модального окна + const bsModal = new bootstrap.Modal(modal); + + // Получаем элементы + const confirmCheckbox = modal.querySelector('#confirmDeleteCheckbox'); + const confirmBtn = modal.querySelector('#confirmDeleteBtn'); + const deleteSpinner = modal.querySelector('#deleteSpinner'); + + // Активация кнопки при подтверждении + confirmCheckbox.addEventListener('change', function () { + confirmBtn.disabled = !this.checked; + }); + + // Обработчик кнопки удаления + confirmBtn.addEventListener('click', async function () { + if (!confirmCheckbox.checked) return; + + // Показываем индикатор загрузки и отключаем кнопку + confirmBtn.disabled = true; + deleteSpinner.style.display = 'inline-block'; + + try { + // Отправляем запрос на удаление + const userId = userData.id; + const resp = await apiRequest('/toolbox/', { toolboxId, userId }, 'DELETE'); + + // Проверяем успешность запроса + if (resp.status == 'ok') { + // Успешное удаление + bsModal.hide(); + showInfo('Склад успешно удален', 'success'); + + await uploadTab('toolbox'); + + } else { + // Обработка ошибок от сервера + let errorMessage = 'Не удалось удалить склад'; + + if (resp.message) { + errorMessage += ': ' + resp.message; + } + + // Показываем конкретное сообщение об ошибке + showInfo(errorMessage, 'error'); + + // Возвращаем кнопку в исходное состояние + confirmBtn.disabled = false; + deleteSpinner.style.display = 'none'; + } + + } catch (error) { + console.error('Ошибка при удалении склада:', error); + + // Возвращаем кнопку в исходное состояние + confirmBtn.disabled = false; + deleteSpinner.style.display = 'none'; + + // Показываем общее сообщение об ошибке + showInfo('Произошла ошибка при удалении склада. Попробуйте еще раз.', 'error'); + } + }); + + // Очистка при закрытии модального окна + modal.addEventListener('hidden.bs.modal', () => { + // Удаляем модальное окно из DOM + setTimeout(() => { + if (modal.parentNode) { + modal.remove(); + } + }, 300); + }); + + // Показываем модальное окно + bsModal.show(); +} + // Функция обработки данных склада function processToolboxData(toolboxData, toolboxId, quantityMonitoring) { const { stocks, toolkits, categories } = toolboxData; @@ -1009,7 +1471,7 @@ async function initializeToolboxTable(data, toolboxOwn, quantityMonitoring) { async function getToolkitStocks(toolkitId) { const userId = userData.id; const allToolboxes = accessData.view_all_toolboxes; - const resp = await apiRequest('/stocks/toolkit', { toolkitId, userId, allToolboxes }); + const resp = await apiRequest('/toolkit/', { toolkitId, userId, allToolboxes }); return resp.data; } @@ -1272,6 +1734,7 @@ async function showOperationModal(operation, selectedItem) { if (success) { bsModal.hide(); + showInfo(`Запрос на ${operationTitles[operation]} успешно создан`, 'success'); await loadToolboxContent(selectedItem.toolboxId); } else { showError('Ошибка выполнения операции'); diff --git a/api/static/js/toast.js b/api/static/js/toast.js new file mode 100644 index 0000000..a57791a --- /dev/null +++ b/api/static/js/toast.js @@ -0,0 +1,68 @@ +// Вспомогательная функция для показа уведомлений с использованием Bootstrap Toasts +export function showInfo(message, type = 'info') { + // Создаем контейнер для тостов если его нет + let toastContainer = document.getElementById('toast-container'); + if (!toastContainer) { + toastContainer = document.createElement('div'); + toastContainer.id = 'toast-container'; + toastContainer.className = 'toast-container position-fixed top-0 end-0 p-3'; + toastContainer.style.cssText = ` + z-index: 99999; + max-width: 350px; + `; + document.body.appendChild(toastContainer); + } + + // Создаем уникальный ID для тоста + const toastId = 'toast-' + Date.now(); + + // Определяем классы в зависимости от типа + const typeConfig = { + 'success': { bgClass: 'bg-success', icon: 'bi-check-circle', delay: 5000 }, + 'error': { bgClass: 'bg-danger', icon: 'bi-exclamation-circle', delay: 10000 }, + 'info': { bgClass: 'bg-info', icon: 'bi-info-circle', delay: 3000 }, + 'warning': { bgClass: 'bg-warning', icon: 'bi-exclamation-triangle', delay: 8000 } + }; + + const config = typeConfig[type] || typeConfig.info; + + // Создаем тост + const toast = document.createElement('div'); + toast.className = `toast ${config.bgClass} text-white`; + toast.id = toastId; + toast.setAttribute('role', 'alert'); + toast.setAttribute('aria-live', 'assertive'); + toast.setAttribute('aria-atomic', 'true'); + + toast.innerHTML = ` +
+ + Уведомление + Только что + +
+
+ ${message} +
+ `; + + toastContainer.appendChild(toast); + + // Инициализируем и показываем тост + const bsToast = new bootstrap.Toast(toast, { + animation: true, + autohide: true, + delay: config.delay + }); + + bsToast.show(); + + // Удаляем тост после скрытия + toast.addEventListener('hidden.bs.toast', function () { + setTimeout(() => { + if (toast.parentNode) { + toast.remove(); + } + }, 300); + }); +} \ No newline at end of file diff --git a/db/handlers/__pycache__/toolkit.cpython-313.pyc b/db/handlers/__pycache__/toolkit.cpython-313.pyc index cfa9592..fa66782 100644 Binary files a/db/handlers/__pycache__/toolkit.cpython-313.pyc and b/db/handlers/__pycache__/toolkit.cpython-313.pyc differ diff --git a/db/handlers/__pycache__/user.cpython-313.pyc b/db/handlers/__pycache__/user.cpython-313.pyc index 375a4c1..a59aea7 100644 Binary files a/db/handlers/__pycache__/user.cpython-313.pyc and b/db/handlers/__pycache__/user.cpython-313.pyc differ diff --git a/db/handlers/user.py b/db/handlers/user.py index feb14a2..f4df3c2 100644 --- a/db/handlers/user.py +++ b/db/handlers/user.py @@ -59,7 +59,7 @@ class UserHandler: return {} if userAccessLevel.get("available_own_toolbox"): newToolboxData = { - "title": f"Т{newUser.username}", + "title": newUser.username, "description": f"Оборудование, полученное сотрудником {newUser.username}, под личную материальную ответственность", "owner_id": newUser.id, } @@ -110,7 +110,7 @@ class UserHandler: if not user.available_own_toolbox: if editedUser.available_own_toolbox: newToolboxData = { - "title": f"Тулбокс {editedUser.username}", + "title": editedUser.username, "description": f"Оборудование, полученное сотрудником '{editedUser.username}' под личную материальную ответственность", "owner_id": editedUser.id, } diff --git a/main.py b/main.py index 5e2761f..598c13e 100644 --- a/main.py +++ b/main.py @@ -23,8 +23,8 @@ async def main(): from db.initialize import DatabaseInitializer try: - force = True - reNewDB = True + force = False + reNewDB = False await DatabaseInitializer(DATABASE_URL).initialize(force, reNewDB) except Exception as e: logger.error(f"Инициализация базы завершилась ошибкой: {str(e)}", exc_info=True)