From 1ead77b2d8943daad15d51b2277987df028c413b Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Fri, 2 Jan 2026 15:38:41 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=BE=D0=BA=D1=80=D1=83=D0=B3=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=BB=D0=B8=D1=87=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=B2=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=BE=D1=80=D1=80?= =?UTF-8?q?=D0=B5=D0=BA=D1=82=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B2=20POS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Проблема: - JavaScript float arithmetic даёт погрешность при вычислениях - На карточке товара показывалось -0.050000000000044 - Происходило при: available - reserved - inCart Решение: - Добавлена функция roundQuantity(value, decimals=3) - Округляет результат вычислений до 3 знаков после запятой - Применяется ТОЛЬКО для отображения, не для расчётов - Используется для: free, reserved, inCart в карточках товаров Результат: - Отображение: -0.05 вместо -0.050000000000044 - Данные с бэка остаются точными (строка) - Погрешность устранена только визуально Примечание: - Округление в JS НЕИЗБЕЖНО для отображения - Это НЕ маскировка - это правильное форматирование - Бэкенд уже отдаёт точные данные как строки --- myproject/pos/static/pos/js/terminal.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/myproject/pos/static/pos/js/terminal.js b/myproject/pos/static/pos/js/terminal.js index c7c01c3..a8aa483 100644 --- a/myproject/pos/static/pos/js/terminal.js +++ b/myproject/pos/static/pos/js/terminal.js @@ -1,5 +1,17 @@ // POS Terminal JavaScript +/** + * Округляет число до N знаков после запятой для корректного отображения. + * Решает проблему погрешности float arithmetic в JavaScript. + * @param {number} value - Число для округления + * @param {number} decimals - Количество знаков после запятой (по умолчанию 3) + * @returns {number} Округлённое число + */ +function roundQuantity(value, decimals = 3) { + if (value === null || value === undefined || isNaN(value)) return 0; + return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals); +} + const CATEGORIES = JSON.parse(document.getElementById('categoriesData').textContent); let ITEMS = []; // Будем загружать через API let showcaseKits = JSON.parse(document.getElementById('showcaseKitsData').textContent); @@ -595,10 +607,11 @@ function renderProducts() { const inCart = cart.has(cartKey) ? cart.get(cartKey).qty : 0; const free = available - reserved - inCart; + const freeRounded = roundQuantity(free, 3); // Округляем для отображения // Создаём элементы для стилизации разных размеров const freeSpan = document.createElement('span'); - freeSpan.textContent = free; + freeSpan.textContent = freeRounded; // Используем округлённое значение freeSpan.style.fontSize = '1.1em'; freeSpan.style.fontWeight = 'bold'; freeSpan.style.fontStyle = 'normal'; @@ -606,10 +619,10 @@ function renderProducts() { // Отображаем резерв и корзину если они есть const suffixParts = []; if (reserved > 0) { - suffixParts.push(`−${reserved}`); + suffixParts.push(`−${roundQuantity(reserved, 3)}`); } if (inCart > 0) { - suffixParts.push(`−${inCart}🛒`); + suffixParts.push(`−${roundQuantity(inCart, 3)}🛒`); } if (suffixParts.length > 0) {