Feature: разделители в поле Цена, убраны стрелки в Цена и Количество

Made-with: Cursor
This commit is contained in:
2026-02-26 13:07:04 +00:00
parent 7b596a4dc2
commit a2577ed3eb
5 changed files with 57 additions and 0 deletions

View File

@@ -1,5 +1,15 @@
# История изменений ERP WaterSurf
## 2025-02-25 23:30 UTC Поле Цена: разделители числа, без стрелок в Цена и Количество
**Проблема**: В поле «Цена» не было разделителей разрядов; стрелки вверх/вниз в полях «Цена» и «Количество» мешали.
**Решение**: Поле «Цена» выводится как текст (TextInput с inputmode="decimal"): при потере фокуса значение форматируется с неразрывными пробелами и запятой как десятичный разделитель; при фокусе показывается «сырое» число для редактирования; при загрузке страницы существующие цены форматируются. Перед отправкой формы пробелы и запятая по-прежнему снимаются. У полей «Количество» (type="number») скрыты спиннеры через CSS (-moz-appearance: textfield и ::-webkit-inner-spin-button).
**Изменения**: documents/forms.py (виджет price — TextInput), order_form.html и supplier_order_form.html (focusin/focusout для форматирования цены, начальное форматирование), theme-compact.css (скрытие спиннеров у .ws-col-qty input[type="number"]).
---
## 2025-02-25 23:15 UTC Удаление строки табличной части по кнопке-крестику
**Проблема**: Удаление строки происходило при сохранении документа (чекбокс «Удалить»), что было неочевидно и неудобно.

View File

@@ -17,6 +17,7 @@ class CustomerOrderItemForm(forms.ModelForm):
model = CustomerOrderItem
fields = ("product", "price", "currency", "quantity")
widgets = {
"price": forms.TextInput(attrs={"inputmode": "decimal", "class": "ws-price-input"}),
"quantity": forms.NumberInput(attrs={"size": 3, "min": 0, "max": 99, "style": "width: 4ch"}),
}
@@ -26,6 +27,7 @@ class SupplierOrderItemForm(forms.ModelForm):
model = SupplierOrderItem
fields = ("product", "price", "currency", "quantity")
widgets = {
"price": forms.TextInput(attrs={"inputmode": "decimal", "class": "ws-price-input"}),
"quantity": forms.NumberInput(attrs={"size": 3, "min": 0, "max": 99, "style": "width: 4ch"}),
}

View File

@@ -167,6 +167,17 @@
box-sizing: border-box;
}
/* Убрать стрелки вверх/вниз у поля Количество (Цена — text, без стрелок) */
.ws-table-items .ws-col-qty input[type="number"] {
-moz-appearance: textfield;
}
.ws-table-items .ws-col-qty input[type="number"]::-webkit-outer-spin-button,
.ws-table-items .ws-col-qty input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.ws-table-items .ws-col-currency select {
max-width: 100%;
}

View File

@@ -131,7 +131,24 @@
});
});
form.addEventListener('focusin', function(e) {
if (e.target.name && e.target.name.indexOf('-price') !== -1) {
var n = parseNum(e.target.value);
e.target.value = (e.target.value.trim() === '' || isNaN(n)) ? '' : n.toFixed(2);
}
});
form.addEventListener('focusout', function(e) {
if (e.target.name && e.target.name.indexOf('-price') !== -1) {
if (e.target.value.trim() === '') return;
var n = parseNum(e.target.value);
e.target.value = isNaN(n) ? '' : formatNum(n);
}
});
updateRowAmounts();
form.querySelectorAll('input[name$="-price"]').forEach(function(input) {
if (input.value && input.value.trim() !== '') input.value = formatNum(parseNum(input.value));
});
function reindexRows() {
var prefix = getPrefix();

View File

@@ -136,7 +136,24 @@
});
});
form.addEventListener('focusin', function(e) {
if (e.target.name && e.target.name.indexOf('-price') !== -1) {
var n = parseNum(e.target.value);
e.target.value = (e.target.value.trim() === '' || isNaN(n)) ? '' : n.toFixed(2);
}
});
form.addEventListener('focusout', function(e) {
if (e.target.name && e.target.name.indexOf('-price') !== -1) {
if (e.target.value.trim() === '') return;
var n = parseNum(e.target.value);
e.target.value = isNaN(n) ? '' : formatNum(n);
}
});
updateRowAmounts();
form.querySelectorAll('input[name$="-price"]').forEach(function(input) {
if (input.value && input.value.trim() !== '') input.value = formatNum(parseNum(input.value));
});
function reindexRows() {
var prefix = getPrefix();